Merge commit '098bd31b7f838a31cce08db4091e989ea42f3ef6'

pull/643/head
Wilfred Hughes 2024-02-13 08:35:07 +07:00
commit a721bef7a7
37 changed files with 129225 additions and 57210 deletions

@ -1,5 +1,9 @@
## 0.56 (unreleased) ## 0.56 (unreleased)
### Parsing
Updated JavaScript parser.
## 0.55 (released 1st February 2024) ## 0.55 (released 1st February 2024)
### Parsing ### Parsing

@ -0,0 +1,20 @@
module.exports = {
'env': {
'commonjs': true,
'es2021': true,
},
'extends': 'google',
'overrides': [
],
'parserOptions': {
'ecmaVersion': 'latest',
'sourceType': 'module',
},
'rules': {
'indent': ['error', 2, {'SwitchCase': 1}],
'max-len': [
'error',
{'code': 120, 'ignoreComments': true, 'ignoreUrls': true, 'ignoreStrings': true},
],
},
};

@ -1,2 +1,6 @@
/src/** linguist-vendored
/examples/* linguist-vendored /examples/* linguist-vendored
src/tree_sitter/* linguist-generated
src/grammar.json linguist-generated
src/node-types.json linguist-generated
src/parser.c linguist-generated

@ -1,8 +1,12 @@
name: CI name: CI
on: on:
workflow_dispatch: workflow_dispatch:
pull_request:
push: push:
branches:
- master
pull_request:
branches:
- "**"
jobs: jobs:
test: test:

@ -0,0 +1,22 @@
name: Fuzz Parser
on:
push:
paths:
- src/scanner.c
pull_request:
paths:
- src/scanner.c
workflow_dispatch:
jobs:
test:
name: Parser fuzzing
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: vigoux/tree-sitter-fuzz-action@v1
with:
language: javascript
external-scanner: src/scanner.c
time: 60

@ -0,0 +1,19 @@
name: Lint
on:
push:
branches:
- master
pull_request:
branches:
- "**"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install modules
run: npm install
- name: Run ESLint
run: npm run lint

@ -0,0 +1,103 @@
name: Release
on:
workflow_run:
workflows: ["CI"]
branches:
- master
types:
- completed
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get previous commit SHA
id: get_previous_commit
run: |
LATEST_TAG=$(git describe --tags --abbrev=0)
if [[ -z "$LATEST_TAG" ]]; then
echo "No tag found. Failing..."
exit 1
fi
echo "latest_tag=${LATEST_TAG#v}" >> "$GITHUB_ENV" # Remove 'v' prefix from the tag
- name: Check if version changed and is greater than the previous
id: version_check
run: |
# Compare the current version with the version from the previous commit
PREVIOUS_NPM_VERSION=${{ env.latest_tag }}
CURRENT_NPM_VERSION=$(jq -r '.version' package.json)
CURRENT_CARGO_VERSION=$(awk -F '"' '/^version/ {print $2}' Cargo.toml)
if [[ "$CURRENT_NPM_VERSION" != "$CURRENT_CARGO_VERSION" ]]; then # Cargo.toml and package.json versions must match
echo "Mismatch: NPM version ($CURRENT_NPM_VERSION) and Cargo.toml version ($CURRENT_CARGO_VERSION)"
echo "version_changed=false" >> "$GITHUB_ENV"
else
if [[ "$PREVIOUS_NPM_VERSION" == "$CURRENT_NPM_VERSION" ]]; then
echo "version_changed=" >> "$GITHUB_ENV"
else
IFS='.' read -ra PREVIOUS_VERSION_PARTS <<< "$PREVIOUS_NPM_VERSION"
IFS='.' read -ra CURRENT_VERSION_PARTS <<< "$CURRENT_NPM_VERSION"
VERSION_CHANGED=false
for i in "${!PREVIOUS_VERSION_PARTS[@]}"; do
if [[ ${CURRENT_VERSION_PARTS[i]} -gt ${PREVIOUS_VERSION_PARTS[i]} ]]; then
VERSION_CHANGED=true
break
elif [[ ${CURRENT_VERSION_PARTS[i]} -lt ${PREVIOUS_VERSION_PARTS[i]} ]]; then
break
fi
done
echo "version_changed=$VERSION_CHANGED" >> "$GITHUB_ENV"
echo "current_version=${CURRENT_NPM_VERSION}" >> "$GITHUB_ENV"
fi
fi
- name: Display result
run: |
echo "Version bump detected: ${{ env.version_changed }}"
- name: Fail if version is lower
if: env.version_changed == 'false'
run: exit 1
- name: Setup Node
if: env.version_changed == 'true'
uses: actions/setup-node@v3
with:
node-version: 18
registry-url: "https://registry.npmjs.org"
- name: Publish to NPM
if: env.version_changed == 'true'
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: npm publish
- name: Setup Rust
if: env.version_changed == 'true'
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Publish to Crates.io
if: env.version_changed == 'true'
uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Tag versions
if: env.version_changed == 'true'
run: |
git checkout master
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git tag -d "v${{ env.current_version }}" || true
git push origin --delete "v${{ env.current_version }}" || true
git tag -a "v${{ env.current_version }}" -m "Version ${{ env.current_version }}"
git push origin "v${{ env.current_version }}"

@ -1,33 +0,0 @@
name: Publish on crates.io
on:
push:
tags:
- v*
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Rust stable
run: |
rustup toolchain install stable --profile minimal --no-self-update
- name: Verify publish crate
uses: katyo/publish-crates@v1
with:
dry-run: true
- name: Publish crate
uses: katyo/publish-crates@v1
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}

@ -1,10 +1,7 @@
Cargo.lock Cargo.lock
package-lock.json
node_modules node_modules
.node-version
build build
*.log *.log
/test.js /examples/*/
/examples/npm
package-lock.json
/target/ /target/
.build/

@ -1,7 +1,6 @@
test /test
build /examples
script /build
examples /script
*.log /target
test.js bindings/rust
target

@ -1,31 +1,27 @@
[package] [package]
name = "tree-sitter-javascript" name = "tree-sitter-javascript"
description = "JavaScript grammar for the tree-sitter parsing library" description = "JavaScript grammar for tree-sitter"
version = "0.20.0" version = "0.20.3"
authors = [ authors = [
"Max Brunsfeld <maxbrunsfeld@gmail.com>", "Max Brunsfeld <maxbrunsfeld@gmail.com>",
"Douglas Creager <dcreager@dcreager.net>", "Douglas Creager <dcreager@dcreager.net>",
"Amaan Qureshi <amaanq12@gmail.com>",
] ]
license = "MIT" license = "MIT"
readme = "bindings/rust/README.md" readme = "bindings/rust/README.md"
keywords = ["incremental", "parsing", "javascript"] keywords = ["incremental", "parsing", "javascript"]
categories = ["parsing", "text-editors"] categories = ["parsing", "text-editors"]
repository = "https://github.com/tree-sitter/tree-sitter-javascript" repository = "https://github.com/tree-sitter/tree-sitter-javascript"
edition = "2018" edition = "2021"
autoexamples = false
build = "bindings/rust/build.rs" build = "bindings/rust/build.rs"
include = [ include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"]
"bindings/rust/*",
"grammar.js",
"queries/*",
"src/*",
]
[lib] [lib]
path = "bindings/rust/lib.rs" path = "bindings/rust/lib.rs"
[dependencies] [dependencies]
tree-sitter = ">= 0.19, < 0.21" tree-sitter = "~0.20.10"
[build-dependencies] [build-dependencies]
cc = "1.0" cc = "~1.0.83"

@ -1,7 +1,6 @@
tree-sitter-javascript # tree-sitter-javascript
===========================
[![CI Status](https://github.com/tree-sitter/tree-sitter-javascript/actions/workflows/ci.yml/badge.svg)](https://github.com/tree-sitter/tree-sitter-javascript/actions/workflows/ci.yml) [![CI](https://github.com/tree-sitter/tree-sitter-javascript/actions/workflows/ci.yml/badge.svg)](https://github.com/tree-sitter/tree-sitter-javascript/actions/workflows/ci.yml)
JavaScript and JSX grammar for [tree-sitter][]. For TypeScript, see [tree-sitter-typescript][]. JavaScript and JSX grammar for [tree-sitter][]. For TypeScript, see [tree-sitter-typescript][].
@ -10,5 +9,5 @@ JavaScript and JSX grammar for [tree-sitter][]. For TypeScript, see [tree-sitter
References References
* [The ESTree Spec](https://github.com/estree/estree) - [The ESTree Spec](https://github.com/estree/estree)
* [The ECMAScript 2015 Spec](http://www.ecma-international.org/ecma-262/6.0/) - [The ECMAScript 2015 Spec](http://www.ecma-international.org/ecma-262/6.0/)

@ -1,15 +1,15 @@
# tree-sitter-javascript # tree-sitter-javascript
This crate provides a JavaScript grammar for the [tree-sitter][] parsing This crate provides a JavaScript grammar for the [tree-sitter][] parsing
library. To use this crate, add it to the `[dependencies]` section of your library. To use this crate, add it to the `[dependencies]` section of your
`Cargo.toml` file. (Note that you will probably also need to depend on the `Cargo.toml` file. (Note that you will probably also need to depend on the
[`tree-sitter`][tree-sitter crate] crate to use the parsed result in any useful [`tree-sitter`][tree-sitter crate] crate to use the parsed result in any useful
way.) way.)
``` toml ```toml
[dependencies] [dependencies]
tree-sitter = "0.20" tree-sitter = "~0.20.10"
tree-sitter-javascript = "0.20" tree-sitter-javascript = "~0.20.3"
``` ```
Typically, you will use the [language][language func] function to add this Typically, you will use the [language][language func] function to add this
@ -18,7 +18,7 @@ grammar to a tree-sitter [Parser][], and then use the parser to parse some code.
The below example demonstrates a simple program that parses a JavaScript The below example demonstrates a simple program that parses a JavaScript
function and prints the result to your terminal. function and prints the result to your terminal.
``` rust ```rust
use tree_sitter::Parser; use tree_sitter::Parser;
fn main() { fn main() {
@ -39,7 +39,6 @@ fn main() {
If you have any questions, please reach out to us in the [tree-sitter If you have any questions, please reach out to us in the [tree-sitter
discussions] page. discussions] page.
[Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
[language func]: https://docs.rs/tree-sitter-javascript/*/tree_sitter_javascript/fn.language.html [language func]: https://docs.rs/tree-sitter-javascript/*/tree_sitter_javascript/fn.language.html
[Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
[tree-sitter]: https://tree-sitter.github.io/ [tree-sitter]: https://tree-sitter.github.io/

@ -5,7 +5,7 @@ fn main() {
let src_dir = Path::new("src"); let src_dir = Path::new("src");
let mut c_config = cc::Build::new(); let mut c_config = cc::Build::new();
c_config.include(&src_dir); c_config.include(src_dir);
c_config c_config
.flag_if_supported("-Wno-unused-parameter") .flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable") .flag_if_supported("-Wno-unused-but-set-variable")

@ -44,27 +44,27 @@ pub fn language() -> Language {
} }
/// The source of the JavaScript tree-sitter grammar description. /// The source of the JavaScript tree-sitter grammar description.
pub const GRAMMAR: &'static str = include_str!("../../grammar.js"); pub const GRAMMAR: &str = include_str!("../../grammar.js");
/// The syntax highlighting query for this language. /// The syntax highlighting query for this language.
pub const HIGHLIGHT_QUERY: &'static str = include_str!("../../queries/highlights.scm"); pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.scm");
/// The syntax highlighting query for languages injected into this one. /// The syntax highlighting query for languages injected into this one.
pub const INJECTION_QUERY: &'static str = include_str!("../../queries/injections.scm"); pub const INJECTION_QUERY: &str = include_str!("../../queries/injections.scm");
/// The syntax highlighting query for JSX. /// The syntax highlighting query for JSX.
pub const JSX_HIGHLIGHT_QUERY: &'static str = include_str!("../../queries/highlights-jsx.scm"); pub const JSX_HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights-jsx.scm");
/// The local-variable syntax highlighting query for this language. /// The local-variable syntax highlighting query for this language.
pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm"); pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
/// The content of the [`node-types.json`][] file for this grammar. /// The content of the [`node-types.json`][] file for this grammar.
/// ///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json"); pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
/// The symbol tagging query for this language. /// The symbol tagging query for this language.
pub const TAGGING_QUERY: &'static str = include_str!("../../queries/tags.scm"); pub const TAGGING_QUERY: &str = include_str!("../../queries/tags.scm");
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

File diff suppressed because it is too large Load Diff

@ -1,11 +1,12 @@
{ {
"name": "tree-sitter-javascript", "name": "tree-sitter-javascript",
"version": "0.20.0", "version": "0.20.3",
"description": "Javascript grammar for node-tree-sitter", "description": "JavaScript grammar for tree-sitter",
"main": "bindings/node", "main": "bindings/node",
"keywords": [ "keywords": [
"parser", "parser",
"lexer" "lexer",
"javascript"
], ],
"repository": { "repository": {
"type": "git", "type": "git",
@ -14,12 +15,17 @@
"author": "Max Brunsfeld", "author": "Max Brunsfeld",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"nan": "^2.12.1" "nan": "^2.18.0"
}, },
"devDependencies": { "devDependencies": {
"tree-sitter-cli": "^0.20.0" "eslint": "^8.56.0",
"eslint-config-google": "^0.14.0",
"tree-sitter-cli": "^0.20.8"
}, },
"scripts": { "scripts": {
"build": "tree-sitter generate && node-gyp build",
"lint": "eslint grammar.js",
"parse": "tree-sitter parse",
"test": "tree-sitter test && script/parse-examples", "test": "tree-sitter test && script/parse-examples",
"test-windows": "tree-sitter test" "test-windows": "tree-sitter test"
}, },

@ -1,4 +1,8 @@
(jsx_opening_element (identifier) @tag) (jsx_opening_element (identifier) @tag (#match? @tag "^[a-z][^.]*$"))
(jsx_closing_element (identifier) @tag) (jsx_closing_element (identifier) @tag (#match? @tag "^[a-z][^.]*$"))
(jsx_self_closing_element (identifier) @tag) (jsx_self_closing_element (identifier) @tag (#match? @tag "^[a-z][^.]*$"))
(jsx_attribute (property_identifier) @attribute) (jsx_attribute (property_identifier) @attribute)
(jsx_opening_element (["<" ">"]) @punctuation.bracket)
(jsx_closing_element (["</" ">"]) @punctuation.bracket)
(jsx_self_closing_element (["<" "/>"]) @punctuation.bracket)

@ -23,7 +23,7 @@
; Function and method definitions ; Function and method definitions
;-------------------------------- ;--------------------------------
(function (function_expression
name: (identifier) @function) name: (identifier) @function)
(function_declaration (function_declaration
name: (identifier) @function) name: (identifier) @function)
@ -32,20 +32,20 @@
(pair (pair
key: (property_identifier) @function.method key: (property_identifier) @function.method
value: [(function) (arrow_function)]) value: [(function_expression) (arrow_function)])
(assignment_expression (assignment_expression
left: (member_expression left: (member_expression
property: (property_identifier) @function.method) property: (property_identifier) @function.method)
right: [(function) (arrow_function)]) right: [(function_expression) (arrow_function)])
(variable_declarator (variable_declarator
name: (identifier) @function name: (identifier) @function
value: [(function) (arrow_function)]) value: [(function_expression) (arrow_function)])
(assignment_expression (assignment_expression
left: (identifier) @function left: (identifier) @function
right: [(function) (arrow_function)]) right: [(function_expression) (arrow_function)])
; Function and method calls ; Function and method calls
;-------------------------- ;--------------------------

@ -7,7 +7,10 @@
(member_expression (member_expression
property: (property_identifier) @injection.language) property: (property_identifier) @injection.language)
] ]
arguments: (template_string) @injection.content) arguments: (template_string (string_fragment) @injection.content)
(#set! injection.combined)
(#set! injection.include-children))
; Parse regex syntax within regex literals ; Parse regex syntax within regex literals

@ -3,7 +3,7 @@
[ [
(statement_block) (statement_block)
(function) (function_expression)
(arrow_function) (arrow_function)
(function_declaration) (function_declaration)
(method_definition) (method_definition)

@ -25,7 +25,7 @@
(comment)* @doc (comment)* @doc
. .
[ [
(function (function_expression
name: (identifier) @name) name: (identifier) @name)
(function_declaration (function_declaration
name: (identifier) @name) name: (identifier) @name)
@ -44,7 +44,7 @@
(lexical_declaration (lexical_declaration
(variable_declarator (variable_declarator
name: (identifier) @name name: (identifier) @name
value: [(arrow_function) (function)]) @definition.function) value: [(arrow_function) (function_expression)]) @definition.function)
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$") (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
(#select-adjacent! @doc @definition.function) (#select-adjacent! @doc @definition.function)
) )
@ -55,7 +55,7 @@
(variable_declaration (variable_declaration
(variable_declarator (variable_declarator
name: (identifier) @name name: (identifier) @name
value: [(arrow_function) (function)]) @definition.function) value: [(arrow_function) (function_expression)]) @definition.function)
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$") (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
(#select-adjacent! @doc @definition.function) (#select-adjacent! @doc @definition.function)
) )
@ -66,12 +66,12 @@
(member_expression (member_expression
property: (property_identifier) @name) property: (property_identifier) @name)
] ]
right: [(arrow_function) (function)] right: [(arrow_function) (function_expression)]
) @definition.function ) @definition.function
(pair (pair
key: (property_identifier) @name key: (property_identifier) @name
value: [(arrow_function) (function)]) @definition.function value: [(arrow_function) (function_expression)]) @definition.function
( (
(call_expression (call_expression

@ -1 +0,0 @@
examples/npm/node_modules/slide/lib/async-map-ordered.js

@ -25,7 +25,7 @@ function clone_repo {
popd > /dev/null popd > /dev/null
} }
clone_repo npm npm ee147fbbca6f2707d3b16f4fa78f4c4606b2d9b1 clone_repo npm cli 0dd03f9450e0cf57fa85ad2ef74b5a54f3c775a9
known_failures="$(cat script/known_failures.txt)" known_failures="$(cat script/known_failures.txt)"

@ -359,6 +359,18 @@
} }
] ]
}, },
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "import_attribute"
},
{
"type": "BLANK"
}
]
},
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_semicolon" "name": "_semicolon"
@ -547,6 +559,19 @@
} }
] ]
}, },
"import_attribute": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "with"
},
{
"type": "SYMBOL",
"name": "object"
}
]
},
"statement": { "statement": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@ -1170,37 +1195,49 @@
] ]
}, },
"do_statement": { "do_statement": {
"type": "SEQ", "type": "PREC_RIGHT",
"members": [ "value": 0,
{ "content": {
"type": "STRING", "type": "SEQ",
"value": "do" "members": [
}, {
{ "type": "STRING",
"type": "FIELD", "value": "do"
"name": "body", },
"content": { {
"type": "SYMBOL", "type": "FIELD",
"name": "statement" "name": "body",
} "content": {
}, "type": "SYMBOL",
{ "name": "statement"
"type": "STRING", }
"value": "while" },
}, {
{ "type": "STRING",
"type": "FIELD", "value": "while"
"name": "condition", },
"content": { {
"type": "SYMBOL", "type": "FIELD",
"name": "parenthesized_expression" "name": "condition",
"content": {
"type": "SYMBOL",
"name": "parenthesized_expression"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_semicolon"
},
{
"type": "BLANK"
}
]
} }
}, ]
{ }
"type": "SYMBOL",
"name": "_semicolon"
}
]
}, },
"try_statement": { "try_statement": {
"type": "SEQ", "type": "SEQ",
@ -1648,10 +1685,6 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "_jsx_element" "name": "_jsx_element"
}, },
{
"type": "SYMBOL",
"name": "jsx_fragment"
},
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "assignment_expression" "name": "assignment_expression"
@ -1754,10 +1787,6 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "null" "name": "null"
}, },
{
"type": "SYMBOL",
"name": "import"
},
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "object" "name": "object"
@ -1768,7 +1797,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "function" "name": "function_expression"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -2445,41 +2474,22 @@
} }
] ]
}, },
"jsx_fragment": { "jsx_text": {
"type": "SEQ", "type": "CHOICE",
"members": [ "members": [
{ {
"type": "STRING", "type": "PATTERN",
"value": "<" "value": "[^{}<>\\n& ]([^{}<>\\n&]*[^{}<>\\n& ])?"
},
{
"type": "STRING",
"value": ">"
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_jsx_child"
}
},
{
"type": "STRING",
"value": "<"
},
{
"type": "STRING",
"value": "/"
}, },
{ {
"type": "STRING", "type": "PATTERN",
"value": ">" "value": "\\/\\/[^\\n]*"
} }
] ]
}, },
"jsx_text": { "html_character_reference": {
"type": "PATTERN", "type": "PATTERN",
"value": "[^{}<>]+" "value": "&(#([xX][0-9a-fA-F]{1,6}|[0-9]{1,5})|[A-Za-z]{1,30});"
}, },
"jsx_expression": { "jsx_expression": {
"type": "SEQ", "type": "SEQ",
@ -2528,11 +2538,11 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_jsx_element" "name": "html_character_reference"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "jsx_fragment" "name": "_jsx_element"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -2551,23 +2561,36 @@
"value": "<" "value": "<"
}, },
{ {
"type": "FIELD", "type": "CHOICE",
"name": "name", "members": [
"content": { {
"type": "SYMBOL", "type": "SEQ",
"name": "_jsx_element_name" "members": [
} {
}, "type": "FIELD",
{ "name": "name",
"type": "REPEAT", "content": {
"content": { "type": "SYMBOL",
"type": "FIELD", "name": "_jsx_element_name"
"name": "attribute", }
"content": { },
"type": "SYMBOL", {
"name": "_jsx_attribute" "type": "REPEAT",
"content": {
"type": "FIELD",
"name": "attribute",
"content": {
"type": "SYMBOL",
"name": "_jsx_attribute"
}
}
}
]
},
{
"type": "BLANK"
} }
} ]
}, },
{ {
"type": "STRING", "type": "STRING",
@ -2605,25 +2628,43 @@
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "CHOICE", "type": "FIELD",
"members": [ "name": "object",
{ "content": {
"type": "SYMBOL", "type": "CHOICE",
"name": "identifier" "members": [
}, {
{ "type": "SYMBOL",
"type": "SYMBOL", "name": "identifier"
"name": "nested_identifier" },
} {
] "type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "nested_identifier"
},
"named": true,
"value": "member_expression"
}
]
}
}, },
{ {
"type": "STRING", "type": "STRING",
"value": "." "value": "."
}, },
{ {
"type": "SYMBOL", "type": "FIELD",
"name": "identifier" "name": "property",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "identifier"
},
"named": true,
"value": "property_identifier"
}
} }
] ]
} }
@ -2653,8 +2694,13 @@
"name": "_jsx_identifier" "name": "_jsx_identifier"
}, },
{ {
"type": "SYMBOL", "type": "ALIAS",
"name": "nested_identifier" "content": {
"type": "SYMBOL",
"name": "nested_identifier"
},
"named": true,
"value": "member_expression"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -2667,19 +2713,23 @@
"members": [ "members": [
{ {
"type": "STRING", "type": "STRING",
"value": "<" "value": "</"
},
{
"type": "STRING",
"value": "/"
}, },
{ {
"type": "FIELD", "type": "CHOICE",
"name": "name", "members": [
"content": { {
"type": "SYMBOL", "type": "FIELD",
"name": "_jsx_element_name" "name": "name",
} "content": {
"type": "SYMBOL",
"name": "_jsx_element_name"
}
},
{
"type": "BLANK"
}
]
}, },
{ {
"type": "STRING", "type": "STRING",
@ -2715,11 +2765,7 @@
}, },
{ {
"type": "STRING", "type": "STRING",
"value": "/" "value": "/>"
},
{
"type": "STRING",
"value": ">"
} }
] ]
}, },
@ -2778,18 +2824,118 @@
] ]
}, },
{ {
"type": "BLANK" "type": "BLANK"
}
]
}
]
},
"_jsx_string": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\""
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "unescaped_double_jsx_string_fragment"
},
"named": true,
"value": "string_fragment"
},
{
"type": "SYMBOL",
"name": "html_character_reference"
}
]
}
},
{
"type": "STRING",
"value": "\""
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "'"
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "unescaped_single_jsx_string_fragment"
},
"named": true,
"value": "string_fragment"
},
{
"type": "SYMBOL",
"name": "html_character_reference"
}
]
}
},
{
"type": "STRING",
"value": "'"
} }
] ]
} }
] ]
}, },
"unescaped_double_jsx_string_fragment": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PREC",
"value": 1,
"content": {
"type": "PATTERN",
"value": "[^\"&]+"
}
}
},
"unescaped_single_jsx_string_fragment": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PREC",
"value": 1,
"content": {
"type": "PATTERN",
"value": "[^'&]+"
}
}
},
"_jsx_attribute_value": { "_jsx_attribute_value": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "ALIAS",
"name": "string" "content": {
"type": "SYMBOL",
"name": "_jsx_string"
},
"named": true,
"value": "string"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -2798,10 +2944,6 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_jsx_element" "name": "_jsx_element"
},
{
"type": "SYMBOL",
"name": "jsx_fragment"
} }
] ]
}, },
@ -2942,7 +3084,7 @@
} }
] ]
}, },
"function": { "function_expression": {
"type": "PREC", "type": "PREC",
"value": "literal", "value": "literal",
"content": { "content": {
@ -3277,8 +3419,17 @@
"type": "FIELD", "type": "FIELD",
"name": "function", "name": "function",
"content": { "content": {
"type": "SYMBOL", "type": "CHOICE",
"name": "expression" "members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "import"
}
]
} }
}, },
{ {
@ -3422,6 +3573,10 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "primary_expression" "name": "primary_expression"
},
{
"type": "SYMBOL",
"name": "import"
} }
] ]
} }
@ -4612,8 +4767,17 @@
"type": "FIELD", "type": "FIELD",
"name": "left", "name": "left",
"content": { "content": {
"type": "SYMBOL", "type": "CHOICE",
"name": "expression" "members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "private_property_identifier"
}
]
} }
}, },
{ {
@ -4761,38 +4925,33 @@
} }
}, },
"sequence_expression": { "sequence_expression": {
"type": "SEQ", "type": "PREC_RIGHT",
"members": [ "value": 0,
{ "content": {
"type": "FIELD", "type": "SEQ",
"name": "left", "members": [
"content": { {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expression" "name": "expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "expression"
}
]
}
} }
}, ]
{ }
"type": "STRING",
"value": ","
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "sequence_expression"
},
{
"type": "SYMBOL",
"name": "expression"
}
]
}
}
]
}, },
"string": { "string": {
"type": "CHOICE", "type": "CHOICE",
@ -4874,7 +5033,7 @@
"value": 1, "value": 1,
"content": { "content": {
"type": "PATTERN", "type": "PATTERN",
"value": "[^\"\\\\]+" "value": "[^\"\\\\\\r\\n]+"
} }
} }
}, },
@ -4885,7 +5044,7 @@
"value": 1, "value": 1,
"content": { "content": {
"type": "PATTERN", "type": "PATTERN",
"value": "[^'\\\\]+" "value": "[^'\\\\\\r\\n]+"
} }
} }
}, },
@ -4920,6 +5079,10 @@
{ {
"type": "PATTERN", "type": "PATTERN",
"value": "u{[0-9a-fA-F]+}" "value": "u{[0-9a-fA-F]+}"
},
{
"type": "PATTERN",
"value": "[\\r?][\\n\\u2028\\u2029]"
} }
] ]
} }
@ -4927,68 +5090,47 @@
} }
}, },
"comment": { "comment": {
"type": "TOKEN", "type": "CHOICE",
"content": { "members": [
"type": "CHOICE", {
"members": [ "type": "TOKEN",
{ "content": {
"type": "SEQ", "type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "//"
},
{
"type": "PATTERN",
"value": ".*"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "/*"
},
{
"type": "PATTERN",
"value": "[^*]*\\*+([^/*][^*]*\\*+)*"
},
{
"type": "STRING",
"value": "/"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<!--"
},
{
"type": "PATTERN",
"value": ".*"
}
]
},
{
"type": "SEQ",
"members": [ "members": [
{ {
"type": "STRING", "type": "SEQ",
"value": "-->" "members": [
{
"type": "STRING",
"value": "//"
},
{
"type": "PATTERN",
"value": ".*"
}
]
}, },
{ {
"type": "PATTERN", "type": "SEQ",
"value": ".*" "members": [
{
"type": "STRING",
"value": "/*"
},
{
"type": "PATTERN",
"value": "[^*]*\\*+([^/*][^*]*\\*+)*"
},
{
"type": "STRING",
"value": "/"
}
]
} }
] ]
} }
] }
} ]
}, },
"template_string": { "template_string": {
"type": "SEQ", "type": "SEQ",
@ -5003,8 +5145,13 @@
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "ALIAS",
"name": "_template_chars" "content": {
"type": "SYMBOL",
"name": "_template_chars"
},
"named": true,
"value": "string_fragment"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -5058,8 +5205,12 @@
{ {
"type": "IMMEDIATE_TOKEN", "type": "IMMEDIATE_TOKEN",
"content": { "content": {
"type": "STRING", "type": "PREC",
"value": "/" "value": 1,
"content": {
"type": "STRING",
"value": "/"
}
} }
}, },
{ {
@ -6014,6 +6165,10 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "glimmer_template" "name": "glimmer_template"
} }
},
{
"type": "STRING",
"value": ";"
} }
] ]
} }
@ -6204,8 +6359,42 @@
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
"type": "STRING", "type": "CHOICE",
"value": "static" "members": [
{
"type": "STRING",
"value": "static"
},
{
"type": "ALIAS",
"content": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "static"
},
{
"type": "PATTERN",
"value": "\\s+"
},
{
"type": "STRING",
"value": "get"
},
{
"type": "PATTERN",
"value": "\\s*\\n"
}
]
}
},
"named": false,
"value": "static get"
}
]
}, },
{ {
"type": "BLANK" "type": "BLANK"
@ -6412,6 +6601,10 @@
{ {
"type": "STRING", "type": "STRING",
"value": "export" "value": "export"
},
{
"type": "STRING",
"value": "let"
} }
] ]
}, },
@ -6434,9 +6627,13 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "comment" "name": "comment"
}, },
{
"type": "SYMBOL",
"name": "html_comment"
},
{ {
"type": "PATTERN", "type": "PATTERN",
"value": "[\\s\\p{Zs}\\uFEFF\\u2060\\u200B]" "value": "[\\s\\p{Zs}\\uFEFF\\u2028\\u2029\\u2060\\u200B]"
} }
], ],
"conflicts": [ "conflicts": [
@ -6648,6 +6845,16 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "primary_expression" "name": "primary_expression"
} }
],
[
{
"type": "SYMBOL",
"name": "lexical_declaration"
},
{
"type": "SYMBOL",
"name": "primary_expression"
}
] ]
], ],
"externals": [ "externals": [
@ -6662,6 +6869,22 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_ternary_qmark" "name": "_ternary_qmark"
},
{
"type": "SYMBOL",
"name": "html_comment"
},
{
"type": "STRING",
"value": "||"
},
{
"type": "SYMBOL",
"name": "escape_sequence"
},
{
"type": "SYMBOL",
"name": "regex_pattern"
} }
], ],
"inline": [ "inline": [
@ -6689,4 +6912,3 @@
"pattern" "pattern"
] ]
} }

@ -53,10 +53,6 @@
"type": "jsx_element", "type": "jsx_element",
"named": true "named": true
}, },
{
"type": "jsx_fragment",
"named": true
},
{ {
"type": "jsx_self_closing_element", "type": "jsx_self_closing_element",
"named": true "named": true
@ -146,7 +142,7 @@
"named": true "named": true
}, },
{ {
"type": "function", "type": "function_expression",
"named": true "named": true
}, },
{ {
@ -157,10 +153,6 @@
"type": "identifier", "type": "identifier",
"named": true "named": true
}, },
{
"type": "import",
"named": true
},
{ {
"type": "member_expression", "type": "member_expression",
"named": true "named": true
@ -608,6 +600,10 @@
{ {
"type": "expression", "type": "expression",
"named": true "named": true
},
{
"type": "private_property_identifier",
"named": true
} }
] ]
}, },
@ -770,6 +766,10 @@
{ {
"type": "expression", "type": "expression",
"named": true "named": true
},
{
"type": "import",
"named": true
} }
] ]
}, },
@ -976,6 +976,11 @@
} }
} }
}, },
{
"type": "comment",
"named": true,
"fields": {}
},
{ {
"type": "computed_property_name", "type": "computed_property_name",
"named": true, "named": true,
@ -1469,7 +1474,7 @@
} }
}, },
{ {
"type": "function", "type": "function_declaration",
"named": true, "named": true,
"fields": { "fields": {
"body": { "body": {
@ -1484,7 +1489,7 @@
}, },
"name": { "name": {
"multiple": false, "multiple": false,
"required": false, "required": true,
"types": [ "types": [
{ {
"type": "identifier", "type": "identifier",
@ -1505,7 +1510,7 @@
} }
}, },
{ {
"type": "function_declaration", "type": "function_expression",
"named": true, "named": true,
"fields": { "fields": {
"body": { "body": {
@ -1520,7 +1525,7 @@
}, },
"name": { "name": {
"multiple": false, "multiple": false,
"required": true, "required": false,
"types": [ "types": [
{ {
"type": "identifier", "type": "identifier",
@ -1689,6 +1694,21 @@
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{
"type": "import_attribute",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "object",
"named": true
}
]
}
},
{ {
"type": "import_clause", "type": "import_clause",
"named": true, "named": true,
@ -1758,9 +1778,13 @@
} }
}, },
"children": { "children": {
"multiple": false, "multiple": true,
"required": false, "required": false,
"types": [ "types": [
{
"type": "import_attribute",
"named": true
},
{ {
"type": "import_clause", "type": "import_clause",
"named": true "named": true
@ -1784,10 +1808,6 @@
"type": "jsx_expression", "type": "jsx_expression",
"named": true "named": true
}, },
{
"type": "jsx_fragment",
"named": true
},
{ {
"type": "jsx_namespace_name", "type": "jsx_namespace_name",
"named": true "named": true
@ -1813,7 +1833,7 @@
"fields": { "fields": {
"name": { "name": {
"multiple": false, "multiple": false,
"required": true, "required": false,
"types": [ "types": [
{ {
"type": "identifier", "type": "identifier",
@ -1824,7 +1844,7 @@
"named": true "named": true
}, },
{ {
"type": "nested_identifier", "type": "member_expression",
"named": true "named": true
} }
] ]
@ -1861,15 +1881,15 @@
"required": false, "required": false,
"types": [ "types": [
{ {
"type": "jsx_element", "type": "html_character_reference",
"named": true "named": true
}, },
{ {
"type": "jsx_expression", "type": "jsx_element",
"named": true "named": true
}, },
{ {
"type": "jsx_fragment", "type": "jsx_expression",
"named": true "named": true
}, },
{ {
@ -1906,37 +1926,6 @@
] ]
} }
}, },
{
"type": "jsx_fragment",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "jsx_element",
"named": true
},
{
"type": "jsx_expression",
"named": true
},
{
"type": "jsx_fragment",
"named": true
},
{
"type": "jsx_self_closing_element",
"named": true
},
{
"type": "jsx_text",
"named": true
}
]
}
},
{ {
"type": "jsx_namespace_name", "type": "jsx_namespace_name",
"named": true, "named": true,
@ -1972,7 +1961,7 @@
}, },
"name": { "name": {
"multiple": false, "multiple": false,
"required": true, "required": false,
"types": [ "types": [
{ {
"type": "identifier", "type": "identifier",
@ -1983,7 +1972,7 @@
"named": true "named": true
}, },
{ {
"type": "nested_identifier", "type": "member_expression",
"named": true "named": true
} }
] ]
@ -2021,13 +2010,18 @@
"named": true "named": true
}, },
{ {
"type": "nested_identifier", "type": "member_expression",
"named": true "named": true
} }
] ]
} }
} }
}, },
{
"type": "jsx_text",
"named": true,
"fields": {}
},
{ {
"type": "labeled_statement", "type": "labeled_statement",
"named": true, "named": true,
@ -2095,6 +2089,10 @@
{ {
"type": "expression", "type": "expression",
"named": true "named": true
},
{
"type": "import",
"named": true
} }
] ]
}, },
@ -2240,25 +2238,6 @@
] ]
} }
}, },
{
"type": "nested_identifier",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "identifier",
"named": true
},
{
"type": "nested_identifier",
"named": true
}
]
}
},
{ {
"type": "new_expression", "type": "new_expression",
"named": true, "named": true,
@ -2586,31 +2565,16 @@
{ {
"type": "sequence_expression", "type": "sequence_expression",
"named": true, "named": true,
"fields": { "fields": {},
"left": { "children": {
"multiple": false, "multiple": true,
"required": true, "required": true,
"types": [ "types": [
{ {
"type": "expression", "type": "expression",
"named": true "named": true
} }
] ]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "sequence_expression",
"named": true
}
]
}
} }
}, },
{ {
@ -2655,6 +2619,10 @@
"type": "escape_sequence", "type": "escape_sequence",
"named": true "named": true
}, },
{
"type": "html_character_reference",
"named": true
},
{ {
"type": "string_fragment", "type": "string_fragment",
"named": true "named": true
@ -2805,6 +2773,10 @@
"type": "escape_sequence", "type": "escape_sequence",
"named": true "named": true
}, },
{
"type": "string_fragment",
"named": true
},
{ {
"type": "template_substitution", "type": "template_substitution",
"named": true "named": true
@ -3234,6 +3206,10 @@
"type": "/=", "type": "/=",
"named": false "named": false
}, },
{
"type": "/>",
"named": false
},
{ {
"type": ":", "type": ":",
"named": false "named": false
@ -3246,6 +3222,10 @@
"type": "<", "type": "<",
"named": false "named": false
}, },
{
"type": "</",
"named": false
},
{ {
"type": "</template>", "type": "</template>",
"named": false "named": false
@ -3370,10 +3350,6 @@
"type": "class", "type": "class",
"named": false "named": false
}, },
{
"type": "comment",
"named": true
},
{ {
"type": "const", "type": "const",
"named": false "named": false
@ -3442,6 +3418,14 @@
"type": "hash_bang_line", "type": "hash_bang_line",
"named": true "named": true
}, },
{
"type": "html_character_reference",
"named": true
},
{
"type": "html_comment",
"named": true
},
{ {
"type": "identifier", "type": "identifier",
"named": true "named": true
@ -3462,10 +3446,6 @@
"type": "instanceof", "type": "instanceof",
"named": false "named": false
}, },
{
"type": "jsx_text",
"named": true
},
{ {
"type": "let", "type": "let",
"named": false "named": false
@ -3530,6 +3510,10 @@
"type": "static", "type": "static",
"named": false "named": false
}, },
{
"type": "static get",
"named": false
},
{ {
"type": "string_fragment", "type": "string_fragment",
"named": true "named": true

File diff suppressed because it is too large Load Diff

@ -1,187 +1,293 @@
#include <tree_sitter/parser.h> #include "tree_sitter/parser.h"
#include <wctype.h> #include <wctype.h>
enum TokenType { enum TokenType {
AUTOMATIC_SEMICOLON, AUTOMATIC_SEMICOLON,
TEMPLATE_CHARS, TEMPLATE_CHARS,
TERNARY_QMARK, TERNARY_QMARK,
HTML_COMMENT,
LOGICAL_OR,
ESCAPE_SEQUENCE,
REGEX_PATTERN,
}; };
void *tree_sitter_javascript_external_scanner_create() { return NULL; } void *tree_sitter_javascript_external_scanner_create() { return NULL; }
void tree_sitter_javascript_external_scanner_destroy(void *p) {} void tree_sitter_javascript_external_scanner_destroy(void *p) {}
void tree_sitter_javascript_external_scanner_reset(void *p) {} void tree_sitter_javascript_external_scanner_reset(void *p) {}
unsigned tree_sitter_javascript_external_scanner_serialize(void *p, char *buffer) { return 0; } unsigned tree_sitter_javascript_external_scanner_serialize(void *p, char *buffer) { return 0; }
void tree_sitter_javascript_external_scanner_deserialize(void *p, const char *b, unsigned n) {} void tree_sitter_javascript_external_scanner_deserialize(void *p, const char *b, unsigned n) {}
static void advance(TSLexer *lexer) { lexer->advance(lexer, false); } static void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
static void skip(TSLexer *lexer) { lexer->advance(lexer, true); } static void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
static bool scan_template_chars(TSLexer *lexer) { static bool scan_template_chars(TSLexer *lexer) {
lexer->result_symbol = TEMPLATE_CHARS; lexer->result_symbol = TEMPLATE_CHARS;
for (bool has_content = false;; has_content = true) { for (bool has_content = false;; has_content = true) {
lexer->mark_end(lexer); lexer->mark_end(lexer);
switch (lexer->lookahead) { switch (lexer->lookahead) {
case '`': case '`':
return has_content; return has_content;
case '\0': case '\0':
return false; return false;
case '$': case '$':
advance(lexer); advance(lexer);
if (lexer->lookahead == '{') return has_content; if (lexer->lookahead == '{') {
break; return has_content;
case '\\': }
return has_content; break;
default: case '\\':
advance(lexer); return has_content;
default:
advance(lexer);
}
} }
}
} }
static bool scan_whitespace_and_comments(TSLexer *lexer) { static bool scan_whitespace_and_comments(TSLexer *lexer, bool *scanned_comment) {
for (;;) { for (;;) {
while (iswspace(lexer->lookahead)) { while (iswspace(lexer->lookahead)) {
skip(lexer); skip(lexer);
}
if (lexer->lookahead == '/') {
skip(lexer);
if (lexer->lookahead == '/') {
skip(lexer);
while (lexer->lookahead != 0 && lexer->lookahead != '\n' && lexer->lookahead != 0x2028 &&
lexer->lookahead != 0x2029) {
skip(lexer);
}
*scanned_comment = true;
} else if (lexer->lookahead == '*') {
skip(lexer);
while (lexer->lookahead != 0) {
if (lexer->lookahead == '*') {
skip(lexer);
if (lexer->lookahead == '/') {
skip(lexer);
*scanned_comment = true;
break;
}
} else {
skip(lexer);
}
}
} else {
return false;
}
} else {
return true;
}
} }
}
if (lexer->lookahead == '/') { static bool scan_automatic_semicolon(TSLexer *lexer, bool comment_condition, bool *scanned_comment) {
skip(lexer); lexer->result_symbol = AUTOMATIC_SEMICOLON;
lexer->mark_end(lexer);
if (lexer->lookahead == '/') { for (;;) {
skip(lexer); if (lexer->lookahead == 0) {
while (lexer->lookahead != 0 && lexer->lookahead != '\n') { return true;
skip(lexer);
} }
} else if (lexer->lookahead == '*') {
if (lexer->lookahead == '/') {
if (!scan_whitespace_and_comments(lexer, scanned_comment)) {
return false;
}
if (comment_condition && lexer->lookahead != ',' && lexer->lookahead != '=') {
return true;
}
}
if (lexer->lookahead == '}') {
return true;
}
if (lexer->is_at_included_range_start(lexer)) {
return true;
}
if (lexer->lookahead == '\n' || lexer->lookahead == 0x2028 || lexer->lookahead == 0x2029) {
break;
}
if (!iswspace(lexer->lookahead)) {
return false;
}
skip(lexer); skip(lexer);
while (lexer->lookahead != 0) { }
if (lexer->lookahead == '*') {
skip(lexer);
if (!scan_whitespace_and_comments(lexer, scanned_comment)) {
return false;
}
switch (lexer->lookahead) {
case ',':
case '.':
case ':':
case ';':
case '*':
case '%':
case '>':
case '<':
case '=':
case '[':
case '(':
case '?':
case '^':
case '|':
case '&':
case '/':
return false;
// Insert a semicolon before `--` and `++`, but not before binary `+` or `-`.
case '+':
skip(lexer); skip(lexer);
if (lexer->lookahead == '/') { return lexer->lookahead == '+';
skip(lexer); case '-':
break; skip(lexer);
return lexer->lookahead == '-';
// Don't insert a semicolon before `!=`, but do insert one before a unary `!`.
case '!':
skip(lexer);
return lexer->lookahead != '=';
// Don't insert a semicolon before `in` or `instanceof`, but do insert one
// before an identifier.
case 'i':
skip(lexer);
if (lexer->lookahead != 'n') {
return true;
} }
} else {
skip(lexer); skip(lexer);
}
} if (!iswalpha(lexer->lookahead)) {
} else { return false;
return false; }
}
} else { for (unsigned i = 0; i < 8; i++) {
return true; if (lexer->lookahead != "stanceof"[i]) {
return true;
}
skip(lexer);
}
if (!iswalpha(lexer->lookahead)) {
return false;
}
break;
default:
break;
} }
}
}
static bool scan_automatic_semicolon(TSLexer *lexer) { return true;
lexer->result_symbol = AUTOMATIC_SEMICOLON; }
lexer->mark_end(lexer);
for (;;) { static bool scan_ternary_qmark(TSLexer *lexer) {
if (lexer->lookahead == 0) return true; for (;;) {
if (lexer->lookahead == '}') return true; if (!iswspace(lexer->lookahead)) {
if (lexer->is_at_included_range_start(lexer)) return true; break;
if (lexer->lookahead == '\n') break; }
if (!iswspace(lexer->lookahead)) return false;
skip(lexer);
}
skip(lexer);
if (!scan_whitespace_and_comments(lexer)) return false;
switch (lexer->lookahead) {
case ',':
case '.':
case ':':
case ';':
case '*':
case '%':
case '>':
case '<':
case '=':
case '[':
case '(':
case '?':
case '^':
case '|':
case '&':
case '/':
return false;
// Insert a semicolon before `--` and `++`, but not before binary `+` or `-`.
case '+':
skip(lexer);
return lexer->lookahead == '+';
case '-':
skip(lexer);
return lexer->lookahead == '-';
// Don't insert a semicolon before `!=`, but do insert one before a unary `!`.
case '!':
skip(lexer);
return lexer->lookahead != '=';
// Don't insert a semicolon before `in` or `instanceof`, but do insert one
// before an identifier.
case 'i':
skip(lexer);
if (lexer->lookahead != 'n') return true;
skip(lexer);
if (!iswalpha(lexer->lookahead)) return false;
for (unsigned i = 0; i < 8; i++) {
if (lexer->lookahead != "stanceof"[i]) return true;
skip(lexer); skip(lexer);
} }
if (lexer->lookahead == '?') {
advance(lexer);
if (lexer->lookahead == '?') {
return false;
}
if (!iswalpha(lexer->lookahead)) return false; lexer->mark_end(lexer);
break; lexer->result_symbol = TERNARY_QMARK;
}
return true; if (lexer->lookahead == '.') {
advance(lexer);
if (iswdigit(lexer->lookahead)) {
return true;
}
return false;
}
return true;
}
return false;
} }
static bool scan_ternary_qmark(TSLexer *lexer) { static bool scan_html_comment(TSLexer *lexer) {
for(;;) { while (iswspace(lexer->lookahead) || lexer->lookahead == 0x2028 || lexer->lookahead == 0x2029) {
if (!iswspace(lexer->lookahead)) break; skip(lexer);
skip(lexer); }
}
if (lexer->lookahead == '?') { const char *comment_start = "<!--";
advance(lexer); const char *comment_end = "-->";
if (lexer->lookahead == '?') return false; if (lexer->lookahead == '<') {
for (unsigned i = 0; i < 4; i++) {
if (lexer->lookahead != comment_start[i]) {
return false;
}
advance(lexer);
}
} else if (lexer->lookahead == '-') {
for (unsigned i = 0; i < 3; i++) {
if (lexer->lookahead != comment_end[i]) {
return false;
}
advance(lexer);
}
} else {
return false;
}
while (lexer->lookahead != 0 && lexer->lookahead != '\n' && lexer->lookahead != 0x2028 &&
lexer->lookahead != 0x2029) {
advance(lexer);
}
lexer->result_symbol = HTML_COMMENT;
lexer->mark_end(lexer); lexer->mark_end(lexer);
lexer->result_symbol = TERNARY_QMARK;
if (lexer->lookahead == '.') {
advance(lexer);
if (iswdigit(lexer->lookahead)) return true;
return false;
}
return true; return true;
}
return false;
} }
bool tree_sitter_javascript_external_scanner_scan(void *payload, TSLexer *lexer, bool tree_sitter_javascript_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) {
const bool *valid_symbols) { if (valid_symbols[TEMPLATE_CHARS]) {
if (valid_symbols[TEMPLATE_CHARS]) { if (valid_symbols[AUTOMATIC_SEMICOLON]) {
if (valid_symbols[AUTOMATIC_SEMICOLON]) return false; return false;
return scan_template_chars(lexer); }
} else if (valid_symbols[AUTOMATIC_SEMICOLON]) { return scan_template_chars(lexer);
bool ret = scan_automatic_semicolon(lexer); }
if (!ret && valid_symbols[TERNARY_QMARK] && lexer->lookahead == '?')
return scan_ternary_qmark(lexer); if (valid_symbols[AUTOMATIC_SEMICOLON]) {
return ret; bool scanned_comment = false;
} bool ret = scan_automatic_semicolon(lexer, !valid_symbols[LOGICAL_OR], &scanned_comment);
if (valid_symbols[TERNARY_QMARK]) { if (!ret && !scanned_comment && valid_symbols[TERNARY_QMARK] && lexer->lookahead == '?') {
return scan_ternary_qmark(lexer); return scan_ternary_qmark(lexer);
} }
return ret;
return false; }
if (valid_symbols[TERNARY_QMARK]) {
return scan_ternary_qmark(lexer);
}
if (valid_symbols[HTML_COMMENT] && !valid_symbols[LOGICAL_OR] && !valid_symbols[ESCAPE_SEQUENCE] &&
!valid_symbols[REGEX_PATTERN]) {
return scan_html_comment(lexer);
}
return false;
} }

@ -13,9 +13,8 @@ extern "C" {
#define ts_builtin_sym_end 0 #define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
typedef uint16_t TSStateId;
#ifndef TREE_SITTER_API_H_ #ifndef TREE_SITTER_API_H_
typedef uint16_t TSStateId;
typedef uint16_t TSSymbol; typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId; typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage; typedef struct TSLanguage TSLanguage;
@ -130,9 +129,16 @@ struct TSLanguage {
* Lexer Macros * Lexer Macros
*/ */
#ifdef _MSC_VER
#define UNUSED __pragma(warning(suppress : 4101))
#else
#define UNUSED __attribute__((unused))
#endif
#define START_LEXER() \ #define START_LEXER() \
bool result = false; \ bool result = false; \
bool skip = false; \ bool skip = false; \
UNUSED \
bool eof = false; \ bool eof = false; \
int32_t lookahead; \ int32_t lookahead; \
goto start; \ goto start; \
@ -166,7 +172,7 @@ struct TSLanguage {
* Parse Table Macros * Parse Table Macros
*/ */
#define SMALL_STATE(id) id - LARGE_STATE_COUNT #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)
#define STATE(id) id #define STATE(id) id
@ -176,7 +182,7 @@ struct TSLanguage {
{{ \ {{ \
.shift = { \ .shift = { \
.type = TSParseActionTypeShift, \ .type = TSParseActionTypeShift, \
.state = state_value \ .state = (state_value) \
} \ } \
}} }}
@ -184,7 +190,7 @@ struct TSLanguage {
{{ \ {{ \
.shift = { \ .shift = { \
.type = TSParseActionTypeShift, \ .type = TSParseActionTypeShift, \
.state = state_value, \ .state = (state_value), \
.repetition = true \ .repetition = true \
} \ } \
}} }}

File diff suppressed because it is too large Load Diff

@ -108,22 +108,6 @@ world';
(expression_statement (expression_statement
(string (string_fragment) (escape_sequence) (string_fragment)))) (string (string_fragment) (escape_sequence) (string_fragment))))
============================================================
Non-standard unescaped newlines legal in TSX attributes
============================================================
"hello
world";
'hello
world';
---
(program
(expression_statement (string (string_fragment)))
(expression_statement (string (string_fragment))))
========================================================= =========================================================
JSX strings with unescaped newlines for TSX attributes JSX strings with unescaped newlines for TSX attributes
========================================================= =========================================================
@ -151,3 +135,37 @@ JSX strings with unescaped newlines for TSX attributes
(jsx_attribute (property_identifier) (string (string_fragment)))) (jsx_attribute (property_identifier) (string (string_fragment))))
(jsx_closing_element (jsx_closing_element
(identifier))))) (identifier)))))
===============================================
JSX with HTML character references (entities)
===============================================
<a>foo &nbsp; bar</a>;
<abbr title="foo &nbsp; \n bar">foo</abbr>;
----
(program
(expression_statement
(jsx_element
(jsx_opening_element
(identifier))
(jsx_text)
(html_character_reference)
(jsx_text)
(jsx_closing_element
(identifier))))
(expression_statement
(jsx_element
(jsx_opening_element
(identifier)
(jsx_attribute
(property_identifier)
(string
(string_fragment)
(html_character_reference)
(string_fragment))))
(jsx_text)
(jsx_closing_element
(identifier)))))

@ -276,8 +276,8 @@ let d
(program (program
(lexical_declaration (lexical_declaration
(variable_declarator (identifier)) (variable_declarator (identifier)))
(comment)) (comment)
(comment) (comment)
(lexical_declaration (lexical_declaration
(variable_declarator (identifier)) (variable_declarator (identifier))

File diff suppressed because it is too large Load Diff

@ -0,0 +1,4 @@
import pkg from "./package.json" with { type: "json" };
// <- keyword
// ^ string
// ^ keyword

@ -0,0 +1,14 @@
class Person {
// ^ definition.class
static foo = bar;
getName() {
// ^ definition.method
}
}
var person = new Person();
// ^ reference.class
person.getName()
// ^ reference.call

@ -0,0 +1,22 @@
function foo() {
// ^ definition.function
}
foo()
// <- reference.call
{ source: $ => repeat($._expression) }
// ^ definition.function
// ^ reference.call
let plus1 = x => x + 1
// ^ definition.function
let plus2 = function(x) { return x + 2 }
// ^ definition.function
function *gen() { }
// ^ definition.function
async function* foo() { yield 1; }
// ^ definition.function