mirror of https://github.com/Wilfred/difftastic/
Merge commit '098bd31b7f838a31cce08db4091e989ea42f3ef6'
commit
a721bef7a7
@ -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
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
examples/npm/node_modules/slide/lib/async-map-ordered.js
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
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
|
||||||
Binary file not shown.
Loading…
Reference in New Issue