From 776d978f09f46b7214b2564155260fb26c35019c Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Fri, 20 Dec 2024 00:09:12 -0800 Subject: [PATCH] Use tree-sitter-typescript from crates.io --- CHANGELOG.md | 2 +- Cargo.lock | 11 + Cargo.toml | 1 + build.rs | 10 - src/parse/tree_sitter_parser.rs | 20 +- vendored_parsers/highlights/typescript.scm | 1 - .../tree-sitter-typescript-src/common | 1 - .../tree-sitter-typescript-src/tsx | 1 - .../tree-sitter-typescript-src/typescript | 1 - .../tree-sitter-typescript/.eslintrc.js | 20 - .../tree-sitter-typescript/.gitattributes | 20 - .../.github/ISSUE_TEMPLATE/bug_report.yml | 59 - .../.github/ISSUE_TEMPLATE/config.yml | 1 - .../ISSUE_TEMPLATE/feature_request.yml | 36 - .../.github/pull_request_template.md | 7 - .../.github/workflows/ci.yml | 30 - .../.github/workflows/lint.yml | 19 - .../.github/workflows/release.yml | 103 - .../tree-sitter-typescript/.gitignore | 24 - .../tree-sitter-typescript/.npmignore | 6 - .../tree-sitter-typescript/Cargo.toml | 32 - .../tree-sitter-typescript/LICENSE | 21 - .../tree-sitter-typescript/Package.swift | 27 - .../tree-sitter-typescript/README.md | 24 - .../tree-sitter-typescript/appveyor.yml | 22 - .../tree-sitter-typescript/binding.gyp | 21 - .../bindings/node/binding.cc | 37 - .../bindings/node/index.js | 20 - .../bindings/node/tsx.js | 1 - .../bindings/node/typescript.js | 1 - .../bindings/rust/README.md | 46 - .../bindings/rust/build.rs | 28 - .../bindings/rust/lib.rs | 62 - .../swift/TreeSitterTypeScript/typescript.h | 17 - .../common/corpus/declarations.txt | 1418 - .../common/corpus/expressions.txt | 357 - .../common/corpus/functions.txt | 340 - .../common/corpus/types.txt | 2114 - .../common/define-grammar.js | 1110 - .../tree-sitter-typescript/common/scanner.h | 297 - .../tree-sitter-typescript/examples/parser.ts | 7555 - .../tree-sitter-typescript/package.json | 100 - .../queries/highlights.scm | 35 - .../tree-sitter-typescript/queries/locals.scm | 2 - .../tree-sitter-typescript/queries/tags.scm | 23 - .../script/check-generated-files | 19 - .../script/known-failures.txt | 1 - .../script/parse-examples | 55 - .../tree-sitter-typescript/tsx/corpus/common | 1 - .../tsx/corpus/expressions.txt | 25 - .../tree-sitter-typescript/tsx/grammar.js | 3 - .../tree-sitter-typescript/tsx/package.json | 3 - .../tsx/src/grammar.json | 11864 - .../tsx/src/node-types.json | 6763 - .../tree-sitter-typescript/tsx/src/parser.c | 402619 -------------- .../tree-sitter-typescript/tsx/src/scanner.c | 15 - .../tsx/src/tree_sitter/parser.h | 230 - .../typescript/corpus/common | 1 - .../typescript/corpus/expressions.txt | 20 - .../typescript/grammar.js | 3 - .../typescript/package.json | 3 - .../typescript/src/grammar.json | 11864 - .../typescript/src/node-types.json | 6778 - .../typescript/src/parser.c | 406857 --------------- .../typescript/src/scanner.c | 15 - .../typescript/src/tree_sitter/parser.h | 230 - .../tree-sitter-typescript/typescript/test.ts | 1 - 67 files changed, 20 insertions(+), 861433 deletions(-) delete mode 120000 vendored_parsers/highlights/typescript.scm delete mode 120000 vendored_parsers/tree-sitter-typescript-src/common delete mode 120000 vendored_parsers/tree-sitter-typescript-src/tsx delete mode 120000 vendored_parsers/tree-sitter-typescript-src/typescript delete mode 100644 vendored_parsers/tree-sitter-typescript/.eslintrc.js delete mode 100644 vendored_parsers/tree-sitter-typescript/.gitattributes delete mode 100644 vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/feature_request.yml delete mode 100644 vendored_parsers/tree-sitter-typescript/.github/pull_request_template.md delete mode 100644 vendored_parsers/tree-sitter-typescript/.github/workflows/ci.yml delete mode 100644 vendored_parsers/tree-sitter-typescript/.github/workflows/lint.yml delete mode 100644 vendored_parsers/tree-sitter-typescript/.github/workflows/release.yml delete mode 100644 vendored_parsers/tree-sitter-typescript/.gitignore delete mode 100644 vendored_parsers/tree-sitter-typescript/.npmignore delete mode 100644 vendored_parsers/tree-sitter-typescript/Cargo.toml delete mode 100644 vendored_parsers/tree-sitter-typescript/LICENSE delete mode 100644 vendored_parsers/tree-sitter-typescript/Package.swift delete mode 100644 vendored_parsers/tree-sitter-typescript/README.md delete mode 100644 vendored_parsers/tree-sitter-typescript/appveyor.yml delete mode 100644 vendored_parsers/tree-sitter-typescript/binding.gyp delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/node/binding.cc delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/node/index.js delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/node/tsx.js delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/node/typescript.js delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/rust/README.md delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/rust/build.rs delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/rust/lib.rs delete mode 100644 vendored_parsers/tree-sitter-typescript/bindings/swift/TreeSitterTypeScript/typescript.h delete mode 100644 vendored_parsers/tree-sitter-typescript/common/corpus/declarations.txt delete mode 100644 vendored_parsers/tree-sitter-typescript/common/corpus/expressions.txt delete mode 100644 vendored_parsers/tree-sitter-typescript/common/corpus/functions.txt delete mode 100644 vendored_parsers/tree-sitter-typescript/common/corpus/types.txt delete mode 100644 vendored_parsers/tree-sitter-typescript/common/define-grammar.js delete mode 100644 vendored_parsers/tree-sitter-typescript/common/scanner.h delete mode 100644 vendored_parsers/tree-sitter-typescript/examples/parser.ts delete mode 100644 vendored_parsers/tree-sitter-typescript/package.json delete mode 100644 vendored_parsers/tree-sitter-typescript/queries/highlights.scm delete mode 100644 vendored_parsers/tree-sitter-typescript/queries/locals.scm delete mode 100644 vendored_parsers/tree-sitter-typescript/queries/tags.scm delete mode 100755 vendored_parsers/tree-sitter-typescript/script/check-generated-files delete mode 100644 vendored_parsers/tree-sitter-typescript/script/known-failures.txt delete mode 100755 vendored_parsers/tree-sitter-typescript/script/parse-examples delete mode 120000 vendored_parsers/tree-sitter-typescript/tsx/corpus/common delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/corpus/expressions.txt delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/grammar.js delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/package.json delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/src/grammar.json delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/src/node-types.json delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/src/parser.c delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/src/scanner.c delete mode 100644 vendored_parsers/tree-sitter-typescript/tsx/src/tree_sitter/parser.h delete mode 120000 vendored_parsers/tree-sitter-typescript/typescript/corpus/common delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/corpus/expressions.txt delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/grammar.js delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/package.json delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/src/grammar.json delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/src/node-types.json delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/src/parser.c delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/src/scanner.c delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/src/tree_sitter/parser.h delete mode 100644 vendored_parsers/tree-sitter-typescript/typescript/test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ae7657815..e4d6bcb86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ with YAML. Improved language detection when one argument is a named pipe. Updated to the latest tree-sitter parser for C, C++, C#, Haskell, -JavaScript, Objective-C, OCaml, Python, Ruby and Scala. +JavaScript, Objective-C, OCaml, Python, Ruby, Scala and TypeScript. ### Syntax Highlighting diff --git a/Cargo.lock b/Cargo.lock index 545c0488c..ecbbbe1ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,6 +260,7 @@ dependencies = [ "tree-sitter-python", "tree-sitter-ruby", "tree-sitter-scala", + "tree-sitter-typescript", "tree_magic_mini", "typed-arena", "unicode-width", @@ -1117,6 +1118,16 @@ dependencies = [ "tree-sitter-language", ] +[[package]] +name = "tree-sitter-typescript" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5f76ed8d947a75cc446d5fccd8b602ebf0cde64ccf2ffa434d873d7a575eff" +dependencies = [ + "cc", + "tree-sitter-language", +] + [[package]] name = "tree_magic_mini" version = "3.1.5" diff --git a/Cargo.toml b/Cargo.toml index be96d5e3c..d3af9118e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,6 +88,7 @@ tree-sitter-python = "0.23.5" tree-sitter-cpp = "0.23.4" tree-sitter-c = "0.23.4" tree-sitter-javascript = "0.23.1" +tree-sitter-typescript = "0.23.2" [dev-dependencies] # assert_cmd 2.0.10 requires predicates 3. diff --git a/build.rs b/build.rs index 6435ed4d6..b2915e1b7 100644 --- a/build.rs +++ b/build.rs @@ -289,16 +289,6 @@ fn main() { src_dir: "vendored_parsers/tree-sitter-toml-src", extra_files: vec!["scanner.c"], }, - TreeSitterParser { - name: "tree-sitter-tsx", - src_dir: "vendored_parsers/tree-sitter-typescript-src/tsx/src", - extra_files: vec!["scanner.c"], - }, - TreeSitterParser { - name: "tree-sitter-typescript", - src_dir: "vendored_parsers/tree-sitter-typescript-src/typescript/src", - extra_files: vec!["scanner.c"], - }, TreeSitterParser { name: "tree-sitter-vhdl", src_dir: "vendored_parsers/tree-sitter-vhdl-src", diff --git a/src/parse/tree_sitter_parser.rs b/src/parse/tree_sitter_parser.rs index bc103b36c..cefc805b7 100644 --- a/src/parse/tree_sitter_parser.rs +++ b/src/parse/tree_sitter_parser.rs @@ -106,8 +106,6 @@ extern "C" { fn tree_sitter_sql() -> ts::Language; fn tree_sitter_swift() -> ts::Language; fn tree_sitter_toml() -> ts::Language; - fn tree_sitter_tsx() -> ts::Language; - fn tree_sitter_typescript() -> ts::Language; fn tree_sitter_vhdl() -> ts::Language; fn tree_sitter_xml() -> ts::Language; fn tree_sitter_yaml() -> ts::Language; @@ -874,9 +872,7 @@ pub(crate) fn from_language(language: guess::Language) -> TreeSitterConfig { let language = unsafe { tree_sitter_qmljs() }; let mut highlight_query = tree_sitter_javascript::HIGHLIGHT_QUERY.to_owned(); - highlight_query.push_str(include_str!( - "../../vendored_parsers/highlights/typescript.scm" - )); + highlight_query.push_str(tree_sitter_typescript::HIGHLIGHTS_QUERY); highlight_query.push_str(include_str!("../../vendored_parsers/highlights/qmljs.scm")); TreeSitterConfig { @@ -1070,12 +1066,11 @@ pub(crate) fn from_language(language: guess::Language) -> TreeSitterConfig { } } TypeScriptTsx => { - let language = unsafe { tree_sitter_tsx() }; + let language_fn = tree_sitter_typescript::LANGUAGE_TSX; + let language = tree_sitter::Language::new(language_fn); let mut highlight_query = tree_sitter_javascript::HIGHLIGHT_QUERY.to_owned(); - highlight_query.push_str(include_str!( - "../../vendored_parsers/highlights/typescript.scm" - )); + highlight_query.push_str(tree_sitter_typescript::HIGHLIGHTS_QUERY); TreeSitterConfig { language: language.clone(), @@ -1086,12 +1081,11 @@ pub(crate) fn from_language(language: guess::Language) -> TreeSitterConfig { } } TypeScript => { - let language = unsafe { tree_sitter_typescript() }; + let language_fn = tree_sitter_typescript::LANGUAGE_TYPESCRIPT; + let language = tree_sitter::Language::new(language_fn); let mut highlight_query = tree_sitter_javascript::HIGHLIGHT_QUERY.to_owned(); - highlight_query.push_str(include_str!( - "../../vendored_parsers/highlights/typescript.scm" - )); + highlight_query.push_str(tree_sitter_typescript::HIGHLIGHTS_QUERY); TreeSitterConfig { language: language.clone(), diff --git a/vendored_parsers/highlights/typescript.scm b/vendored_parsers/highlights/typescript.scm deleted file mode 120000 index 41e5cf5b3..000000000 --- a/vendored_parsers/highlights/typescript.scm +++ /dev/null @@ -1 +0,0 @@ -../tree-sitter-typescript/queries/highlights.scm \ No newline at end of file diff --git a/vendored_parsers/tree-sitter-typescript-src/common b/vendored_parsers/tree-sitter-typescript-src/common deleted file mode 120000 index 61b8d6752..000000000 --- a/vendored_parsers/tree-sitter-typescript-src/common +++ /dev/null @@ -1 +0,0 @@ -../tree-sitter-typescript/common \ No newline at end of file diff --git a/vendored_parsers/tree-sitter-typescript-src/tsx b/vendored_parsers/tree-sitter-typescript-src/tsx deleted file mode 120000 index 42b786215..000000000 --- a/vendored_parsers/tree-sitter-typescript-src/tsx +++ /dev/null @@ -1 +0,0 @@ -../tree-sitter-typescript/tsx \ No newline at end of file diff --git a/vendored_parsers/tree-sitter-typescript-src/typescript b/vendored_parsers/tree-sitter-typescript-src/typescript deleted file mode 120000 index 7a86d9da8..000000000 --- a/vendored_parsers/tree-sitter-typescript-src/typescript +++ /dev/null @@ -1 +0,0 @@ -../tree-sitter-typescript/typescript \ No newline at end of file diff --git a/vendored_parsers/tree-sitter-typescript/.eslintrc.js b/vendored_parsers/tree-sitter-typescript/.eslintrc.js deleted file mode 100644 index b2e707a9e..000000000 --- a/vendored_parsers/tree-sitter-typescript/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -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}, - ], - }, -}; diff --git a/vendored_parsers/tree-sitter-typescript/.gitattributes b/vendored_parsers/tree-sitter-typescript/.gitattributes deleted file mode 100644 index 469cb1d97..000000000 --- a/vendored_parsers/tree-sitter-typescript/.gitattributes +++ /dev/null @@ -1,20 +0,0 @@ -typescript/src/** linguist-vendored -tsx/src/** linguist-vendored - -/examples/* linguist-vendored - -typescript/src/grammar.json linguist-generated -typescript/src/node-types.json linguist-generated -typescript/src/parser.c linguist-generated - -tsx/src/grammar.json linguist-generated -tsx/src/node-types.json linguist-generated -tsx/src/parser.c linguist-generated - -typescript/src/grammar.json -diff -typescript/src/node-types.json -diff -typescript/src/parser.c -diff - -tsx/src/grammar.json -diff -tsx/src/node-types.json -diff -tsx/src/parser.c -diff diff --git a/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/bug_report.yml b/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/bug_report.yml deleted file mode 100644 index 136c76496..000000000 --- a/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/bug_report.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Bug Report -description: File a bug or issue -title: "bug: " -labels: [bug] -body: - - type: markdown - attributes: - value: | - **Before** reporting an issue, make sure to search [existing issues](https://github.com/tree-sitter/tree-sitter-typescript/issues). Usage questions such as ***"How do I...?"*** either belong in [Discussions](https://github.com/tree-sitter/tree-sitter/discussions) upstream or in our [Discord server](https://discord.gg/w7nTvsVJhm) and will be closed. - If your issue is related to a bug in your editor-experience because your editor *leverages* tree-sitter and this parser, then it is likely your issue does *NOT* belong here and belongs in the relevant editor's repository. - - type: checkboxes - attributes: - label: Did you check existing issues? - description: Make sure you've checked all of the below before submitting an issue - options: - - label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser - required: false - - label: I have searched the existing issues of tree-sitter-typescript - required: true - - type: input - attributes: - label: "Tree-Sitter CLI Version, if relevant (output of `tree-sitter --version`)" - placeholder: "tree-sitter 0.20.8 (6bbb50bef8249e6460e7d69e42cc8146622fa4fd)" - validations: - required: false - - type: textarea - attributes: - label: Describe the bug - description: A clear and concise description of what the bug is. Please include any related errors you see such as parsing errors or tree-sitter cli errors. - validations: - required: true - - type: textarea - attributes: - label: Steps To Reproduce/Bad Parse Tree - description: Steps to reproduce the behavior. If you have a bad parse tree, please include it here. You can get this by running `tree-sitter parse ` and copying the output. - placeholder: | - 1. - 2. - 3. - validations: - required: true - - type: textarea - attributes: - label: Expected Behavior/Parse Tree - description: A concise description of what you expected to happen, or in the case of a bad parse tree, the expected parse tree. - validations: - required: true - - type: textarea - attributes: - label: Repro - description: Minimal code to reproduce this issue. Ideally this should be reproducible with the C library or the tree-sitter cli, do not suggest an editor or external tool. Also, a link to the TypeScript Playground showing that the snippet below is valid JavaScript or TypeScript would be great (https://www.typescriptlang.org/play) - value: | - // Example code that causes the issue - function foo() { - // Code that fails to parse, or causes an error - } - render: TypeScript - validations: - required: false diff --git a/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/config.yml b/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 3ba13e0ce..000000000 --- a/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1 +0,0 @@ -blank_issues_enabled: false diff --git a/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/feature_request.yml b/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/feature_request.yml deleted file mode 100644 index 9619c0048..000000000 --- a/vendored_parsers/tree-sitter-typescript/.github/ISSUE_TEMPLATE/feature_request.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Feature Request -description: Suggest a new feature -title: "feature: " -labels: [enhancement] -body: - - type: checkboxes - attributes: - label: Did you check the tree-sitter docs? - description: Make sure you read all the docs before submitting a feature request - options: - - label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser - required: false - - type: textarea - validations: - required: true - attributes: - label: Is your feature request related to a problem? Please describe. - description: A clear and concise description of what the problem is. Ex. I think the grammar models this rule incorrectly and can be improved, or the TypeScript spec has officially added a new feature that should be added to the grammar. - - type: textarea - validations: - required: true - attributes: - label: Describe the solution you'd like - description: A clear and concise description of what you want to happen. - - type: textarea - validations: - required: true - attributes: - label: Describe alternatives you've considered - description: A clear and concise description of any alternative solutions or features you've considered. - - type: textarea - validations: - required: false - attributes: - label: Additional context - description: Add any other context or screenshots about the feature request here. If your feature request is related to a new TypeScript feature, please include a link to the relevant **official** TypeScript documentation. diff --git a/vendored_parsers/tree-sitter-typescript/.github/pull_request_template.md b/vendored_parsers/tree-sitter-typescript/.github/pull_request_template.md deleted file mode 100644 index d6ee77b24..000000000 --- a/vendored_parsers/tree-sitter-typescript/.github/pull_request_template.md +++ /dev/null @@ -1,7 +0,0 @@ -# Checklist - -- [ ] All tests pass in CI. -- [ ] There are sufficient tests for the new fix/feature. -- [ ] Grammar rules have not been renamed unless absolutely necessary. -- [ ] The conflicts section hasn't grown too much. -- [ ] The parser size hasn't grown too much (check the value of STATE_COUNT in src/parser.c). diff --git a/vendored_parsers/tree-sitter-typescript/.github/workflows/ci.yml b/vendored_parsers/tree-sitter-typescript/.github/workflows/ci.yml deleted file mode 100644 index 084480365..000000000 --- a/vendored_parsers/tree-sitter-typescript/.github/workflows/ci.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: CI -on: - workflow_dispatch: - pull_request: - push: - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: true - matrix: - os: [macos-latest, ubuntu-latest] - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 18 - - run: npm install - - run: npm test - - test_windows: - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 18 - - run: npm install - - run: npm run test-windows diff --git a/vendored_parsers/tree-sitter-typescript/.github/workflows/lint.yml b/vendored_parsers/tree-sitter-typescript/.github/workflows/lint.yml deleted file mode 100644 index 103e92ae7..000000000 --- a/vendored_parsers/tree-sitter-typescript/.github/workflows/lint.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Lint - -on: - push: - branches: - - master - pull_request: - branches: - - "**" - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install modules - run: npm install - - name: Run ESLint - run: npm run lint diff --git a/vendored_parsers/tree-sitter-typescript/.github/workflows/release.yml b/vendored_parsers/tree-sitter-typescript/.github/workflows/release.yml deleted file mode 100644 index 870eb84b1..000000000 --- a/vendored_parsers/tree-sitter-typescript/.github/workflows/release.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: Release - -on: - workflow_run: - workflows: ["CI"] - branches: - - master - types: - - completed - -jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - 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@v4 - 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 }}" diff --git a/vendored_parsers/tree-sitter-typescript/.gitignore b/vendored_parsers/tree-sitter-typescript/.gitignore deleted file mode 100644 index 1dc211f8c..000000000 --- a/vendored_parsers/tree-sitter-typescript/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -Cargo.lock -node_modules -.node-version -target -build -/.build -*.log -Cargo.lock -package-lock.json -/test.ts -examples/desktop -examples/redux -examples/vscode -log.html -yarn.lock - -# These files would be generated by 'tree-sitter generate' with the default -# settings. We don't want them because there's already a copy at the root. -/tsx/Cargo.toml -/tsx/binding.gyp -/tsx/bindings -/typescript/Cargo.toml -/typescript/binding.gyp -/typescript/bindings diff --git a/vendored_parsers/tree-sitter-typescript/.npmignore b/vendored_parsers/tree-sitter-typescript/.npmignore deleted file mode 100644 index 3ff284137..000000000 --- a/vendored_parsers/tree-sitter-typescript/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -/test -/examples -/build -/script -/target -appveyor.yml diff --git a/vendored_parsers/tree-sitter-typescript/Cargo.toml b/vendored_parsers/tree-sitter-typescript/Cargo.toml deleted file mode 100644 index 80bb93244..000000000 --- a/vendored_parsers/tree-sitter-typescript/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "tree-sitter-typescript" -description = "Typescript grammar for tree-sitter" -version = "0.20.5" -authors = ["Max Brunsfeld "] -license = "MIT" -readme = "bindings/rust/README.md" -keywords = ["incremental", "parsing", "typescript", "tsx"] -categories = ["parsing", "text-editors"] -repository = "https://github.com/tree-sitter/tree-sitter-typescript" -edition = "2021" -autoexamples = false - -build = "bindings/rust/build.rs" -include = [ - "common", - "bindings/rust", - "typescript/grammar.js", - "typescript/src", - "tsx/grammar.js", - "tsx/src", - "queries", -] - -[lib] -path = "bindings/rust/lib.rs" - -[dependencies] -tree-sitter = "~0.20.10" - -[build-dependencies] -cc = "~1.0.83" diff --git a/vendored_parsers/tree-sitter-typescript/LICENSE b/vendored_parsers/tree-sitter-typescript/LICENSE deleted file mode 100644 index 131d9c019..000000000 --- a/vendored_parsers/tree-sitter-typescript/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 GitHub - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendored_parsers/tree-sitter-typescript/Package.swift b/vendored_parsers/tree-sitter-typescript/Package.swift deleted file mode 100644 index f789c0200..000000000 --- a/vendored_parsers/tree-sitter-typescript/Package.swift +++ /dev/null @@ -1,27 +0,0 @@ -// swift-tools-version: 5.6 -import PackageDescription - -let package = Package( - name: "TreeSitterTypeScript", - platforms: [.macOS(.v10_13), .iOS(.v11)], - products: [.library(name: "TreeSitterTypeScript", targets: ["TreeSitterTypeScript"])], - targets: [ - .target( - name: "TreeSitterTypeScript", - path: ".", - exclude: [ - ], - sources: [ - "typescript/src/parser.c", - "typescript/src/scanner.c", - "tsx/src/parser.c", - "tsx/src/scanner.c", - ], - resources: [ - .copy("queries"), - ], - publicHeadersPath: "bindings/swift", - cSettings: [.headerSearchPath("typescript/src")] - ), - ] -) diff --git a/vendored_parsers/tree-sitter-typescript/README.md b/vendored_parsers/tree-sitter-typescript/README.md deleted file mode 100644 index be10a5227..000000000 --- a/vendored_parsers/tree-sitter-typescript/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# tree-sitter-typescript - -[![CI](https://github.com/tree-sitter/tree-sitter-typescript/actions/workflows/ci.yml/badge.svg)](https://github.com/tree-sitter/tree-sitter-typescript/actions/workflows/ci.yml) -[![Discord](https://img.shields.io/discord/1063097320771698699?logo=discord)](https://discord.gg/w7nTvsVJhm) -[![Rust Crate](https://img.shields.io/crates/v/tree-sitter-typescript.svg)](https://crates.io/crates/tree-sitter-typescript) -[![Node Package](https://img.shields.io/npm/v/tree-sitter-typescript.svg)](https://www.npmjs.com/package/tree-sitter-typescript) - -TypeScript and TSX grammars for [tree-sitter][]. - -Because TSX and TypeScript are actually two different dialects, this module defines two grammars. Require them as follows: - -```js -require("tree-sitter-typescript").typescript; // TypeScript grammar -require("tree-sitter-typescript").tsx; // TSX grammar -``` - -For Javascript files with [flow] type annotations you can use the the `tsx` parser. - -[tree-sitter]: https://github.com/tree-sitter/tree-sitter -[flow]: https://flow.org/en/ - -References - -- [TypeScript Language Spec](https://github.com/microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md) diff --git a/vendored_parsers/tree-sitter-typescript/appveyor.yml b/vendored_parsers/tree-sitter-typescript/appveyor.yml deleted file mode 100644 index b21947bc1..000000000 --- a/vendored_parsers/tree-sitter-typescript/appveyor.yml +++ /dev/null @@ -1,22 +0,0 @@ -image: Visual Studio 2015 - -environment: - nodejs_version: "8" - -platform: - - x64 - -install: - - ps: Install-Product node $env:nodejs_version - - node --version - - npm --version - - npm install - -test_script: - - npm run test-windows - -build: off - -branches: - only: - - master diff --git a/vendored_parsers/tree-sitter-typescript/binding.gyp b/vendored_parsers/tree-sitter-typescript/binding.gyp deleted file mode 100644 index 3b4daf46a..000000000 --- a/vendored_parsers/tree-sitter-typescript/binding.gyp +++ /dev/null @@ -1,21 +0,0 @@ -{ - "targets": [ - { - "target_name": "tree_sitter_typescript_binding", - "include_dirs": [ - " -#include "nan.h" - -using namespace v8; - -extern "C" TSLanguage * tree_sitter_typescript(); -extern "C" TSLanguage * tree_sitter_tsx(); - -namespace { - -NAN_METHOD(New) {} - -void Init(Local exports, Local module) { - Local ts_tpl = Nan::New(New); - ts_tpl->SetClassName(Nan::New("Language").ToLocalChecked()); - ts_tpl->InstanceTemplate()->SetInternalFieldCount(1); - Local ts_constructor = Nan::GetFunction(ts_tpl).ToLocalChecked(); - Local ts_instance = ts_constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked(); - Nan::SetInternalFieldPointer(ts_instance, 0, tree_sitter_typescript()); - Nan::Set(ts_instance, Nan::New("name").ToLocalChecked(), Nan::New("typescript").ToLocalChecked()); - - Local tsx_tpl = Nan::New(New); - tsx_tpl->SetClassName(Nan::New("Language").ToLocalChecked()); - tsx_tpl->InstanceTemplate()->SetInternalFieldCount(1); - Local tsx_constructor = Nan::GetFunction(tsx_tpl).ToLocalChecked(); - Local tsx_instance = tsx_constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked(); - Nan::SetInternalFieldPointer(tsx_instance, 0, tree_sitter_tsx()); - Nan::Set(tsx_instance, Nan::New("name").ToLocalChecked(), Nan::New("tsx").ToLocalChecked()); - - Nan::Set(exports, Nan::New("typescript").ToLocalChecked(), ts_instance); - Nan::Set(exports, Nan::New("tsx").ToLocalChecked(), tsx_instance); -} - -NODE_MODULE(tree_sitter_typescript_binding, Init) - -} // namespace diff --git a/vendored_parsers/tree-sitter-typescript/bindings/node/index.js b/vendored_parsers/tree-sitter-typescript/bindings/node/index.js deleted file mode 100644 index b929899da..000000000 --- a/vendored_parsers/tree-sitter-typescript/bindings/node/index.js +++ /dev/null @@ -1,20 +0,0 @@ -try { - module.exports = require("../../build/Release/tree_sitter_typescript_binding"); -} catch (error1) { - if (error1.code !== 'MODULE_NOT_FOUND') { - throw error1; - } - try { - module.exports = require("../../build/Debug/tree_sitter_typescript_binding"); - } catch (error2) { - if (error2.code !== 'MODULE_NOT_FOUND') { - throw error2; - } - throw error1 - } -} - -try { - module.exports.typescript.nodeTypeInfo = require("../../typescript/src/node-types.json"); - module.exports.tsx.nodeTypeInfo = require("../../tsx/src/node-types.json"); -} catch (_) {} diff --git a/vendored_parsers/tree-sitter-typescript/bindings/node/tsx.js b/vendored_parsers/tree-sitter-typescript/bindings/node/tsx.js deleted file mode 100644 index a970e7633..000000000 --- a/vendored_parsers/tree-sitter-typescript/bindings/node/tsx.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./index').tsx; diff --git a/vendored_parsers/tree-sitter-typescript/bindings/node/typescript.js b/vendored_parsers/tree-sitter-typescript/bindings/node/typescript.js deleted file mode 100644 index 49141147e..000000000 --- a/vendored_parsers/tree-sitter-typescript/bindings/node/typescript.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./index').typescript; diff --git a/vendored_parsers/tree-sitter-typescript/bindings/rust/README.md b/vendored_parsers/tree-sitter-typescript/bindings/rust/README.md deleted file mode 100644 index 0c837394b..000000000 --- a/vendored_parsers/tree-sitter-typescript/bindings/rust/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# tree-sitter-typescript - -This crate provides a TypeScript grammar for the [tree-sitter][] parsing -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 -[`tree-sitter`][tree-sitter crate] crate to use the parsed result in any useful -way.) - -```toml -[dependencies] -tree-sitter = "~0.20.10" -tree-sitter-typescript = "~0.20.5" -``` - -Typically, you will use the [language][language func] function to add this -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 TypeScript -function and prints the result to your terminal. - -```rust -use tree_sitter::Parser; - -fn main() { - let code = r#" - function double(x) { - return x * 2; - } -"#; - let mut parser = Parser::new(); - parser - .set_language(tree_sitter_typescript::language()) - .expect("Error loading TypeScript grammar"); - let parsed = parser.parse(code, None); - println!("{:#?}", parsed); -} -``` - -If you have any questions, please reach out to us in the [tree-sitter -discussions] page. - -[language func]: https://docs.rs/tree-sitter-typescript/*/tree_sitter_typescript/fn.language.html -[Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html -[tree-sitter]: https://tree-sitter.github.io/ -[tree-sitter crate]: https://crates.io/crates/tree-sitter -[tree-sitter discussions]: https://github.com/tree-sitter/tree-sitter/discussions diff --git a/vendored_parsers/tree-sitter-typescript/bindings/rust/build.rs b/vendored_parsers/tree-sitter-typescript/bindings/rust/build.rs deleted file mode 100644 index b7cda9251..000000000 --- a/vendored_parsers/tree-sitter-typescript/bindings/rust/build.rs +++ /dev/null @@ -1,28 +0,0 @@ -fn main() { - let root_dir = std::path::Path::new("."); - let typescript_dir = root_dir.join("typescript").join("src"); - let tsx_dir = root_dir.join("tsx").join("src"); - - let mut config = cc::Build::new(); - config.include(&typescript_dir); - config - .flag_if_supported("-Wno-unused-parameter") - .flag_if_supported("-Wno-unused-but-set-variable"); - - for path in &[ - typescript_dir.join("parser.c"), - typescript_dir.join("scanner.c"), - tsx_dir.join("parser.c"), - tsx_dir.join("scanner.c"), - ] { - config.file(&path); - println!("cargo:rerun-if-changed={}", path.to_str().unwrap()); - } - - println!( - "cargo:rerun-if-changed={}", - root_dir.join("common").join("scanner.h").to_str().unwrap() - ); - - config.compile("parser-scanner"); -} diff --git a/vendored_parsers/tree-sitter-typescript/bindings/rust/lib.rs b/vendored_parsers/tree-sitter-typescript/bindings/rust/lib.rs deleted file mode 100644 index c61eeba3b..000000000 --- a/vendored_parsers/tree-sitter-typescript/bindings/rust/lib.rs +++ /dev/null @@ -1,62 +0,0 @@ -//! This crate provides Typescript and TSX grammars for the [tree-sitter][] parsing library. -//! -//! Typically, you will use the [language_typescript][language func] function to add this grammar to a -//! tree-sitter [Parser][], and then use the parser to parse some code: -//! -//! ``` -//! use tree_sitter::Parser; -//! -//! let code = r#" -//! function double(x: number): number { -//! return x * 2; -//! } -//! "#; -//! let mut parser = Parser::new(); -//! parser -//! .set_language(tree_sitter_typescript::language_typescript()) -//! .expect("Error loading typescript grammar"); -//! let parsed = parser.parse(code, None).unwrap(); -//! let root = parsed.root_node(); -//! assert!(!root.has_error()); -//! ``` -//! -//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html -//! [language func]: fn.language_typescript.html -//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html -//! [tree-sitter]: https://tree-sitter.github.io/ - -use tree_sitter::Language; - -extern "C" { - fn tree_sitter_typescript() -> Language; - fn tree_sitter_tsx() -> Language; -} - -/// Returns the tree-sitter [Language][] for this Typescript. -/// -/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html -pub fn language_typescript() -> Language { - unsafe { tree_sitter_typescript() } -} - -/// Returns the tree-sitter [Language][] for TSX. -/// -/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html -pub fn language_tsx() -> Language { - unsafe { tree_sitter_tsx() } -} - -/// The syntax highlighting query for this language. -pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.scm"); - -/// The local-variable syntax highlighting query for this language. -pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); - -/// The symbol tagging query for this language. -pub const TAGGING_QUERY: &str = include_str!("../../queries/tags.scm"); - -/// 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 -pub const TYPESCRIPT_NODE_TYPES: &str = include_str!("../../typescript/src/node-types.json"); -pub const TSX_NODE_TYPES: &str = include_str!("../../tsx/src/node-types.json"); diff --git a/vendored_parsers/tree-sitter-typescript/bindings/swift/TreeSitterTypeScript/typescript.h b/vendored_parsers/tree-sitter-typescript/bindings/swift/TreeSitterTypeScript/typescript.h deleted file mode 100644 index 5778d7768..000000000 --- a/vendored_parsers/tree-sitter-typescript/bindings/swift/TreeSitterTypeScript/typescript.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef TREE_SITTER_TYPESCRIPT_H_ -#define TREE_SITTER_TYPESCRIPT_H_ - -typedef struct TSLanguage TSLanguage; - -#ifdef __cplusplus -extern "C" { -#endif - -extern TSLanguage *tree_sitter_typescript(); -extern TSLanguage *tree_sitter_tsx(); - -#ifdef __cplusplus -} -#endif - -#endif // TREE_SITTER_TYPESCRIPT_H_ diff --git a/vendored_parsers/tree-sitter-typescript/common/corpus/declarations.txt b/vendored_parsers/tree-sitter-typescript/common/corpus/declarations.txt deleted file mode 100644 index d4dd7336d..000000000 --- a/vendored_parsers/tree-sitter-typescript/common/corpus/declarations.txt +++ /dev/null @@ -1,1418 +0,0 @@ -================================== -Ambient declarations -================================== - -declare class Error { - constructor: Function -} - -declare var foo: number; - -declare const bar = "baz"; - -declare function greet(greeting: string): void; - -declare namespace myLib { - function makeGreeting(s: string): string; - let numberOfGreetings: number; - - interface LogOptions { - verbose?: boolean; - } - interface AlertOptions { - modal: boolean; - title?: string; - color?: string; - } -} - -declare class Greeter { - constructor(greeting: string); - - greeting: string; - showGreeting(): void; -} - -declare module Foo.Bar { export var foo; }; - -declare module Foo { - break; - continue; - debugger; - do { } while (true); - for (x in null) { } - for (;;) { } - if (true) { } else { } - 1; - return; - switch (x) { - case 1: - break; - default: - break; - } - throw "hello"; - try { } - catch (e) { } - finally { } -} - ---- - -(program - (ambient_declaration - (class_declaration - name: (type_identifier) - body: (class_body - (public_field_definition - name: (property_identifier) - type: (type_annotation - (type_identifier)))))) - (ambient_declaration - (variable_declaration - (variable_declarator - name: (identifier) - type: (type_annotation - (predefined_type))))) - (ambient_declaration - (lexical_declaration - (variable_declarator - name: (identifier) - value: (string - (string_fragment))))) - (ambient_declaration - (function_signature - name: (identifier) - parameters: (formal_parameters - (required_parameter - pattern: (identifier) - type: (type_annotation - (predefined_type)))) - return_type: (type_annotation - (predefined_type)))) - (ambient_declaration - (internal_module - name: (identifier) - body: (statement_block - (function_signature - name: (identifier) - parameters: (formal_parameters - (required_parameter - pattern: (identifier) - type: (type_annotation - (predefined_type)))) - return_type: (type_annotation - (predefined_type))) - (lexical_declaration - (variable_declarator - name: (identifier) - type: (type_annotation - (predefined_type)))) - (interface_declaration - name: (type_identifier) - body: (interface_body - (property_signature - name: (property_identifier) - type: (type_annotation - (predefined_type))))) - (interface_declaration - name: (type_identifier) - body: (interface_body - (property_signature - name: (property_identifier) - type: (type_annotation - (predefined_type))) - (property_signature - name: (property_identifier) - type: (type_annotation - (predefined_type))) - (property_signature - name: (property_identifier) - type: (type_annotation - (predefined_type)))))))) - (ambient_declaration - (class_declaration - name: (type_identifier) - body: (class_body - (method_signature - name: (property_identifier) - parameters: (formal_parameters - (required_parameter - pattern: (identifier) - type: (type_annotation - (predefined_type))))) - (public_field_definition - name: (property_identifier) - type: (type_annotation - (predefined_type))) - (method_signature - name: (property_identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (predefined_type)))))) - (ambient_declaration - (module - name: (nested_identifier - object: (identifier) - property: (property_identifier)) - body: (statement_block - (export_statement - declaration: (variable_declaration - (variable_declarator - name: (identifier))))))) - (empty_statement) - (ambient_declaration - (module - name: (identifier) - body: (statement_block - (break_statement) - (continue_statement) - (debugger_statement) - (do_statement - body: (statement_block) - condition: (parenthesized_expression - (true))) - (empty_statement) - (for_in_statement - left: (identifier) - right: (null) - body: (statement_block)) - (for_statement - initializer: (empty_statement) - condition: (empty_statement) - body: (statement_block)) - (if_statement - condition: (parenthesized_expression - (true)) - consequence: (statement_block) - alternative: (else_clause - (statement_block))) - (expression_statement - (number)) - (return_statement) - (switch_statement - value: (parenthesized_expression - (identifier)) - body: (switch_body - (switch_case - value: (number) - body: (break_statement)) - (switch_default - body: (break_statement)))) - (throw_statement - (string - (string_fragment))) - (try_statement - body: (statement_block) - handler: (catch_clause - parameter: (identifier) - body: (statement_block)) - finalizer: (finally_clause - body: (statement_block))))))) - -================================================== -Exception handling -================================================== - -try {} -catch (e: unknown) {} -finally {} - ---- - -(program - (try_statement - body: (statement_block) - handler: (catch_clause - parameter: (identifier) - type: (type_annotation - (predefined_type)) - body: (statement_block)) - finalizer: (finally_clause - body: (statement_block)))) - -================================================== -Flow-style ambient class declarations with commas -================================================== - -declare interface IFoo { - bar(): number, - baz(): IBaz, -} - -declare class Foo { - bar(): number, - baz(): Baz, -} - ---- - -(program - (ambient_declaration - (interface_declaration - (type_identifier) - (interface_body - (method_signature - (property_identifier) - (formal_parameters) - (type_annotation - (predefined_type))) - (method_signature - (property_identifier) - (formal_parameters) - (type_annotation - (type_identifier)))))) - (ambient_declaration - (class_declaration - (type_identifier) - (class_body - (method_signature - (property_identifier) - (formal_parameters) - (type_annotation - (predefined_type))) - (method_signature - (property_identifier) - (formal_parameters) - (type_annotation - (type_identifier))))))) - -================================== -Flow module.exports declarations -================================== - -declare module.exports: { - foo: string; -} - ---- - -(program - (ambient_declaration - (property_identifier) - (object_type - (property_signature - (property_identifier) - (type_annotation - (predefined_type)))))) - -================================== -Ambient exports -================================== - -export default function point(x: number, y: number) { - return { x, y }; -} - -// a comment - -export default class A {} - -export async function readFile(filename: string): Promise - ---- - -(program - (export_statement - (function_declaration - (identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type))) - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (statement_block - (return_statement - (object - (shorthand_property_identifier) - (shorthand_property_identifier)))))) - (comment) - (export_statement - (class_declaration - (type_identifier) - (class_body))) - (export_statement - (function_signature - (identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (type_identifier))))))) - -================================== -Typeof types -================================== - -declare class Linter { - static findConfiguration: typeof findConfiguration; -} - ---- - -(program - (ambient_declaration - (class_declaration - (type_identifier) - (class_body - (public_field_definition - (property_identifier) - (type_annotation - (type_query - (identifier)))))))) - -================================== -Export assignments -================================== - -export = Linter; -export = {}; - ---- - -(program - (export_statement - (identifier)) - (export_statement - (object))) - -================================== -Import aliases -================================== - -import r = X.N; - ---- - -(program - (import_alias - (identifier) - (nested_identifier - (identifier) - (property_identifier)))) - -================================== -Import aliases in modules -================================== - -module C { - import r = X.N; -} - ---- - -(program - (module - (identifier) - (statement_block - (import_alias - (identifier) - (nested_identifier - (identifier) - (property_identifier)))))) - -================================== -Export import aliases -================================== - -module M { - export module N { - } - export import X = N; -} - ---- - -(program - (module - (identifier) - (statement_block - (export_statement - (module - (identifier) - (statement_block))) - (export_statement - (import_alias - (identifier) - (identifier)))))) - -================================== -Property signatures with accessibility modifiers -================================== - -export interface IAppState { - public readonly users: ReadonlyArray -} - -export class CloningRepository { - public readonly id = CloningRepositoryID++ -} - - ---- - -(program - (export_statement - (interface_declaration - (type_identifier) - (interface_body - (property_signature - (accessibility_modifier) - (property_identifier) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (type_identifier)))))))) - (export_statement - (class_declaration - (type_identifier) - (class_body - (public_field_definition - (accessibility_modifier) - (property_identifier) - (update_expression - (identifier))))))) - -================================== -Ambient type declarations -================================== - -declare type IndexableType = string | number | Date | Array; - ---- - -(program - (ambient_declaration - (type_alias_declaration - (type_identifier) - (union_type - (union_type - (union_type - (predefined_type) - (predefined_type)) - (type_identifier)) - (generic_type - (type_identifier) - (type_arguments - (union_type - (union_type - (predefined_type) - (predefined_type)) - (type_identifier)))))))) - -================================== -Ambient module declarations -================================== - -module Promise { - var on: {} - export function resolve(value?: Thenable): Promise; -} - -declare module "example" - -declare module "example" { } - ---- - -(program - (module - (identifier) - (statement_block - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (object_type)))) - (export_statement - (function_signature - (identifier) - (type_parameters - (type_parameter - (type_identifier))) - (formal_parameters - (optional_parameter - (identifier) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (type_identifier)))))) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (type_identifier)))))))) - (ambient_declaration - (module - (string - (string_fragment)))) - (ambient_declaration - (module - (string - (string_fragment)) - (statement_block)))) - -================================= -Accessibility modifiers as pair keywords -================================= - -x = { name, description, private: private_ } - ---- - -(program - (expression_statement - (assignment_expression - (identifier) - (object - (shorthand_property_identifier) - (shorthand_property_identifier) - (pair - (property_identifier) - (identifier)))))) - -================================= -Type casts -================================= - -foo as any as Array -bar satisfies number[] -"foobar" as const - ---- - -(program - (expression_statement - (as_expression - (as_expression - (identifier) - (predefined_type)) - (generic_type - (type_identifier) - (type_arguments - (predefined_type))))) - (expression_statement - (satisfies_expression - (identifier) - (array_type - (predefined_type)))) - (expression_statement - (as_expression - (string - (string_fragment))))) - -================================= -Ambient export function declarations -================================= - -export interface Foo { - export function OrderedMap(iter: Iterable.Keyed): OrderedMap; -} - ---- - -(program - (export_statement - (interface_declaration - (type_identifier) - (interface_body - (export_statement - (function_signature - (identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (generic_type - (nested_type_identifier - (identifier) - (type_identifier)) - (type_arguments - (type_identifier) - (type_identifier)))))) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (type_identifier) - (type_identifier)))))))))) - -================================= -Ambient type alias declarations in namespaces -================================= - -declare namespace moment { - type formatFunction = () => string; - - export var x: string; - export class foo { - - } - export function utc(): Moment; - export const enum Blah { Blaz, Bloz, Bleez } -} - ---- - -(program - (ambient_declaration - (internal_module - (identifier) - (statement_block - (type_alias_declaration - (type_identifier) - (function_type - (formal_parameters) - (predefined_type))) - (export_statement - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (predefined_type))))) - (export_statement - (class_declaration - (type_identifier) - (class_body))) - (export_statement - (function_signature - (identifier) - (formal_parameters) - (type_annotation - (type_identifier)))) - (export_statement - (enum_declaration - (identifier) - (enum_body - (property_identifier) - (property_identifier) - (property_identifier)))))))) - -================================= -Export interfaces in namespaces -================================= - -declare namespace Foo { - export interface Bar { - } -} - ---- - -(program - (ambient_declaration - (internal_module - (identifier) - (statement_block - (export_statement - (interface_declaration - (type_identifier) - (interface_body))))))) - -================================= -Namespaces as internal modules -================================= - -namespace Foo { -} - -namespace Bar { - var x; -} - ---- - -(program - (expression_statement - (internal_module - (identifier) - (statement_block))) - (expression_statement - (internal_module - (identifier) - (statement_block - (variable_declaration - (variable_declarator - (identifier))))))) - -=========================================== -Method declarations with keywords as names -=========================================== - -class Foo { - private async() {}; - get(): Result {}; - private set(plugin) {}; -} - ---- - -(program - (class_declaration - (type_identifier) - (class_body - (method_definition - (accessibility_modifier) - (property_identifier) - (formal_parameters) - (statement_block)) - (method_definition - (property_identifier) - (formal_parameters) - (type_annotation - (type_identifier)) - (statement_block)) - (method_definition - (accessibility_modifier) - (property_identifier) - (formal_parameters - (required_parameter - (identifier))) - (statement_block))))) - -======================================= -Classes with method signatures -======================================= - -class Foo { - public async waitFor(func: () => T | Promise, accept?: (result: T) => boolean | Promise, timeoutMessage?: string, retryCount?: number): Promise; - - public readonly async bar?(); - private static bar(); - private static async bar(): T; -} - ---- - -(program - (class_declaration - (type_identifier) - (class_body - (method_signature - (accessibility_modifier) - (property_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (function_type - (formal_parameters) - (union_type - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (union_type - (type_identifier) - (literal_type - (undefined))))))))) - (optional_parameter - (identifier) - (type_annotation - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (union_type - (predefined_type) - (generic_type - (type_identifier) - (type_arguments - (predefined_type))))))) - (optional_parameter - (identifier) - (type_annotation - (predefined_type))) - (optional_parameter - (identifier) - (type_annotation - (predefined_type)))) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (type_identifier))))) - (method_signature - (accessibility_modifier) - (property_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (formal_parameters)) - (method_signature - (accessibility_modifier) - (property_identifier) - (formal_parameters)) - (method_signature - (accessibility_modifier) - (property_identifier) - (formal_parameters) - (type_annotation - (type_identifier)))))) - -======================================= -Classes with property names as strings or numbers -======================================= - -class Foo { - static 2: string; - public static 2: string = 'string'; - public static readonly 'hello'?: int = 'string'; - static readonly 'hello'?: int = 'string'; - readonly 'hello'?: int = 'string'; -} - ---- - -(program - (class_declaration - (type_identifier) - (class_body - (public_field_definition - (number) - (type_annotation - (predefined_type))) - (public_field_definition - (accessibility_modifier) - (number) - (type_annotation - (predefined_type)) - (string - (string_fragment))) - (public_field_definition - (accessibility_modifier) - (string - (string_fragment)) - (type_annotation - (type_identifier)) - (string - (string_fragment))) - (public_field_definition - (string - (string_fragment)) - (type_annotation - (type_identifier)) - (string - (string_fragment))) - (public_field_definition - (string - (string_fragment)) - (type_annotation - (type_identifier)) - (string - (string_fragment)))))) - -======================================= -Classes with decorators -======================================= - -@baz @bam class Foo { - @foo static 2: string; - @bar.buzz(grue) public static 2: string = 'string'; - @readonly readonly 'hello'?: int = 'string'; - @readonly fooBar(@required param: any, @optional param2?: any) { - } -} - ---- - -(program - (class_declaration - (decorator - (identifier)) - (decorator - (identifier)) - (type_identifier) - (class_body - (public_field_definition - (decorator - (identifier)) - (number) - (type_annotation - (predefined_type))) - (public_field_definition - (decorator - (call_expression - (member_expression - (identifier) - (property_identifier)) - (arguments - (identifier)))) - (accessibility_modifier) - (number) - (type_annotation - (predefined_type)) - (string - (string_fragment))) - (public_field_definition - (decorator - (identifier)) - (string - (string_fragment)) - (type_annotation - (type_identifier)) - (string - (string_fragment))) - (decorator - (identifier)) - (method_definition - (property_identifier) - (formal_parameters - (required_parameter - (decorator - (identifier)) - (identifier) - (type_annotation - (predefined_type))) - (optional_parameter - (decorator - (identifier)) - (identifier) - (type_annotation - (predefined_type)))) - (statement_block))))) - -======================================= -Classes with methods with and without trailing semicolons on one line -======================================= - -class Foo extends Baz { bar = 5; static one(a) { return a; }; two(b) { return b; } three(c) { return c; } } - ---- - -(program - (class_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (class_heritage - (extends_clause - (identifier))) - (class_body - (public_field_definition - (property_identifier) - (number)) - (method_definition - (property_identifier) - (formal_parameters - (required_parameter - (identifier))) - (statement_block - (return_statement - (identifier)))) - (method_definition - (property_identifier) - (formal_parameters - (required_parameter - (identifier))) - (statement_block - (return_statement - (identifier)))) - (method_definition - (property_identifier) - (formal_parameters - (required_parameter - (identifier))) - (statement_block - (return_statement - (identifier))))))) - -======================================= -Classes with static blocks -======================================= - -class Foo { - static { - this.#bar = ''; - } - static { - this.baz(); - } -} - ---- - -(program - (class_declaration - (type_identifier) - (class_body - (class_static_block - (statement_block - (expression_statement - (assignment_expression - (member_expression - (this) - (private_property_identifier)) - (string))))) - (class_static_block - (statement_block - (expression_statement - (call_expression - (member_expression - (this) - (property_identifier)) - (arguments)))))))) - -======================================= -Global namespace declarations -======================================= - -declare global { -} - ---- - -(program - (ambient_declaration - (statement_block))) - -======================================= -Abstract classes -======================================= - -abstract class Foo { -} - -abstract class Animal { - readonly abstract prop: string; - requiredProp!: string; - abstract makeSound(): void; - abstract get readonlyProp(): string; - protected abstract readonlyProp?(): string; - move(): void { - console.log("roaming the earth..."); - } -} - -@bar -abstract class Foo { -} - ---- - -(program - (abstract_class_declaration - name: (type_identifier) - body: (class_body)) - (abstract_class_declaration - name: (type_identifier) - body: (class_body - (public_field_definition - name: (property_identifier) - type: (type_annotation - (predefined_type))) - (public_field_definition - name: (property_identifier) - type: (type_annotation - (predefined_type))) - (abstract_method_signature - name: (property_identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (predefined_type))) - (abstract_method_signature - name: (property_identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (predefined_type))) - (abstract_method_signature - (accessibility_modifier) - name: (property_identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (predefined_type))) - (method_definition - name: (property_identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (predefined_type)) - body: (statement_block - (expression_statement - (call_expression - function: (member_expression - object: (identifier) - property: (property_identifier)) - arguments: (arguments - (string - (string_fragment))))))))) - (abstract_class_declaration - decorator: (decorator - (identifier)) - name: (type_identifier) - body: (class_body))) - -================================== -Index type queries -================================== - -export type Extracted = keyof Pick - ---- - -(program - (export_statement - declaration: (type_alias_declaration - name: (type_identifier) - value: (index_type_query - (generic_type - name: (type_identifier) - type_arguments: (type_arguments - (type_identifier) - (literal_type - (string - (string_fragment))))))))) - -================================== -Definite assignment assertions -================================== - -var a!: b; -let a!: b; - ---- - -(program - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (type_identifier)))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (type_identifier))))) - -==================================== -Top-level exports -==================================== - -export default abstract class C { } -export default class C { } -export class C { } -export default interface I { } -export interface I { } - ---- - -(program - (export_statement - (abstract_class_declaration - (type_identifier) - (class_body))) - (export_statement - (class_declaration - (type_identifier) - (class_body))) - (export_statement - (class_declaration - (type_identifier) - (class_body))) - (export_statement - (interface_declaration - (type_identifier) - (interface_body))) - (export_statement - (interface_declaration - (type_identifier) - (interface_body)))) - -======================================= -Classes with generic parameters -======================================= - -class A< - B, - C, -> {} - -class D extends A< - X, - Y, -> {} - ---- - -(program - (class_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (class_body)) - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (identifier) - (type_arguments - (type_identifier) - (type_identifier)))) - (class_body))) - -======================================= -Classes with extensions -======================================= - -class A extends B(D) implements C {} -export class A extends B(D) implements C {} - -class A extends B(D) implements C {} -export class A extends B(D) implements C {} - -export class A extends B implements C {} - ---- - -(program - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (call_expression - (identifier) - (type_arguments - (type_identifier)) - (arguments - (identifier)))) - (implements_clause - (type_identifier))) - (class_body)) - (export_statement - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (call_expression - (identifier) - (type_arguments - (type_identifier)) - (arguments - (identifier)))) - (implements_clause - (type_identifier))) - (class_body))) - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (call_expression - (identifier) - (type_arguments - (type_identifier)) - (arguments - (identifier))) - (type_arguments - (type_identifier))) - (implements_clause - (type_identifier))) - (class_body)) - (export_statement - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (call_expression - (identifier) - (type_arguments - (type_identifier)) - (arguments - (identifier))) - (type_arguments - (type_identifier))) - (implements_clause - (type_identifier))) - (class_body))) - (export_statement - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (identifier) - (type_arguments - (type_identifier) - (type_identifier))) - (implements_clause - (type_identifier))) - (class_body)))) - -========================================================================== -Semicolon is not automatically inserted for method definitions with a body -========================================================================== - -class Foo { - public bar() - { - } -} - ---- - -(program - (class_declaration - (type_identifier) - (class_body - (method_definition - (accessibility_modifier) - (property_identifier) - (formal_parameters) - (statement_block))))) - -===================== -Override modifier -===================== - -abstract class Foo { - abstract baz(): void; -} - -class Bar extends Foo { - override baz() {} -} - ---- - -(program - (abstract_class_declaration - name: (type_identifier) - body: (class_body - (abstract_method_signature - name: (property_identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (predefined_type))))) - (class_declaration - name: (type_identifier) - (class_heritage - (extends_clause - value: (identifier))) - body: (class_body - (method_definition - (override_modifier) - name: (property_identifier) - parameters: (formal_parameters) - body: (statement_block))))) diff --git a/vendored_parsers/tree-sitter-typescript/common/corpus/expressions.txt b/vendored_parsers/tree-sitter-typescript/common/corpus/expressions.txt deleted file mode 100644 index 522fd7430..000000000 --- a/vendored_parsers/tree-sitter-typescript/common/corpus/expressions.txt +++ /dev/null @@ -1,357 +0,0 @@ -================================== -As expressions -================================== - -h as `hello` -T as {} & { [t: T]: T } -T as {} & { [t: T]: T } & { [g: G]: G } - ---- - -(program - (expression_statement - (as_expression - (identifier) - (template_literal_type))) - (expression_statement - (as_expression - (identifier) - (intersection_type - (object_type) - (object_type - (index_signature - (identifier) - (type_identifier) - (type_annotation - (type_identifier))))))) - (expression_statement - (as_expression - (identifier) - (intersection_type - (intersection_type - (object_type) - (object_type - (index_signature - (identifier) - (type_identifier) - (type_annotation - (type_identifier))))) - (object_type - (index_signature - (identifier) - (type_identifier) - (type_annotation - (type_identifier)))))))) - -================================== -Satisfies expressions -================================== - -h satisfies `hello` -T satisfies {} & { [t: T]: T } -T satisfies {} & { [t: T]: T } & { [g: G]: G } - ---- - -(program - (expression_statement - (satisfies_expression - (identifier) - (template_literal_type))) - (expression_statement - (satisfies_expression - (identifier) - (intersection_type - (object_type) - (object_type - (index_signature - (identifier) - (type_identifier) - (type_annotation - (type_identifier))))))) - (expression_statement - (satisfies_expression - (identifier) - (intersection_type - (intersection_type - (object_type) - (object_type - (index_signature - (identifier) - (type_identifier) - (type_annotation - (type_identifier))))) - (object_type - (index_signature - (identifier) - (type_identifier) - (type_annotation - (type_identifier)))))))) - -================================== -Typeof expressions -================================== - -typeof class {} === "function"; - -typeof module === "object" && typeof module.exports === "object" - ---- - -(program - (expression_statement - (binary_expression - (unary_expression - (class - (class_body))) - (string - (string_fragment)))) - (expression_statement - (binary_expression - (binary_expression - (unary_expression - (identifier)) - (string - (string_fragment))) - (binary_expression - (unary_expression - (member_expression - (identifier) - (property_identifier))) - (string - (string_fragment)))))) - -================================== -Array with empty elements -================================== - -[, a, , b, , , , s, , , ] - ---- - -(program - (expression_statement - (array - (identifier) - (identifier) - (identifier)))) - -================================== -Variable named 'module' -================================== - -var module; -module; - ---- - -(program - (variable_declaration - (variable_declarator - (identifier))) - (expression_statement - (identifier))) - -================================== -Multi-line variable declarations -================================== - -var a = b - , c = d - , e = f - ---- - -(program - (variable_declaration - (variable_declarator - (identifier) - (identifier)) - (variable_declarator - (identifier) - (identifier)) - (variable_declarator - (identifier) - (identifier)))) - -===================================== -The 'less than' operator -===================================== - -i < foo.length; -i < type.length; -i < string.length; - ---- - -(program - (expression_statement - (binary_expression - (identifier) - (member_expression - (identifier) - (property_identifier)))) - (expression_statement - (binary_expression - (identifier) - (member_expression - (identifier) - (property_identifier)))) - (expression_statement - (binary_expression - (identifier) - (member_expression - (identifier) - (property_identifier))))) - -===================================== -Subscript expressions in if statements -===================================== - -if ( foo ) { - set[ 1 ].apply() -} - ---- - -(program - (if_statement - (parenthesized_expression - (identifier)) - (statement_block - (expression_statement - (call_expression - (member_expression - (subscript_expression - (identifier) - (number)) - (property_identifier)) - (arguments)))))) - -==================================== -Objects with reserved words as keys -==================================== - -{ - public: true, - private: true, - readonly: true -}; - -{ - readonly: 1, - abstract: 1, - static: 1 -}; - ---- - -(program - (expression_statement - (object - (pair - key: (property_identifier) - value: (true)) - (pair - key: (property_identifier) - value: (true)) - (pair - key: (property_identifier) - value: (true)))) - (expression_statement - (object - (pair - key: (property_identifier) - value: (number)) - (pair - key: (property_identifier) - value: (number)) - (pair - key: (property_identifier) - value: (number))))) - -==================================== -Assignment to non-null LHS -==================================== - -foo! = bar; -foo! += bar; -(foo)! = bar; -(foo)! += bar; - ---- - -(program - (expression_statement - (assignment_expression - (non_null_expression - (identifier)) - (identifier))) - (expression_statement - (augmented_assignment_expression - (non_null_expression - (identifier)) - (identifier))) - (expression_statement - (assignment_expression - (non_null_expression - (parenthesized_expression - (identifier))) - (identifier))) - (expression_statement - (augmented_assignment_expression - (non_null_expression - (parenthesized_expression - (identifier))) - (identifier)))) - -================================== -Generic calls -================================== - -f(x) - ---- - -(program - (expression_statement - (call_expression - (identifier) - (type_arguments - (type_identifier)) - (arguments - (identifier))))) - -================================== -Instantiation expressions -================================== - -const makeHammerBox = makeBox; -const makeStringBox = makeBox; -const ErrorMap = Map; - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (instantiation_expression - (identifier) - (type_arguments - (type_identifier))))) - (lexical_declaration - (variable_declarator - (identifier) - (instantiation_expression - (identifier) - (type_arguments - (predefined_type))))) - (lexical_declaration - (variable_declarator - (identifier) - (instantiation_expression - (identifier) - (type_arguments - (predefined_type) - (type_identifier)))))) diff --git a/vendored_parsers/tree-sitter-typescript/common/corpus/functions.txt b/vendored_parsers/tree-sitter-typescript/common/corpus/functions.txt deleted file mode 100644 index 738baadff..000000000 --- a/vendored_parsers/tree-sitter-typescript/common/corpus/functions.txt +++ /dev/null @@ -1,340 +0,0 @@ -================================== -Functions with typed parameters -================================== - -function greeter(person: string) { - return "Hello, " + person; -} - -function foo(x: T): T { - -} - -function foo(a: T[], f: (x: T) => U): U[] { - -} - -function foo(this: T[]): U[] { - return [] -} - -function foo(x: T, y: U) { - -} - ---- - -(program - (function_declaration - name: (identifier) - parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (predefined_type)))) - body: (statement_block - (return_statement (binary_expression - left: (string (string_fragment)) - right: (identifier))))) - (function_declaration - name: (identifier) - type_parameters: (type_parameters (type_parameter name: (type_identifier))) - parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (type_identifier)))) - return_type: (type_annotation (type_identifier)) - body: (statement_block)) - (function_declaration - name: (identifier) - type_parameters: (type_parameters (type_parameter name: (type_identifier)) (type_parameter name: (type_identifier))) - parameters: (formal_parameters - (required_parameter - pattern: (identifier) - type: (type_annotation (array_type (type_identifier)))) - (required_parameter - pattern: (identifier) - type: (type_annotation - (function_type - parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (type_identifier)))) - return_type: (type_identifier))))) - return_type: (type_annotation (array_type (type_identifier))) - body: (statement_block)) - (function_declaration - name: (identifier) - type_parameters: (type_parameters (type_parameter name: (type_identifier)) (type_parameter name: (type_identifier))) - parameters: (formal_parameters - (required_parameter - pattern: (this) - type: (type_annotation (array_type (type_identifier))))) - return_type: (type_annotation (array_type (type_identifier))) - body: (statement_block (return_statement (array)))) - (function_declaration - name: (identifier) - type_parameters: (type_parameters - (type_parameter name: (type_identifier)) - (type_parameter name: (type_identifier) constraint: (constraint (predefined_type)))) - parameters: (formal_parameters - (required_parameter - pattern: (identifier) - type: (type_annotation (type_identifier))) - (required_parameter - pattern: (identifier) - type: (type_annotation (type_identifier)))) - body: (statement_block))) - -================================== -New object with type arguments -================================== - -const lines = new Array() - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (new_expression - (identifier) - (type_arguments (type_identifier)) - (arguments))))) - -=================================================== -Function calls with array and tuple type arguments -=================================================== - -a.b<[C]>(); -a(); - ---- - -(program - (expression_statement - (call_expression - function: (member_expression - object: (identifier) - property: (property_identifier)) - type_arguments: (type_arguments (tuple_type (type_identifier))) - arguments: (arguments))) - (expression_statement - (call_expression - function: (identifier) - type_arguments: (type_arguments - (array_type (nested_type_identifier - module: (identifier) - name: (type_identifier)))) - arguments: (arguments)))) - -========================================================= -Function calls with optional chaining and type arguments -========================================================= - -A?.(); - ---- - -(program - (expression_statement - (call_expression - (identifier) - (type_arguments (type_identifier)) - (arguments)))) - -================================== -Arrow functions and generators with call signatures -================================== - -(amount, interestRate, duration): number => 2 - -function* foo(amount, interestRate, duration): number { - yield amount * interestRate * duration / 12 -} - -(module: any): number => 2 - ---- - -(program - (expression_statement - (arrow_function - type_parameters: (type_parameters (type_parameter name: (type_identifier))) - parameters: (formal_parameters - (required_parameter pattern: (identifier)) - (required_parameter pattern: (identifier)) - (required_parameter pattern: (identifier))) - return_type: (type_annotation (predefined_type)) - body: (number))) - (generator_function_declaration - name: (identifier) - type_parameters: (type_parameters (type_parameter name: (type_identifier))) - parameters: (formal_parameters - (required_parameter pattern: (identifier)) - (required_parameter pattern: (identifier)) - (required_parameter pattern: (identifier))) - return_type: (type_annotation (predefined_type)) - body: (statement_block - (expression_statement (yield_expression (binary_expression - left: (binary_expression left: (binary_expression left: (identifier) right: (identifier)) right: (identifier)) - right: (number)))))) - (expression_statement - (arrow_function - parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (predefined_type)))) - return_type: (type_annotation (predefined_type)) - body: (number)))) - -================================== -Arrow function with parameter named async -================================== - -const x = async => async; - ---- - -(program - (lexical_declaration (variable_declarator (identifier) (arrow_function (identifier) (identifier))))) - -================================== -Super -================================== - -class A extends B { - constructor(x: number, y: number) { - super(x); - } - public toString() { - return super.toString() + " y=" + this.y; - } -} - ---- - -(program - (class_declaration - name: (type_identifier) - (class_heritage (extends_clause value: (identifier))) - body: (class_body - (method_definition - name: (property_identifier) - parameters: (formal_parameters - (required_parameter pattern: (identifier) type: (type_annotation (predefined_type))) - (required_parameter pattern: (identifier) type: (type_annotation (predefined_type)))) - body: (statement_block - (expression_statement (call_expression - function: (super) - arguments: (arguments (identifier)))))) - (method_definition - (accessibility_modifier) - name: (property_identifier) - parameters: (formal_parameters) - body: (statement_block - (return_statement - (binary_expression - left: (binary_expression - left: (call_expression - function: (member_expression - object: (super) - property: (property_identifier)) - arguments: (arguments)) - right: (string (string_fragment))) - right: (member_expression - object: (this) - property: (property_identifier))))))))) - - -================== -Function signature -================== - -export default function foo(): bar - ---- - -(program - (export_statement - (function_signature - (identifier) - (formal_parameters) - (type_annotation (type_identifier))))) - -============================================================= -Ambiguity between function signature and function declaration -============================================================= - -function foo() -{} - -function foo(bar) -function foo(bar): baz; -function foo(bar) - -function foo(): () => { [key: foo]: bar } -function foo(): () => { [key: foo]: bar } {} - ---- - -(program - (function_declaration - name: (identifier) - parameters: (formal_parameters) - body: (statement_block)) - (function_signature - name: (identifier) - parameters: (formal_parameters (required_parameter pattern: (identifier)))) - (function_signature - name: (identifier) - parameters: (formal_parameters (required_parameter pattern: (identifier))) - return_type: (type_annotation (type_identifier))) - (function_signature - name: (identifier) - parameters: (formal_parameters - (required_parameter pattern: (identifier)))) - (function_signature - name: (identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (function_type - parameters: (formal_parameters) - return_type: (object_type - (index_signature - name: (identifier) - index_type: (type_identifier) - type: (type_annotation (type_identifier))))))) - (function_declaration - name: (identifier) - parameters: (formal_parameters) - return_type: (type_annotation - (function_type - parameters: (formal_parameters) - return_type: (object_type - (index_signature - name: (identifier) - index_type: (type_identifier) - type: (type_annotation (type_identifier)))))) - body: (statement_block))) - -==================================================================================== -Ambiguity between function signature and function declaration: comments and newlines -==================================================================================== - -function foo() - // above is a signature -foo(); - -function bar() - // above is a function declaration -{} - -function foo() - : number; - ---- - -(program - (function_signature (identifier) (formal_parameters)) - (comment) - (expression_statement (call_expression (identifier) (arguments))) - - (function_declaration - (identifier) - (formal_parameters) - (comment) - (statement_block)) - - (function_signature - (identifier) - (formal_parameters) - (type_annotation (predefined_type)))) diff --git a/vendored_parsers/tree-sitter-typescript/common/corpus/types.txt b/vendored_parsers/tree-sitter-typescript/common/corpus/types.txt deleted file mode 100644 index d3a83e813..000000000 --- a/vendored_parsers/tree-sitter-typescript/common/corpus/types.txt +++ /dev/null @@ -1,2114 +0,0 @@ -======================================= -Built-in types -======================================= - -var x: string = 'hi'; -var y: number; - ---- - -(program - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (predefined_type)) - (string - (string_fragment)))) - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (predefined_type))))) - -======================================= -Parenthesized types -======================================= - -var x: (string); -var x: ({a: any}); - ---- - -(program - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (parenthesized_type - (predefined_type))))) - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (parenthesized_type - (object_type - (property_signature - (property_identifier) - (type_annotation - (predefined_type))))))))) - -======================================= -Object types -======================================= - -let person: {name: string, age: number}; -let thing: { [type: string]: string }; -type T = { [K in keyof T]-?: any } -type T = { [K in keyof T]?: any } -type T = { -readonly [K in keyof T]: any } - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (object_type - (property_signature - (property_identifier) - (type_annotation - (predefined_type))) - (property_signature - (property_identifier) - (type_annotation - (predefined_type))))))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (object_type - (index_signature - (identifier) - (predefined_type) - (type_annotation - (predefined_type))))))) - (type_alias_declaration - (type_identifier) - (object_type - (index_signature - (mapped_type_clause - (type_identifier) - (index_type_query - (type_identifier))) - (omitting_type_annotation - (predefined_type))))) - (type_alias_declaration - (type_identifier) - (object_type - (index_signature - (mapped_type_clause - (type_identifier) - (index_type_query - (type_identifier))) - (opting_type_annotation - (predefined_type))))) - (type_alias_declaration - (type_identifier) - (object_type - (index_signature - (mapped_type_clause - (type_identifier) - (index_type_query - (type_identifier))) - (type_annotation - (predefined_type)))))) - -======================================= -Object types with call signatures -======================================= - -let MyFunction: { - (string): string, - length: number -}; - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (object_type - (call_signature - (formal_parameters - (required_parameter - (identifier))) - (type_annotation - (predefined_type))) - (property_signature - (property_identifier) - (type_annotation - (predefined_type)))))))) - -==================================================== -Index signatures -==================================================== - -type Foo = { - [b: string]: any; - readonly [c: number]: string; -} - ---- - -(program - (type_alias_declaration - (type_identifier) - (object_type - (index_signature - (identifier) - (predefined_type) - (type_annotation - (predefined_type))) - (index_signature - (identifier) - (predefined_type) - (type_annotation - (predefined_type)))))) - -==================================================== -Object types with automatic semicolon insertion -==================================================== - -type Something = { - length: number - (string): string - [index:string] : number -} - ---- - -(program - (type_alias_declaration - (type_identifier) - (object_type - (property_signature - (property_identifier) - (type_annotation - (predefined_type))) - (call_signature - (formal_parameters - (required_parameter - (identifier))) - (type_annotation - (predefined_type))) - (index_signature - (identifier) - (predefined_type) - (type_annotation - (predefined_type)))))) - -========================================================== -Automatic semicolon disabled before return type -========================================================== - -function f(): any { - 'a'; - 'b'; -} - -function -f -() - : - any { - 'a' - 'b' -} - ---- - -(program - (function_declaration - (identifier) - (formal_parameters) - (type_annotation - (predefined_type)) - (statement_block - (expression_statement - (string - (string_fragment))) - (expression_statement - (string - (string_fragment))))) - (function_declaration - (identifier) - (formal_parameters) - (type_annotation - (predefined_type)) - (statement_block - (expression_statement - (string - (string_fragment))) - (expression_statement - (string - (string_fragment)))))) - -======================================= -Array types -======================================= - -let x: X[]; - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (array_type - (type_identifier)))))) - -======================================= -Function types -======================================= - -let x: (result: string) => any; -const foo: (this: Readable, size?: number) => any; - - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (predefined_type))))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (function_type - (formal_parameters - (required_parameter - (this) - (type_annotation - (type_identifier))) - (optional_parameter - (identifier) - (type_annotation - (predefined_type)))) - (predefined_type)))))) - -====================================== -Functions with destructured parameters -====================================== - -let foo: ({a}: Foo) => number - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (function_type - (formal_parameters - (required_parameter - (object_pattern - (shorthand_property_identifier_pattern)) - (type_annotation - (type_identifier)))) - (predefined_type)))))) - -======================================= -Constructor types -======================================= - -let x: new < T1, T2 > ( p1, p2 ) => R; - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (constructor_type - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (formal_parameters - (required_parameter - (identifier)) - (required_parameter - (identifier))) - (type_identifier)))))) - -======================================= -Symbol types -======================================= - -const symFoo: unique symbol = Symbol("foo"); -const symBar: symbol = Symbol.for("bar"); - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (predefined_type)) - (call_expression - (identifier) - (arguments - (string - (string_fragment)))))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (predefined_type)) - (call_expression - (member_expression - (identifier) - (property_identifier)) - (arguments - (string - (string_fragment))))))) - -======================================= -Type annotations in parenthesized expressions -======================================= - -const range = (document: any).selection.createRange() - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (call_expression - (member_expression - (member_expression - (parenthesized_expression - (identifier) - (type_annotation - (predefined_type))) - (property_identifier)) - (property_identifier)) - (arguments))))) - -======================================= -Flow Maybe Types -======================================= - -const editor: ?CodeEditor -const miscArray: ?T[] - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (flow_maybe_type - (type_identifier))))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (flow_maybe_type - (array_type - (type_identifier))))))) - -======================================= -Flow Import Types -======================================= - -import type {UserID, User} from "./User.js"; -import {type UserID, type User} from "./User.js"; -import typeof {jimiguitar as GuitarT} from "./User.js"; -import type UserID, {addUser, removeUser} from './User.js'; - -import type from './User.js'; -import type, {addUser} from './User.js'; -import {type} from './User.js'; -import {addUser as type} from './User.js'; -import {type as addUser} from './User.js'; -import {type, addUser} from './User.js'; -import {addUser, type} from './User.js'; -import type, {addUser, type User} from './User.js'; - ---- - -(program - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier)) - (import_specifier - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier)) - (import_specifier - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier) - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (identifier) - (named_imports - (import_specifier - (identifier)) - (import_specifier - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (identifier)) - (string - (string_fragment))) - (import_statement - (import_clause - (identifier) - (named_imports - (import_specifier - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier) - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier) - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier)) - (import_specifier - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (named_imports - (import_specifier - (identifier)) - (import_specifier - (identifier)))) - (string - (string_fragment))) - (import_statement - (import_clause - (identifier) - (named_imports - (import_specifier - (identifier)) - (import_specifier - (identifier)))) - (string - (string_fragment)))) - -======================================= -Type-only Export -======================================= - -export type { UserType } -export type { UserType } from "./User.js"; -export type { A, B, C as D } from 'mymodule'; - ---- - -(program - (export_statement - (export_clause - (export_specifier - (identifier)))) - (export_statement - (export_clause - (export_specifier - (identifier))) - (string - (string_fragment))) - (export_statement - (export_clause - (export_specifier - (identifier)) - (export_specifier - (identifier)) - (export_specifier - (identifier) - (identifier))) - (string - (string_fragment)))) - -======================================= -Flow Export Types -======================================= - -export type UserType = {}; -export interface UserInterface {} - ---- - -(program - (export_statement - (type_alias_declaration - (type_identifier) - (object_type))) - (export_statement - (interface_declaration - (type_identifier) - (interface_body)))) - -======================================= -Type alias declarations -======================================= - -type FileMergeData = { - document: Doc, - headDocument: Doc, - baseDocument: Doc, - conflicts: ConflictInfo[] -} - -type ConflictInfo = { - start?: LineHandle, - middle?: LineHandle, - end?: LineHandle -} - ---- - -(program - (type_alias_declaration - (type_identifier) - (object_type - (property_signature - (property_identifier) - (type_annotation - (type_identifier))) - (property_signature - (property_identifier) - (type_annotation - (type_identifier))) - (property_signature - (property_identifier) - (type_annotation - (type_identifier))) - (property_signature - (property_identifier) - (type_annotation - (array_type - (type_identifier)))))) - (type_alias_declaration - (type_identifier) - (object_type - (property_signature - (property_identifier) - (type_annotation - (type_identifier))) - (property_signature - (property_identifier) - (type_annotation - (type_identifier))) - (property_signature - (property_identifier) - (type_annotation - (type_identifier)))))) - -======================================= -Enum declarations -======================================= - -enum Test { - A, - 'B', - 'C' = Math.floor(Math.random() * 1000), - D = 10, - E -} - -enum Style { - None = 0, - Bold = 1, - Italic = 2, - Underline = 4, - Emphasis = Bold | Italic, - Hyperlink = Bold | Underline -} - ---- - -(program - (enum_declaration - (identifier) - (enum_body - (property_identifier) - (string - (string_fragment)) - (enum_assignment - (string - (string_fragment)) - (call_expression - (member_expression - (identifier) - (property_identifier)) - (arguments - (binary_expression - (call_expression - (member_expression - (identifier) - (property_identifier)) - (arguments)) - (number))))) - (enum_assignment - (property_identifier) - (number)) - (property_identifier))) - (enum_declaration - (identifier) - (enum_body - (enum_assignment - (property_identifier) - (number)) - (enum_assignment - (property_identifier) - (number)) - (enum_assignment - (property_identifier) - (number)) - (enum_assignment - (property_identifier) - (number)) - (enum_assignment - (property_identifier) - (binary_expression - (identifier) - (identifier))) - (enum_assignment - (property_identifier) - (binary_expression - (identifier) - (identifier)))))) - -======================================= -Interface declarations -======================================= - -interface A { a: string; } - -interface B extends A { b: string; } - -interface Friend { - name: string; - favoriteColor?: string; -} - -interface G { - x: T; - y: U; -} - -interface X { - hook: { - } - get(key: Key): Promise; -} - -interface Enum extends Bar, Baz, Foo { - public toEnum(): Int; -} - ---- - -(program - (interface_declaration - (type_identifier) - (interface_body - (property_signature - (property_identifier) - (type_annotation - (predefined_type))))) - (interface_declaration - (type_identifier) - (extends_type_clause - (type_identifier)) - (interface_body - (property_signature - (property_identifier) - (type_annotation - (predefined_type))))) - (interface_declaration - (type_identifier) - (interface_body - (property_signature - (property_identifier) - (type_annotation - (predefined_type))) - (property_signature - (property_identifier) - (type_annotation - (predefined_type))))) - (interface_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier) - (constraint - (type_identifier)))) - (interface_body - (property_signature - (property_identifier) - (type_annotation - (type_identifier))) - (property_signature - (property_identifier) - (type_annotation - (type_identifier))))) - (interface_declaration - (type_identifier) - (interface_body - (property_signature - (property_identifier) - (type_annotation - (object_type))) - (method_signature - (property_identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (type_identifier))))))) - (interface_declaration - (type_identifier) - (extends_type_clause - (type_identifier) - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (type_identifier)))) - (interface_body - (method_signature - (accessibility_modifier) - (property_identifier) - (formal_parameters) - (type_annotation - (type_identifier)))))) - -======================================= -Generic types -======================================= - -class A< - B, - C, -> {} - -class D extends A< - X, - Y, -> {} - -class E extends funThatEvalsToClass()< - X, - Y, -> {} - -class F extends G, H {} - ---- - -(program - (class_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (class_body)) - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (identifier) - (type_arguments - (type_identifier) - (type_identifier)))) - (class_body)) - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (call_expression - (identifier) - (arguments)) - (type_arguments - (type_identifier) - (type_identifier)))) - (class_body)) - (class_declaration - (type_identifier) - (class_heritage - (extends_clause - (identifier) - (identifier) - (type_arguments - (type_identifier)))) - (class_body))) - -======================================= -Existential types -======================================= - -let x: Array<*> - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (existential_type))))))) - -======================================= -Flow Union types -======================================= - -type U = number | string; -type Z = | "foo" | "bar"; -type Z = | "foo"; - ---- - -(program - (type_alias_declaration - (type_identifier) - (union_type - (predefined_type) - (predefined_type))) - (type_alias_declaration - (type_identifier) - (union_type - (union_type - (literal_type - (string - (string_fragment)))) - (literal_type - (string - (string_fragment))))) - (type_alias_declaration - (type_identifier) - (union_type - (literal_type - (string - (string_fragment)))))) - -======================================= -Flow Intersection types -======================================= - -type BrowserStats$ResourceTiming = number & string; - ---- - -(program - (type_alias_declaration - (type_identifier) - (intersection_type - (predefined_type) - (predefined_type)))) - -======================================= -Flow exact object types -======================================= - -type BrowserStats = {| - url: string, - ms: number -|} - ---- - -(program - (type_alias_declaration - (type_identifier) - (object_type - (property_signature - (property_identifier) - (type_annotation - (predefined_type))) - (property_signature - (property_identifier) - (type_annotation - (predefined_type)))))) - -======================================= -Literal types -======================================= - -let x: 2 -let x: 2 | -3 | +4 -let x: "string" -let x: false - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (literal_type - (number))))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (union_type - (union_type - (literal_type - (number)) - (literal_type - (unary_expression - (number)))) - (literal_type - (unary_expression - (number))))))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (literal_type - (string - (string_fragment)))))) - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (literal_type - (false)))))) - -======================================= -Flow type parameter constraint syntax -======================================= - -type HandlerFunction = void - ---- - -(program - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier) - (constraint - (type_identifier)))) - (predefined_type))) - -======================================= -Nested type arguments -======================================= - -interface X { - x(): Promise>; -} - -var y: Map>>> - ---- - -(program - (interface_declaration - (type_identifier) - (interface_body - (method_signature - (property_identifier) - (formal_parameters) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (generic_type - (type_identifier) - (type_arguments - (type_identifier))))))))) - (variable_declaration - (variable_declarator - (identifier) - (type_annotation - (generic_type - (type_identifier) - (type_arguments - (predefined_type) - (generic_type - (type_identifier) - (type_arguments - (generic_type - (type_identifier) - (type_arguments - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (type_identifier) - (type_identifier))))))))))))) - -======================================= -predefined types as identifiers -======================================= - -let score: (string: string, query: string) => number - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type))) - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (predefined_type)))))) - -======================================= -Non-null assertion operator -======================================= - -const repository = foo++! - ---- - -(program - (lexical_declaration - (variable_declarator - (identifier) - (non_null_expression - (update_expression - (identifier)))))) - -======================================= -Type query and index type query types -======================================= - -type T = keyof Person; -type T = keyof Person.P; -type T = keyof Person

; -type T = keyof (Person); - -type T = typeof Person; -type T = typeof Person.P; -type T = typeof import('person'); - -type T = keyof typeof Person; - -type T = keyof U[number]; -type T = keyof U & V; - -type T = typeof array[number]; - ---- - -(program - (type_alias_declaration - (type_identifier) - (index_type_query - (type_identifier))) - (type_alias_declaration - (type_identifier) - (index_type_query - (nested_type_identifier - (identifier) - (type_identifier)))) - (type_alias_declaration - (type_identifier) - (index_type_query - (generic_type - (type_identifier) - (type_arguments - (type_identifier))))) - (type_alias_declaration - (type_identifier) - (index_type_query - (parenthesized_type - (type_identifier)))) - (type_alias_declaration - (type_identifier) - (type_query - (identifier))) - (type_alias_declaration - (type_identifier) - (type_query - (member_expression - (identifier) - (property_identifier)))) - (type_alias_declaration - (type_identifier) - (type_query - (call_expression - (import) - (arguments - (string - (string_fragment)))))) - (type_alias_declaration - (type_identifier) - (index_type_query - (type_query - (identifier)))) - (type_alias_declaration - (type_identifier) - (index_type_query - (lookup_type - (type_identifier) - (predefined_type)))) - (type_alias_declaration - (type_identifier) - (intersection_type - (index_type_query - (type_identifier)) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (lookup_type - (type_query - (identifier)) - (predefined_type)))) - -======================================= -Lookup types -======================================= - -type K1 = Foo[bar] -type K1 = Foo['bar' | 'baz'] - ---- - -(program - (type_alias_declaration - (type_identifier) - (lookup_type - (type_identifier) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (lookup_type - (type_identifier) - (union_type - (literal_type - (string - (string_fragment))) - (literal_type - (string - (string_fragment))))))) - -======================================= -Mapped types -======================================= - -export type NoInfer = T & { [K in keyof T]: T[K] }; - ---- - -(program - (export_statement - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (intersection_type - (type_identifier) - (object_type - (index_signature - (mapped_type_clause - (type_identifier) - (index_type_query - (type_identifier))) - (type_annotation - (lookup_type - (type_identifier) - (type_identifier))))))))) - -======================================= -Assertion functions checking a value -======================================= - -function f(x: any): asserts x { -} - ---- - -(program - (function_declaration - (identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (asserts_annotation - (asserts - (identifier))) - (statement_block))) - -======================================= -Assertion functions checking a type -======================================= - -function f(x: any): asserts x is number { -} - -class Foo { - test(): this is T {} -} - -function isT(t: T): t is T { - return true -} - ---- - -(program - (function_declaration - (identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (asserts_annotation - (asserts - (type_predicate - (identifier) - (predefined_type)))) - (statement_block)) - (class_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (class_body - (method_definition - (property_identifier) - (formal_parameters) - (type_predicate_annotation - (type_predicate - (this) - (type_identifier))) - (statement_block)))) - (function_declaration - (identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (type_predicate_annotation - (type_predicate - (identifier) - (type_identifier))) - (statement_block - (return_statement - (true))))) - -======================================= -Type of an assertion function -======================================= - -declare const f: (x: any) => asserts x; -declare const g: (x: any) => asserts x is number; - ---- - -(program - (ambient_declaration - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (asserts - (identifier))))))) - (ambient_declaration - (lexical_declaration - (variable_declarator - (identifier) - (type_annotation - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (predefined_type)))) - (asserts - (type_predicate - (identifier) - (predefined_type))))))))) - -================================== -Type predicate and predefined types -================================== - -function isFish(pet: Fish): pet is Fish { -} - -function isFish(object: Fish): object is Fish { -} - ---- - -(program - (function_declaration - (identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (type_predicate_annotation - (type_predicate - (identifier) - (type_identifier))) - (statement_block)) - (function_declaration - (identifier) - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (type_predicate_annotation - (type_predicate - (identifier) - (type_identifier))) - (statement_block))) - -================================== -Read-only arrays -================================== - -type t = a[] -type t = readonly a[] -type t = readonly a[][] -type t = (readonly a[])[] -type t = readonly (readonly a[]) [] - ---- - -(program - (type_alias_declaration - (type_identifier) - (array_type - (type_identifier))) - (type_alias_declaration - (type_identifier) - (readonly_type - (array_type - (type_identifier)))) - (type_alias_declaration - (type_identifier) - (readonly_type - (array_type - (array_type - (type_identifier))))) - (type_alias_declaration - (type_identifier) - (array_type - (parenthesized_type - (readonly_type - (array_type - (type_identifier)))))) - (type_alias_declaration - (type_identifier) - (readonly_type - (array_type - (parenthesized_type - (readonly_type - (array_type - (type_identifier)))))))) - -================================== -Tuple types -================================== - -type t = [] -type t = [A,] -type t = [A|B, C] -type t = readonly [A[], B.C] - -// special optional and rest type syntax -type t = [string?, ...B] - -// labeled elements -type t = [a: A, b?: B, ...c: C[]] - ---- - -(program - (type_alias_declaration - (type_identifier) - (tuple_type)) - (type_alias_declaration - (type_identifier) - (tuple_type - (type_identifier))) - (type_alias_declaration - (type_identifier) - (tuple_type - (union_type - (type_identifier) - (type_identifier)) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (readonly_type - (tuple_type - (array_type - (type_identifier)) - (nested_type_identifier - (identifier) - (type_identifier))))) - (comment) - (type_alias_declaration - (type_identifier) - (tuple_type - (optional_type - (predefined_type)) - (rest_type - (type_identifier)))) - (comment) - (type_alias_declaration - (type_identifier) - (tuple_type - (required_parameter - (identifier) - (type_annotation - (type_identifier))) - (optional_parameter - (identifier) - (type_annotation - (type_identifier))) - (required_parameter - (rest_pattern - (identifier)) - (type_annotation - (array_type - (type_identifier))))))) - -================================== -Conditional types -================================== - -type T = X extends Y ? Z : Y -type T = X extends ?Y ? ?X : Y -type F = ((t: T) => X extends Y ? X : Y) extends ((t: T) => X extends Y ? Y : X) ? X : Y -type F = (t: T) => X extends Y ? X : Y extends (t: T) => X extends Y ? Y : X ? X : Y -type T = T extends X ? Y : X -type T = X extends (infer X)[] ? X : never; -type T = T extends { x: infer X } ? X : never; -type T = T extends { x: infer X extends number } ? X : never; - ---- - -(program - (type_alias_declaration - (type_identifier) - (conditional_type - (type_identifier) - (type_identifier) - (type_identifier) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (conditional_type - (type_identifier) - (flow_maybe_type - (type_identifier)) - (flow_maybe_type - (type_identifier)) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (conditional_type - (parenthesized_type - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (conditional_type - (type_identifier) - (type_identifier) - (type_identifier) - (type_identifier)))) - (parenthesized_type - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (conditional_type - (type_identifier) - (type_identifier) - (type_identifier) - (type_identifier)))) - (type_identifier) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (conditional_type - (type_identifier) - (type_identifier) - (type_identifier) - (conditional_type - (type_identifier) - (function_type - (formal_parameters - (required_parameter - (identifier) - (type_annotation - (type_identifier)))) - (conditional_type - (type_identifier) - (type_identifier) - (type_identifier) - (type_identifier))) - (type_identifier) - (type_identifier))))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (conditional_type - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (infer_type - (type_identifier)))) - (type_identifier) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (conditional_type - (type_identifier) - (array_type - (parenthesized_type - (infer_type - (type_identifier)))) - (type_identifier) - (predefined_type))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (conditional_type - (type_identifier) - (object_type - (property_signature - (property_identifier) - (type_annotation - (infer_type - (type_identifier))))) - (type_identifier) - (predefined_type))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (conditional_type - (type_identifier) - (object_type - (property_signature - (property_identifier) - (type_annotation - (infer_type - (type_identifier) - (predefined_type))))) - (type_identifier) - (predefined_type)))) - -================================== -Template literal types -================================== - -type A = `${B}${C}`; -type A = `${B[0]}-foo-${C}-bar-${D}` -type A = `[${'a'}${0}]` -type A = B extends C - ? C extends string - ? `${C}${"" extends C ? "" : "."}${B}` - : never - : never -type Trim = S extends `${infer R}` ? Trim : S; -type A = `${true & ('foo' | false)}`; -type StringToNumber = S extends `${infer N extends number}` ? N : never; ---- - -(program - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (template_literal_type - (template_type - (type_identifier)) - (template_type - (type_identifier)))) - (type_alias_declaration - (type_identifier) - (template_literal_type - (template_type - (lookup_type - (type_identifier) - (literal_type - (number)))) - (template_type - (type_identifier)) - (template_type - (generic_type - (type_identifier) - (type_arguments - (type_identifier) - (type_identifier)))))) - (type_alias_declaration - (type_identifier) - (template_literal_type - (template_type - (literal_type - (string - (string_fragment)))) - (template_type - (literal_type - (number))))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier)) - (type_parameter - (type_identifier))) - (conditional_type - (type_identifier) - (type_identifier) - (conditional_type - (type_identifier) - (predefined_type) - (template_literal_type - (template_type - (type_identifier)) - (template_type - (conditional_type - (literal_type - (string)) - (type_identifier) - (literal_type - (string)) - (literal_type - (string - (string_fragment))))) - (template_type - (type_identifier))) - (predefined_type)) - (predefined_type))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier) - (constraint - (predefined_type)))) - (conditional_type - (type_identifier) - (template_literal_type - (template_type - (infer_type - (type_identifier)))) - (generic_type - (type_identifier) - (type_arguments - (type_identifier))) - (type_identifier))) - (type_alias_declaration - (type_identifier) - (template_literal_type - (template_type - (intersection_type - (literal_type - (true)) - (parenthesized_type - (union_type - (literal_type - (string - (string_fragment))) - (literal_type - (false)))))))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier) - (constraint - (predefined_type)))) - (conditional_type - (type_identifier) - (template_literal_type - (template_type - (infer_type - (type_identifier) - (predefined_type)))) - (type_identifier) - (predefined_type)))) - -================================== -Mapped type 'as' clauses -================================== - -type A = { [B in keyof C & string as `get${Capitalize

}`]: () => A[B] }; -type A = { [B in keyof C & string as `${P}1` | `${P}2`]: A[B] } - ---- - -(program - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (object_type - (index_signature - (mapped_type_clause - (type_identifier) - (intersection_type - (index_type_query - (type_identifier)) - (predefined_type)) - (template_literal_type - (template_type - (generic_type - (type_identifier) - (type_arguments - (type_identifier)))))) - (type_annotation - (function_type - (formal_parameters) - (lookup_type - (type_identifier) - (type_identifier))))))) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (object_type - (index_signature - (mapped_type_clause - (type_identifier) - (intersection_type - (index_type_query - (type_identifier)) - (predefined_type)) - (union_type - (template_literal_type - (template_type - (type_identifier))) - (template_literal_type - (template_type - (type_identifier))))) - (type_annotation - (lookup_type - (type_identifier) - (type_identifier))))))) - -============================ -typeof in generic arguments -============================ - -type T = Foo> -type T = Foo> -type T = Foo> - ---- - -(program - (type_alias_declaration - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (generic_type - (type_identifier) - (type_arguments - (type_query - (identifier))))))) - (type_alias_declaration - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (generic_type - (type_identifier) - (type_arguments - (type_query - (member_expression - (identifier) - (property_identifier)))))))) - (type_alias_declaration - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (generic_type - (type_identifier) - (type_arguments - (lookup_type - (type_query - (identifier)) - (literal_type - (string - (string_fragment)))))))))) - -================================== -Literal types and pre-defined types -================================== - -type T = Foo - ---- - -(program - (type_alias_declaration - (type_identifier) - (generic_type - (type_identifier) - (type_arguments - (predefined_type) - (predefined_type) - (predefined_type) - (predefined_type) - (predefined_type) - (literal_type - (true)) - (literal_type - (false)) - (literal_type - (null)) - (literal_type - (undefined)) - (literal_type - (number)) - (literal_type - (string - (string_fragment))))))) - -================================== -Extends -================================== - -type Foo any> = T; -type Foo any> = T; - ---- - -(program - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier) - (constraint - (constructor_type - (formal_parameters - (required_parameter - (rest_pattern - (identifier)) - (type_annotation - (predefined_type)))) - (predefined_type))))) - (type_identifier)) - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier) - (constraint - (constructor_type - (formal_parameters - (required_parameter - (rest_pattern - (identifier)) - (type_annotation - (predefined_type)))) - (predefined_type))))) - (type_identifier))) - -======== -Abstract -======== - -type Foo = abstract new () => T; - ---- - -(program - (type_alias_declaration - (type_identifier) - (type_parameters - (type_parameter - (type_identifier))) - (constructor_type - (formal_parameters) - (type_identifier)))) - -========================= -Indexed Access Precedence -========================= - -// These should generate the same AST aside from the parenthesized_type node -type X1 = typeof Y[keyof typeof Z]; -type X2 = (typeof Y)[keyof typeof Z]; - ---- - -(program - (comment) - (type_alias_declaration - (type_identifier) - (lookup_type - (type_query - (identifier)) - (index_type_query - (type_query - (identifier))))) - (type_alias_declaration - (type_identifier) - (lookup_type - (parenthesized_type - (type_query - (identifier))) - (index_type_query - (type_query - (identifier)))))) - -========================= -Type of instantiation expressions -========================= - -// This is a special construct, different from both "typeof (f)" and -// "(typeof f)" (which are both invalid) -type T = typeof f; - ---- - -(program - (comment) - (comment) - (type_alias_declaration - (type_identifier) - (type_query - (instantiation_expression - (identifier) - (type_arguments - (type_identifier)))))) diff --git a/vendored_parsers/tree-sitter-typescript/common/define-grammar.js b/vendored_parsers/tree-sitter-typescript/common/define-grammar.js deleted file mode 100644 index 75aa6906b..000000000 --- a/vendored_parsers/tree-sitter-typescript/common/define-grammar.js +++ /dev/null @@ -1,1110 +0,0 @@ -const JavaScript = require('tree-sitter-javascript/grammar'); - -module.exports = function defineGrammar(dialect) { - return grammar(JavaScript, { - name: dialect, - - externals: ($, previous) => previous.concat([ - $._function_signature_automatic_semicolon, - ]), - - supertypes: ($, previous) => previous.concat([ - $._primary_type, - ]), - - precedences: ($, previous) => previous.concat([ - [ - 'call', - 'instantiation', - 'unary', - 'binary', - $.await_expression, - $.arrow_function, - ], - [ - 'extends', - 'instantiation', - ], - [ - $.intersection_type, - $.union_type, - $.conditional_type, - $.function_type, - 'binary', - $.type_predicate, - $.readonly_type, - ], - [$.mapped_type_clause, $.primary_expression], - [$.accessibility_modifier, $.primary_expression], - ['unary_void', $.expression], - [$.extends_clause, $.primary_expression], - ['unary', 'assign'], - ['declaration', $.expression], - [$.predefined_type, $.unary_expression], - [$._type, $.flow_maybe_type], - [$.tuple_type, $.array_type, $.pattern, $._type], - [$.readonly_type, $.pattern], - [$.readonly_type, $.primary_expression], - [$.type_query, $.subscript_expression, $.expression], - [$.type_query, $._type_query_subscript_expression], - [$.nested_type_identifier, $.generic_type, $._primary_type, $.lookup_type, $.index_type_query, $._type], - [$.as_expression, $.satisfies_expression, $._primary_type], - [$._type_query_member_expression, $.member_expression], - [$.member_expression, $._type_query_member_expression_in_type_annotation], - [$._type_query_member_expression, $.primary_expression], - [$._type_query_subscript_expression, $.subscript_expression], - [$._type_query_subscript_expression, $.primary_expression], - [$._type_query_call_expression, $.primary_expression], - [$._type_query_instantiation_expression, $.primary_expression], - [$.type_query, $.primary_expression], - [$.override_modifier, $.primary_expression], - [$.decorator_call_expression, $.decorator], - [$.literal_type, $.pattern], - [$.predefined_type, $.pattern], - [$.call_expression, $._type_query_call_expression], - [$.call_expression, $._type_query_call_expression_in_type_annotation], - [$.new_expression, $.primary_expression], - [$.meta_property, $.primary_expression], - [$.construct_signature, $._property_name], - ]), - - conflicts: ($, previous) => previous.concat([ - [$.call_expression, $.instantiation_expression, $.binary_expression], - [$.call_expression, $.instantiation_expression, $.binary_expression, $.unary_expression], - [$.call_expression, $.instantiation_expression, $.binary_expression, $.update_expression], - [$.call_expression, $.instantiation_expression, $.binary_expression, $.await_expression], - - // This appears to be necessary to parse a parenthesized class expression - [$.class], - - [$.nested_identifier, $.nested_type_identifier, $.primary_expression], - [$.nested_identifier, $.nested_type_identifier], - - [$._call_signature, $.function_type], - [$._call_signature, $.constructor_type], - - [$._primary_type, $.type_parameter], - [$.jsx_opening_element, $.type_parameter], - [$.jsx_namespace_name, $._primary_type], - - [$.primary_expression, $._parameter_name], - [$.primary_expression, $._parameter_name, $._primary_type], - [$.primary_expression, $.literal_type], - [$.primary_expression, $.literal_type, $.rest_pattern], - [$.primary_expression, $.predefined_type, $.rest_pattern], - [$.primary_expression, $._primary_type], - [$.primary_expression, $.generic_type], - [$.primary_expression, $.predefined_type], - [$.primary_expression, $.pattern, $._primary_type], - [$._parameter_name, $._primary_type], - [$.pattern, $._primary_type], - - [$.optional_tuple_parameter, $._primary_type], - [$.rest_pattern, $._primary_type, $.primary_expression], - - [$.object, $.object_type], - [$.object, $.object_pattern, $.object_type], - [$.object, $.object_pattern, $._property_name], - [$.object_pattern, $.object_type], - [$.object_pattern, $.object_type], - - [$.array, $.tuple_type], - [$.array, $.array_pattern, $.tuple_type], - [$.array_pattern, $.tuple_type], - - [$.template_literal_type, $.template_string], - ]), - - inline: ($, previous) => previous - .filter((rule) => ![ - '_formal_parameter', - '_call_signature', - ].includes(rule.name)) - .concat([ - $._type_identifier, - $._jsx_start_opening_element, - ]), - - rules: { - public_field_definition: ($) => seq( - repeat(field('decorator', $.decorator)), - optional(choice( - seq('declare', optional($.accessibility_modifier)), - seq($.accessibility_modifier, optional('declare')), - )), - choice( - seq(optional('static'), optional($.override_modifier), optional('readonly')), - seq(optional('abstract'), optional('readonly')), - seq(optional('readonly'), optional('abstract')), - ), - field('name', $._property_name), - optional(choice('?', '!')), - field('type', optional($.type_annotation)), - optional($._initializer), - ), - - // override original catch_clause, add optional type annotation - catch_clause: ($) => seq( - 'catch', - optional( - seq( - '(', - field( - 'parameter', - choice($.identifier, $._destructuring_pattern), - ), - optional( - // only types that resolve to 'any' or 'unknown' are supported - // by the language but it's simpler to accept any type here. - field('type', $.type_annotation), - ), - ')', - ), - ), - field('body', $.statement_block), - ), - - call_expression: ($) => choice( - prec('call', seq( - field('function', choice($.expression, $.import)), - field('type_arguments', optional($.type_arguments)), - field('arguments', choice($.arguments, $.template_string)), - )), - prec('member', seq( - field('function', $.primary_expression), - '?.', - field('type_arguments', optional($.type_arguments)), - field('arguments', $.arguments), - )), - ), - - new_expression: ($) => prec.right('new', seq( - 'new', - field('constructor', $.primary_expression), - field('type_arguments', optional($.type_arguments)), - field('arguments', optional($.arguments)), - )), - - assignment_expression: ($) => prec.right('assign', seq( - optional('using'), - field('left', choice($.parenthesized_expression, $._lhs_expression)), - '=', - field('right', $.expression), - )), - - _augmented_assignment_lhs: ($, previous) => choice(previous, $.non_null_expression), - - _lhs_expression: ($, previous) => choice(previous, $.non_null_expression), - - primary_expression: ($, previous) => choice( - previous, - $.non_null_expression, - ), - - // If the dialect is regular typescript, we exclude JSX expressions and - // include type assertions. If the dialect is TSX, we do the opposite. - expression: ($, previous) => { - const choices = [ - $.as_expression, - $.satisfies_expression, - $.instantiation_expression, - $.internal_module, - ]; - - if (dialect === 'typescript') { - choices.push($.type_assertion); - choices.push(...previous.members.filter((member) => - member.name !== '_jsx_element', - )); - } else if (dialect === 'tsx') { - choices.push(...previous.members); - } else { - throw new Error(`Unknown dialect ${dialect}`); - } - - return choice(...choices); - }, - - _jsx_start_opening_element: ($) => seq( - '<', - optional( - seq( - choice( - field('name', choice( - $._jsx_identifier, - $.jsx_namespace_name, - )), - seq( - field('name', choice( - $.identifier, - alias($.nested_identifier, $.member_expression), - )), - field('type_arguments', optional($.type_arguments)), - ), - ), - repeat(field('attribute', $._jsx_attribute)), - ), - ), - ), - - // This rule is only referenced by expression when the dialect is 'tsx' - jsx_opening_element: ($) => prec.dynamic(-1, seq( - $._jsx_start_opening_element, - '>', - )), - - // tsx only. See jsx_opening_element. - jsx_self_closing_element: ($) => prec.dynamic(-1, seq( - $._jsx_start_opening_element, - '/>', - )), - - export_specifier: (_, previous) => seq( - optional(choice('type', 'typeof')), - previous, - ), - - _import_identifier: ($) => choice($.identifier, alias('type', $.identifier)), - - import_specifier: ($) => seq( - optional(choice('type', 'typeof')), - choice( - field('name', $._import_identifier), - seq( - field('name', choice($._module_export_name, alias('type', $.identifier))), - 'as', - field('alias', $._import_identifier), - ), - )), - - import_clause: ($) => choice( - $.namespace_import, - $.named_imports, - seq( - $._import_identifier, - optional(seq( - ',', - choice( - $.namespace_import, - $.named_imports, - ), - )), - ), - ), - - import_statement: ($) => seq( - 'import', - optional(choice('type', 'typeof')), - choice( - seq($.import_clause, $._from_clause), - $.import_require_clause, - field('source', $.string), - ), - optional($.import_attribute), - $._semicolon, - ), - - export_statement: ($, previous) => choice( - previous, - seq( - 'export', - 'type', - $.export_clause, - optional($._from_clause), - $._semicolon, - ), - seq('export', '=', $.expression, $._semicolon), - seq('export', 'as', 'namespace', $.identifier, $._semicolon), - ), - - non_null_expression: ($) => prec.left('unary', seq( - $.expression, '!', - )), - - variable_declarator: ($) => choice( - seq( - field('name', choice($.identifier, $._destructuring_pattern)), - field('type', optional($.type_annotation)), - optional($._initializer), - ), - prec('declaration', seq( - field('name', $.identifier), - '!', - field('type', $.type_annotation), - )), - ), - - method_signature: ($) => seq( - optional($.accessibility_modifier), - optional('static'), - optional($.override_modifier), - optional('readonly'), - optional('async'), - optional(choice('get', 'set', '*')), - field('name', $._property_name), - optional('?'), - $._call_signature, - ), - - abstract_method_signature: ($) => seq( - optional($.accessibility_modifier), - 'abstract', - optional($.override_modifier), - optional(choice('get', 'set', '*')), - field('name', $._property_name), - optional('?'), - $._call_signature, - ), - - parenthesized_expression: ($) => seq( - '(', - choice( - seq($.expression, field('type', optional($.type_annotation))), - $.sequence_expression, - ), - ')', - ), - - _formal_parameter: ($) => choice( - $.required_parameter, - $.optional_parameter, - ), - - function_signature: ($) => seq( - optional('async'), - 'function', - field('name', $.identifier), - $._call_signature, - choice($._semicolon, $._function_signature_automatic_semicolon), - ), - - class_body: ($) => seq( - '{', - repeat(choice( - seq( - repeat(field('decorator', $.decorator)), - $.method_definition, - optional($._semicolon), - ), - // As it happens for functions, the semicolon insertion should not - // happen if a block follows the closing paren, because then it's a - // *definition*, not a declaration. Example: - // public foo() - // { <--- this brace made the method signature become a definition - // } - // The same rule applies for functions and that's why we use - // "_function_signature_automatic_semicolon". - seq($.method_signature, choice($._function_signature_automatic_semicolon, ',')), - $.class_static_block, - seq( - choice( - $.abstract_method_signature, - $.index_signature, - $.method_signature, - $.public_field_definition, - ), - choice($._semicolon, ','), - ), - ';', - )), - '}', - ), - - method_definition: ($) => prec.left(seq( - optional($.accessibility_modifier), - optional('static'), - optional($.override_modifier), - optional('readonly'), - optional('async'), - optional(choice('get', 'set', '*')), - field('name', $._property_name), - optional('?'), - $._call_signature, - field('body', $.statement_block), - )), - - declaration: ($, previous) => choice( - previous, - $.function_signature, - $.abstract_class_declaration, - $.module, - prec('declaration', $.internal_module), - $.type_alias_declaration, - $.enum_declaration, - $.interface_declaration, - $.import_alias, - $.ambient_declaration, - ), - - type_assertion: ($) => prec.left('unary', seq( - $.type_arguments, - $.expression, - )), - - as_expression: ($) => prec.left('binary', seq( - $.expression, - 'as', - choice('const', $._type), - )), - - satisfies_expression: ($) => prec.left('binary', seq( - $.expression, - 'satisfies', - $._type, - )), - - instantiation_expression: ($) => prec('instantiation', seq( - $.expression, - field('type_arguments', $.type_arguments), - )), - - class_heritage: ($) => choice( - seq($.extends_clause, optional($.implements_clause)), - $.implements_clause, - ), - - import_require_clause: ($) => seq( - $.identifier, - '=', - 'require', - '(', - field('source', $.string), - ')', - ), - - extends_clause: ($) => seq( - 'extends', - commaSep1($._extends_clause_single), - ), - - _extends_clause_single: ($) => prec('extends', seq( - field('value', $.expression), - field('type_arguments', optional($.type_arguments)), - )), - - implements_clause: ($) => seq( - 'implements', - commaSep1($._type), - ), - - ambient_declaration: ($) => seq( - 'declare', - choice( - $.declaration, - seq('global', $.statement_block), - seq('module', '.', alias($.identifier, $.property_identifier), ':', $._type, $._semicolon), - ), - ), - - class: ($) => prec('literal', seq( - repeat(field('decorator', $.decorator)), - 'class', - field('name', optional($._type_identifier)), - field('type_parameters', optional($.type_parameters)), - optional($.class_heritage), - field('body', $.class_body), - )), - - abstract_class_declaration: ($) => prec('declaration', seq( - repeat(field('decorator', $.decorator)), - 'abstract', - 'class', - field('name', $._type_identifier), - field('type_parameters', optional($.type_parameters)), - optional($.class_heritage), - field('body', $.class_body), - )), - - class_declaration: ($) => prec.left('declaration', seq( - repeat(field('decorator', $.decorator)), - 'class', - field('name', $._type_identifier), - field('type_parameters', optional($.type_parameters)), - optional($.class_heritage), - field('body', $.class_body), - optional($._automatic_semicolon), - )), - - module: ($) => seq( - 'module', - $._module, - ), - - internal_module: ($) => seq( - 'namespace', - $._module, - ), - - _module: ($) => prec.right(seq( - field('name', choice($.string, $.identifier, $.nested_identifier)), - // On .d.ts files "declare module foo" desugars to "declare module foo {}", - // hence why it is optional here - field('body', optional($.statement_block)), - )), - - import_alias: ($) => seq( - 'import', - $.identifier, - '=', - choice($.identifier, $.nested_identifier), - $._semicolon, - ), - - nested_type_identifier: ($) => prec('member', seq( - field('module', choice($.identifier, $.nested_identifier)), - '.', - field('name', $._type_identifier), - )), - - interface_declaration: ($) => seq( - 'interface', - field('name', $._type_identifier), - field('type_parameters', optional($.type_parameters)), - optional($.extends_type_clause), - field('body', alias($.object_type, $.interface_body)), - ), - - extends_type_clause: ($) => seq( - 'extends', - commaSep1(field('type', choice( - $._type_identifier, - $.nested_type_identifier, - $.generic_type, - ))), - ), - - enum_declaration: ($) => seq( - optional('const'), - 'enum', - field('name', $.identifier), - field('body', $.enum_body), - ), - - enum_body: ($) => seq( - '{', - optional(seq( - sepBy1(',', choice( - field('name', $._property_name), - $.enum_assignment, - )), - optional(','), - )), - '}', - ), - - enum_assignment: ($) => seq( - field('name', $._property_name), - $._initializer, - ), - - type_alias_declaration: ($) => seq( - 'type', - field('name', $._type_identifier), - field('type_parameters', optional($.type_parameters)), - '=', - field('value', $._type), - $._semicolon, - ), - - accessibility_modifier: (_) => choice( - 'public', - 'private', - 'protected', - ), - - override_modifier: (_) => 'override', - - required_parameter: ($) => seq( - $._parameter_name, - field('type', optional($.type_annotation)), - optional($._initializer), - ), - - optional_parameter: ($) => seq( - $._parameter_name, - '?', - field('type', optional($.type_annotation)), - optional($._initializer), - ), - - _parameter_name: ($) => seq( - repeat(field('decorator', $.decorator)), - optional($.accessibility_modifier), - optional($.override_modifier), - optional('readonly'), - field('pattern', choice($.pattern, $.this)), - ), - - omitting_type_annotation: ($) => seq('-?:', $._type), - adding_type_annotation: ($) => seq('+?:', $._type), - opting_type_annotation: ($) => seq('?:', $._type), - type_annotation: ($) => seq( - ':', - choice( - $._type, - alias($._type_query_member_expression_in_type_annotation, $.member_expression), - alias($._type_query_call_expression_in_type_annotation, $.call_expression), - ), - ), - - // Oh boy - // The issue is these special type queries need a lower relative precedence than the normal ones, - // since these are used in type annotations whereas the other ones are used where `typeof` is - // required beforehand. This allows for parsing of annotations such as - // foo: import('x').y.z; - // but was a nightmare to get working. - _type_query_member_expression_in_type_annotation: ($) => seq( - field('object', choice( - $.import, - alias($._type_query_member_expression_in_type_annotation, $.member_expression), - alias($._type_query_call_expression_in_type_annotation, $.call_expression), - )), - '.', - field('property', choice( - $.private_property_identifier, - alias($.identifier, $.property_identifier), - )), - ), - _type_query_call_expression_in_type_annotation: ($) => seq( - field('function', choice( - $.import, - alias($._type_query_member_expression_in_type_annotation, $.member_expression), - )), - field('arguments', $.arguments), - ), - - asserts: ($) => seq( - 'asserts', - choice($.type_predicate, $.identifier, $.this), - ), - - asserts_annotation: ($) => seq( - seq(':', $.asserts), - ), - - _type: ($) => choice( - $._primary_type, - $.function_type, - $.readonly_type, - $.constructor_type, - $.infer_type, - ), - - tuple_parameter: ($) => seq( - field('name', choice($.identifier, $.rest_pattern)), - field('type', $.type_annotation), - ), - - optional_tuple_parameter: ($) => seq( - field('name', $.identifier), - '?', - field('type', $.type_annotation), - ), - - optional_type: ($) => seq($._type, '?'), - rest_type: ($) => seq('...', $._type), - - _tuple_type_member: ($) => choice( - alias($.tuple_parameter, $.required_parameter), - alias($.optional_tuple_parameter, $.optional_parameter), - $.optional_type, - $.rest_type, - $._type, - ), - - constructor_type: ($) => prec.left(seq( - optional('abstract'), - 'new', - field('type_parameters', optional($.type_parameters)), - field('parameters', $.formal_parameters), - '=>', - field('type', $._type), - )), - - _primary_type: ($) => choice( - $.parenthesized_type, - $.predefined_type, - $._type_identifier, - $.nested_type_identifier, - $.generic_type, - $.object_type, - $.array_type, - $.tuple_type, - $.flow_maybe_type, - $.type_query, - $.index_type_query, - alias($.this, $.this_type), - $.existential_type, - $.literal_type, - $.lookup_type, - $.conditional_type, - $.template_literal_type, - $.intersection_type, - $.union_type, - 'const', - ), - - template_type: ($) => seq('${', choice($._primary_type, $.infer_type), '}'), - - template_literal_type: ($) => seq( - '`', - repeat(choice( - $._template_chars, - $.template_type, - )), - '`', - ), - - infer_type: ($) => prec.right(seq( - 'infer', - $._type_identifier, - optional(seq( - 'extends', - $._type, - )), - )), - - conditional_type: ($) => prec.right(seq( - field('left', $._type), - 'extends', - field('right', $._type), - '?', - field('consequence', $._type), - ':', - field('alternative', $._type), - )), - - generic_type: ($) => prec('call', seq( - field('name', choice( - $._type_identifier, - $.nested_type_identifier, - )), - field('type_arguments', $.type_arguments), - )), - - type_predicate: ($) => seq( - field('name', choice( - $.identifier, - $.this, - // Sometimes tree-sitter contextual lexing is not good enough to know - // that 'object' in ':object is foo' is really an identifier and not - // a predefined_type, so we must explicitely list all possibilities. - // TODO: should we use '_reserved_identifier'? Should all the element in - // 'predefined_type' be added to '_reserved_identifier'? - alias($.predefined_type, $.identifier), - )), - 'is', - field('type', $._type), - ), - - type_predicate_annotation: ($) => seq( - seq(':', $.type_predicate), - ), - - // Type query expressions are more restrictive than regular expressions - _type_query_member_expression: ($) => seq( - field('object', choice( - $.identifier, - alias($._type_query_subscript_expression, $.subscript_expression), - alias($._type_query_member_expression, $.member_expression), - alias($._type_query_call_expression, $.call_expression), - )), - choice('.', '?.'), - field('property', choice( - $.private_property_identifier, - alias($.identifier, $.property_identifier), - )), - ), - _type_query_subscript_expression: ($) => seq( - field('object', choice( - $.identifier, - alias($._type_query_subscript_expression, $.subscript_expression), - alias($._type_query_member_expression, $.member_expression), - alias($._type_query_call_expression, $.call_expression), - )), - optional('?.'), - '[', field('index', choice($.predefined_type, $.string, $.number)), ']', - ), - _type_query_call_expression: ($) => seq( - field('function', choice( - $.import, - $.identifier, - alias($._type_query_member_expression, $.member_expression), - alias($._type_query_subscript_expression, $.subscript_expression), - )), - field('arguments', $.arguments), - ), - _type_query_instantiation_expression: ($) => seq( - field('function', choice( - $.import, - $.identifier, - alias($._type_query_member_expression, $.member_expression), - alias($._type_query_subscript_expression, $.subscript_expression), - )), - field('type_arguments', $.type_arguments), - ), - type_query: ($) => prec.right(seq( - 'typeof', - choice( - alias($._type_query_subscript_expression, $.subscript_expression), - alias($._type_query_member_expression, $.member_expression), - alias($._type_query_call_expression, $.call_expression), - alias($._type_query_instantiation_expression, $.instantiation_expression), - $.identifier, - ), - )), - - index_type_query: ($) => seq( - 'keyof', - $._primary_type, - ), - - lookup_type: ($) => seq( - $._primary_type, - '[', - $._type, - ']', - ), - - mapped_type_clause: ($) => seq( - field('name', $._type_identifier), - 'in', - field('type', $._type), - optional(seq('as', field('alias', $._type))), - ), - - literal_type: ($) => choice( - alias($._number, $.unary_expression), - $.number, - $.string, - $.true, - $.false, - $.null, - $.undefined, - ), - - _number: ($) => prec.left(1, seq( - field('operator', choice('-', '+')), - field('argument', $.number), - )), - - existential_type: (_) => '*', - - flow_maybe_type: ($) => prec.right(seq('?', $._primary_type)), - - parenthesized_type: ($) => seq('(', $._type, ')'), - - predefined_type: (_) => choice( - 'any', - 'number', - 'boolean', - 'string', - 'symbol', - alias(seq('unique', 'symbol'), 'unique symbol'), - 'void', - 'unknown', - 'string', - 'never', - 'object', - ), - - type_arguments: ($) => seq( - '<', - commaSep1(choice( - $._type, - alias($._type_query_member_expression_in_type_annotation, $.member_expression), - alias($._type_query_call_expression_in_type_annotation, $.call_expression), - )), - optional(','), - '>', - ), - - object_type: ($) => seq( - choice('{', '{|'), - optional(seq( - optional(choice(',', ';')), - sepBy1( - choice(',', $._semicolon), - choice( - $.export_statement, - $.property_signature, - $.call_signature, - $.construct_signature, - $.index_signature, - $.method_signature, - ), - ), - optional(choice(',', $._semicolon)), - )), - choice('}', '|}'), - ), - - call_signature: ($) => $._call_signature, - - property_signature: ($) => seq( - optional($.accessibility_modifier), - optional('static'), - optional($.override_modifier), - optional('readonly'), - field('name', $._property_name), - optional('?'), - field('type', optional($.type_annotation)), - ), - - _call_signature: ($) => seq( - field('type_parameters', optional($.type_parameters)), - field('parameters', $.formal_parameters), - field('return_type', optional( - choice($.type_annotation, $.asserts_annotation, $.type_predicate_annotation), - )), - ), - - type_parameters: ($) => seq( - '<', commaSep1($.type_parameter), optional(','), '>', - ), - - type_parameter: ($) => seq( - optional('const'), - field('name', $._type_identifier), - field('constraint', optional($.constraint)), - field('value', optional($.default_type)), - ), - - default_type: ($) => seq( - '=', - $._type, - ), - - constraint: ($) => seq( - choice('extends', ':'), - $._type, - ), - - construct_signature: ($) => seq( - optional('abstract'), - 'new', - field('type_parameters', optional($.type_parameters)), - field('parameters', $.formal_parameters), - field('type', optional($.type_annotation)), - ), - - index_signature: ($) => seq( - optional( - seq( - field('sign', optional(choice('-', '+'))), - 'readonly', - ), - ), - '[', - choice( - seq( - field('name', choice( - $.identifier, - alias($._reserved_identifier, $.identifier), - )), - ':', - field('index_type', $._type), - ), - $.mapped_type_clause, - ), - ']', - field('type', choice( - $.type_annotation, - $.omitting_type_annotation, - $.adding_type_annotation, - $.opting_type_annotation, - )), - ), - - array_type: ($) => seq($._primary_type, '[', ']'), - tuple_type: ($) => seq( - '[', commaSep($._tuple_type_member), optional(','), ']', - ), - readonly_type: ($) => seq('readonly', $._type), - - union_type: ($) => prec.left(seq(optional($._type), '|', $._type)), - intersection_type: ($) => prec.left(seq(optional($._type), '&', $._type)), - - function_type: ($) => prec.left(seq( - field('type_parameters', optional($.type_parameters)), - field('parameters', $.formal_parameters), - '=>', - field('return_type', choice($._type, $.asserts, $.type_predicate)), - )), - - _type_identifier: ($) => alias($.identifier, $.type_identifier), - - _reserved_identifier: (_, previous) => choice( - 'declare', - 'namespace', - 'type', - 'public', - 'private', - 'protected', - 'override', - 'readonly', - 'module', - 'any', - 'number', - 'boolean', - 'string', - 'symbol', - 'export', - 'object', - 'new', - 'readonly', - previous, - ), - }, - }); -}; - -/** - * Creates a rule to match one or more of the rules separated by a comma - * - * @param {RuleOrLiteral} rule - * - * @return {SeqRule} - * - */ -function commaSep1(rule) { - return sepBy1(',', rule); -} - -/** - * Creates a rule to optionally match one or more of the rules separated by a comma - * - * @param {RuleOrLiteral} rule - * - * @return {SeqRule} - * - */ -function commaSep(rule) { - return sepBy(',', rule); -} - -/** - * Creates a rule to optionally match one or more of the rules separated by a separator - * - * @param {RuleOrLiteral} sep - * - * @param {RuleOrLiteral} rule - * - * @return {ChoiceRule} - */ -function sepBy(sep, rule) { - return optional(sepBy1(sep, rule)); -} - -/** - * Creates a rule to match one or more of the rules separated by a separator - * - * @param {RuleOrLiteral} sep - * - * @param {RuleOrLiteral} rule - * - * @return {SeqRule} - */ -function sepBy1(sep, rule) { - return seq(rule, repeat(seq(sep, rule))); -} diff --git a/vendored_parsers/tree-sitter-typescript/common/scanner.h b/vendored_parsers/tree-sitter-typescript/common/scanner.h deleted file mode 100644 index e2f370ace..000000000 --- a/vendored_parsers/tree-sitter-typescript/common/scanner.h +++ /dev/null @@ -1,297 +0,0 @@ -#include "tree_sitter/parser.h" - -#include - -enum TokenType { - AUTOMATIC_SEMICOLON, - TEMPLATE_CHARS, - TERNARY_QMARK, - HTML_COMMENT, - LOGICAL_OR, - ESCAPE_SEQUENCE, - FUNCTION_SIGNATURE_AUTOMATIC_SEMICOLON, - ERROR_RECOVERY, -}; - -static void advance(TSLexer *lexer) { lexer->advance(lexer, false); } - -static void skip(TSLexer *lexer) { lexer->advance(lexer, true); } - -static bool scan_template_chars(TSLexer *lexer) { - lexer->result_symbol = TEMPLATE_CHARS; - for (bool has_content = false;; has_content = true) { - lexer->mark_end(lexer); - switch (lexer->lookahead) { - case '`': - return has_content; - case '\0': - return false; - case '$': - advance(lexer); - if (lexer->lookahead == '{') { - return has_content; - } - break; - case '\\': - return has_content; - default: - advance(lexer); - } - } -} - -static bool scan_whitespace_and_comments(TSLexer *lexer, bool *scanned_comment) { - for (;;) { - while (iswspace(lexer->lookahead)) { - skip(lexer); - } - - if (lexer->lookahead == '/') { - skip(lexer); - - if (lexer->lookahead == '/') { - skip(lexer); - while (lexer->lookahead != 0 && lexer->lookahead != '\n') { - 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); - break; - } - } else { - skip(lexer); - } - } - } else { - return false; - } - } else { - return true; - } - } -} - -static bool scan_automatic_semicolon(TSLexer *lexer, const bool *valid_symbols, bool *scanned_comment) { - lexer->result_symbol = AUTOMATIC_SEMICOLON; - lexer->mark_end(lexer); - - for (;;) { - if (lexer->lookahead == 0) { - return true; - } - if (lexer->lookahead == '}') { - // Automatic semicolon insertion breaks detection of object patterns - // in a typed context: - // type F = ({a}: {a: number}) => number; - // Therefore, disable automatic semicolons when followed by typing - do { - skip(lexer); - } while (iswspace(lexer->lookahead)); - if (lexer->lookahead == ':') { - return false; - } - return true; - } - if (!iswspace(lexer->lookahead)) { - return false; - } - if (lexer->lookahead == '\n') { - break; - } - skip(lexer); - } - - 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 ':': - return false; - - case '{': - if (valid_symbols[FUNCTION_SIGNATURE_AUTOMATIC_SEMICOLON]) { - return false; - } - break; - - // Don't insert a semicolon before a '[' or '(', unless we're parsing - // a type. Detect whether we're parsing a type or an expression using - // the validity of a binary operator token. - case '(': - case '[': - if (valid_symbols[LOGICAL_OR]) { - return false; - } - break; - - // 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); - } - - if (!iswalpha(lexer->lookahead)) { - return false; - } - break; - } - - return true; -} - -static bool scan_ternary_qmark(TSLexer *lexer) { - for (;;) { - if (!iswspace(lexer->lookahead)) { - break; - } - skip(lexer); - } - - if (lexer->lookahead == '?') { - advance(lexer); - - /* Optional chaining. */ - if (lexer->lookahead == '?' || lexer->lookahead == '.') { - return false; - } - - lexer->mark_end(lexer); - lexer->result_symbol = TERNARY_QMARK; - - /* TypeScript optional arguments contain the ?: sequence, possibly - with whitespace. */ - for (;;) { - if (!iswspace(lexer->lookahead)) { - break; - } - advance(lexer); - } - - if (lexer->lookahead == ':' || lexer->lookahead == ')' || lexer->lookahead == ',') { - return false; - } - - if (lexer->lookahead == '.') { - advance(lexer); - if (iswdigit(lexer->lookahead)) { - return true; - } - return false; - } - return true; - } - return false; -} - -static bool scan_closing_comment(TSLexer *lexer) { - while (iswspace(lexer->lookahead) || lexer->lookahead == 0x2028 || lexer->lookahead == 0x2029) { - skip(lexer); - } - - const char *comment_start = ""; - - 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); - - return true; -} - -static inline bool external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) { - if (valid_symbols[TEMPLATE_CHARS]) { - if (valid_symbols[AUTOMATIC_SEMICOLON]) { - return false; - } - return scan_template_chars(lexer); - } - if (valid_symbols[AUTOMATIC_SEMICOLON] || valid_symbols[FUNCTION_SIGNATURE_AUTOMATIC_SEMICOLON]) { - bool scanned_comment = false; - bool ret = scan_automatic_semicolon(lexer, valid_symbols, &scanned_comment); - if (!ret && !scanned_comment && valid_symbols[TERNARY_QMARK] && lexer->lookahead == '?') { - return scan_ternary_qmark(lexer); - } - return ret; - } - if (valid_symbols[TERNARY_QMARK]) { - return scan_ternary_qmark(lexer); - } - - if (valid_symbols[HTML_COMMENT] && !valid_symbols[LOGICAL_OR] && !valid_symbols[ESCAPE_SEQUENCE]) { - return scan_closing_comment(lexer); - } - - return false; -} diff --git a/vendored_parsers/tree-sitter-typescript/examples/parser.ts b/vendored_parsers/tree-sitter-typescript/examples/parser.ts deleted file mode 100644 index b2bb3f467..000000000 --- a/vendored_parsers/tree-sitter-typescript/examples/parser.ts +++ /dev/null @@ -1,7555 +0,0 @@ -/// -/// - -namespace ts { - const enum SignatureFlags { - None = 0, - Yield = 1 << 0, - Await = 1 << 1, - Type = 1 << 2, - RequireCompleteParameterList = 1 << 3, - IgnoreMissingOpenBrace = 1 << 4, - JSDoc = 1 << 5, - } - - // tslint:disable variable-name - let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - // tslint:enable variable-name - - export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node { - if (kind === SyntaxKind.SourceFile) { - return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, pos, end); - } - else if (kind === SyntaxKind.Identifier) { - return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end); - } - else if (!isNodeKind(kind)) { - return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end); - } - else { - return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, pos, end); - } - } - - function visitNode(cbNode: (node: Node) => T, node: Node): T | undefined { - return node && cbNode(node); - } - - function visitNodes(cbNode: (node: Node) => T, cbNodes: (node: NodeArray) => T | undefined, nodes: NodeArray): T | undefined { - if (nodes) { - if (cbNodes) { - return cbNodes(nodes); - } - for (const node of nodes) { - const result = cbNode(node); - if (result) { - return result; - } - } - } - } - - /** - * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes - * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, - * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns - * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. - * - * @param node a given node to visit its children - * @param cbNode a callback to be invoked for all child nodes - * @param cbNodes a callback to be invoked for embedded array - * - * @remarks `forEachChild` must visit the children of a node in the order - * that they appear in the source code. The language service depends on this property to locate nodes by position. - */ - export function forEachChild(node: Node, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - if (!node || node.kind <= SyntaxKind.LastToken) { - return; - } - switch (node.kind) { - case SyntaxKind.QualifiedName: - return visitNode(cbNode, (node).left) || - visitNode(cbNode, (node).right); - case SyntaxKind.TypeParameter: - return visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).constraint) || - visitNode(cbNode, (node).default) || - visitNode(cbNode, (node).expression); - case SyntaxKind.ShorthandPropertyAssignment: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).questionToken) || - visitNode(cbNode, (node).equalsToken) || - visitNode(cbNode, (node).objectAssignmentInitializer); - case SyntaxKind.SpreadAssignment: - return visitNode(cbNode, (node).expression); - case SyntaxKind.Parameter: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).dotDotDotToken) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).questionToken) || - visitNode(cbNode, (node).type) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.PropertyDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).questionToken) || - visitNode(cbNode, (node).exclamationToken) || - visitNode(cbNode, (node).type) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.PropertySignature: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).questionToken) || - visitNode(cbNode, (node).type) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.PropertyAssignment: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).questionToken) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.VariableDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).exclamationToken) || - visitNode(cbNode, (node).type) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.BindingElement: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).dotDotDotToken) || - visitNode(cbNode, (node).propertyName) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNodes(cbNode, cbNodes, (node).typeParameters) || - visitNodes(cbNode, cbNodes, (node).parameters) || - visitNode(cbNode, (node).type); - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).asteriskToken) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).questionToken) || - visitNodes(cbNode, cbNodes, (node).typeParameters) || - visitNodes(cbNode, cbNodes, (node).parameters) || - visitNode(cbNode, (node).type) || - visitNode(cbNode, (node).equalsGreaterThanToken) || - visitNode(cbNode, (node).body); - case SyntaxKind.TypeReference: - return visitNode(cbNode, (node).typeName) || - visitNodes(cbNode, cbNodes, (node).typeArguments); - case SyntaxKind.TypePredicate: - return visitNode(cbNode, (node).parameterName) || - visitNode(cbNode, (node).type); - case SyntaxKind.TypeQuery: - return visitNode(cbNode, (node).exprName); - case SyntaxKind.TypeLiteral: - return visitNodes(cbNode, cbNodes, (node).members); - case SyntaxKind.ArrayType: - return visitNode(cbNode, (node).elementType); - case SyntaxKind.TupleType: - return visitNodes(cbNode, cbNodes, (node).elementTypes); - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - return visitNodes(cbNode, cbNodes, (node).types); - case SyntaxKind.ConditionalType: - return visitNode(cbNode, (node).checkType) || - visitNode(cbNode, (node).extendsType) || - visitNode(cbNode, (node).trueType) || - visitNode(cbNode, (node).falseType); - case SyntaxKind.InferType: - return visitNode(cbNode, (node).typeParameter); - case SyntaxKind.ParenthesizedType: - case SyntaxKind.TypeOperator: - return visitNode(cbNode, (node).type); - case SyntaxKind.IndexedAccessType: - return visitNode(cbNode, (node).objectType) || - visitNode(cbNode, (node).indexType); - case SyntaxKind.MappedType: - return visitNode(cbNode, (node).readonlyToken) || - visitNode(cbNode, (node).typeParameter) || - visitNode(cbNode, (node).questionToken) || - visitNode(cbNode, (node).type); - case SyntaxKind.LiteralType: - return visitNode(cbNode, (node).literal); - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - return visitNodes(cbNode, cbNodes, (node).elements); - case SyntaxKind.ArrayLiteralExpression: - return visitNodes(cbNode, cbNodes, (node).elements); - case SyntaxKind.ObjectLiteralExpression: - return visitNodes(cbNode, cbNodes, (node).properties); - case SyntaxKind.PropertyAccessExpression: - return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).name); - case SyntaxKind.ElementAccessExpression: - return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).argumentExpression); - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - return visitNode(cbNode, (node).expression) || - visitNodes(cbNode, cbNodes, (node).typeArguments) || - visitNodes(cbNode, cbNodes, (node).arguments); - case SyntaxKind.TaggedTemplateExpression: - return visitNode(cbNode, (node).tag) || - visitNode(cbNode, (node).template); - case SyntaxKind.TypeAssertionExpression: - return visitNode(cbNode, (node).type) || - visitNode(cbNode, (node).expression); - case SyntaxKind.ParenthesizedExpression: - return visitNode(cbNode, (node).expression); - case SyntaxKind.DeleteExpression: - return visitNode(cbNode, (node).expression); - case SyntaxKind.TypeOfExpression: - return visitNode(cbNode, (node).expression); - case SyntaxKind.VoidExpression: - return visitNode(cbNode, (node).expression); - case SyntaxKind.PrefixUnaryExpression: - return visitNode(cbNode, (node).operand); - case SyntaxKind.YieldExpression: - return visitNode(cbNode, (node).asteriskToken) || - visitNode(cbNode, (node).expression); - case SyntaxKind.AwaitExpression: - return visitNode(cbNode, (node).expression); - case SyntaxKind.PostfixUnaryExpression: - return visitNode(cbNode, (node).operand); - case SyntaxKind.BinaryExpression: - return visitNode(cbNode, (node).left) || - visitNode(cbNode, (node).operatorToken) || - visitNode(cbNode, (node).right); - case SyntaxKind.AsExpression: - return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).type); - case SyntaxKind.NonNullExpression: - return visitNode(cbNode, (node).expression); - case SyntaxKind.MetaProperty: - return visitNode(cbNode, (node).name); - case SyntaxKind.ConditionalExpression: - return visitNode(cbNode, (node).condition) || - visitNode(cbNode, (node).questionToken) || - visitNode(cbNode, (node).whenTrue) || - visitNode(cbNode, (node).colonToken) || - visitNode(cbNode, (node).whenFalse); - case SyntaxKind.SpreadElement: - return visitNode(cbNode, (node).expression); - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - return visitNodes(cbNode, cbNodes, (node).statements); - case SyntaxKind.SourceFile: - return visitNodes(cbNode, cbNodes, (node).statements) || - visitNode(cbNode, (node).endOfFileToken); - case SyntaxKind.VariableStatement: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).declarationList); - case SyntaxKind.VariableDeclarationList: - return visitNodes(cbNode, cbNodes, (node).declarations); - case SyntaxKind.ExpressionStatement: - return visitNode(cbNode, (node).expression); - case SyntaxKind.IfStatement: - return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).thenStatement) || - visitNode(cbNode, (node).elseStatement); - case SyntaxKind.DoStatement: - return visitNode(cbNode, (node).statement) || - visitNode(cbNode, (node).expression); - case SyntaxKind.WhileStatement: - return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).statement); - case SyntaxKind.ForStatement: - return visitNode(cbNode, (node).initializer) || - visitNode(cbNode, (node).condition) || - visitNode(cbNode, (node).incrementor) || - visitNode(cbNode, (node).statement); - case SyntaxKind.ForInStatement: - return visitNode(cbNode, (node).initializer) || - visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).statement); - case SyntaxKind.ForOfStatement: - return visitNode(cbNode, (node).awaitModifier) || - visitNode(cbNode, (node).initializer) || - visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).statement); - case SyntaxKind.ContinueStatement: - case SyntaxKind.BreakStatement: - return visitNode(cbNode, (node).label); - case SyntaxKind.ReturnStatement: - return visitNode(cbNode, (node).expression); - case SyntaxKind.WithStatement: - return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).statement); - case SyntaxKind.SwitchStatement: - return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).caseBlock); - case SyntaxKind.CaseBlock: - return visitNodes(cbNode, cbNodes, (node).clauses); - case SyntaxKind.CaseClause: - return visitNode(cbNode, (node).expression) || - visitNodes(cbNode, cbNodes, (node).statements); - case SyntaxKind.DefaultClause: - return visitNodes(cbNode, cbNodes, (node).statements); - case SyntaxKind.LabeledStatement: - return visitNode(cbNode, (node).label) || - visitNode(cbNode, (node).statement); - case SyntaxKind.ThrowStatement: - return visitNode(cbNode, (node).expression); - case SyntaxKind.TryStatement: - return visitNode(cbNode, (node).tryBlock) || - visitNode(cbNode, (node).catchClause) || - visitNode(cbNode, (node).finallyBlock); - case SyntaxKind.CatchClause: - return visitNode(cbNode, (node).variableDeclaration) || - visitNode(cbNode, (node).block); - case SyntaxKind.Decorator: - return visitNode(cbNode, (node).expression); - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNodes(cbNode, cbNodes, (node).typeParameters) || - visitNodes(cbNode, cbNodes, (node).heritageClauses) || - visitNodes(cbNode, cbNodes, (node).members); - case SyntaxKind.InterfaceDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNodes(cbNode, cbNodes, (node).typeParameters) || - visitNodes(cbNode, cbNodes, (node).heritageClauses) || - visitNodes(cbNode, cbNodes, (node).members); - case SyntaxKind.TypeAliasDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNodes(cbNode, cbNodes, (node).typeParameters) || - visitNode(cbNode, (node).type); - case SyntaxKind.EnumDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNodes(cbNode, cbNodes, (node).members); - case SyntaxKind.EnumMember: - return visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.ModuleDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).body); - case SyntaxKind.ImportEqualsDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).moduleReference); - case SyntaxKind.ImportDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).importClause) || - visitNode(cbNode, (node).moduleSpecifier); - case SyntaxKind.ImportClause: - return visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).namedBindings); - case SyntaxKind.NamespaceExportDeclaration: - return visitNode(cbNode, (node).name); - - case SyntaxKind.NamespaceImport: - return visitNode(cbNode, (node).name); - case SyntaxKind.NamedImports: - case SyntaxKind.NamedExports: - return visitNodes(cbNode, cbNodes, (node).elements); - case SyntaxKind.ExportDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).exportClause) || - visitNode(cbNode, (node).moduleSpecifier); - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - return visitNode(cbNode, (node).propertyName) || - visitNode(cbNode, (node).name); - case SyntaxKind.ExportAssignment: - return visitNodes(cbNode, cbNodes, node.decorators) || - visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node).expression); - case SyntaxKind.TemplateExpression: - return visitNode(cbNode, (node).head) || visitNodes(cbNode, cbNodes, (node).templateSpans); - case SyntaxKind.TemplateSpan: - return visitNode(cbNode, (node).expression) || visitNode(cbNode, (node).literal); - case SyntaxKind.ComputedPropertyName: - return visitNode(cbNode, (node).expression); - case SyntaxKind.HeritageClause: - return visitNodes(cbNode, cbNodes, (node).types); - case SyntaxKind.ExpressionWithTypeArguments: - return visitNode(cbNode, (node).expression) || - visitNodes(cbNode, cbNodes, (node).typeArguments); - case SyntaxKind.ExternalModuleReference: - return visitNode(cbNode, (node).expression); - case SyntaxKind.MissingDeclaration: - return visitNodes(cbNode, cbNodes, node.decorators); - case SyntaxKind.CommaListExpression: - return visitNodes(cbNode, cbNodes, (node).elements); - - case SyntaxKind.JsxElement: - return visitNode(cbNode, (node).openingElement) || - visitNodes(cbNode, cbNodes, (node).children) || - visitNode(cbNode, (node).closingElement); - case SyntaxKind.JsxFragment: - return visitNode(cbNode, (node).openingFragment) || - visitNodes(cbNode, cbNodes, (node).children) || - visitNode(cbNode, (node).closingFragment); - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxOpeningElement: - return visitNode(cbNode, (node).tagName) || - visitNode(cbNode, (node).attributes); - case SyntaxKind.JsxAttributes: - return visitNodes(cbNode, cbNodes, (node).properties); - case SyntaxKind.JsxAttribute: - return visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).initializer); - case SyntaxKind.JsxSpreadAttribute: - return visitNode(cbNode, (node).expression); - case SyntaxKind.JsxExpression: - return visitNode(cbNode, (node as JsxExpression).dotDotDotToken) || - visitNode(cbNode, (node as JsxExpression).expression); - case SyntaxKind.JsxClosingElement: - return visitNode(cbNode, (node).tagName); - - case SyntaxKind.JSDocTypeExpression: - return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocNonNullableType: - return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocNullableType: - return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocOptionalType: - return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocFunctionType: - return visitNodes(cbNode, cbNodes, (node).parameters) || - visitNode(cbNode, (node).type); - case SyntaxKind.JSDocVariadicType: - return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocComment: - return visitNodes(cbNode, cbNodes, (node).tags); - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocPropertyTag: - if ((node as JSDocPropertyLikeTag).isNameFirst) { - return visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).typeExpression); - } - else { - return visitNode(cbNode, (node).typeExpression) || - visitNode(cbNode, (node).name); - } - case SyntaxKind.JSDocReturnTag: - return visitNode(cbNode, (node).typeExpression); - case SyntaxKind.JSDocTypeTag: - return visitNode(cbNode, (node).typeExpression); - case SyntaxKind.JSDocAugmentsTag: - return visitNode(cbNode, (node).class); - case SyntaxKind.JSDocTemplateTag: - return visitNodes(cbNode, cbNodes, (node).typeParameters); - case SyntaxKind.JSDocTypedefTag: - if ((node as JSDocTypedefTag).typeExpression && - (node as JSDocTypedefTag).typeExpression.kind === SyntaxKind.JSDocTypeExpression) { - return visitNode(cbNode, (node).typeExpression) || - visitNode(cbNode, (node).fullName); - } - else { - return visitNode(cbNode, (node).fullName) || - visitNode(cbNode, (node).typeExpression); - } - case SyntaxKind.JSDocTypeLiteral: - if ((node as JSDocTypeLiteral).jsDocPropertyTags) { - for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) { - visitNode(cbNode, tag); - } - } - return; - case SyntaxKind.PartiallyEmittedExpression: - return visitNode(cbNode, (node).expression); - } - } - - export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false, scriptKind?: ScriptKind): SourceFile { - performance.mark("beforeParse"); - const result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind); - performance.mark("afterParse"); - performance.measure("Parse", "beforeParse", "afterParse"); - return result; - } - - export function parseIsolatedEntityName(text: string, languageVersion: ScriptTarget): EntityName { - return Parser.parseIsolatedEntityName(text, languageVersion); - } - - /** - * Parse json text into SyntaxTree and return node and parse errors if any - * @param fileName - * @param sourceText - */ - export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile { - return Parser.parseJsonText(fileName, sourceText); - } - - // See also `isExternalOrCommonJsModule` in utilities.ts - export function isExternalModule(file: SourceFile): boolean { - return file.externalModuleIndicator !== undefined; - } - - // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter - // indicates what changed between the 'text' that this SourceFile has and the 'newText'. - // The SourceFile will be created with the compiler attempting to reuse as many nodes from - // this file as possible. - // - // Note: this function mutates nodes from this SourceFile. That means any existing nodes - // from this SourceFile that are being held onto may change as a result (including - // becoming detached from any SourceFile). It is recommended that this SourceFile not - // be used once 'update' is called on it. - export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile { - const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); - // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. - // We will manually port the flag to the new source file. - newSourceFile.flags |= (sourceFile.flags & NodeFlags.PossiblyContainsDynamicImport); - return newSourceFile; - } - - /* @internal */ - export function parseIsolatedJSDocComment(content: string, start?: number, length?: number) { - const result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); - if (result && result.jsDoc) { - // because the jsDocComment was parsed out of the source file, it might - // not be covered by the fixupParentReferences. - Parser.fixupParentReferences(result.jsDoc); - } - - return result; - } - - /* @internal */ - // Exposed only for testing. - export function parseJSDocTypeExpressionForTests(content: string, start?: number, length?: number) { - return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); - } - - // Implement the parser as a singleton module. We do this for perf reasons because creating - // parser instances can actually be expensive enough to impact us on projects with many source - // files. - namespace Parser { - // Share a single scanner across all calls to parse a source file. This helps speed things - // up by avoiding the cost of creating/compiling scanners over and over again. - const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - const disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext; - - // capture constructors in 'initializeState' to avoid null checks - // tslint:disable variable-name - let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - // tslint:enable variable-name - - let sourceFile: SourceFile; - let parseDiagnostics: Diagnostic[]; - let syntaxCursor: IncrementalParser.SyntaxCursor; - - let currentToken: SyntaxKind; - let sourceText: string; - let nodeCount: number; - let identifiers: Map; - let identifierCount: number; - - let parsingContext: ParsingContext; - - // Flags that dictate what parsing context we're in. For example: - // Whether or not we are in strict parsing mode. All that changes in strict parsing mode is - // that some tokens that would be considered identifiers may be considered keywords. - // - // When adding more parser context flags, consider which is the more common case that the - // flag will be in. This should be the 'false' state for that flag. The reason for this is - // that we don't store data in our nodes unless the value is in the *non-default* state. So, - // for example, more often than code 'allows-in' (or doesn't 'disallow-in'). We opt for - // 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost - // all nodes would need extra state on them to store this info. - // - // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 - // grammar specification. - // - // An important thing about these context concepts. By default they are effectively inherited - // while parsing through every grammar production. i.e. if you don't change them, then when - // you parse a sub-production, it will have the same context values as the parent production. - // This is great most of the time. After all, consider all the 'expression' grammar productions - // and how nearly all of them pass along the 'in' and 'yield' context values: - // - // EqualityExpression[In, Yield] : - // RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield] - // - // Where you have to be careful is then understanding what the points are in the grammar - // where the values are *not* passed along. For example: - // - // SingleNameBinding[Yield,GeneratorParameter] - // [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt - // [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt - // - // Here this is saying that if the GeneratorParameter context flag is set, that we should - // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier - // and we should explicitly unset the 'yield' context flag before calling into the Initializer. - // production. Conversely, if the GeneratorParameter context flag is not set, then we - // should leave the 'yield' context flag alone. - // - // Getting this all correct is tricky and requires careful reading of the grammar to - // understand when these values should be changed versus when they should be inherited. - // - // Note: it should not be necessary to save/restore these flags during speculative/lookahead - // parsing. These context flags are naturally stored and restored through normal recursive - // descent parsing and unwinding. - let contextFlags: NodeFlags; - - // Whether or not we've had a parse error since creating the last AST node. If we have - // encountered an error, it will be stored on the next AST node we create. Parse errors - // can be broken down into three categories: - // - // 1) An error that occurred during scanning. For example, an unterminated literal, or a - // character that was completely not understood. - // - // 2) A token was expected, but was not present. This type of error is commonly produced - // by the 'parseExpected' function. - // - // 3) A token was present that no parsing function was able to consume. This type of error - // only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser - // decides to skip the token. - // - // In all of these cases, we want to mark the next node as having had an error before it. - // With this mark, we can know in incremental settings if this node can be reused, or if - // we have to reparse it. If we don't keep this information around, we may just reuse the - // node. in that event we would then not produce the same errors as we did before, causing - // significant confusion problems. - // - // Note: it is necessary that this value be saved/restored during speculative/lookahead - // parsing. During lookahead parsing, we will often create a node. That node will have - // this value attached, and then this value will be set back to 'false'. If we decide to - // rewind, we must get back to the same value we had prior to the lookahead. - // - // Note: any errors at the end of the file that do not precede a regular node, should get - // attached to the EOF token. - let parseErrorBeforeNextFinishedNode = false; - - export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile { - scriptKind = ensureScriptKind(fileName, scriptKind); - - initializeState(sourceText, languageVersion, syntaxCursor, scriptKind); - - const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind); - - clearState(); - - return result; - } - - export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName { - // Choice of `isDeclarationFile` should be arbitrary - initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS); - // Prime the scanner. - nextToken(); - const entityName = parseEntityName(/*allowReservedWords*/ true); - const isInvalid = token() === SyntaxKind.EndOfFileToken && !parseDiagnostics.length; - clearState(); - return isInvalid ? entityName : undefined; - } - - export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile { - initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON); - // Set source file so that errors will be reported with this file name - sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); - const result = sourceFile; - - // Prime the scanner. - nextToken(); - if (token() === SyntaxKind.EndOfFileToken) { - sourceFile.endOfFileToken = parseTokenNode(); - } - else if (token() === SyntaxKind.OpenBraceToken || - lookAhead(() => token() === SyntaxKind.StringLiteral)) { - result.jsonObject = parseObjectLiteralExpression(); - sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); - } - else { - parseExpected(SyntaxKind.OpenBraceToken); - } - - sourceFile.parseDiagnostics = parseDiagnostics; - clearState(); - return result; - } - - function getLanguageVariant(scriptKind: ScriptKind) { - // .tsx and .jsx files are treated as jsx language variant. - return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; - } - - function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) { - NodeConstructor = objectAllocator.getNodeConstructor(); - TokenConstructor = objectAllocator.getTokenConstructor(); - IdentifierConstructor = objectAllocator.getIdentifierConstructor(); - SourceFileConstructor = objectAllocator.getSourceFileConstructor(); - - sourceText = _sourceText; - syntaxCursor = _syntaxCursor; - - parseDiagnostics = []; - parsingContext = 0; - identifiers = createMap(); - identifierCount = 0; - nodeCount = 0; - - switch (scriptKind) { - case ScriptKind.JS: - case ScriptKind.JSX: - case ScriptKind.JSON: - contextFlags = NodeFlags.JavaScriptFile; - break; - default: - contextFlags = NodeFlags.None; - break; - } - parseErrorBeforeNextFinishedNode = false; - - // Initialize and prime the scanner before parsing the source elements. - scanner.setText(sourceText); - scanner.setOnError(scanError); - scanner.setScriptTarget(languageVersion); - scanner.setLanguageVariant(getLanguageVariant(scriptKind)); - } - - function clearState() { - // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily. - scanner.setText(""); - scanner.setOnError(undefined); - - // Clear any data. We don't want to accidentally hold onto it for too long. - parseDiagnostics = undefined; - sourceFile = undefined; - identifiers = undefined; - syntaxCursor = undefined; - sourceText = undefined; - } - - function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile { - const isDeclarationFile = isDeclarationFileName(fileName); - if (isDeclarationFile) { - contextFlags |= NodeFlags.Ambient; - } - - sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile); - sourceFile.flags = contextFlags; - - // Prime the scanner. - nextToken(); - processReferenceComments(sourceFile); - - sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement); - Debug.assert(token() === SyntaxKind.EndOfFileToken); - sourceFile.endOfFileToken = addJSDocComment(parseTokenNode() as EndOfFileToken); - - setExternalModuleIndicator(sourceFile); - - sourceFile.nodeCount = nodeCount; - sourceFile.identifierCount = identifierCount; - sourceFile.identifiers = identifiers; - sourceFile.parseDiagnostics = parseDiagnostics; - - if (setParentNodes) { - fixupParentReferences(sourceFile); - } - - return sourceFile; - } - - function addJSDocComment(node: T): T { - const comments = getJSDocCommentRanges(node, sourceFile.text); - if (comments) { - for (const comment of comments) { - node.jsDoc = append(node.jsDoc, JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); - } - } - - return node; - } - - export function fixupParentReferences(rootNode: Node) { - // normally parent references are set during binding. However, for clients that only need - // a syntax tree, and no semantic features, then the binding process is an unnecessary - // overhead. This functions allows us to set all the parents, without all the expense of - // binding. - - let parent: Node = rootNode; - forEachChild(rootNode, visitNode); - return; - - function visitNode(n: Node): void { - // walk down setting parents that differ from the parent we think it should be. This - // allows us to quickly bail out of setting parents for subtrees during incremental - // parsing - if (n.parent !== parent) { - n.parent = parent; - - const saveParent = parent; - parent = n; - forEachChild(n, visitNode); - if (hasJSDocNodes(n)) { - for (const jsDoc of n.jsDoc) { - jsDoc.parent = n; - parent = jsDoc; - forEachChild(jsDoc, visitNode); - } - } - parent = saveParent; - } - } - } - - function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean): SourceFile { - // code from createNode is inlined here so createNode won't have to deal with special case of creating source files - // this is quite rare comparing to other nodes and createNode should be as fast as possible - const sourceFile = new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length); - nodeCount++; - - sourceFile.text = sourceText; - sourceFile.bindDiagnostics = []; - sourceFile.languageVersion = languageVersion; - sourceFile.fileName = normalizePath(fileName); - sourceFile.languageVariant = getLanguageVariant(scriptKind); - sourceFile.isDeclarationFile = isDeclarationFile; - sourceFile.scriptKind = scriptKind; - - return sourceFile; - } - - function setContextFlag(val: boolean, flag: NodeFlags) { - if (val) { - contextFlags |= flag; - } - else { - contextFlags &= ~flag; - } - } - - function setDisallowInContext(val: boolean) { - setContextFlag(val, NodeFlags.DisallowInContext); - } - - function setYieldContext(val: boolean) { - setContextFlag(val, NodeFlags.YieldContext); - } - - function setDecoratorContext(val: boolean) { - setContextFlag(val, NodeFlags.DecoratorContext); - } - - function setAwaitContext(val: boolean) { - setContextFlag(val, NodeFlags.AwaitContext); - } - - function doOutsideOfContext(context: NodeFlags, func: () => T): T { - // contextFlagsToClear will contain only the context flags that are - // currently set that we need to temporarily clear - // We don't just blindly reset to the previous flags to ensure - // that we do not mutate cached flags for the incremental - // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and - // HasAggregatedChildData). - const contextFlagsToClear = context & contextFlags; - if (contextFlagsToClear) { - // clear the requested context flags - setContextFlag(/*val*/ false, contextFlagsToClear); - const result = func(); - // restore the context flags we just cleared - setContextFlag(/*val*/ true, contextFlagsToClear); - return result; - } - - // no need to do anything special as we are not in any of the requested contexts - return func(); - } - - function doInsideOfContext(context: NodeFlags, func: () => T): T { - // contextFlagsToSet will contain only the context flags that - // are not currently set that we need to temporarily enable. - // We don't just blindly reset to the previous flags to ensure - // that we do not mutate cached flags for the incremental - // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and - // HasAggregatedChildData). - const contextFlagsToSet = context & ~contextFlags; - if (contextFlagsToSet) { - // set the requested context flags - setContextFlag(/*val*/ true, contextFlagsToSet); - const result = func(); - // reset the context flags we just set - setContextFlag(/*val*/ false, contextFlagsToSet); - return result; - } - - // no need to do anything special as we are already in all of the requested contexts - return func(); - } - - function allowInAnd(func: () => T): T { - return doOutsideOfContext(NodeFlags.DisallowInContext, func); - } - - function disallowInAnd(func: () => T): T { - return doInsideOfContext(NodeFlags.DisallowInContext, func); - } - - function doInYieldContext(func: () => T): T { - return doInsideOfContext(NodeFlags.YieldContext, func); - } - - function doInDecoratorContext(func: () => T): T { - return doInsideOfContext(NodeFlags.DecoratorContext, func); - } - - function doInAwaitContext(func: () => T): T { - return doInsideOfContext(NodeFlags.AwaitContext, func); - } - - function doOutsideOfAwaitContext(func: () => T): T { - return doOutsideOfContext(NodeFlags.AwaitContext, func); - } - - function doInYieldAndAwaitContext(func: () => T): T { - return doInsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext, func); - } - - function inContext(flags: NodeFlags) { - return (contextFlags & flags) !== 0; - } - - function inYieldContext() { - return inContext(NodeFlags.YieldContext); - } - - function inDisallowInContext() { - return inContext(NodeFlags.DisallowInContext); - } - - function inDecoratorContext() { - return inContext(NodeFlags.DecoratorContext); - } - - function inAwaitContext() { - return inContext(NodeFlags.AwaitContext); - } - - function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void { - const start = scanner.getTokenPos(); - const length = scanner.getTextPos() - start; - - parseErrorAtPosition(start, length, message, arg0); - } - - function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): void { - // Don't report another error if it would just be at the same position as the last error. - const lastError = lastOrUndefined(parseDiagnostics); - if (!lastError || start !== lastError.start) { - parseDiagnostics.push(createFileDiagnostic(sourceFile, start, length, message, arg0)); - } - - // Mark that we've encountered an error. We'll set an appropriate bit on the next - // node we finish so that it can't be reused incrementally. - parseErrorBeforeNextFinishedNode = true; - } - - function scanError(message: DiagnosticMessage, length?: number) { - const pos = scanner.getTextPos(); - parseErrorAtPosition(pos, length || 0, message); - } - - function getNodePos(): number { - return scanner.getStartPos(); - } - - // Use this function to access the current token instead of reading the currentToken - // variable. Since function results aren't narrowed in control flow analysis, this ensures - // that the type checker doesn't make wrong assumptions about the type of the current - // token (e.g. a call to nextToken() changes the current token but the checker doesn't - // reason about this side effect). Mainstream VMs inline simple functions like this, so - // there is no performance penalty. - function token(): SyntaxKind { - return currentToken; - } - - function nextToken(): SyntaxKind { - return currentToken = scanner.scan(); - } - - function reScanGreaterToken(): SyntaxKind { - return currentToken = scanner.reScanGreaterToken(); - } - - function reScanSlashToken(): SyntaxKind { - return currentToken = scanner.reScanSlashToken(); - } - - function reScanTemplateToken(): SyntaxKind { - return currentToken = scanner.reScanTemplateToken(); - } - - function scanJsxIdentifier(): SyntaxKind { - return currentToken = scanner.scanJsxIdentifier(); - } - - function scanJsxText(): SyntaxKind { - return currentToken = scanner.scanJsxToken(); - } - - function scanJsxAttributeValue(): SyntaxKind { - return currentToken = scanner.scanJsxAttributeValue(); - } - - function speculationHelper(callback: () => T, isLookAhead: boolean): T { - // Keep track of the state we'll need to rollback to if lookahead fails (or if the - // caller asked us to always reset our state). - const saveToken = currentToken; - const saveParseDiagnosticsLength = parseDiagnostics.length; - const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; - - // Note: it is not actually necessary to save/restore the context flags here. That's - // because the saving/restoring of these flags happens naturally through the recursive - // descent nature of our parser. However, we still store this here just so we can - // assert that invariant holds. - const saveContextFlags = contextFlags; - - // If we're only looking ahead, then tell the scanner to only lookahead as well. - // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the - // same. - const result = isLookAhead - ? scanner.lookAhead(callback) - : scanner.tryScan(callback); - - Debug.assert(saveContextFlags === contextFlags); - - // If our callback returned something 'falsy' or we're just looking ahead, - // then unconditionally restore us to where we were. - if (!result || isLookAhead) { - currentToken = saveToken; - parseDiagnostics.length = saveParseDiagnosticsLength; - parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; - } - - return result; - } - - /** Invokes the provided callback then unconditionally restores the parser to the state it - * was in immediately prior to invoking the callback. The result of invoking the callback - * is returned from this function. - */ - function lookAhead(callback: () => T): T { - return speculationHelper(callback, /*isLookAhead*/ true); - } - - /** Invokes the provided callback. If the callback returns something falsy, then it restores - * the parser to the state it was in immediately prior to invoking the callback. If the - * callback returns something truthy, then the parser state is not rolled back. The result - * of invoking the callback is returned from this function. - */ - function tryParse(callback: () => T): T { - return speculationHelper(callback, /*isLookAhead*/ false); - } - - // Ignore strict mode flag because we will report an error in type checker instead. - function isIdentifier(): boolean { - if (token() === SyntaxKind.Identifier) { - return true; - } - - // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is - // considered a keyword and is not an identifier. - if (token() === SyntaxKind.YieldKeyword && inYieldContext()) { - return false; - } - - // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is - // considered a keyword and is not an identifier. - if (token() === SyntaxKind.AwaitKeyword && inAwaitContext()) { - return false; - } - - return token() > SyntaxKind.LastReservedWord; - } - - function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean { - if (token() === kind) { - if (shouldAdvance) { - nextToken(); - } - return true; - } - - // Report specific message if provided with one. Otherwise, report generic fallback message. - if (diagnosticMessage) { - parseErrorAtCurrentToken(diagnosticMessage); - } - else { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); - } - return false; - } - - function parseOptional(t: SyntaxKind): boolean { - if (token() === t) { - nextToken(); - return true; - } - return false; - } - - function parseOptionalToken(t: TKind): Token; - function parseOptionalToken(t: SyntaxKind): Node { - if (token() === t) { - return parseTokenNode(); - } - return undefined; - } - - function parseExpectedToken(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Token; - function parseExpectedToken(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Node { - return parseOptionalToken(t) || - createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics._0_expected, arg0 || tokenToString(t)); - } - - function parseTokenNode(): T { - const node = createNode(token()); - nextToken(); - return finishNode(node); - } - - function canParseSemicolon() { - // If there's a real semicolon, then we can always parse it out. - if (token() === SyntaxKind.SemicolonToken) { - return true; - } - - // We can parse out an optional semicolon in ASI cases in the following cases. - return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak(); - } - - function parseSemicolon(): boolean { - if (canParseSemicolon()) { - if (token() === SyntaxKind.SemicolonToken) { - // consume the semicolon if it was explicitly provided. - nextToken(); - } - - return true; - } - else { - return parseExpected(SyntaxKind.SemicolonToken); - } - } - - function createNode(kind: SyntaxKind, pos?: number): Node { - nodeCount++; - const p = pos >= 0 ? pos : scanner.getStartPos(); - return isNodeKind(kind) || kind === SyntaxKind.Unknown ? new NodeConstructor(kind, p, p) : - kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, p, p) : - new TokenConstructor(kind, p, p); - } - - function createNodeWithJSDoc(kind: SyntaxKind): Node { - const node = createNode(kind); - if (scanner.getTokenFlags() & TokenFlags.PrecedingJSDocComment) { - addJSDocComment(node); - } - return node; - } - - function createNodeArray(elements: T[], pos: number, end?: number): NodeArray { - // Since the element list of a node array is typically created by starting with an empty array and - // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for - // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation. - const length = elements.length; - const array = >(length >= 1 && length <= 4 ? elements.slice() : elements); - array.pos = pos; - array.end = end === undefined ? scanner.getStartPos() : end; - return array; - } - - function finishNode(node: T, end?: number): T { - node.end = end === undefined ? scanner.getStartPos() : end; - - if (contextFlags) { - node.flags |= contextFlags; - } - - // Keep track on the node if we encountered an error while parsing it. If we did, then - // we cannot reuse the node incrementally. Once we've marked this node, clear out the - // flag so that we don't mark any subsequent nodes. - if (parseErrorBeforeNextFinishedNode) { - parseErrorBeforeNextFinishedNode = false; - node.flags |= NodeFlags.ThisNodeHasError; - } - - return node; - } - - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T { - if (reportAtCurrentPosition) { - parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); - } - else { - parseErrorAtCurrentToken(diagnosticMessage, arg0); - } - - const result = createNode(kind); - - if (kind === SyntaxKind.Identifier) { - (result as Identifier).escapedText = "" as __String; - } - else if (isLiteralKind(kind) || isTemplateLiteralKind(kind)) { - (result as LiteralLikeNode).text = ""; - } - - return finishNode(result) as T; - } - - function internIdentifier(text: string): string { - let identifier = identifiers.get(text); - if (identifier === undefined) { - identifiers.set(text, identifier = text); - } - return identifier; - } - - // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues - // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for - // each identifier in order to reduce memory consumption. - function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage): Identifier { - identifierCount++; - if (isIdentifier) { - const node = createNode(SyntaxKind.Identifier); - - // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker - if (token() !== SyntaxKind.Identifier) { - node.originalKeywordKind = token(); - } - node.escapedText = escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue())); - nextToken(); - return finishNode(node); - } - - // Only for end of file because the error gets reported incorrectly on embedded script tags. - const reportAtCurrentPosition = token() === SyntaxKind.EndOfFileToken; - - return createMissingNode(SyntaxKind.Identifier, reportAtCurrentPosition, diagnosticMessage || Diagnostics.Identifier_expected); - } - - function parseIdentifier(diagnosticMessage?: DiagnosticMessage): Identifier { - return createIdentifier(isIdentifier(), diagnosticMessage); - } - - function parseIdentifierName(diagnosticMessage?: DiagnosticMessage): Identifier { - return createIdentifier(tokenIsIdentifierOrKeyword(token()), diagnosticMessage); - } - - function isLiteralPropertyName(): boolean { - return tokenIsIdentifierOrKeyword(token()) || - token() === SyntaxKind.StringLiteral || - token() === SyntaxKind.NumericLiteral; - } - - function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName { - if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) { - const node = parseLiteralNode(); - node.text = internIdentifier(node.text); - return node; - } - if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) { - return parseComputedPropertyName(); - } - return parseIdentifierName(); - } - - function parsePropertyName(): PropertyName { - return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true); - } - - function parseComputedPropertyName(): ComputedPropertyName { - // PropertyName [Yield]: - // LiteralPropertyName - // ComputedPropertyName[?Yield] - const node = createNode(SyntaxKind.ComputedPropertyName); - parseExpected(SyntaxKind.OpenBracketToken); - - // We parse any expression (including a comma expression). But the grammar - // says that only an assignment expression is allowed, so the grammar checker - // will error if it sees a comma expression. - node.expression = allowInAnd(parseExpression); - - parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(node); - } - - function parseContextualModifier(t: SyntaxKind): boolean { - return token() === t && tryParse(nextTokenCanFollowModifier); - } - - function nextTokenIsOnSameLineAndCanFollowModifier() { - nextToken(); - if (scanner.hasPrecedingLineBreak()) { - return false; - } - return canFollowModifier(); - } - - function nextTokenCanFollowModifier() { - if (token() === SyntaxKind.ConstKeyword) { - // 'const' is only a modifier if followed by 'enum'. - return nextToken() === SyntaxKind.EnumKeyword; - } - if (token() === SyntaxKind.ExportKeyword) { - nextToken(); - if (token() === SyntaxKind.DefaultKeyword) { - return lookAhead(nextTokenCanFollowDefaultKeyword); - } - return token() !== SyntaxKind.AsteriskToken && token() !== SyntaxKind.AsKeyword && token() !== SyntaxKind.OpenBraceToken && canFollowModifier(); - } - if (token() === SyntaxKind.DefaultKeyword) { - return nextTokenCanFollowDefaultKeyword(); - } - if (token() === SyntaxKind.StaticKeyword) { - nextToken(); - return canFollowModifier(); - } - - return nextTokenIsOnSameLineAndCanFollowModifier(); - } - - function parseAnyContextualModifier(): boolean { - return isModifierKind(token()) && tryParse(nextTokenCanFollowModifier); - } - - function canFollowModifier(): boolean { - return token() === SyntaxKind.OpenBracketToken - || token() === SyntaxKind.OpenBraceToken - || token() === SyntaxKind.AsteriskToken - || token() === SyntaxKind.DotDotDotToken - || isLiteralPropertyName(); - } - - function nextTokenCanFollowDefaultKeyword(): boolean { - nextToken(); - return token() === SyntaxKind.ClassKeyword || token() === SyntaxKind.FunctionKeyword || - token() === SyntaxKind.InterfaceKeyword || - (token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) || - (token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); - } - - // True if positioned at the start of a list element - function isListElement(parsingContext: ParsingContext, inErrorRecovery: boolean): boolean { - const node = currentNode(parsingContext); - if (node) { - return true; - } - - switch (parsingContext) { - case ParsingContext.SourceElements: - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauseStatements: - // If we're in error recovery, then we don't want to treat ';' as an empty statement. - // The problem is that ';' can show up in far too many contexts, and if we see one - // and assume it's a statement, then we may bail out inappropriately from whatever - // we're parsing. For example, if we have a semicolon in the middle of a class, then - // we really don't want to assume the class is over and we're on a statement in the - // outer module. We just want to consume and move on. - return !(token() === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfStatement(); - case ParsingContext.SwitchClauses: - return token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; - case ParsingContext.TypeMembers: - return lookAhead(isTypeMemberStart); - case ParsingContext.ClassMembers: - // We allow semicolons as class elements (as specified by ES6) as long as we're - // not in error recovery. If we're in error recovery, we don't want an errant - // semicolon to be treated as a class member (since they're almost always used - // for statements. - return lookAhead(isClassMemberStart) || (token() === SyntaxKind.SemicolonToken && !inErrorRecovery); - case ParsingContext.EnumMembers: - // Include open bracket computed properties. This technically also lets in indexers, - // which would be a candidate for improved error reporting. - return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName(); - case ParsingContext.ObjectLiteralMembers: - return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName(); - case ParsingContext.RestProperties: - return isLiteralPropertyName(); - case ParsingContext.ObjectBindingElements: - return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName(); - case ParsingContext.HeritageClauseElement: - // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{` - // That way we won't consume the body of a class in its heritage clause. - if (token() === SyntaxKind.OpenBraceToken) { - return lookAhead(isValidHeritageClauseObjectLiteral); - } - - if (!inErrorRecovery) { - return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword(); - } - else { - // If we're in error recovery we tighten up what we're willing to match. - // That way we don't treat something like "this" as a valid heritage clause - // element during recovery. - return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword(); - } - case ParsingContext.VariableDeclarations: - return isIdentifierOrPattern(); - case ParsingContext.ArrayBindingElements: - return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isIdentifierOrPattern(); - case ParsingContext.TypeParameters: - return isIdentifier(); - case ParsingContext.ArrayLiteralMembers: - if (token() === SyntaxKind.CommaToken) { - return true; - } - // falls through - case ParsingContext.ArgumentExpressions: - return token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); - case ParsingContext.Parameters: - return isStartOfParameter(); - case ParsingContext.TypeArguments: - case ParsingContext.TupleElementTypes: - return token() === SyntaxKind.CommaToken || isStartOfType(); - case ParsingContext.HeritageClauses: - return isHeritageClause(); - case ParsingContext.ImportOrExportSpecifiers: - return tokenIsIdentifierOrKeyword(token()); - case ParsingContext.JsxAttributes: - return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.OpenBraceToken; - case ParsingContext.JsxChildren: - return true; - } - - Debug.fail("Non-exhaustive case in 'isListElement'."); - } - - function isValidHeritageClauseObjectLiteral() { - Debug.assert(token() === SyntaxKind.OpenBraceToken); - if (nextToken() === SyntaxKind.CloseBraceToken) { - // if we see "extends {}" then only treat the {} as what we're extending (and not - // the class body) if we have: - // - // extends {} { - // extends {}, - // extends {} extends - // extends {} implements - - const next = nextToken(); - return next === SyntaxKind.CommaToken || next === SyntaxKind.OpenBraceToken || next === SyntaxKind.ExtendsKeyword || next === SyntaxKind.ImplementsKeyword; - } - - return true; - } - - function nextTokenIsIdentifier() { - nextToken(); - return isIdentifier(); - } - - function nextTokenIsIdentifierOrKeyword() { - nextToken(); - return tokenIsIdentifierOrKeyword(token()); - } - - function nextTokenIsIdentifierOrKeywordOrGreaterThan() { - nextToken(); - return tokenIsIdentifierOrKeywordOrGreaterThan(token()); - } - - function isHeritageClauseExtendsOrImplementsKeyword(): boolean { - if (token() === SyntaxKind.ImplementsKeyword || - token() === SyntaxKind.ExtendsKeyword) { - - return lookAhead(nextTokenIsStartOfExpression); - } - - return false; - } - - function nextTokenIsStartOfExpression() { - nextToken(); - return isStartOfExpression(); - } - - function nextTokenIsStartOfType() { - nextToken(); - return isStartOfType(); - } - - // True if positioned at a list terminator - function isListTerminator(kind: ParsingContext): boolean { - if (token() === SyntaxKind.EndOfFileToken) { - // Being at the end of the file ends all lists. - return true; - } - - switch (kind) { - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauses: - case ParsingContext.TypeMembers: - case ParsingContext.ClassMembers: - case ParsingContext.EnumMembers: - case ParsingContext.ObjectLiteralMembers: - case ParsingContext.ObjectBindingElements: - case ParsingContext.ImportOrExportSpecifiers: - return token() === SyntaxKind.CloseBraceToken; - case ParsingContext.SwitchClauseStatements: - return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; - case ParsingContext.HeritageClauseElement: - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; - case ParsingContext.VariableDeclarations: - return isVariableDeclaratorListTerminator(); - case ParsingContext.TypeParameters: - // Tokens other than '>' are here for better error recovery - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; - case ParsingContext.ArgumentExpressions: - // Tokens other than ')' are here for better error recovery - return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.SemicolonToken; - case ParsingContext.ArrayLiteralMembers: - case ParsingContext.TupleElementTypes: - case ParsingContext.ArrayBindingElements: - return token() === SyntaxKind.CloseBracketToken; - case ParsingContext.Parameters: - case ParsingContext.RestProperties: - // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery - return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/; - case ParsingContext.TypeArguments: - // All other tokens should cause the type-argument to terminate except comma token - return token() !== SyntaxKind.CommaToken; - case ParsingContext.HeritageClauses: - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken; - case ParsingContext.JsxAttributes: - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.SlashToken; - case ParsingContext.JsxChildren: - return token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash); - } - } - - function isVariableDeclaratorListTerminator(): boolean { - // If we can consume a semicolon (either explicitly, or with ASI), then consider us done - // with parsing the list of variable declarators. - if (canParseSemicolon()) { - return true; - } - - // in the case where we're parsing the variable declarator of a 'for-in' statement, we - // are done if we see an 'in' keyword in front of us. Same with for-of - if (isInOrOfKeyword(token())) { - return true; - } - - // ERROR RECOVERY TWEAK: - // For better error recovery, if we see an '=>' then we just stop immediately. We've got an - // arrow function here and it's going to be very unlikely that we'll resynchronize and get - // another variable declaration. - if (token() === SyntaxKind.EqualsGreaterThanToken) { - return true; - } - - // Keep trying to parse out variable declarators. - return false; - } - - // True if positioned at element or terminator of the current list or any enclosing list - function isInSomeParsingContext(): boolean { - for (let kind = 0; kind < ParsingContext.Count; kind++) { - if (parsingContext & (1 << kind)) { - if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) { - return true; - } - } - } - - return false; - } - - // Parses a list of elements - function parseList(kind: ParsingContext, parseElement: () => T): NodeArray { - const saveParsingContext = parsingContext; - parsingContext |= 1 << kind; - const list = []; - const listPos = getNodePos(); - - while (!isListTerminator(kind)) { - if (isListElement(kind, /*inErrorRecovery*/ false)) { - const element = parseListElement(kind, parseElement); - list.push(element); - - continue; - } - - if (abortParsingListOrMoveToNextToken(kind)) { - break; - } - } - - parsingContext = saveParsingContext; - return createNodeArray(list, listPos); - } - - function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { - const node = currentNode(parsingContext); - if (node) { - return consumeNode(node); - } - - return parseElement(); - } - - function currentNode(parsingContext: ParsingContext): Node { - // If there is an outstanding parse error that we've encountered, but not attached to - // some node, then we cannot get a node from the old source tree. This is because we - // want to mark the next node we encounter as being unusable. - // - // Note: This may be too conservative. Perhaps we could reuse the node and set the bit - // on it (or its leftmost child) as having the error. For now though, being conservative - // is nice and likely won't ever affect perf. - if (parseErrorBeforeNextFinishedNode) { - return undefined; - } - - if (!syntaxCursor) { - // if we don't have a cursor, we could never return a node from the old tree. - return undefined; - } - - const node = syntaxCursor.currentNode(scanner.getStartPos()); - - // Can't reuse a missing node. - if (nodeIsMissing(node)) { - return undefined; - } - - // Can't reuse a node that intersected the change range. - if (node.intersectsChange) { - return undefined; - } - - // Can't reuse a node that contains a parse error. This is necessary so that we - // produce the same set of errors again. - if (containsParseError(node)) { - return undefined; - } - - // We can only reuse a node if it was parsed under the same strict mode that we're - // currently in. i.e. if we originally parsed a node in non-strict mode, but then - // the user added 'using strict' at the top of the file, then we can't use that node - // again as the presence of strict mode may cause us to parse the tokens in the file - // differently. - // - // Note: we *can* reuse tokens when the strict mode changes. That's because tokens - // are unaffected by strict mode. It's just the parser will decide what to do with it - // differently depending on what mode it is in. - // - // This also applies to all our other context flags as well. - const nodeContextFlags = node.flags & NodeFlags.ContextFlags; - if (nodeContextFlags !== contextFlags) { - return undefined; - } - - // Ok, we have a node that looks like it could be reused. Now verify that it is valid - // in the current list parsing context that we're currently at. - if (!canReuseNode(node, parsingContext)) { - return undefined; - } - - if ((node as JSDocContainer).jsDocCache) { - // jsDocCache may include tags from parent nodes, which might have been modified. - (node as JSDocContainer).jsDocCache = undefined; - } - - return node; - } - - function consumeNode(node: Node) { - // Move the scanner so it is after the node we just consumed. - scanner.setTextPos(node.end); - nextToken(); - return node; - } - - function canReuseNode(node: Node, parsingContext: ParsingContext): boolean { - switch (parsingContext) { - case ParsingContext.ClassMembers: - return isReusableClassMember(node); - - case ParsingContext.SwitchClauses: - return isReusableSwitchClause(node); - - case ParsingContext.SourceElements: - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauseStatements: - return isReusableStatement(node); - - case ParsingContext.EnumMembers: - return isReusableEnumMember(node); - - case ParsingContext.TypeMembers: - return isReusableTypeMember(node); - - case ParsingContext.VariableDeclarations: - return isReusableVariableDeclaration(node); - - case ParsingContext.Parameters: - return isReusableParameter(node); - - case ParsingContext.RestProperties: - return false; - - // Any other lists we do not care about reusing nodes in. But feel free to add if - // you can do so safely. Danger areas involve nodes that may involve speculative - // parsing. If speculative parsing is involved with the node, then the range the - // parser reached while looking ahead might be in the edited range (see the example - // in canReuseVariableDeclaratorNode for a good case of this). - case ParsingContext.HeritageClauses: - // This would probably be safe to reuse. There is no speculative parsing with - // heritage clauses. - - case ParsingContext.TypeParameters: - // This would probably be safe to reuse. There is no speculative parsing with - // type parameters. Note that that's because type *parameters* only occur in - // unambiguous *type* contexts. While type *arguments* occur in very ambiguous - // *expression* contexts. - - case ParsingContext.TupleElementTypes: - // This would probably be safe to reuse. There is no speculative parsing with - // tuple types. - - // Technically, type argument list types are probably safe to reuse. While - // speculative parsing is involved with them (since type argument lists are only - // produced from speculative parsing a < as a type argument list), we only have - // the types because speculative parsing succeeded. Thus, the lookahead never - // went past the end of the list and rewound. - case ParsingContext.TypeArguments: - - // Note: these are almost certainly not safe to ever reuse. Expressions commonly - // need a large amount of lookahead, and we should not reuse them as they may - // have actually intersected the edit. - case ParsingContext.ArgumentExpressions: - - // This is not safe to reuse for the same reason as the 'AssignmentExpression' - // cases. i.e. a property assignment may end with an expression, and thus might - // have lookahead far beyond it's old node. - case ParsingContext.ObjectLiteralMembers: - - // This is probably not safe to reuse. There can be speculative parsing with - // type names in a heritage clause. There can be generic names in the type - // name list, and there can be left hand side expressions (which can have type - // arguments.) - case ParsingContext.HeritageClauseElement: - - // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes - // on any given element. Same for children. - case ParsingContext.JsxAttributes: - case ParsingContext.JsxChildren: - - } - - return false; - } - - function isReusableClassMember(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.IndexSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.SemicolonClassElement: - return true; - case SyntaxKind.MethodDeclaration: - // Method declarations are not necessarily reusable. An object-literal - // may have a method calls "constructor(...)" and we must reparse that - // into an actual .ConstructorDeclaration. - const methodDeclaration = node; - const nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier && - (methodDeclaration.name).originalKeywordKind === SyntaxKind.ConstructorKeyword; - - return !nameIsConstructor; - } - } - - return false; - } - - function isReusableSwitchClause(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - return true; - } - } - - return false; - } - - function isReusableStatement(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.VariableStatement: - case SyntaxKind.Block: - case SyntaxKind.IfStatement: - case SyntaxKind.ExpressionStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.EmptyStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.LabeledStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.DebuggerStatement: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExportAssignment: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - return true; - } - } - - return false; - } - - function isReusableEnumMember(node: Node) { - return node.kind === SyntaxKind.EnumMember; - } - - function isReusableTypeMember(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.ConstructSignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.PropertySignature: - case SyntaxKind.CallSignature: - return true; - } - } - - return false; - } - - function isReusableVariableDeclaration(node: Node) { - if (node.kind !== SyntaxKind.VariableDeclaration) { - return false; - } - - // Very subtle incremental parsing bug. Consider the following code: - // - // let v = new List < A, B - // - // This is actually legal code. It's a list of variable declarators "v = new List() - // - // then we have a problem. "v = new Listnode; - return variableDeclarator.initializer === undefined; - } - - function isReusableParameter(node: Node) { - if (node.kind !== SyntaxKind.Parameter) { - return false; - } - - // See the comment in isReusableVariableDeclaration for why we do this. - const parameter = node; - return parameter.initializer === undefined; - } - - // Returns true if we should abort parsing. - function abortParsingListOrMoveToNextToken(kind: ParsingContext) { - parseErrorAtCurrentToken(parsingContextErrors(kind)); - if (isInSomeParsingContext()) { - return true; - } - - nextToken(); - return false; - } - - function parsingContextErrors(context: ParsingContext): DiagnosticMessage { - switch (context) { - case ParsingContext.SourceElements: return Diagnostics.Declaration_or_statement_expected; - case ParsingContext.BlockStatements: return Diagnostics.Declaration_or_statement_expected; - case ParsingContext.SwitchClauses: return Diagnostics.case_or_default_expected; - case ParsingContext.SwitchClauseStatements: return Diagnostics.Statement_expected; - case ParsingContext.RestProperties: // fallthrough - case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected; - case ParsingContext.ClassMembers: return Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected; - case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected; - case ParsingContext.HeritageClauseElement: return Diagnostics.Expression_expected; - case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected; - case ParsingContext.ObjectBindingElements: return Diagnostics.Property_destructuring_pattern_expected; - case ParsingContext.ArrayBindingElements: return Diagnostics.Array_element_destructuring_pattern_expected; - case ParsingContext.ArgumentExpressions: return Diagnostics.Argument_expression_expected; - case ParsingContext.ObjectLiteralMembers: return Diagnostics.Property_assignment_expected; - case ParsingContext.ArrayLiteralMembers: return Diagnostics.Expression_or_comma_expected; - case ParsingContext.Parameters: return Diagnostics.Parameter_declaration_expected; - case ParsingContext.TypeParameters: return Diagnostics.Type_parameter_declaration_expected; - case ParsingContext.TypeArguments: return Diagnostics.Type_argument_expected; - case ParsingContext.TupleElementTypes: return Diagnostics.Type_expected; - case ParsingContext.HeritageClauses: return Diagnostics.Unexpected_token_expected; - case ParsingContext.ImportOrExportSpecifiers: return Diagnostics.Identifier_expected; - case ParsingContext.JsxAttributes: return Diagnostics.Identifier_expected; - case ParsingContext.JsxChildren: return Diagnostics.Identifier_expected; - } - } - - // Parses a comma-delimited list of elements - function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray { - const saveParsingContext = parsingContext; - parsingContext |= 1 << kind; - const list = []; - const listPos = getNodePos(); - - let commaStart = -1; // Meaning the previous token was not a comma - while (true) { - if (isListElement(kind, /*inErrorRecovery*/ false)) { - const startPos = scanner.getStartPos(); - list.push(parseListElement(kind, parseElement)); - commaStart = scanner.getTokenPos(); - - if (parseOptional(SyntaxKind.CommaToken)) { - // No need to check for a zero length node since we know we parsed a comma - continue; - } - - commaStart = -1; // Back to the state where the last token was not a comma - if (isListTerminator(kind)) { - break; - } - - // We didn't get a comma, and the list wasn't terminated, explicitly parse - // out a comma so we give a good error message. - parseExpected(SyntaxKind.CommaToken); - - // If the token was a semicolon, and the caller allows that, then skip it and - // continue. This ensures we get back on track and don't result in tons of - // parse errors. For example, this can happen when people do things like use - // a semicolon to delimit object literal members. Note: we'll have already - // reported an error when we called parseExpected above. - if (considerSemicolonAsDelimiter && token() === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) { - nextToken(); - } - if (startPos === scanner.getStartPos()) { - // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever - // Consume a token to advance the parser in some way and avoid an infinite loop - // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions, - // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied - nextToken(); - } - continue; - } - - if (isListTerminator(kind)) { - break; - } - - if (abortParsingListOrMoveToNextToken(kind)) { - break; - } - } - - parsingContext = saveParsingContext; - const result = createNodeArray(list, listPos); - // Recording the trailing comma is deliberately done after the previous - // loop, and not just if we see a list terminator. This is because the list - // may have ended incorrectly, but it is still important to know if there - // was a trailing comma. - // Check if the last token was a comma. - if (commaStart >= 0) { - // Always preserve a trailing comma by marking it on the NodeArray - result.hasTrailingComma = true; - } - return result; - } - - function createMissingList(): NodeArray { - return createNodeArray([], getNodePos()); - } - - function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: SyntaxKind, close: SyntaxKind): NodeArray { - if (parseExpected(open)) { - const result = parseDelimitedList(kind, parseElement); - parseExpected(close); - return result; - } - - return createMissingList(); - } - - function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { - let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); - let dotPos = scanner.getStartPos(); - while (parseOptional(SyntaxKind.DotToken)) { - if (token() === SyntaxKind.LessThanToken) { - // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting - entity.jsdocDotPos = dotPos; - break; - } - dotPos = scanner.getStartPos(); - entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords)); - } - return entity; - } - - function createQualifiedName(entity: EntityName, name: Identifier): QualifiedName { - const node = createNode(SyntaxKind.QualifiedName, entity.pos) as QualifiedName; - node.left = entity; - node.right = name; - return finishNode(node); - } - - function parseRightSideOfDot(allowIdentifierNames: boolean): Identifier { - // Technically a keyword is valid here as all identifiers and keywords are identifier names. - // However, often we'll encounter this in error situations when the identifier or keyword - // is actually starting another valid construct. - // - // So, we check for the following specific case: - // - // name. - // identifierOrKeyword identifierNameOrKeyword - // - // Note: the newlines are important here. For example, if that above code - // were rewritten into: - // - // name.identifierOrKeyword - // identifierNameOrKeyword - // - // Then we would consider it valid. That's because ASI would take effect and - // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword". - // In the first case though, ASI will not take effect because there is not a - // line terminator after the identifier or keyword. - if (scanner.hasPrecedingLineBreak() && tokenIsIdentifierOrKeyword(token())) { - const matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); - - if (matchesPattern) { - // Report that we need an identifier. However, report it right after the dot, - // and not on the next token. This is because the next token might actually - // be an identifier and the error would be quite confusing. - return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); - } - } - - return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); - } - - function parseTemplateExpression(): TemplateExpression { - const template = createNode(SyntaxKind.TemplateExpression); - - template.head = parseTemplateHead(); - Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); - - const list = []; - const listPos = getNodePos(); - - do { - list.push(parseTemplateSpan()); - } - while (lastOrUndefined(list).literal.kind === SyntaxKind.TemplateMiddle); - - template.templateSpans = createNodeArray(list, listPos); - - return finishNode(template); - } - - function parseTemplateSpan(): TemplateSpan { - const span = createNode(SyntaxKind.TemplateSpan); - span.expression = allowInAnd(parseExpression); - - let literal: TemplateMiddle | TemplateTail; - if (token() === SyntaxKind.CloseBraceToken) { - reScanTemplateToken(); - literal = parseTemplateMiddleOrTemplateTail(); - } - else { - literal = parseExpectedToken(SyntaxKind.TemplateTail, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); - } - - span.literal = literal; - return finishNode(span); - } - - function parseLiteralNode(): LiteralExpression { - return parseLiteralLikeNode(token()); - } - - function parseTemplateHead(): TemplateHead { - const fragment = parseLiteralLikeNode(token()); - Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); - return fragment; - } - - function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail { - const fragment = parseLiteralLikeNode(token()); - Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind"); - return fragment; - } - - function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode { - const node = createNode(kind); - const text = scanner.getTokenValue(); - node.text = text; - - if (scanner.hasExtendedUnicodeEscape()) { - node.hasExtendedUnicodeEscape = true; - } - - if (scanner.isUnterminated()) { - node.isUnterminated = true; - } - - // Octal literals are not allowed in strict mode or ES5 - // Note that theoretically the following condition would hold true literals like 009, - // which is not octal.But because of how the scanner separates the tokens, we would - // never get a token like this. Instead, we would get 00 and 9 as two separate tokens. - // We also do not need to check for negatives because any prefix operator would be part of a - // parent unary expression. - if (node.kind === SyntaxKind.NumericLiteral) { - (node).numericLiteralFlags = scanner.getTokenFlags() & TokenFlags.NumericLiteralFlags; - } - - nextToken(); - finishNode(node); - - return node; - } - - // TYPES - - function parseTypeReference(): TypeReferenceNode { - const node = createNode(SyntaxKind.TypeReference); - node.typeName = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); - if (!scanner.hasPrecedingLineBreak() && token() === SyntaxKind.LessThanToken) { - node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); - } - return finishNode(node); - } - - function parseThisTypePredicate(lhs: ThisTypeNode): TypePredicateNode { - nextToken(); - const node = createNode(SyntaxKind.TypePredicate, lhs.pos) as TypePredicateNode; - node.parameterName = lhs; - node.type = parseType(); - return finishNode(node); - } - - function parseThisTypeNode(): ThisTypeNode { - const node = createNode(SyntaxKind.ThisType) as ThisTypeNode; - nextToken(); - return finishNode(node); - } - - function parseJSDocAllType(): JSDocAllType { - const result = createNode(SyntaxKind.JSDocAllType); - nextToken(); - return finishNode(result); - } - - function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType { - const pos = scanner.getStartPos(); - // skip the ? - nextToken(); - - // Need to lookahead to decide if this is a nullable or unknown type. - - // Here are cases where we'll pick the unknown type: - // - // Foo(?, - // { a: ? } - // Foo(?) - // Foo - // Foo(?= - // (?| - if (token() === SyntaxKind.CommaToken || - token() === SyntaxKind.CloseBraceToken || - token() === SyntaxKind.CloseParenToken || - token() === SyntaxKind.GreaterThanToken || - token() === SyntaxKind.EqualsToken || - token() === SyntaxKind.BarToken) { - - const result = createNode(SyntaxKind.JSDocUnknownType, pos); - return finishNode(result); - } - else { - const result = createNode(SyntaxKind.JSDocNullableType, pos); - result.type = parseType(); - return finishNode(result); - } - } - - function parseJSDocFunctionType(): JSDocFunctionType | TypeReferenceNode { - if (lookAhead(nextTokenIsOpenParen)) { - const result = createNodeWithJSDoc(SyntaxKind.JSDocFunctionType); - nextToken(); - fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type | SignatureFlags.JSDoc, result); - return finishNode(result); - } - const node = createNode(SyntaxKind.TypeReference); - node.typeName = parseIdentifierName(); - return finishNode(node); - } - - function parseJSDocParameter(): ParameterDeclaration { - const parameter = createNode(SyntaxKind.Parameter) as ParameterDeclaration; - if (token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword) { - parameter.name = parseIdentifierName(); - parseExpected(SyntaxKind.ColonToken); - } - parameter.type = parseType(); - return finishNode(parameter); - } - - function parseJSDocNodeWithType(kind: SyntaxKind.JSDocVariadicType | SyntaxKind.JSDocNonNullableType): TypeNode { - const result = createNode(kind) as JSDocVariadicType | JSDocNonNullableType; - nextToken(); - result.type = parseNonArrayType(); - return finishNode(result); - } - - function parseTypeQuery(): TypeQueryNode { - const node = createNode(SyntaxKind.TypeQuery); - parseExpected(SyntaxKind.TypeOfKeyword); - node.exprName = parseEntityName(/*allowReservedWords*/ true); - return finishNode(node); - } - - function parseTypeParameter(): TypeParameterDeclaration { - const node = createNode(SyntaxKind.TypeParameter); - node.name = parseIdentifier(); - if (parseOptional(SyntaxKind.ExtendsKeyword)) { - // It's not uncommon for people to write improper constraints to a generic. If the - // user writes a constraint that is an expression and not an actual type, then parse - // it out as an expression (so we can recover well), but report that a type is needed - // instead. - if (isStartOfType() || !isStartOfExpression()) { - node.constraint = parseType(); - } - else { - // It was not a type, and it looked like an expression. Parse out an expression - // here so we recover well. Note: it is important that we call parseUnaryExpression - // and not parseExpression here. If the user has: - // - // - // - // We do *not* want to consume the `>` as we're consuming the expression for "". - node.expression = parseUnaryExpressionOrHigher(); - } - } - - if (parseOptional(SyntaxKind.EqualsToken)) { - node.default = parseType(); - } - - return finishNode(node); - } - - function parseTypeParameters(): NodeArray | undefined { - if (token() === SyntaxKind.LessThanToken) { - return parseBracketedList(ParsingContext.TypeParameters, parseTypeParameter, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); - } - } - - function parseParameterType(): TypeNode { - if (parseOptional(SyntaxKind.ColonToken)) { - return parseType(); - } - - return undefined; - } - - function isStartOfParameter(): boolean { - return token() === SyntaxKind.DotDotDotToken || - isIdentifierOrPattern() || - isModifierKind(token()) || - token() === SyntaxKind.AtToken || - isStartOfType(/*inStartOfParameter*/ true); - } - - function parseParameter(): ParameterDeclaration { - const node = createNodeWithJSDoc(SyntaxKind.Parameter); - if (token() === SyntaxKind.ThisKeyword) { - node.name = createIdentifier(/*isIdentifier*/ true); - node.type = parseParameterType(); - return finishNode(node); - } - - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(); - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - - // FormalParameter [Yield,Await]: - // BindingElement[?Yield,?Await] - node.name = parseIdentifierOrPattern(); - if (getFullWidth(node.name) === 0 && !hasModifiers(node) && isModifierKind(token())) { - // in cases like - // 'use strict' - // function foo(static) - // isParameter('static') === true, because of isModifier('static') - // however 'static' is not a legal identifier in a strict mode. - // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined) - // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM) - // to avoid this we'll advance cursor to the next token. - nextToken(); - } - - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - node.type = parseParameterType(); - node.initializer = parseInitializer(); - - return finishNode(node); - } - - function fillSignature( - returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, - flags: SignatureFlags, - signature: SignatureDeclaration): void { - if (!(flags & SignatureFlags.JSDoc)) { - signature.typeParameters = parseTypeParameters(); - } - signature.parameters = parseParameterList(flags); - signature.type = parseReturnType(returnToken, !!(flags & SignatureFlags.Type)); - } - - function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined { - return shouldParseReturnType(returnToken, isType) ? parseTypeOrTypePredicate() : undefined; - } - function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean { - if (returnToken === SyntaxKind.EqualsGreaterThanToken) { - parseExpected(returnToken); - return true; - } - else if (parseOptional(SyntaxKind.ColonToken)) { - return true; - } - else if (isType && token() === SyntaxKind.EqualsGreaterThanToken) { - // This is easy to get backward, especially in type contexts, so parse the type anyway - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); - nextToken(); - return true; - } - return false; - } - - function parseParameterList(flags: SignatureFlags) { - // FormalParameters [Yield,Await]: (modified) - // [empty] - // FormalParameterList[?Yield,Await] - // - // FormalParameter[Yield,Await]: (modified) - // BindingElement[?Yield,Await] - // - // BindingElement [Yield,Await]: (modified) - // SingleNameBinding[?Yield,?Await] - // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - // - // SingleNameBinding [Yield,Await]: - // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - if (parseExpected(SyntaxKind.OpenParenToken)) { - const savedYieldContext = inYieldContext(); - const savedAwaitContext = inAwaitContext(); - - setYieldContext(!!(flags & SignatureFlags.Yield)); - setAwaitContext(!!(flags & SignatureFlags.Await)); - - const result = parseDelimitedList(ParsingContext.Parameters, flags & SignatureFlags.JSDoc ? parseJSDocParameter : parseParameter); - - setYieldContext(savedYieldContext); - setAwaitContext(savedAwaitContext); - - if (!parseExpected(SyntaxKind.CloseParenToken) && (flags & SignatureFlags.RequireCompleteParameterList)) { - // Caller insisted that we had to end with a ) We didn't. So just return - // undefined here. - return undefined; - } - - return result; - } - - // We didn't even have an open paren. If the caller requires a complete parameter list, - // we definitely can't provide that. However, if they're ok with an incomplete one, - // then just return an empty set of parameters. - return (flags & SignatureFlags.RequireCompleteParameterList) ? undefined : createMissingList(); - } - - function parseTypeMemberSemicolon() { - // We allow type members to be separated by commas or (possibly ASI) semicolons. - // First check if it was a comma. If so, we're done with the member. - if (parseOptional(SyntaxKind.CommaToken)) { - return; - } - - // Didn't have a comma. We must have a (possible ASI) semicolon. - parseSemicolon(); - } - - function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration { - const node = createNodeWithJSDoc(kind); - if (kind === SyntaxKind.ConstructSignature) { - parseExpected(SyntaxKind.NewKeyword); - } - fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type, node); - parseTypeMemberSemicolon(); - return finishNode(node); - } - - function isIndexSignature(): boolean { - return token() === SyntaxKind.OpenBracketToken && lookAhead(isUnambiguouslyIndexSignature); - } - - function isUnambiguouslyIndexSignature() { - // The only allowed sequence is: - // - // [id: - // - // However, for error recovery, we also check the following cases: - // - // [... - // [id, - // [id?, - // [id?: - // [id?] - // [public id - // [private id - // [protected id - // [] - // - nextToken(); - if (token() === SyntaxKind.DotDotDotToken || token() === SyntaxKind.CloseBracketToken) { - return true; - } - - if (isModifierKind(token())) { - nextToken(); - if (isIdentifier()) { - return true; - } - } - else if (!isIdentifier()) { - return false; - } - else { - // Skip the identifier - nextToken(); - } - - // A colon signifies a well formed indexer - // A comma should be a badly formed indexer because comma expressions are not allowed - // in computed properties. - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken) { - return true; - } - - // Question mark could be an indexer with an optional property, - // or it could be a conditional expression in a computed property. - if (token() !== SyntaxKind.QuestionToken) { - return false; - } - - // If any of the following tokens are after the question mark, it cannot - // be a conditional expression, so treat it as an indexer. - nextToken(); - return token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBracketToken; - } - - function parseIndexSignatureDeclaration(node: IndexSignatureDeclaration): IndexSignatureDeclaration { - node.kind = SyntaxKind.IndexSignature; - node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); - node.type = parseTypeAnnotation(); - parseTypeMemberSemicolon(); - return finishNode(node); - } - - function parsePropertyOrMethodSignature(node: PropertySignature | MethodSignature): PropertySignature | MethodSignature { - node.name = parsePropertyName(); - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - node.kind = SyntaxKind.MethodSignature; - // Method signatures don't exist in expression contexts. So they have neither - // [Yield] nor [Await] - fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type, node); - } - else { - node.kind = SyntaxKind.PropertySignature; - node.type = parseTypeAnnotation(); - if (token() === SyntaxKind.EqualsToken) { - // Although type literal properties cannot not have initializers, we attempt - // to parse an initializer so we can report in the checker that an interface - // property or type literal property cannot have an initializer. - (node).initializer = parseInitializer(); - } - } - parseTypeMemberSemicolon(); - return finishNode(node); - } - - function isTypeMemberStart(): boolean { - // Return true if we have the start of a signature member - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return true; - } - let idToken: boolean; - // Eat up all modifiers, but hold on to the last one in case it is actually an identifier - while (isModifierKind(token())) { - idToken = true; - nextToken(); - } - // Index signatures and computed property names are type members - if (token() === SyntaxKind.OpenBracketToken) { - return true; - } - // Try to get the first property-like token following all modifiers - if (isLiteralPropertyName()) { - idToken = true; - nextToken(); - } - // If we were able to get any potential identifier, check that it is - // the start of a member declaration - if (idToken) { - return token() === SyntaxKind.OpenParenToken || - token() === SyntaxKind.LessThanToken || - token() === SyntaxKind.QuestionToken || - token() === SyntaxKind.ColonToken || - token() === SyntaxKind.CommaToken || - canParseSemicolon(); - } - return false; - } - - function parseTypeMember(): TypeElement { - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseSignatureMember(SyntaxKind.CallSignature); - } - if (token() === SyntaxKind.NewKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { - return parseSignatureMember(SyntaxKind.ConstructSignature); - } - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - node.modifiers = parseModifiers(); - if (isIndexSignature()) { - return parseIndexSignatureDeclaration(node); - } - return parsePropertyOrMethodSignature(node); - } - - function nextTokenIsOpenParenOrLessThan() { - nextToken(); - return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken; - } - - function parseTypeLiteral(): TypeLiteralNode { - const node = createNode(SyntaxKind.TypeLiteral); - node.members = parseObjectTypeMembers(); - return finishNode(node); - } - - function parseObjectTypeMembers(): NodeArray { - let members: NodeArray; - if (parseExpected(SyntaxKind.OpenBraceToken)) { - members = parseList(ParsingContext.TypeMembers, parseTypeMember); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - members = createMissingList(); - } - - return members; - } - - function isStartOfMappedType() { - nextToken(); - if (token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - return nextToken() === SyntaxKind.ReadonlyKeyword; - } - if (token() === SyntaxKind.ReadonlyKeyword) { - nextToken(); - } - return token() === SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === SyntaxKind.InKeyword; - } - - function parseMappedTypeParameter() { - const node = createNode(SyntaxKind.TypeParameter); - node.name = parseIdentifier(); - parseExpected(SyntaxKind.InKeyword); - node.constraint = parseType(); - return finishNode(node); - } - - function parseMappedType() { - const node = createNode(SyntaxKind.MappedType); - parseExpected(SyntaxKind.OpenBraceToken); - if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - node.readonlyToken = parseTokenNode(); - if (node.readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { - parseExpectedToken(SyntaxKind.ReadonlyKeyword); - } - } - parseExpected(SyntaxKind.OpenBracketToken); - node.typeParameter = parseMappedTypeParameter(); - parseExpected(SyntaxKind.CloseBracketToken); - if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - node.questionToken = parseTokenNode(); - if (node.questionToken.kind !== SyntaxKind.QuestionToken) { - parseExpectedToken(SyntaxKind.QuestionToken); - } - } - node.type = parseTypeAnnotation(); - parseSemicolon(); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(node); - } - - function parseTupleType(): TupleTypeNode { - const node = createNode(SyntaxKind.TupleType); - node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); - return finishNode(node); - } - - function parseParenthesizedType(): ParenthesizedTypeNode { - const node = createNode(SyntaxKind.ParenthesizedType); - parseExpected(SyntaxKind.OpenParenToken); - node.type = parseType(); - parseExpected(SyntaxKind.CloseParenToken); - return finishNode(node); - } - - function parseFunctionOrConstructorType(kind: SyntaxKind): FunctionOrConstructorTypeNode { - const node = createNodeWithJSDoc(kind); - if (kind === SyntaxKind.ConstructorType) { - parseExpected(SyntaxKind.NewKeyword); - } - fillSignature(SyntaxKind.EqualsGreaterThanToken, SignatureFlags.Type, node); - return finishNode(node); - } - - function parseKeywordAndNoDot(): TypeNode | undefined { - const node = parseTokenNode(); - return token() === SyntaxKind.DotToken ? undefined : node; - } - - function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode { - const node = createNode(SyntaxKind.LiteralType) as LiteralTypeNode; - let unaryMinusExpression: PrefixUnaryExpression; - if (negative) { - unaryMinusExpression = createNode(SyntaxKind.PrefixUnaryExpression) as PrefixUnaryExpression; - unaryMinusExpression.operator = SyntaxKind.MinusToken; - nextToken(); - } - let expression: BooleanLiteral | LiteralExpression | PrefixUnaryExpression = token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword - ? parseTokenNode() - : parseLiteralLikeNode(token()) as LiteralExpression; - if (negative) { - unaryMinusExpression.operand = expression; - finishNode(unaryMinusExpression); - expression = unaryMinusExpression; - } - node.literal = expression; - return finishNode(node); - } - - function nextTokenIsNumericLiteral() { - return nextToken() === SyntaxKind.NumericLiteral; - } - - function parseNonArrayType(): TypeNode { - switch (token()) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.ObjectKeyword: - // If these are followed by a dot, then parse these out as a dotted type reference instead. - return tryParse(parseKeywordAndNoDot) || parseTypeReference(); - case SyntaxKind.AsteriskToken: - return parseJSDocAllType(); - case SyntaxKind.QuestionToken: - return parseJSDocUnknownOrNullableType(); - case SyntaxKind.FunctionKeyword: - return parseJSDocFunctionType(); - case SyntaxKind.ExclamationToken: - return parseJSDocNodeWithType(SyntaxKind.JSDocNonNullableType); - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - return parseLiteralTypeNode(); - case SyntaxKind.MinusToken: - return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); - case SyntaxKind.VoidKeyword: - case SyntaxKind.NullKeyword: - return parseTokenNode(); - case SyntaxKind.ThisKeyword: { - const thisKeyword = parseThisTypeNode(); - if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { - return parseThisTypePredicate(thisKeyword); - } - else { - return thisKeyword; - } - } - case SyntaxKind.TypeOfKeyword: - return parseTypeQuery(); - case SyntaxKind.OpenBraceToken: - return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral(); - case SyntaxKind.OpenBracketToken: - return parseTupleType(); - case SyntaxKind.OpenParenToken: - return parseParenthesizedType(); - default: - return parseTypeReference(); - } - } - - function isStartOfType(inStartOfParameter?: boolean): boolean { - switch (token()) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.UniqueKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.ThisKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.BarToken: - case SyntaxKind.AmpersandToken: - case SyntaxKind.NewKeyword: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.AsteriskToken: - case SyntaxKind.QuestionToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DotDotDotToken: - case SyntaxKind.InferKeyword: - return true; - case SyntaxKind.MinusToken: - return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); - case SyntaxKind.OpenParenToken: - // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, - // or something that starts a type. We don't want to consider things like '(1)' a type. - return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); - default: - return isIdentifier(); - } - } - - function isStartOfParenthesizedOrFunctionType() { - nextToken(); - return token() === SyntaxKind.CloseParenToken || isStartOfParameter() || isStartOfType(); - } - - function parsePostfixTypeOrHigher(): TypeNode { - let type = parseNonArrayType(); - while (!scanner.hasPrecedingLineBreak()) { - switch (token()) { - case SyntaxKind.EqualsToken: - // only parse postfix = inside jsdoc, because it's ambiguous elsewhere - if (!(contextFlags & NodeFlags.JSDoc)) { - return type; - } - type = createJSDocPostfixType(SyntaxKind.JSDocOptionalType, type); - break; - case SyntaxKind.ExclamationToken: - type = createJSDocPostfixType(SyntaxKind.JSDocNonNullableType, type); - break; - case SyntaxKind.QuestionToken: - // If not in JSDoc and next token is start of a type we have a conditional type - if (!(contextFlags & NodeFlags.JSDoc) && lookAhead(nextTokenIsStartOfType)) { - return type; - } - type = createJSDocPostfixType(SyntaxKind.JSDocNullableType, type); - break; - case SyntaxKind.OpenBracketToken: - parseExpected(SyntaxKind.OpenBracketToken); - if (isStartOfType()) { - const node = createNode(SyntaxKind.IndexedAccessType, type.pos) as IndexedAccessTypeNode; - node.objectType = type; - node.indexType = parseType(); - parseExpected(SyntaxKind.CloseBracketToken); - type = finishNode(node); - } - else { - const node = createNode(SyntaxKind.ArrayType, type.pos) as ArrayTypeNode; - node.elementType = type; - parseExpected(SyntaxKind.CloseBracketToken); - type = finishNode(node); - } - break; - default: - return type; - } - } - return type; - } - - function createJSDocPostfixType(kind: SyntaxKind, type: TypeNode) { - nextToken(); - const postfix = createNode(kind, type.pos) as JSDocOptionalType | JSDocNonNullableType | JSDocNullableType; - postfix.type = type; - return finishNode(postfix); - } - - function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword) { - const node = createNode(SyntaxKind.TypeOperator); - parseExpected(operator); - node.operator = operator; - node.type = parseTypeOperatorOrHigher(); - return finishNode(node); - } - - function parseInferType(): InferTypeNode { - const node = createNode(SyntaxKind.InferType); - parseExpected(SyntaxKind.InferKeyword); - const typeParameter = createNode(SyntaxKind.TypeParameter); - typeParameter.name = parseIdentifier(); - node.typeParameter = finishNode(typeParameter); - return finishNode(node); - } - - function parseTypeOperatorOrHigher(): TypeNode { - const operator = token(); - switch (operator) { - case SyntaxKind.KeyOfKeyword: - case SyntaxKind.UniqueKeyword: - return parseTypeOperator(operator); - case SyntaxKind.InferKeyword: - return parseInferType(); - case SyntaxKind.DotDotDotToken: { - const result = createNode(SyntaxKind.JSDocVariadicType) as JSDocVariadicType; - nextToken(); - result.type = parsePostfixTypeOrHigher(); - return finishNode(result); - } - } - return parsePostfixTypeOrHigher(); - } - - function parseUnionOrIntersectionType(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, parseConstituentType: () => TypeNode, operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken): TypeNode { - parseOptional(operator); - let type = parseConstituentType(); - if (token() === operator) { - const types = [type]; - while (parseOptional(operator)) { - types.push(parseConstituentType()); - } - const node = createNode(kind, type.pos); - node.types = createNodeArray(types, type.pos); - type = finishNode(node); - } - return type; - } - - function parseIntersectionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseTypeOperatorOrHigher, SyntaxKind.AmpersandToken); - } - - function parseUnionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.UnionType, parseIntersectionTypeOrHigher, SyntaxKind.BarToken); - } - - function isStartOfFunctionType(): boolean { - if (token() === SyntaxKind.LessThanToken) { - return true; - } - return token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType); - } - - function skipParameterStart(): boolean { - if (isModifierKind(token())) { - // Skip modifiers - parseModifiers(); - } - if (isIdentifier() || token() === SyntaxKind.ThisKeyword) { - nextToken(); - return true; - } - if (token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken) { - // Return true if we can parse an array or object binding pattern with no errors - const previousErrorCount = parseDiagnostics.length; - parseIdentifierOrPattern(); - return previousErrorCount === parseDiagnostics.length; - } - return false; - } - - function isUnambiguouslyStartOfFunctionType() { - nextToken(); - if (token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.DotDotDotToken) { - // ( ) - // ( ... - return true; - } - if (skipParameterStart()) { - // We successfully skipped modifiers (if any) and an identifier or binding pattern, - // now see if we have something that indicates a parameter declaration - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || - token() === SyntaxKind.QuestionToken || token() === SyntaxKind.EqualsToken) { - // ( xxx : - // ( xxx , - // ( xxx ? - // ( xxx = - return true; - } - if (token() === SyntaxKind.CloseParenToken) { - nextToken(); - if (token() === SyntaxKind.EqualsGreaterThanToken) { - // ( xxx ) => - return true; - } - } - } - return false; - } - - function parseTypeOrTypePredicate(): TypeNode { - const typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix); - const type = parseType(); - if (typePredicateVariable) { - const node = createNode(SyntaxKind.TypePredicate, typePredicateVariable.pos); - node.parameterName = typePredicateVariable; - node.type = type; - return finishNode(node); - } - else { - return type; - } - } - - function parseTypePredicatePrefix() { - const id = parseIdentifier(); - if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { - nextToken(); - return id; - } - } - - function parseType(): TypeNode { - // The rules about 'yield' only apply to actual code/expression contexts. They don't - // apply to 'type' contexts. So we disable these parameters here before moving on. - return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseTypeWorker); - } - - function parseTypeWorker(noConditionalTypes?: boolean): TypeNode { - if (isStartOfFunctionType()) { - return parseFunctionOrConstructorType(SyntaxKind.FunctionType); - } - if (token() === SyntaxKind.NewKeyword) { - return parseFunctionOrConstructorType(SyntaxKind.ConstructorType); - } - const type = parseUnionTypeOrHigher(); - if (!noConditionalTypes && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.ExtendsKeyword)) { - const node = createNode(SyntaxKind.ConditionalType, type.pos); - node.checkType = type; - // The type following 'extends' is not permitted to be another conditional type - node.extendsType = parseTypeWorker(/*noConditionalTypes*/ true); - parseExpected(SyntaxKind.QuestionToken); - node.trueType = parseTypeWorker(); - parseExpected(SyntaxKind.ColonToken); - node.falseType = parseTypeWorker(); - return finishNode(node); - } - return type; - } - - function parseTypeAnnotation(): TypeNode { - return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined; - } - - // EXPRESSIONS - function isStartOfLeftHandSideExpression(): boolean { - switch (token()) { - case SyntaxKind.ThisKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.OpenParenToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.NewKeyword: - case SyntaxKind.SlashToken: - case SyntaxKind.SlashEqualsToken: - case SyntaxKind.Identifier: - return true; - case SyntaxKind.ImportKeyword: - return lookAhead(nextTokenIsOpenParenOrLessThan); - default: - return isIdentifier(); - } - } - - function isStartOfExpression(): boolean { - if (isStartOfLeftHandSideExpression()) { - return true; - } - - switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DeleteKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.PlusPlusToken: - case SyntaxKind.MinusMinusToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.AwaitKeyword: - case SyntaxKind.YieldKeyword: - // Yield/await always starts an expression. Either it is an identifier (in which case - // it is definitely an expression). Or it's a keyword (either because we're in - // a generator or async function, or in strict mode (or both)) and it started a yield or await expression. - return true; - default: - // Error tolerance. If we see the start of some binary operator, we consider - // that the start of an expression. That way we'll parse out a missing identifier, - // give a good message about an identifier being missing, and then consume the - // rest of the binary expression. - if (isBinaryOperator()) { - return true; - } - - return isIdentifier(); - } - } - - function isStartOfExpressionStatement(): boolean { - // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement. - return token() !== SyntaxKind.OpenBraceToken && - token() !== SyntaxKind.FunctionKeyword && - token() !== SyntaxKind.ClassKeyword && - token() !== SyntaxKind.AtToken && - isStartOfExpression(); - } - - function parseExpression(): Expression { - // Expression[in]: - // AssignmentExpression[in] - // Expression[in] , AssignmentExpression[in] - - // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator - const saveDecoratorContext = inDecoratorContext(); - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ false); - } - - let expr = parseAssignmentExpressionOrHigher(); - let operatorToken: BinaryOperatorToken; - while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) { - expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher()); - } - - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ true); - } - return expr; - } - - function parseInitializer(): Expression | undefined { - return parseOptional(SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher() : undefined; - } - - function parseAssignmentExpressionOrHigher(): Expression { - // AssignmentExpression[in,yield]: - // 1) ConditionalExpression[?in,?yield] - // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] - // 3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield] - // 4) ArrowFunctionExpression[?in,?yield] - // 5) AsyncArrowFunctionExpression[in,yield,await] - // 6) [+Yield] YieldExpression[?In] - // - // Note: for ease of implementation we treat productions '2' and '3' as the same thing. - // (i.e. they're both BinaryExpressions with an assignment operator in it). - - // First, do the simple check if we have a YieldExpression (production '6'). - if (isYieldExpression()) { - return parseYieldExpression(); - } - - // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized - // parameter list or is an async arrow function. - // AsyncArrowFunctionExpression: - // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] - // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] - // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression". - // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression". - // - // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is - // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done - // with AssignmentExpression if we see one. - const arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression(); - if (arrowExpression) { - return arrowExpression; - } - - // Now try to see if we're in production '1', '2' or '3'. A conditional expression can - // start with a LogicalOrExpression, while the assignment productions can only start with - // LeftHandSideExpressions. - // - // So, first, we try to just parse out a BinaryExpression. If we get something that is a - // LeftHandSide or higher, then we can try to parse out the assignment expression part. - // Otherwise, we try to parse out the conditional expression bit. We want to allow any - // binary expression here, so we pass in the 'lowest' precedence here so that it matches - // and consumes anything. - const expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); - - // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized - // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single - // identifier and the current token is an arrow. - if (expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { - return parseSimpleArrowFunctionExpression(expr); - } - - // Now see if we might be in cases '2' or '3'. - // If the expression was a LHS expression, and we have an assignment operator, then - // we're in '2' or '3'. Consume the assignment and return. - // - // Note: we call reScanGreaterToken so that we get an appropriately merged token - // for cases like `> > =` becoming `>>=` - if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { - return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); - } - - // It wasn't an assignment or a lambda. This is a conditional expression: - return parseConditionalExpressionRest(expr); - } - - function isYieldExpression(): boolean { - if (token() === SyntaxKind.YieldKeyword) { - // If we have a 'yield' keyword, and this is a context where yield expressions are - // allowed, then definitely parse out a yield expression. - if (inYieldContext()) { - return true; - } - - // We're in a context where 'yield expr' is not allowed. However, if we can - // definitely tell that the user was trying to parse a 'yield expr' and not - // just a normal expr that start with a 'yield' identifier, then parse out - // a 'yield expr'. We can then report an error later that they are only - // allowed in generator expressions. - // - // for example, if we see 'yield(foo)', then we'll have to treat that as an - // invocation expression of something called 'yield'. However, if we have - // 'yield foo' then that is not legal as a normal expression, so we can - // definitely recognize this as a yield expression. - // - // for now we just check if the next token is an identifier. More heuristics - // can be added here later as necessary. We just need to make sure that we - // don't accidentally consume something legal. - return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); - } - - return false; - } - - function nextTokenIsIdentifierOnSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && isIdentifier(); - } - - function parseYieldExpression(): YieldExpression { - const node = createNode(SyntaxKind.YieldExpression); - - // YieldExpression[In] : - // yield - // yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] - // yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] - nextToken(); - - if (!scanner.hasPrecedingLineBreak() && - (token() === SyntaxKind.AsteriskToken || isStartOfExpression())) { - node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - node.expression = parseAssignmentExpressionOrHigher(); - return finishNode(node); - } - else { - // if the next token is not on the same line as yield. or we don't have an '*' or - // the start of an expression, then this is just a simple "yield" expression. - return finishNode(node); - } - } - - function parseSimpleArrowFunctionExpression(identifier: Identifier, asyncModifier?: NodeArray): ArrowFunction { - Debug.assert(token() === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); - - let node: ArrowFunction; - if (asyncModifier) { - node = createNode(SyntaxKind.ArrowFunction, asyncModifier.pos); - node.modifiers = asyncModifier; - } - else { - node = createNode(SyntaxKind.ArrowFunction, identifier.pos); - } - - const parameter = createNode(SyntaxKind.Parameter, identifier.pos); - parameter.name = identifier; - finishNode(parameter); - - node.parameters = createNodeArray([parameter], parameter.pos, parameter.end); - - node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); - node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); - - return addJSDocComment(finishNode(node)); - } - - function tryParseParenthesizedArrowFunctionExpression(): Expression | undefined { - const triState = isParenthesizedArrowFunctionExpression(); - if (triState === Tristate.False) { - // It's definitely not a parenthesized arrow function expression. - return undefined; - } - - // If we definitely have an arrow function, then we can just parse one, not requiring a - // following => or { token. Otherwise, we *might* have an arrow function. Try to parse - // it out, but don't allow any ambiguity, and return 'undefined' if this could be an - // expression instead. - const arrowFunction = triState === Tristate.True - ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true) - : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead); - - if (!arrowFunction) { - // Didn't appear to actually be a parenthesized arrow function. Just bail out. - return undefined; - } - - const isAsync = hasModifier(arrowFunction, ModifierFlags.Async); - - // If we have an arrow, then try to parse the body. Even if not, try to parse if we - // have an opening brace, just in case we're in an error state. - const lastToken = token(); - arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); - arrowFunction.body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) - ? parseArrowFunctionExpressionBody(isAsync) - : parseIdentifier(); - - return finishNode(arrowFunction); - } - - // True -> We definitely expect a parenthesized arrow function here. - // False -> There *cannot* be a parenthesized arrow function here. - // Unknown -> There *might* be a parenthesized arrow function here. - // Speculatively look ahead to be sure, and rollback if not. - function isParenthesizedArrowFunctionExpression(): Tristate { - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken || token() === SyntaxKind.AsyncKeyword) { - return lookAhead(isParenthesizedArrowFunctionExpressionWorker); - } - - if (token() === SyntaxKind.EqualsGreaterThanToken) { - // ERROR RECOVERY TWEAK: - // If we see a standalone => try to parse it as an arrow function expression as that's - // likely what the user intended to write. - return Tristate.True; - } - // Definitely not a parenthesized arrow function. - return Tristate.False; - } - - function isParenthesizedArrowFunctionExpressionWorker() { - if (token() === SyntaxKind.AsyncKeyword) { - nextToken(); - if (scanner.hasPrecedingLineBreak()) { - return Tristate.False; - } - if (token() !== SyntaxKind.OpenParenToken && token() !== SyntaxKind.LessThanToken) { - return Tristate.False; - } - } - - const first = token(); - const second = nextToken(); - - if (first === SyntaxKind.OpenParenToken) { - if (second === SyntaxKind.CloseParenToken) { - // Simple cases: "() =>", "(): ", and "() {". - // This is an arrow function with no parameters. - // The last one is not actually an arrow function, - // but this is probably what the user intended. - const third = nextToken(); - switch (third) { - case SyntaxKind.EqualsGreaterThanToken: - case SyntaxKind.ColonToken: - case SyntaxKind.OpenBraceToken: - return Tristate.True; - default: - return Tristate.False; - } - } - - // If encounter "([" or "({", this could be the start of a binding pattern. - // Examples: - // ([ x ]) => { } - // ({ x }) => { } - // ([ x ]) - // ({ x }) - if (second === SyntaxKind.OpenBracketToken || second === SyntaxKind.OpenBraceToken) { - return Tristate.Unknown; - } - - // Simple case: "(..." - // This is an arrow function with a rest parameter. - if (second === SyntaxKind.DotDotDotToken) { - return Tristate.True; - } - - // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This - // isn't actually allowed, but we want to treat it as a lambda so we can provide - // a good error message. - if (isModifierKind(second) && second !== SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsIdentifier)) { - return Tristate.True; - } - - // If we had "(" followed by something that's not an identifier, - // then this definitely doesn't look like a lambda. - if (!isIdentifier()) { - return Tristate.False; - } - - switch (nextToken()) { - case SyntaxKind.ColonToken: - // If we have something like "(a:", then we must have a - // type-annotated parameter in an arrow function expression. - return Tristate.True; - case SyntaxKind.QuestionToken: - nextToken(); - // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda. - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.EqualsToken || token() === SyntaxKind.CloseParenToken) { - return Tristate.True; - } - // Otherwise it is definitely not a lambda. - return Tristate.False; - case SyntaxKind.CommaToken: - case SyntaxKind.EqualsToken: - case SyntaxKind.CloseParenToken: - // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function - return Tristate.Unknown; - } - // It is definitely not an arrow function - return Tristate.False; - } - else { - Debug.assert(first === SyntaxKind.LessThanToken); - - // If we have "<" not followed by an identifier, - // then this definitely is not an arrow function. - if (!isIdentifier()) { - return Tristate.False; - } - - // JSX overrides - if (sourceFile.languageVariant === LanguageVariant.JSX) { - const isArrowFunctionInJsx = lookAhead(() => { - const third = nextToken(); - if (third === SyntaxKind.ExtendsKeyword) { - const fourth = nextToken(); - switch (fourth) { - case SyntaxKind.EqualsToken: - case SyntaxKind.GreaterThanToken: - return false; - default: - return true; - } - } - else if (third === SyntaxKind.CommaToken) { - return true; - } - return false; - }); - - if (isArrowFunctionInJsx) { - return Tristate.True; - } - - return Tristate.False; - } - - // This *could* be a parenthesized arrow function. - return Tristate.Unknown; - } - } - - function parsePossibleParenthesizedArrowFunctionExpressionHead(): ArrowFunction { - return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false); - } - - function tryParseAsyncSimpleArrowFunctionExpression(): ArrowFunction | undefined { - // We do a check here so that we won't be doing unnecessarily call to "lookAhead" - if (token() === SyntaxKind.AsyncKeyword) { - if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === Tristate.True) { - const asyncModifier = parseModifiersForArrowFunction(); - const expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); - return parseSimpleArrowFunctionExpression(expr, asyncModifier); - } - } - return undefined; - } - - function isUnParenthesizedAsyncArrowFunctionWorker(): Tristate { - // AsyncArrowFunctionExpression: - // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] - // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] - if (token() === SyntaxKind.AsyncKeyword) { - nextToken(); - // If the "async" is followed by "=>" token then it is not a begining of an async arrow-function - // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher" - if (scanner.hasPrecedingLineBreak() || token() === SyntaxKind.EqualsGreaterThanToken) { - return Tristate.False; - } - // Check for un-parenthesized AsyncArrowFunction - const expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); - if (!scanner.hasPrecedingLineBreak() && expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { - return Tristate.True; - } - } - - return Tristate.False; - } - - function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction { - const node = createNodeWithJSDoc(SyntaxKind.ArrowFunction); - node.modifiers = parseModifiersForArrowFunction(); - const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; - // Arrow functions are never generators. - // - // If we're speculatively parsing a signature for a parenthesized arrow function, then - // we have to have a complete parameter list. Otherwise we might see something like - // a => (b => c) - // And think that "(b =>" was actually a parenthesized arrow function with a missing - // close paren. - fillSignature(SyntaxKind.ColonToken, isAsync | (allowAmbiguity ? SignatureFlags.None : SignatureFlags.RequireCompleteParameterList), node); - - // If we couldn't get parameters, we definitely could not parse out an arrow function. - if (!node.parameters) { - return undefined; - } - - // Parsing a signature isn't enough. - // Parenthesized arrow signatures often look like other valid expressions. - // For instance: - // - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value. - // - "(x,y)" is a comma expression parsed as a signature with two parameters. - // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. - // - // So we need just a bit of lookahead to ensure that it can only be a signature. - if (!allowAmbiguity && token() !== SyntaxKind.EqualsGreaterThanToken && token() !== SyntaxKind.OpenBraceToken) { - // Returning undefined here will cause our caller to rewind to where we started from. - return undefined; - } - - return node; - } - - function parseArrowFunctionExpressionBody(isAsync: boolean): Block | Expression { - if (token() === SyntaxKind.OpenBraceToken) { - return parseFunctionBlock(isAsync ? SignatureFlags.Await : SignatureFlags.None); - } - - if (token() !== SyntaxKind.SemicolonToken && - token() !== SyntaxKind.FunctionKeyword && - token() !== SyntaxKind.ClassKeyword && - isStartOfStatement() && - !isStartOfExpressionStatement()) { - // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) - // - // Here we try to recover from a potential error situation in the case where the - // user meant to supply a block. For example, if the user wrote: - // - // a => - // let v = 0; - // } - // - // they may be missing an open brace. Check to see if that's the case so we can - // try to recover better. If we don't do this, then the next close curly we see may end - // up preemptively closing the containing construct. - // - // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error. - return parseFunctionBlock(SignatureFlags.IgnoreMissingOpenBrace | (isAsync ? SignatureFlags.Await : SignatureFlags.None)); - } - - return isAsync - ? doInAwaitContext(parseAssignmentExpressionOrHigher) - : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher); - } - - function parseConditionalExpressionRest(leftOperand: Expression): Expression { - // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - if (!questionToken) { - return leftOperand; - } - - // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and - // we do not that for the 'whenFalse' part. - const node = createNode(SyntaxKind.ConditionalExpression, leftOperand.pos); - node.condition = leftOperand; - node.questionToken = questionToken; - node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher); - node.colonToken = parseExpectedToken(SyntaxKind.ColonToken); - node.whenFalse = nodeIsPresent(node.colonToken) - ? parseAssignmentExpressionOrHigher() - : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); - return finishNode(node); - } - - function parseBinaryExpressionOrHigher(precedence: number): Expression { - const leftOperand = parseUnaryExpressionOrHigher(); - return parseBinaryExpressionRest(precedence, leftOperand); - } - - function isInOrOfKeyword(t: SyntaxKind) { - return t === SyntaxKind.InKeyword || t === SyntaxKind.OfKeyword; - } - - function parseBinaryExpressionRest(precedence: number, leftOperand: Expression): Expression { - while (true) { - // We either have a binary operator here, or we're finished. We call - // reScanGreaterToken so that we merge token sequences like > and = into >= - - reScanGreaterToken(); - const newPrecedence = getBinaryOperatorPrecedence(); - - // Check the precedence to see if we should "take" this operator - // - For left associative operator (all operator but **), consume the operator, - // recursively call the function below, and parse binaryExpression as a rightOperand - // of the caller if the new precedence of the operator is greater then or equal to the current precedence. - // For example: - // a - b - c; - // ^token; leftOperand = b. Return b to the caller as a rightOperand - // a * b - c - // ^token; leftOperand = b. Return b to the caller as a rightOperand - // a - b * c; - // ^token; leftOperand = b. Return b * c to the caller as a rightOperand - // - For right associative operator (**), consume the operator, recursively call the function - // and parse binaryExpression as a rightOperand of the caller if the new precedence of - // the operator is strictly grater than the current precedence - // For example: - // a ** b ** c; - // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand - // a - b ** c; - // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand - // a ** b - c - // ^token; leftOperand = b. Return b to the caller as a rightOperand - const consumeCurrentOperator = token() === SyntaxKind.AsteriskAsteriskToken ? - newPrecedence >= precedence : - newPrecedence > precedence; - - if (!consumeCurrentOperator) { - break; - } - - if (token() === SyntaxKind.InKeyword && inDisallowInContext()) { - break; - } - - if (token() === SyntaxKind.AsKeyword) { - // Make sure we *do* perform ASI for constructs like this: - // var x = foo - // as (Bar) - // This should be parsed as an initialized variable, followed - // by a function call to 'as' with the argument 'Bar' - if (scanner.hasPrecedingLineBreak()) { - break; - } - else { - nextToken(); - leftOperand = makeAsExpression(leftOperand, parseType()); - } - } - else { - leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); - } - } - - return leftOperand; - } - - function isBinaryOperator() { - if (inDisallowInContext() && token() === SyntaxKind.InKeyword) { - return false; - } - - return getBinaryOperatorPrecedence() > 0; - } - - function getBinaryOperatorPrecedence(): number { - switch (token()) { - case SyntaxKind.BarBarToken: - return 1; - case SyntaxKind.AmpersandAmpersandToken: - return 2; - case SyntaxKind.BarToken: - return 3; - case SyntaxKind.CaretToken: - return 4; - case SyntaxKind.AmpersandToken: - return 5; - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: - return 6; - case SyntaxKind.LessThanToken: - case SyntaxKind.GreaterThanToken: - case SyntaxKind.LessThanEqualsToken: - case SyntaxKind.GreaterThanEqualsToken: - case SyntaxKind.InstanceOfKeyword: - case SyntaxKind.InKeyword: - case SyntaxKind.AsKeyword: - return 7; - case SyntaxKind.LessThanLessThanToken: - case SyntaxKind.GreaterThanGreaterThanToken: - case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return 8; - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - return 9; - case SyntaxKind.AsteriskToken: - case SyntaxKind.SlashToken: - case SyntaxKind.PercentToken: - return 10; - case SyntaxKind.AsteriskAsteriskToken: - return 11; - } - - // -1 is lower than all other precedences. Returning it will cause binary expression - // parsing to stop. - return -1; - } - - function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression): BinaryExpression { - const node = createNode(SyntaxKind.BinaryExpression, left.pos); - node.left = left; - node.operatorToken = operatorToken; - node.right = right; - return finishNode(node); - } - - function makeAsExpression(left: Expression, right: TypeNode): AsExpression { - const node = createNode(SyntaxKind.AsExpression, left.pos); - node.expression = left; - node.type = right; - return finishNode(node); - } - - function parsePrefixUnaryExpression() { - const node = createNode(SyntaxKind.PrefixUnaryExpression); - node.operator = token(); - nextToken(); - node.operand = parseSimpleUnaryExpression(); - - return finishNode(node); - } - - function parseDeleteExpression() { - const node = createNode(SyntaxKind.DeleteExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); - } - - function parseTypeOfExpression() { - const node = createNode(SyntaxKind.TypeOfExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); - } - - function parseVoidExpression() { - const node = createNode(SyntaxKind.VoidExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); - } - - function isAwaitExpression(): boolean { - if (token() === SyntaxKind.AwaitKeyword) { - if (inAwaitContext()) { - return true; - } - - // here we are using similar heuristics as 'isYieldExpression' - return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); - } - - return false; - } - - function parseAwaitExpression() { - const node = createNode(SyntaxKind.AwaitExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); - } - - /** - * Parse ES7 exponential expression and await expression - * - * ES7 ExponentiationExpression: - * 1) UnaryExpression[?Yield] - * 2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield] - * - */ - function parseUnaryExpressionOrHigher(): UnaryExpression | BinaryExpression { - /** - * ES7 UpdateExpression: - * 1) LeftHandSideExpression[?Yield] - * 2) LeftHandSideExpression[?Yield][no LineTerminator here]++ - * 3) LeftHandSideExpression[?Yield][no LineTerminator here]-- - * 4) ++UnaryExpression[?Yield] - * 5) --UnaryExpression[?Yield] - */ - if (isUpdateExpression()) { - const updateExpression = parseUpdateExpression(); - return token() === SyntaxKind.AsteriskAsteriskToken ? - parseBinaryExpressionRest(getBinaryOperatorPrecedence(), updateExpression) : - updateExpression; - } - - /** - * ES7 UnaryExpression: - * 1) UpdateExpression[?yield] - * 2) delete UpdateExpression[?yield] - * 3) void UpdateExpression[?yield] - * 4) typeof UpdateExpression[?yield] - * 5) + UpdateExpression[?yield] - * 6) - UpdateExpression[?yield] - * 7) ~ UpdateExpression[?yield] - * 8) ! UpdateExpression[?yield] - */ - const unaryOperator = token(); - const simpleUnaryExpression = parseSimpleUnaryExpression(); - if (token() === SyntaxKind.AsteriskAsteriskToken) { - const start = skipTrivia(sourceText, simpleUnaryExpression.pos); - if (simpleUnaryExpression.kind === SyntaxKind.TypeAssertionExpression) { - parseErrorAtPosition(start, simpleUnaryExpression.end - start, Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses); - } - else { - parseErrorAtPosition(start, simpleUnaryExpression.end - start, Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, tokenToString(unaryOperator)); - } - } - return simpleUnaryExpression; - } - - /** - * Parse ES7 simple-unary expression or higher: - * - * ES7 UnaryExpression: - * 1) UpdateExpression[?yield] - * 2) delete UnaryExpression[?yield] - * 3) void UnaryExpression[?yield] - * 4) typeof UnaryExpression[?yield] - * 5) + UnaryExpression[?yield] - * 6) - UnaryExpression[?yield] - * 7) ~ UnaryExpression[?yield] - * 8) ! UnaryExpression[?yield] - * 9) [+Await] await UnaryExpression[?yield] - */ - function parseSimpleUnaryExpression(): UnaryExpression { - switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - return parsePrefixUnaryExpression(); - case SyntaxKind.DeleteKeyword: - return parseDeleteExpression(); - case SyntaxKind.TypeOfKeyword: - return parseTypeOfExpression(); - case SyntaxKind.VoidKeyword: - return parseVoidExpression(); - case SyntaxKind.LessThanToken: - // This is modified UnaryExpression grammar in TypeScript - // UnaryExpression (modified): - // < type > UnaryExpression - return parseTypeAssertion(); - case SyntaxKind.AwaitKeyword: - if (isAwaitExpression()) { - return parseAwaitExpression(); - } - // falls through - default: - return parseUpdateExpression(); - } - } - - /** - * Check if the current token can possibly be an ES7 increment expression. - * - * ES7 UpdateExpression: - * LeftHandSideExpression[?Yield] - * LeftHandSideExpression[?Yield][no LineTerminator here]++ - * LeftHandSideExpression[?Yield][no LineTerminator here]-- - * ++LeftHandSideExpression[?Yield] - * --LeftHandSideExpression[?Yield] - */ - function isUpdateExpression(): boolean { - // This function is called inside parseUnaryExpression to decide - // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly - switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DeleteKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.AwaitKeyword: - return false; - case SyntaxKind.LessThanToken: - // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression - if (sourceFile.languageVariant !== LanguageVariant.JSX) { - return false; - } - // We are in JSX context and the token is part of JSXElement. - // falls through - default: - return true; - } - } - - /** - * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression. - * - * ES7 UpdateExpression[yield]: - * 1) LeftHandSideExpression[?yield] - * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++ - * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]-- - * 4) ++LeftHandSideExpression[?yield] - * 5) --LeftHandSideExpression[?yield] - * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression - */ - function parseUpdateExpression(): UpdateExpression { - if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) { - const node = createNode(SyntaxKind.PrefixUnaryExpression); - node.operator = token(); - nextToken(); - node.operand = parseLeftHandSideExpressionOrHigher(); - return finishNode(node); - } - else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { - // JSXElement is part of primaryExpression - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); - } - - const expression = parseLeftHandSideExpressionOrHigher(); - - Debug.assert(isLeftHandSideExpression(expression)); - if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { - const node = createNode(SyntaxKind.PostfixUnaryExpression, expression.pos); - node.operand = expression; - node.operator = token(); - nextToken(); - return finishNode(node); - } - - return expression; - } - - function parseLeftHandSideExpressionOrHigher(): LeftHandSideExpression { - // Original Ecma: - // LeftHandSideExpression: See 11.2 - // NewExpression - // CallExpression - // - // Our simplification: - // - // LeftHandSideExpression: See 11.2 - // MemberExpression - // CallExpression - // - // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with - // MemberExpression to make our lives easier. - // - // to best understand the below code, it's important to see how CallExpression expands - // out into its own productions: - // - // CallExpression: - // MemberExpression Arguments - // CallExpression Arguments - // CallExpression[Expression] - // CallExpression.IdentifierName - // import (AssignmentExpression) - // super Arguments - // super.IdentifierName - // - // Because of the recursion in these calls, we need to bottom out first. There are three - // bottom out states we can run into: 1) We see 'super' which must start either of - // the last two CallExpression productions. 2) We see 'import' which must start import call. - // 3)we have a MemberExpression which either completes the LeftHandSideExpression, - // or starts the beginning of the first four CallExpression productions. - let expression: MemberExpression; - if (token() === SyntaxKind.ImportKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { - // We don't want to eagerly consume all import keyword as import call expression so we look a head to find "(" - // For example: - // var foo3 = require("subfolder - // import * as foo1 from "module-from-node - // We want this import to be a statement rather than import call expression - sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport; - expression = parseTokenNode(); - } - else { - expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher(); - } - - // Now, we *may* be complete. However, we might have consumed the start of a - // CallExpression. As such, we need to consume the rest of it here to be complete. - return parseCallExpressionRest(expression); - } - - function parseMemberExpressionOrHigher(): MemberExpression { - // Note: to make our lives simpler, we decompose the NewExpression productions and - // place ObjectCreationExpression and FunctionExpression into PrimaryExpression. - // like so: - // - // PrimaryExpression : See 11.1 - // this - // Identifier - // Literal - // ArrayLiteral - // ObjectLiteral - // (Expression) - // FunctionExpression - // new MemberExpression Arguments? - // - // MemberExpression : See 11.2 - // PrimaryExpression - // MemberExpression[Expression] - // MemberExpression.IdentifierName - // - // CallExpression : See 11.2 - // MemberExpression - // CallExpression Arguments - // CallExpression[Expression] - // CallExpression.IdentifierName - // - // Technically this is ambiguous. i.e. CallExpression defines: - // - // CallExpression: - // CallExpression Arguments - // - // If you see: "new Foo()" - // - // Then that could be treated as a single ObjectCreationExpression, or it could be - // treated as the invocation of "new Foo". We disambiguate that in code (to match - // the original grammar) by making sure that if we see an ObjectCreationExpression - // we always consume arguments if they are there. So we treat "new Foo()" as an - // object creation only, and not at all as an invocation. Another way to think - // about this is that for every "new" that we see, we will consume an argument list if - // it is there as part of the *associated* object creation node. Any additional - // argument lists we see, will become invocation expressions. - // - // Because there are no other places in the grammar now that refer to FunctionExpression - // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression - // production. - // - // Because CallExpression and MemberExpression are left recursive, we need to bottom out - // of the recursion immediately. So we parse out a primary expression to start with. - const expression = parsePrimaryExpression(); - return parseMemberExpressionRest(expression); - } - - function parseSuperExpression(): MemberExpression { - const expression = parseTokenNode(); - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.DotToken || token() === SyntaxKind.OpenBracketToken) { - return expression; - } - - // If we have seen "super" it must be followed by '(' or '.'. - // If it wasn't then just try to parse out a '.' and report an error. - const node = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); - node.expression = expression; - parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); - node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); - return finishNode(node); - } - - function tagNamesAreEquivalent(lhs: JsxTagNameExpression, rhs: JsxTagNameExpression): boolean { - if (lhs.kind !== rhs.kind) { - return false; - } - - if (lhs.kind === SyntaxKind.Identifier) { - return (lhs).escapedText === (rhs).escapedText; - } - - if (lhs.kind === SyntaxKind.ThisKeyword) { - return true; - } - - // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only - // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression - // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element - return (lhs).name.escapedText === (rhs).name.escapedText && - tagNamesAreEquivalent((lhs).expression as JsxTagNameExpression, (rhs).expression as JsxTagNameExpression); - } - - - function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement | JsxFragment { - const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); - let result: JsxElement | JsxSelfClosingElement | JsxFragment; - if (opening.kind === SyntaxKind.JsxOpeningElement) { - const node = createNode(SyntaxKind.JsxElement, opening.pos); - node.openingElement = opening; - - node.children = parseJsxChildren(node.openingElement); - node.closingElement = parseJsxClosingElement(inExpressionContext); - - if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) { - parseErrorAtPosition(node.closingElement.pos, node.closingElement.end - node.closingElement.pos, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, node.openingElement.tagName)); - } - - result = finishNode(node); - } - else if (opening.kind === SyntaxKind.JsxOpeningFragment) { - const node = createNode(SyntaxKind.JsxFragment, opening.pos); - node.openingFragment = opening; - node.children = parseJsxChildren(node.openingFragment); - node.closingFragment = parseJsxClosingFragment(inExpressionContext); - - result = finishNode(node); - } - else { - Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement); - // Nothing else to do for self-closing elements - result = opening; - } - - // If the user writes the invalid code '

' in an expression context (i.e. not wrapped in - // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag - // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX - // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter - // does less damage and we can report a better error. - // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios - // of one sort or another. - if (inExpressionContext && token() === SyntaxKind.LessThanToken) { - const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true)); - if (invalidElement) { - parseErrorAtCurrentToken(Diagnostics.JSX_expressions_must_have_one_parent_element); - const badNode = createNode(SyntaxKind.BinaryExpression, result.pos); - badNode.end = invalidElement.end; - badNode.left = result; - badNode.right = invalidElement; - badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined); - badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos; - return badNode; - } - } - - return result; - } - - function parseJsxText(): JsxText { - const node = createNode(SyntaxKind.JsxText); - node.containsOnlyWhiteSpaces = currentToken === SyntaxKind.JsxTextAllWhiteSpaces; - currentToken = scanner.scanJsxToken(); - return finishNode(node); - } - - function parseJsxChild(): JsxChild { - switch (token()) { - case SyntaxKind.JsxText: - case SyntaxKind.JsxTextAllWhiteSpaces: - return parseJsxText(); - case SyntaxKind.OpenBraceToken: - return parseJsxExpression(/*inExpressionContext*/ false); - case SyntaxKind.LessThanToken: - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false); - } - Debug.fail("Unknown JSX child kind " + token()); - } - - function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray { - const list = []; - const listPos = getNodePos(); - const saveParsingContext = parsingContext; - parsingContext |= 1 << ParsingContext.JsxChildren; - - while (true) { - currentToken = scanner.reScanJsxToken(); - if (token() === SyntaxKind.LessThanSlashToken) { - // Closing tag - break; - } - else if (token() === SyntaxKind.EndOfFileToken) { - // If we hit EOF, issue the error at the tag that lacks the closing element - // rather than at the end of the file (which is useless) - if (isJsxOpeningFragment(openingTag)) { - parseErrorAtPosition(openingTag.pos, openingTag.end - openingTag.pos, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag); - } - else { - const openingTagName = openingTag.tagName; - parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName)); - } - break; - } - else if (token() === SyntaxKind.ConflictMarkerTrivia) { - break; - } - const child = parseJsxChild(); - if (child) { - list.push(child); - } - } - - parsingContext = saveParsingContext; - - return createNodeArray(list, listPos); - } - - function parseJsxAttributes(): JsxAttributes { - const jsxAttributes = createNode(SyntaxKind.JsxAttributes); - jsxAttributes.properties = parseList(ParsingContext.JsxAttributes, parseJsxAttribute); - return finishNode(jsxAttributes); - } - - function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment { - const fullStart = scanner.getStartPos(); - - parseExpected(SyntaxKind.LessThanToken); - - if (token() === SyntaxKind.GreaterThanToken) { - parseExpected(SyntaxKind.GreaterThanToken); - const node: JsxOpeningFragment = createNode(SyntaxKind.JsxOpeningFragment, fullStart); - return finishNode(node); - } - - const tagName = parseJsxElementName(); - const attributes = parseJsxAttributes(); - - let node: JsxOpeningLikeElement; - - if (token() === SyntaxKind.GreaterThanToken) { - // Closing tag, so scan the immediately-following text with the JSX scanning instead - // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate - // scanning errors - node = createNode(SyntaxKind.JsxOpeningElement, fullStart); - scanJsxText(); - } - else { - parseExpected(SyntaxKind.SlashToken); - if (inExpressionContext) { - parseExpected(SyntaxKind.GreaterThanToken); - } - else { - parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); - scanJsxText(); - } - node = createNode(SyntaxKind.JsxSelfClosingElement, fullStart); - } - - node.tagName = tagName; - node.attributes = attributes; - - return finishNode(node); - } - - function parseJsxElementName(): JsxTagNameExpression { - scanJsxIdentifier(); - // JsxElement can have name in the form of - // propertyAccessExpression - // primaryExpression in the form of an identifier and "this" keyword - // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword - // We only want to consider "this" as a primaryExpression - let expression: JsxTagNameExpression = token() === SyntaxKind.ThisKeyword ? - parseTokenNode() : parseIdentifierName(); - while (parseOptional(SyntaxKind.DotToken)) { - const propertyAccess: PropertyAccessExpression = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); - propertyAccess.expression = expression; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); - expression = finishNode(propertyAccess); - } - return expression; - } - - function parseJsxExpression(inExpressionContext: boolean): JsxExpression { - const node = createNode(SyntaxKind.JsxExpression); - - parseExpected(SyntaxKind.OpenBraceToken); - if (token() !== SyntaxKind.CloseBraceToken) { - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - node.expression = parseAssignmentExpressionOrHigher(); - } - if (inExpressionContext) { - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*shouldAdvance*/ false); - scanJsxText(); - } - - return finishNode(node); - } - - function parseJsxAttribute(): JsxAttribute | JsxSpreadAttribute { - if (token() === SyntaxKind.OpenBraceToken) { - return parseJsxSpreadAttribute(); - } - - scanJsxIdentifier(); - const node = createNode(SyntaxKind.JsxAttribute); - node.name = parseIdentifierName(); - if (token() === SyntaxKind.EqualsToken) { - switch (scanJsxAttributeValue()) { - case SyntaxKind.StringLiteral: - node.initializer = parseLiteralNode(); - break; - default: - node.initializer = parseJsxExpression(/*inExpressionContext*/ true); - break; - } - } - return finishNode(node); - } - - function parseJsxSpreadAttribute(): JsxSpreadAttribute { - const node = createNode(SyntaxKind.JsxSpreadAttribute); - parseExpected(SyntaxKind.OpenBraceToken); - parseExpected(SyntaxKind.DotDotDotToken); - node.expression = parseExpression(); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(node); - } - - function parseJsxClosingElement(inExpressionContext: boolean): JsxClosingElement { - const node = createNode(SyntaxKind.JsxClosingElement); - parseExpected(SyntaxKind.LessThanSlashToken); - node.tagName = parseJsxElementName(); - if (inExpressionContext) { - parseExpected(SyntaxKind.GreaterThanToken); - } - else { - parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); - scanJsxText(); - } - return finishNode(node); - } - - function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment { - const node = createNode(SyntaxKind.JsxClosingFragment); - parseExpected(SyntaxKind.LessThanSlashToken); - if (tokenIsIdentifierOrKeyword(token())) { - const unexpectedTagName = parseJsxElementName(); - parseErrorAtPosition(unexpectedTagName.pos, unexpectedTagName.end - unexpectedTagName.pos, Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment); - } - if (inExpressionContext) { - parseExpected(SyntaxKind.GreaterThanToken); - } - else { - parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); - scanJsxText(); - } - return finishNode(node); - } - - function parseTypeAssertion(): TypeAssertion { - const node = createNode(SyntaxKind.TypeAssertionExpression); - parseExpected(SyntaxKind.LessThanToken); - node.type = parseType(); - parseExpected(SyntaxKind.GreaterThanToken); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); - } - - function parseMemberExpressionRest(expression: LeftHandSideExpression): MemberExpression { - while (true) { - const dotToken = parseOptionalToken(SyntaxKind.DotToken); - if (dotToken) { - const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); - propertyAccess.expression = expression; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); - expression = finishNode(propertyAccess); - continue; - } - - if (token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - nextToken(); - const nonNullExpression = createNode(SyntaxKind.NonNullExpression, expression.pos); - nonNullExpression.expression = expression; - expression = finishNode(nonNullExpression); - continue; - } - - // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName - if (!inDecoratorContext() && parseOptional(SyntaxKind.OpenBracketToken)) { - const indexedAccess = createNode(SyntaxKind.ElementAccessExpression, expression.pos); - indexedAccess.expression = expression; - - // It's not uncommon for a user to write: "new Type[]". - // Check for that common pattern and report a better error message. - if (token() !== SyntaxKind.CloseBracketToken) { - indexedAccess.argumentExpression = allowInAnd(parseExpression); - if (indexedAccess.argumentExpression.kind === SyntaxKind.StringLiteral || indexedAccess.argumentExpression.kind === SyntaxKind.NumericLiteral) { - const literal = indexedAccess.argumentExpression; - literal.text = internIdentifier(literal.text); - } - } - - parseExpected(SyntaxKind.CloseBracketToken); - expression = finishNode(indexedAccess); - continue; - } - - if (token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead) { - const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, expression.pos); - tagExpression.tag = expression; - tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral - ? parseLiteralNode() - : parseTemplateExpression(); - expression = finishNode(tagExpression); - continue; - } - - return expression; - } - } - - function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression { - while (true) { - expression = parseMemberExpressionRest(expression); - if (token() === SyntaxKind.LessThanToken) { - // See if this is the start of a generic invocation. If so, consume it and - // keep checking for postfix expressions. Otherwise, it's just a '<' that's - // part of an arithmetic expression. Break out so we consume it higher in the - // stack. - const typeArguments = tryParse(parseTypeArgumentsInExpression); - if (!typeArguments) { - return expression; - } - - const callExpr = createNode(SyntaxKind.CallExpression, expression.pos); - callExpr.expression = expression; - callExpr.typeArguments = typeArguments; - callExpr.arguments = parseArgumentList(); - expression = finishNode(callExpr); - continue; - } - else if (token() === SyntaxKind.OpenParenToken) { - const callExpr = createNode(SyntaxKind.CallExpression, expression.pos); - callExpr.expression = expression; - callExpr.arguments = parseArgumentList(); - expression = finishNode(callExpr); - continue; - } - - return expression; - } - } - - function parseArgumentList() { - parseExpected(SyntaxKind.OpenParenToken); - const result = parseDelimitedList(ParsingContext.ArgumentExpressions, parseArgumentExpression); - parseExpected(SyntaxKind.CloseParenToken); - return result; - } - - function parseTypeArgumentsInExpression() { - if (!parseOptional(SyntaxKind.LessThanToken)) { - return undefined; - } - - const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); - if (!parseExpected(SyntaxKind.GreaterThanToken)) { - // If it doesn't have the closing `>` then it's definitely not an type argument list. - return undefined; - } - - // If we have a '<', then only parse this as a argument list if the type arguments - // are complete and we have an open paren. if we don't, rewind and return nothing. - return typeArguments && canFollowTypeArgumentsInExpression() - ? typeArguments - : undefined; - } - - function canFollowTypeArgumentsInExpression(): boolean { - switch (token()) { - case SyntaxKind.OpenParenToken: // foo( - // this case are the only case where this token can legally follow a type argument - // list. So we definitely want to treat this as a type arg list. - - case SyntaxKind.DotToken: // foo. - case SyntaxKind.CloseParenToken: // foo) - case SyntaxKind.CloseBracketToken: // foo] - case SyntaxKind.ColonToken: // foo: - case SyntaxKind.SemicolonToken: // foo; - case SyntaxKind.QuestionToken: // foo? - case SyntaxKind.EqualsEqualsToken: // foo == - case SyntaxKind.EqualsEqualsEqualsToken: // foo === - case SyntaxKind.ExclamationEqualsToken: // foo != - case SyntaxKind.ExclamationEqualsEqualsToken: // foo !== - case SyntaxKind.AmpersandAmpersandToken: // foo && - case SyntaxKind.BarBarToken: // foo || - case SyntaxKind.CaretToken: // foo ^ - case SyntaxKind.AmpersandToken: // foo & - case SyntaxKind.BarToken: // foo | - case SyntaxKind.CloseBraceToken: // foo } - case SyntaxKind.EndOfFileToken: // foo - // these cases can't legally follow a type arg list. However, they're not legal - // expressions either. The user is probably in the middle of a generic type. So - // treat it as such. - return true; - - case SyntaxKind.CommaToken: // foo, - case SyntaxKind.OpenBraceToken: // foo { - // We don't want to treat these as type arguments. Otherwise we'll parse this - // as an invocation expression. Instead, we want to parse out the expression - // in isolation from the type arguments. - - default: - // Anything else treat as an expression. - return false; - } - } - - function parsePrimaryExpression(): PrimaryExpression { - switch (token()) { - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - return parseLiteralNode(); - case SyntaxKind.ThisKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - return parseTokenNode(); - case SyntaxKind.OpenParenToken: - return parseParenthesizedExpression(); - case SyntaxKind.OpenBracketToken: - return parseArrayLiteralExpression(); - case SyntaxKind.OpenBraceToken: - return parseObjectLiteralExpression(); - case SyntaxKind.AsyncKeyword: - // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher. - // If we encounter `async [no LineTerminator here] function` then this is an async - // function; otherwise, its an identifier. - if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) { - break; - } - - return parseFunctionExpression(); - case SyntaxKind.ClassKeyword: - return parseClassExpression(); - case SyntaxKind.FunctionKeyword: - return parseFunctionExpression(); - case SyntaxKind.NewKeyword: - return parseNewExpression(); - case SyntaxKind.SlashToken: - case SyntaxKind.SlashEqualsToken: - if (reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) { - return parseLiteralNode(); - } - break; - case SyntaxKind.TemplateHead: - return parseTemplateExpression(); - } - - return parseIdentifier(Diagnostics.Expression_expected); - } - - function parseParenthesizedExpression(): ParenthesizedExpression { - const node = createNodeWithJSDoc(SyntaxKind.ParenthesizedExpression); - parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - return finishNode(node); - } - - function parseSpreadElement(): Expression { - const node = createNode(SyntaxKind.SpreadElement); - parseExpected(SyntaxKind.DotDotDotToken); - node.expression = parseAssignmentExpressionOrHigher(); - return finishNode(node); - } - - function parseArgumentOrArrayLiteralElement(): Expression { - return token() === SyntaxKind.DotDotDotToken ? parseSpreadElement() : - token() === SyntaxKind.CommaToken ? createNode(SyntaxKind.OmittedExpression) : - parseAssignmentExpressionOrHigher(); - } - - function parseArgumentExpression(): Expression { - return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement); - } - - function parseArrayLiteralExpression(): ArrayLiteralExpression { - const node = createNode(SyntaxKind.ArrayLiteralExpression); - parseExpected(SyntaxKind.OpenBracketToken); - if (scanner.hasPrecedingLineBreak()) { - node.multiLine = true; - } - node.elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); - parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(node); - } - - function parseObjectLiteralElement(): ObjectLiteralElementLike { - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - - if (parseOptionalToken(SyntaxKind.DotDotDotToken)) { - node.kind = SyntaxKind.SpreadAssignment; - (node).expression = parseAssignmentExpressionOrHigher(); - return finishNode(node); - } - - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(); - - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.GetAccessor); - } - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.SetAccessor); - } - - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - const tokenIsIdentifier = isIdentifier(); - node.name = parsePropertyName(); - // Disallowing of optional property assignments happens in the grammar checker. - (node).questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseMethodDeclaration(node, asteriskToken); - } - - // check if it is short-hand property assignment or normal property assignment - // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production - // CoverInitializedName[Yield] : - // IdentifierReference[?Yield] Initializer[In, ?Yield] - // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern - const isShorthandPropertyAssignment = - tokenIsIdentifier && (token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.EqualsToken); - if (isShorthandPropertyAssignment) { - node.kind = SyntaxKind.ShorthandPropertyAssignment; - const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken); - if (equalsToken) { - (node).equalsToken = equalsToken; - (node).objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher); - } - } - else { - node.kind = SyntaxKind.PropertyAssignment; - parseExpected(SyntaxKind.ColonToken); - (node).initializer = allowInAnd(parseAssignmentExpressionOrHigher); - } - return finishNode(node); - } - - function parseObjectLiteralExpression(): ObjectLiteralExpression { - const node = createNode(SyntaxKind.ObjectLiteralExpression); - parseExpected(SyntaxKind.OpenBraceToken); - if (scanner.hasPrecedingLineBreak()) { - node.multiLine = true; - } - - node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(node); - } - - function parseFunctionExpression(): FunctionExpression { - // GeneratorExpression: - // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody } - // - // FunctionExpression: - // function BindingIdentifier[opt](FormalParameters){ FunctionBody } - const saveDecoratorContext = inDecoratorContext(); - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ false); - } - - const node = createNodeWithJSDoc(SyntaxKind.FunctionExpression); - node.modifiers = parseModifiers(); - parseExpected(SyntaxKind.FunctionKeyword); - node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - - const isGenerator = node.asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; - node.name = - isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : - isGenerator ? doInYieldContext(parseOptionalIdentifier) : - isAsync ? doInAwaitContext(parseOptionalIdentifier) : - parseOptionalIdentifier(); - - fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node); - node.body = parseFunctionBlock(isGenerator | isAsync); - - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ true); - } - - return finishNode(node); - } - - function parseOptionalIdentifier(): Identifier | undefined { - return isIdentifier() ? parseIdentifier() : undefined; - } - - function parseNewExpression(): NewExpression | MetaProperty { - const fullStart = scanner.getStartPos(); - parseExpected(SyntaxKind.NewKeyword); - if (parseOptional(SyntaxKind.DotToken)) { - const node = createNode(SyntaxKind.MetaProperty, fullStart); - node.keywordToken = SyntaxKind.NewKeyword; - node.name = parseIdentifierName(); - return finishNode(node); - } - - const node = createNode(SyntaxKind.NewExpression, fullStart); - node.expression = parseMemberExpressionOrHigher(); - node.typeArguments = tryParse(parseTypeArgumentsInExpression); - if (node.typeArguments || token() === SyntaxKind.OpenParenToken) { - node.arguments = parseArgumentList(); - } - return finishNode(node); - } - - // STATEMENTS - function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block { - const node = createNode(SyntaxKind.Block); - if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) { - if (scanner.hasPrecedingLineBreak()) { - node.multiLine = true; - } - - node.statements = parseList(ParsingContext.BlockStatements, parseStatement); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - node.statements = createMissingList(); - } - return finishNode(node); - } - - function parseFunctionBlock(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block { - const savedYieldContext = inYieldContext(); - setYieldContext(!!(flags & SignatureFlags.Yield)); - - const savedAwaitContext = inAwaitContext(); - setAwaitContext(!!(flags & SignatureFlags.Await)); - - // We may be in a [Decorator] context when parsing a function expression or - // arrow function. The body of the function is not in [Decorator] context. - const saveDecoratorContext = inDecoratorContext(); - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ false); - } - - const block = parseBlock(!!(flags & SignatureFlags.IgnoreMissingOpenBrace), diagnosticMessage); - - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ true); - } - - setYieldContext(savedYieldContext); - setAwaitContext(savedAwaitContext); - - return block; - } - - function parseEmptyStatement(): Statement { - const node = createNode(SyntaxKind.EmptyStatement); - parseExpected(SyntaxKind.SemicolonToken); - return finishNode(node); - } - - function parseIfStatement(): IfStatement { - const node = createNode(SyntaxKind.IfStatement); - parseExpected(SyntaxKind.IfKeyword); - parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - node.thenStatement = parseStatement(); - node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; - return finishNode(node); - } - - function parseDoStatement(): DoStatement { - const node = createNode(SyntaxKind.DoStatement); - parseExpected(SyntaxKind.DoKeyword); - node.statement = parseStatement(); - parseExpected(SyntaxKind.WhileKeyword); - parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - - // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html - // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in - // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby - // do;while(0)x will have a semicolon inserted before x. - parseOptional(SyntaxKind.SemicolonToken); - return finishNode(node); - } - - function parseWhileStatement(): WhileStatement { - const node = createNode(SyntaxKind.WhileStatement); - parseExpected(SyntaxKind.WhileKeyword); - parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - node.statement = parseStatement(); - return finishNode(node); - } - - function parseForOrForInOrForOfStatement(): Statement { - const pos = getNodePos(); - parseExpected(SyntaxKind.ForKeyword); - const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword); - parseExpected(SyntaxKind.OpenParenToken); - - let initializer: VariableDeclarationList | Expression = undefined; - if (token() !== SyntaxKind.SemicolonToken) { - if (token() === SyntaxKind.VarKeyword || token() === SyntaxKind.LetKeyword || token() === SyntaxKind.ConstKeyword) { - initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true); - } - else { - initializer = disallowInAnd(parseExpression); - } - } - let forOrForInOrForOfStatement: IterationStatement; - if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) { - const forOfStatement = createNode(SyntaxKind.ForOfStatement, pos); - forOfStatement.awaitModifier = awaitToken; - forOfStatement.initializer = initializer; - forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher); - parseExpected(SyntaxKind.CloseParenToken); - forOrForInOrForOfStatement = forOfStatement; - } - else if (parseOptional(SyntaxKind.InKeyword)) { - const forInStatement = createNode(SyntaxKind.ForInStatement, pos); - forInStatement.initializer = initializer; - forInStatement.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - forOrForInOrForOfStatement = forInStatement; - } - else { - const forStatement = createNode(SyntaxKind.ForStatement, pos); - forStatement.initializer = initializer; - parseExpected(SyntaxKind.SemicolonToken); - if (token() !== SyntaxKind.SemicolonToken && token() !== SyntaxKind.CloseParenToken) { - forStatement.condition = allowInAnd(parseExpression); - } - parseExpected(SyntaxKind.SemicolonToken); - if (token() !== SyntaxKind.CloseParenToken) { - forStatement.incrementor = allowInAnd(parseExpression); - } - parseExpected(SyntaxKind.CloseParenToken); - forOrForInOrForOfStatement = forStatement; - } - - forOrForInOrForOfStatement.statement = parseStatement(); - - return finishNode(forOrForInOrForOfStatement); - } - - function parseBreakOrContinueStatement(kind: SyntaxKind): BreakOrContinueStatement { - const node = createNode(kind); - - parseExpected(kind === SyntaxKind.BreakStatement ? SyntaxKind.BreakKeyword : SyntaxKind.ContinueKeyword); - if (!canParseSemicolon()) { - node.label = parseIdentifier(); - } - - parseSemicolon(); - return finishNode(node); - } - - function parseReturnStatement(): ReturnStatement { - const node = createNode(SyntaxKind.ReturnStatement); - - parseExpected(SyntaxKind.ReturnKeyword); - if (!canParseSemicolon()) { - node.expression = allowInAnd(parseExpression); - } - - parseSemicolon(); - return finishNode(node); - } - - function parseWithStatement(): WithStatement { - const node = createNode(SyntaxKind.WithStatement); - parseExpected(SyntaxKind.WithKeyword); - parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - node.statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); - return finishNode(node); - } - - function parseCaseClause(): CaseClause { - const node = createNode(SyntaxKind.CaseClause); - parseExpected(SyntaxKind.CaseKeyword); - node.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); - return finishNode(node); - } - - function parseDefaultClause(): DefaultClause { - const node = createNode(SyntaxKind.DefaultClause); - parseExpected(SyntaxKind.DefaultKeyword); - parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); - return finishNode(node); - } - - function parseCaseOrDefaultClause(): CaseOrDefaultClause { - return token() === SyntaxKind.CaseKeyword ? parseCaseClause() : parseDefaultClause(); - } - - function parseSwitchStatement(): SwitchStatement { - const node = createNode(SyntaxKind.SwitchStatement); - parseExpected(SyntaxKind.SwitchKeyword); - parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - const caseBlock = createNode(SyntaxKind.CaseBlock); - parseExpected(SyntaxKind.OpenBraceToken); - caseBlock.clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause); - parseExpected(SyntaxKind.CloseBraceToken); - node.caseBlock = finishNode(caseBlock); - return finishNode(node); - } - - function parseThrowStatement(): ThrowStatement { - // ThrowStatement[Yield] : - // throw [no LineTerminator here]Expression[In, ?Yield]; - - // Because of automatic semicolon insertion, we need to report error if this - // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' - // directly as that might consume an expression on the following line. - // We just return 'undefined' in that case. The actual error will be reported in the - // grammar walker. - const node = createNode(SyntaxKind.ThrowStatement); - parseExpected(SyntaxKind.ThrowKeyword); - node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression); - parseSemicolon(); - return finishNode(node); - } - - // TODO: Review for error recovery - function parseTryStatement(): TryStatement { - const node = createNode(SyntaxKind.TryStatement); - - parseExpected(SyntaxKind.TryKeyword); - node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); - node.catchClause = token() === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; - - // If we don't have a catch clause, then we must have a finally clause. Try to parse - // one out no matter what. - if (!node.catchClause || token() === SyntaxKind.FinallyKeyword) { - parseExpected(SyntaxKind.FinallyKeyword); - node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); - } - - return finishNode(node); - } - - function parseCatchClause(): CatchClause { - const result = createNode(SyntaxKind.CatchClause); - parseExpected(SyntaxKind.CatchKeyword); - - if (parseOptional(SyntaxKind.OpenParenToken)) { - result.variableDeclaration = parseVariableDeclaration(); - parseExpected(SyntaxKind.CloseParenToken); - } - else { - // Keep shape of node to avoid degrading performance. - result.variableDeclaration = undefined; - } - - result.block = parseBlock(/*ignoreMissingOpenBrace*/ false); - return finishNode(result); - } - - function parseDebuggerStatement(): Statement { - const node = createNode(SyntaxKind.DebuggerStatement); - parseExpected(SyntaxKind.DebuggerKeyword); - parseSemicolon(); - return finishNode(node); - } - - function parseExpressionOrLabeledStatement(): ExpressionStatement | LabeledStatement { - // Avoiding having to do the lookahead for a labeled statement by just trying to parse - // out an expression, seeing if it is identifier and then seeing if it is followed by - // a colon. - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - const expression = allowInAnd(parseExpression); - if (expression.kind === SyntaxKind.Identifier && parseOptional(SyntaxKind.ColonToken)) { - node.kind = SyntaxKind.LabeledStatement; - (node).label = expression; - (node).statement = parseStatement(); - } - else { - node.kind = SyntaxKind.ExpressionStatement; - (node).expression = expression; - parseSemicolon(); - } - return finishNode(node); - } - - function nextTokenIsIdentifierOrKeywordOnSameLine() { - nextToken(); - return tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak(); - } - - function nextTokenIsClassKeywordOnSameLine() { - nextToken(); - return token() === SyntaxKind.ClassKeyword && !scanner.hasPrecedingLineBreak(); - } - - function nextTokenIsFunctionKeywordOnSameLine() { - nextToken(); - return token() === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak(); - } - - function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() { - nextToken(); - return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak(); - } - - function isDeclaration(): boolean { - while (true) { - switch (token()) { - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.EnumKeyword: - return true; - - // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers; - // however, an identifier cannot be followed by another identifier on the same line. This is what we - // count on to parse out the respective declarations. For instance, we exploit this to say that - // - // namespace n - // - // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees - // - // namespace - // n - // - // as the identifier 'namespace' on one line followed by the identifier 'n' on another. - // We need to look one token ahead to see if it permissible to try parsing a declaration. - // - // *Note*: 'interface' is actually a strict mode reserved word. So while - // - // "use strict" - // interface - // I {} - // - // could be legal, it would add complexity for very little gain. - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.TypeKeyword: - return nextTokenIsIdentifierOnSameLine(); - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - return nextTokenIsIdentifierOrStringLiteralOnSameLine(); - case SyntaxKind.AbstractKeyword: - case SyntaxKind.AsyncKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.ReadonlyKeyword: - nextToken(); - // ASI takes effect for this modifier. - if (scanner.hasPrecedingLineBreak()) { - return false; - } - continue; - - case SyntaxKind.GlobalKeyword: - nextToken(); - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.Identifier || token() === SyntaxKind.ExportKeyword; - - case SyntaxKind.ImportKeyword: - nextToken(); - return token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || - token() === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token()); - case SyntaxKind.ExportKeyword: - nextToken(); - if (token() === SyntaxKind.EqualsToken || token() === SyntaxKind.AsteriskToken || - token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.DefaultKeyword || - token() === SyntaxKind.AsKeyword) { - return true; - } - continue; - - case SyntaxKind.StaticKeyword: - nextToken(); - continue; - default: - return false; - } - } - } - - function isStartOfDeclaration(): boolean { - return lookAhead(isDeclaration); - } - - function isStartOfStatement(): boolean { - switch (token()) { - case SyntaxKind.AtToken: - case SyntaxKind.SemicolonToken: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.IfKeyword: - case SyntaxKind.DoKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.ForKeyword: - case SyntaxKind.ContinueKeyword: - case SyntaxKind.BreakKeyword: - case SyntaxKind.ReturnKeyword: - case SyntaxKind.WithKeyword: - case SyntaxKind.SwitchKeyword: - case SyntaxKind.ThrowKeyword: - case SyntaxKind.TryKeyword: - case SyntaxKind.DebuggerKeyword: - // 'catch' and 'finally' do not actually indicate that the code is part of a statement, - // however, we say they are here so that we may gracefully parse them and error later. - case SyntaxKind.CatchKeyword: - case SyntaxKind.FinallyKeyword: - return true; - - case SyntaxKind.ImportKeyword: - return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThan); - - case SyntaxKind.ConstKeyword: - case SyntaxKind.ExportKeyword: - return isStartOfDeclaration(); - - case SyntaxKind.AsyncKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.GlobalKeyword: - // When these don't start a declaration, they're an identifier in an expression statement - return true; - - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.ReadonlyKeyword: - // When these don't start a declaration, they may be the start of a class member if an identifier - // immediately follows. Otherwise they're an identifier in an expression statement. - return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); - - default: - return isStartOfExpression(); - } - } - - function nextTokenIsIdentifierOrStartOfDestructuring() { - nextToken(); - return isIdentifier() || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken; - } - - function isLetDeclaration() { - // In ES6 'let' always starts a lexical declaration if followed by an identifier or { - // or [. - return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring); - } - - function parseStatement(): Statement { - switch (token()) { - case SyntaxKind.SemicolonToken: - return parseEmptyStatement(); - case SyntaxKind.OpenBraceToken: - return parseBlock(/*ignoreMissingOpenBrace*/ false); - case SyntaxKind.VarKeyword: - return parseVariableStatement(createNodeWithJSDoc(SyntaxKind.VariableDeclaration)); - case SyntaxKind.LetKeyword: - if (isLetDeclaration()) { - return parseVariableStatement(createNodeWithJSDoc(SyntaxKind.VariableDeclaration)); - } - break; - case SyntaxKind.FunctionKeyword: - return parseFunctionDeclaration(createNodeWithJSDoc(SyntaxKind.FunctionDeclaration)); - case SyntaxKind.ClassKeyword: - return parseClassDeclaration(createNodeWithJSDoc(SyntaxKind.ClassDeclaration)); - case SyntaxKind.IfKeyword: - return parseIfStatement(); - case SyntaxKind.DoKeyword: - return parseDoStatement(); - case SyntaxKind.WhileKeyword: - return parseWhileStatement(); - case SyntaxKind.ForKeyword: - return parseForOrForInOrForOfStatement(); - case SyntaxKind.ContinueKeyword: - return parseBreakOrContinueStatement(SyntaxKind.ContinueStatement); - case SyntaxKind.BreakKeyword: - return parseBreakOrContinueStatement(SyntaxKind.BreakStatement); - case SyntaxKind.ReturnKeyword: - return parseReturnStatement(); - case SyntaxKind.WithKeyword: - return parseWithStatement(); - case SyntaxKind.SwitchKeyword: - return parseSwitchStatement(); - case SyntaxKind.ThrowKeyword: - return parseThrowStatement(); - case SyntaxKind.TryKeyword: - // Include 'catch' and 'finally' for error recovery. - case SyntaxKind.CatchKeyword: - case SyntaxKind.FinallyKeyword: - return parseTryStatement(); - case SyntaxKind.DebuggerKeyword: - return parseDebuggerStatement(); - case SyntaxKind.AtToken: - return parseDeclaration(); - case SyntaxKind.AsyncKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.ExportKeyword: - case SyntaxKind.ImportKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.AbstractKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.GlobalKeyword: - if (isStartOfDeclaration()) { - return parseDeclaration(); - } - break; - } - return parseExpressionOrLabeledStatement(); - } - - function isDeclareModifier(modifier: Modifier) { - return modifier.kind === SyntaxKind.DeclareKeyword; - } - - function parseDeclaration(): Statement { - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(); - if (some(node.modifiers, isDeclareModifier)) { - for (const m of node.modifiers) { - m.flags |= NodeFlags.Ambient; - } - return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(node)); - } - else { - return parseDeclarationWorker(node); - } - } - - function parseDeclarationWorker(node: Statement): Statement { - switch (token()) { - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: - return parseVariableStatement(node); - case SyntaxKind.FunctionKeyword: - return parseFunctionDeclaration(node); - case SyntaxKind.ClassKeyword: - return parseClassDeclaration(node); - case SyntaxKind.InterfaceKeyword: - return parseInterfaceDeclaration(node); - case SyntaxKind.TypeKeyword: - return parseTypeAliasDeclaration(node); - case SyntaxKind.EnumKeyword: - return parseEnumDeclaration(node); - case SyntaxKind.GlobalKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - return parseModuleDeclaration(node); - case SyntaxKind.ImportKeyword: - return parseImportDeclarationOrImportEqualsDeclaration(node); - case SyntaxKind.ExportKeyword: - nextToken(); - switch (token()) { - case SyntaxKind.DefaultKeyword: - case SyntaxKind.EqualsToken: - return parseExportAssignment(node); - case SyntaxKind.AsKeyword: - return parseNamespaceExportDeclaration(node); - default: - return parseExportDeclaration(node); - } - default: - if (node.decorators || node.modifiers) { - // We reached this point because we encountered decorators and/or modifiers and assumed a declaration - // would follow. For recovery and error reporting purposes, return an incomplete declaration. - const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - missing.pos = node.pos; - missing.decorators = node.decorators; - missing.modifiers = node.modifiers; - return finishNode(missing); - } - } - } - - function nextTokenIsIdentifierOrStringLiteralOnSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === SyntaxKind.StringLiteral); - } - - function parseFunctionBlockOrSemicolon(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block { - if (token() !== SyntaxKind.OpenBraceToken && canParseSemicolon()) { - parseSemicolon(); - return; - } - - return parseFunctionBlock(flags, diagnosticMessage); - } - - // DECLARATIONS - - function parseArrayBindingElement(): ArrayBindingElement { - if (token() === SyntaxKind.CommaToken) { - return createNode(SyntaxKind.OmittedExpression); - } - const node = createNode(SyntaxKind.BindingElement); - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - node.name = parseIdentifierOrPattern(); - node.initializer = parseInitializer(); - return finishNode(node); - } - - function parseObjectBindingElement(): BindingElement { - const node = createNode(SyntaxKind.BindingElement); - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - const tokenIsIdentifier = isIdentifier(); - const propertyName = parsePropertyName(); - if (tokenIsIdentifier && token() !== SyntaxKind.ColonToken) { - node.name = propertyName; - } - else { - parseExpected(SyntaxKind.ColonToken); - node.propertyName = propertyName; - node.name = parseIdentifierOrPattern(); - } - node.initializer = parseInitializer(); - return finishNode(node); - } - - function parseObjectBindingPattern(): ObjectBindingPattern { - const node = createNode(SyntaxKind.ObjectBindingPattern); - parseExpected(SyntaxKind.OpenBraceToken); - node.elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(node); - } - - function parseArrayBindingPattern(): ArrayBindingPattern { - const node = createNode(SyntaxKind.ArrayBindingPattern); - parseExpected(SyntaxKind.OpenBracketToken); - node.elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement); - parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(node); - } - - function isIdentifierOrPattern() { - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken || isIdentifier(); - } - - function parseIdentifierOrPattern(): Identifier | BindingPattern { - if (token() === SyntaxKind.OpenBracketToken) { - return parseArrayBindingPattern(); - } - if (token() === SyntaxKind.OpenBraceToken) { - return parseObjectBindingPattern(); - } - return parseIdentifier(); - } - - function parseVariableDeclarationAllowExclamation() { - return parseVariableDeclaration(/*allowExclamation*/ true); - } - - function parseVariableDeclaration(allowExclamation?: boolean): VariableDeclaration { - const node = createNode(SyntaxKind.VariableDeclaration); - node.name = parseIdentifierOrPattern(); - if (allowExclamation && node.name.kind === SyntaxKind.Identifier && - token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - node.exclamationToken = parseTokenNode(); - } - node.type = parseTypeAnnotation(); - if (!isInOrOfKeyword(token())) { - node.initializer = parseInitializer(); - } - return finishNode(node); - } - - function parseVariableDeclarationList(inForStatementInitializer: boolean): VariableDeclarationList { - const node = createNode(SyntaxKind.VariableDeclarationList); - - switch (token()) { - case SyntaxKind.VarKeyword: - break; - case SyntaxKind.LetKeyword: - node.flags |= NodeFlags.Let; - break; - case SyntaxKind.ConstKeyword: - node.flags |= NodeFlags.Const; - break; - default: - Debug.fail(); - } - - nextToken(); - - // The user may have written the following: - // - // for (let of X) { } - // - // In this case, we want to parse an empty declaration list, and then parse 'of' - // as a keyword. The reason this is not automatic is that 'of' is a valid identifier. - // So we need to look ahead to determine if 'of' should be treated as a keyword in - // this context. - // The checker will then give an error that there is an empty declaration list. - if (token() === SyntaxKind.OfKeyword && lookAhead(canFollowContextualOfKeyword)) { - node.declarations = createMissingList(); - } - else { - const savedDisallowIn = inDisallowInContext(); - setDisallowInContext(inForStatementInitializer); - - node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations, - inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation); - - setDisallowInContext(savedDisallowIn); - } - - return finishNode(node); - } - - function canFollowContextualOfKeyword(): boolean { - return nextTokenIsIdentifier() && nextToken() === SyntaxKind.CloseParenToken; - } - - function parseVariableStatement(node: VariableStatement): VariableStatement { - node.kind = SyntaxKind.VariableStatement; - node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false); - parseSemicolon(); - return finishNode(node); - } - - function parseFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration { - node.kind = SyntaxKind.FunctionDeclaration; - parseExpected(SyntaxKind.FunctionKeyword); - node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - node.name = hasModifier(node, ModifierFlags.Default) ? parseOptionalIdentifier() : parseIdentifier(); - const isGenerator = node.asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; - fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node); - node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, Diagnostics.or_expected); - return finishNode(node); - } - - function parseConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration { - node.kind = SyntaxKind.Constructor; - parseExpected(SyntaxKind.ConstructorKeyword); - fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node); - node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); - return finishNode(node); - } - - function parseMethodDeclaration(node: MethodDeclaration, asteriskToken: AsteriskToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration { - node.kind = SyntaxKind.MethodDeclaration; - node.asteriskToken = asteriskToken; - const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; - fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node); - node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage); - return finishNode(node); - } - - function parsePropertyDeclaration(node: PropertyDeclaration): PropertyDeclaration { - node.kind = SyntaxKind.PropertyDeclaration; - if (!node.questionToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - node.exclamationToken = parseTokenNode(); - } - node.type = parseTypeAnnotation(); - - // For instance properties specifically, since they are evaluated inside the constructor, - // we do *not * want to parse yield expressions, so we specifically turn the yield context - // off. The grammar would look something like this: - // - // MemberVariableDeclaration[Yield]: - // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In]; - // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield]; - // - // The checker may still error in the static case to explicitly disallow the yield expression. - node.initializer = hasModifier(node, ModifierFlags.Static) - ? allowInAnd(parseInitializer) - : doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.DisallowInContext, parseInitializer); - - parseSemicolon(); - return finishNode(node); - } - - function parsePropertyOrMethodDeclaration(node: PropertyDeclaration | MethodDeclaration): PropertyDeclaration | MethodDeclaration { - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - node.name = parsePropertyName(); - // Note: this is not legal as per the grammar. But we allow it in the parser and - // report an error in the grammar checker. - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseMethodDeclaration(node, asteriskToken, Diagnostics.or_expected); - } - return parsePropertyDeclaration(node); - } - - function parseAccessorDeclaration(node: AccessorDeclaration, kind: AccessorDeclaration["kind"]): AccessorDeclaration { - node.kind = kind; - node.name = parsePropertyName(); - fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node); - node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None); - return finishNode(node); - } - - function isClassMemberModifier(idToken: SyntaxKind) { - switch (idToken) { - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.ReadonlyKeyword: - return true; - default: - return false; - } - } - - function isClassMemberStart(): boolean { - let idToken: SyntaxKind; - - if (token() === SyntaxKind.AtToken) { - return true; - } - - // Eat up all modifiers, but hold on to the last one in case it is actually an identifier. - while (isModifierKind(token())) { - idToken = token(); - // If the idToken is a class modifier (protected, private, public, and static), it is - // certain that we are starting to parse class member. This allows better error recovery - // Example: - // public foo() ... // true - // public @dec blah ... // true; we will then report an error later - // export public ... // true; we will then report an error later - if (isClassMemberModifier(idToken)) { - return true; - } - - nextToken(); - } - - if (token() === SyntaxKind.AsteriskToken) { - return true; - } - - // Try to get the first property-like token following all modifiers. - // This can either be an identifier or the 'get' or 'set' keywords. - if (isLiteralPropertyName()) { - idToken = token(); - nextToken(); - } - - // Index signatures and computed properties are class members; we can parse. - if (token() === SyntaxKind.OpenBracketToken) { - return true; - } - - // If we were able to get any potential identifier... - if (idToken !== undefined) { - // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse. - if (!isKeyword(idToken) || idToken === SyntaxKind.SetKeyword || idToken === SyntaxKind.GetKeyword) { - return true; - } - - // If it *is* a keyword, but not an accessor, check a little farther along - // to see if it should actually be parsed as a class member. - switch (token()) { - case SyntaxKind.OpenParenToken: // Method declaration - case SyntaxKind.LessThanToken: // Generic Method declaration - case SyntaxKind.ExclamationToken: // Non-null assertion on property name - case SyntaxKind.ColonToken: // Type Annotation for declaration - case SyntaxKind.EqualsToken: // Initializer for declaration - case SyntaxKind.QuestionToken: // Not valid, but permitted so that it gets caught later on. - return true; - default: - // Covers - // - Semicolons (declaration termination) - // - Closing braces (end-of-class, must be declaration) - // - End-of-files (not valid, but permitted so that it gets caught later on) - // - Line-breaks (enabling *automatic semicolon insertion*) - return canParseSemicolon(); - } - } - - return false; - } - - function parseDecorators(): NodeArray | undefined { - let list: Decorator[] | undefined; - const listPos = getNodePos(); - while (true) { - const decoratorStart = getNodePos(); - if (!parseOptional(SyntaxKind.AtToken)) { - break; - } - const decorator = createNode(SyntaxKind.Decorator, decoratorStart); - decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher); - finishNode(decorator); - (list || (list = [])).push(decorator); - } - return list && createNodeArray(list, listPos); - } - - /* - * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member. - * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect - * and turns it into a standalone declaration), then it is better to parse it and report an error later. - * - * In such situations, 'permitInvalidConstAsModifier' should be set to true. - */ - function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray | undefined { - let list: Modifier[]; - const listPos = getNodePos(); - while (true) { - const modifierStart = scanner.getStartPos(); - const modifierKind = token(); - - if (token() === SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) { - // We need to ensure that any subsequent modifiers appear on the same line - // so that when 'const' is a standalone declaration, we don't issue an error. - if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { - break; - } - } - else { - if (!parseAnyContextualModifier()) { - break; - } - } - - const modifier = finishNode(createNode(modifierKind, modifierStart)); - (list || (list = [])).push(modifier); - } - return list && createNodeArray(list, listPos); - } - - function parseModifiersForArrowFunction(): NodeArray { - let modifiers: NodeArray; - if (token() === SyntaxKind.AsyncKeyword) { - const modifierStart = scanner.getStartPos(); - const modifierKind = token(); - nextToken(); - const modifier = finishNode(createNode(modifierKind, modifierStart)); - modifiers = createNodeArray([modifier], modifierStart); - } - return modifiers; - } - - function parseClassElement(): ClassElement { - if (token() === SyntaxKind.SemicolonToken) { - const result = createNode(SyntaxKind.SemicolonClassElement); - nextToken(); - return finishNode(result); - } - - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true); - - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.GetAccessor); - } - - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.SetAccessor); - } - - if (token() === SyntaxKind.ConstructorKeyword) { - return parseConstructorDeclaration(node); - } - - if (isIndexSignature()) { - return parseIndexSignatureDeclaration(node); - } - - // It is very important that we check this *after* checking indexers because - // the [ token can start an index signature or a computed property name - if (tokenIsIdentifierOrKeyword(token()) || - token() === SyntaxKind.StringLiteral || - token() === SyntaxKind.NumericLiteral || - token() === SyntaxKind.AsteriskToken || - token() === SyntaxKind.OpenBracketToken) { - - return parsePropertyOrMethodDeclaration(node); - } - - if (node.decorators || node.modifiers) { - // treat this as a property declaration with a missing name. - node.name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - return parsePropertyDeclaration(node); - } - - // 'isClassMemberStart' should have hinted not to attempt parsing. - Debug.fail("Should not have attempted to parse class member declaration."); - } - - function parseClassExpression(): ClassExpression { - return parseClassDeclarationOrExpression(createNodeWithJSDoc(SyntaxKind.Unknown), SyntaxKind.ClassExpression); - } - - function parseClassDeclaration(node: ClassLikeDeclaration): ClassDeclaration { - return parseClassDeclarationOrExpression(node, SyntaxKind.ClassDeclaration); - } - - function parseClassDeclarationOrExpression(node: ClassLikeDeclaration, kind: ClassLikeDeclaration["kind"]): ClassLikeDeclaration { - node.kind = kind; - parseExpected(SyntaxKind.ClassKeyword); - node.name = parseNameOfClassDeclarationOrExpression(); - node.typeParameters = parseTypeParameters(); - node.heritageClauses = parseHeritageClauses(); - - if (parseExpected(SyntaxKind.OpenBraceToken)) { - // ClassTail[Yield,Await] : (Modified) See 14.5 - // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } - node.members = parseClassMembers(); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - node.members = createMissingList(); - } - - return finishNode(node); - } - - function parseNameOfClassDeclarationOrExpression(): Identifier | undefined { - // implements is a future reserved word so - // 'class implements' might mean either - // - class expression with omitted name, 'implements' starts heritage clause - // - class with name 'implements' - // 'isImplementsClause' helps to disambiguate between these two cases - return isIdentifier() && !isImplementsClause() - ? parseIdentifier() - : undefined; - } - - function isImplementsClause() { - return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword); - } - - function parseHeritageClauses(): NodeArray | undefined { - // ClassTail[Yield,Await] : (Modified) See 14.5 - // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } - - if (isHeritageClause()) { - return parseList(ParsingContext.HeritageClauses, parseHeritageClause); - } - - return undefined; - } - - function parseHeritageClause(): HeritageClause | undefined { - const tok = token(); - if (tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword) { - const node = createNode(SyntaxKind.HeritageClause); - node.token = tok; - nextToken(); - node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments); - return finishNode(node); - } - - return undefined; - } - - function parseExpressionWithTypeArguments(): ExpressionWithTypeArguments { - const node = createNode(SyntaxKind.ExpressionWithTypeArguments); - node.expression = parseLeftHandSideExpressionOrHigher(); - node.typeArguments = tryParseTypeArguments(); - return finishNode(node); - } - - function tryParseTypeArguments(): NodeArray | undefined { - return token() === SyntaxKind.LessThanToken - ? parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) - : undefined; - } - - function isHeritageClause(): boolean { - return token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; - } - - function parseClassMembers(): NodeArray { - return parseList(ParsingContext.ClassMembers, parseClassElement); - } - - function parseInterfaceDeclaration(node: InterfaceDeclaration): InterfaceDeclaration { - node.kind = SyntaxKind.InterfaceDeclaration; - parseExpected(SyntaxKind.InterfaceKeyword); - node.name = parseIdentifier(); - node.typeParameters = parseTypeParameters(); - node.heritageClauses = parseHeritageClauses(); - node.members = parseObjectTypeMembers(); - return finishNode(node); - } - - function parseTypeAliasDeclaration(node: TypeAliasDeclaration): TypeAliasDeclaration { - node.kind = SyntaxKind.TypeAliasDeclaration; - parseExpected(SyntaxKind.TypeKeyword); - node.name = parseIdentifier(); - node.typeParameters = parseTypeParameters(); - parseExpected(SyntaxKind.EqualsToken); - node.type = parseType(); - parseSemicolon(); - return finishNode(node); - } - - // In an ambient declaration, the grammar only allows integer literals as initializers. - // In a non-ambient declaration, the grammar allows uninitialized members only in a - // ConstantEnumMemberSection, which starts at the beginning of an enum declaration - // or any time an integer literal initializer is encountered. - function parseEnumMember(): EnumMember { - const node = createNodeWithJSDoc(SyntaxKind.EnumMember); - node.name = parsePropertyName(); - node.initializer = allowInAnd(parseInitializer); - return finishNode(node); - } - - function parseEnumDeclaration(node: EnumDeclaration): EnumDeclaration { - node.kind = SyntaxKind.EnumDeclaration; - parseExpected(SyntaxKind.EnumKeyword); - node.name = parseIdentifier(); - if (parseExpected(SyntaxKind.OpenBraceToken)) { - node.members = parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - node.members = createMissingList(); - } - return finishNode(node); - } - - function parseModuleBlock(): ModuleBlock { - const node = createNode(SyntaxKind.ModuleBlock); - if (parseExpected(SyntaxKind.OpenBraceToken)) { - node.statements = parseList(ParsingContext.BlockStatements, parseStatement); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - node.statements = createMissingList(); - } - return finishNode(node); - } - - function parseModuleOrNamespaceDeclaration(node: ModuleDeclaration, flags: NodeFlags): ModuleDeclaration { - node.kind = SyntaxKind.ModuleDeclaration; - // If we are parsing a dotted namespace name, we want to - // propagate the 'Namespace' flag across the names if set. - const namespaceFlag = flags & NodeFlags.Namespace; - node.flags |= flags; - node.name = parseIdentifier(); - node.body = parseOptional(SyntaxKind.DotToken) - ? parseModuleOrNamespaceDeclaration(createNode(SyntaxKind.Unknown), NodeFlags.NestedNamespace | namespaceFlag) - : parseModuleBlock(); - return finishNode(node); - } - - function parseAmbientExternalModuleDeclaration(node: ModuleDeclaration): ModuleDeclaration { - node.kind = SyntaxKind.ModuleDeclaration; - if (token() === SyntaxKind.GlobalKeyword) { - // parse 'global' as name of global scope augmentation - node.name = parseIdentifier(); - node.flags |= NodeFlags.GlobalAugmentation; - } - else { - node.name = parseLiteralNode(); - node.name.text = internIdentifier(node.name.text); - } - if (token() === SyntaxKind.OpenBraceToken) { - node.body = parseModuleBlock(); - } - else { - parseSemicolon(); - } - return finishNode(node); - } - - function parseModuleDeclaration(node: ModuleDeclaration): ModuleDeclaration { - let flags: NodeFlags = 0; - if (token() === SyntaxKind.GlobalKeyword) { - // global augmentation - return parseAmbientExternalModuleDeclaration(node); - } - else if (parseOptional(SyntaxKind.NamespaceKeyword)) { - flags |= NodeFlags.Namespace; - } - else { - parseExpected(SyntaxKind.ModuleKeyword); - if (token() === SyntaxKind.StringLiteral) { - return parseAmbientExternalModuleDeclaration(node); - } - } - return parseModuleOrNamespaceDeclaration(node, flags); - } - - function isExternalModuleReference() { - return token() === SyntaxKind.RequireKeyword && - lookAhead(nextTokenIsOpenParen); - } - - function nextTokenIsOpenParen() { - return nextToken() === SyntaxKind.OpenParenToken; - } - - function nextTokenIsSlash() { - return nextToken() === SyntaxKind.SlashToken; - } - - function parseNamespaceExportDeclaration(node: NamespaceExportDeclaration): NamespaceExportDeclaration { - node.kind = SyntaxKind.NamespaceExportDeclaration; - parseExpected(SyntaxKind.AsKeyword); - parseExpected(SyntaxKind.NamespaceKeyword); - node.name = parseIdentifier(); - parseSemicolon(); - return finishNode(node); - } - - function parseImportDeclarationOrImportEqualsDeclaration(node: ImportEqualsDeclaration | ImportDeclaration): ImportEqualsDeclaration | ImportDeclaration { - parseExpected(SyntaxKind.ImportKeyword); - const afterImportPos = scanner.getStartPos(); - - let identifier: Identifier; - if (isIdentifier()) { - identifier = parseIdentifier(); - if (token() !== SyntaxKind.CommaToken && token() !== SyntaxKind.FromKeyword) { - return parseImportEqualsDeclaration(node, identifier); - } - } - - // Import statement - node.kind = SyntaxKind.ImportDeclaration; - // ImportDeclaration: - // import ImportClause from ModuleSpecifier ; - // import ModuleSpecifier; - if (identifier || // import id - token() === SyntaxKind.AsteriskToken || // import * - token() === SyntaxKind.OpenBraceToken) { // import { - (node).importClause = parseImportClause(identifier, afterImportPos); - parseExpected(SyntaxKind.FromKeyword); - } - - (node).moduleSpecifier = parseModuleSpecifier(); - parseSemicolon(); - return finishNode(node); - } - - function parseImportEqualsDeclaration(node: ImportEqualsDeclaration, identifier: ts.Identifier): ImportEqualsDeclaration { - node.kind = SyntaxKind.ImportEqualsDeclaration; - node.name = identifier; - parseExpected(SyntaxKind.EqualsToken); - node.moduleReference = parseModuleReference(); - parseSemicolon(); - return finishNode(node); - } - - function parseImportClause(identifier: Identifier, fullStart: number) { - // ImportClause: - // ImportedDefaultBinding - // NameSpaceImport - // NamedImports - // ImportedDefaultBinding, NameSpaceImport - // ImportedDefaultBinding, NamedImports - - const importClause = createNode(SyntaxKind.ImportClause, fullStart); - if (identifier) { - // ImportedDefaultBinding: - // ImportedBinding - importClause.name = identifier; - } - - // If there was no default import or if there is comma token after default import - // parse namespace or named imports - if (!importClause.name || - parseOptional(SyntaxKind.CommaToken)) { - importClause.namedBindings = token() === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports); - } - - return finishNode(importClause); - } - - function parseModuleReference() { - return isExternalModuleReference() - ? parseExternalModuleReference() - : parseEntityName(/*allowReservedWords*/ false); - } - - function parseExternalModuleReference() { - const node = createNode(SyntaxKind.ExternalModuleReference); - parseExpected(SyntaxKind.RequireKeyword); - parseExpected(SyntaxKind.OpenParenToken); - node.expression = parseModuleSpecifier(); - parseExpected(SyntaxKind.CloseParenToken); - return finishNode(node); - } - - function parseModuleSpecifier(): Expression { - if (token() === SyntaxKind.StringLiteral) { - const result = parseLiteralNode(); - result.text = internIdentifier(result.text); - return result; - } - else { - // We allow arbitrary expressions here, even though the grammar only allows string - // literals. We check to ensure that it is only a string literal later in the grammar - // check pass. - return parseExpression(); - } - } - - function parseNamespaceImport(): NamespaceImport { - // NameSpaceImport: - // * as ImportedBinding - const namespaceImport = createNode(SyntaxKind.NamespaceImport); - parseExpected(SyntaxKind.AsteriskToken); - parseExpected(SyntaxKind.AsKeyword); - namespaceImport.name = parseIdentifier(); - return finishNode(namespaceImport); - } - - function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports; - function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports; - function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports { - const node = createNode(kind); - - // NamedImports: - // { } - // { ImportsList } - // { ImportsList, } - - // ImportsList: - // ImportSpecifier - // ImportsList, ImportSpecifier - node.elements = | NodeArray>parseBracketedList(ParsingContext.ImportOrExportSpecifiers, - kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier, - SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken); - return finishNode(node); - } - - function parseExportSpecifier() { - return parseImportOrExportSpecifier(SyntaxKind.ExportSpecifier); - } - - function parseImportSpecifier() { - return parseImportOrExportSpecifier(SyntaxKind.ImportSpecifier); - } - - function parseImportOrExportSpecifier(kind: SyntaxKind): ImportOrExportSpecifier { - const node = createNode(kind); - // ImportSpecifier: - // BindingIdentifier - // IdentifierName as BindingIdentifier - // ExportSpecifier: - // IdentifierName - // IdentifierName as IdentifierName - let checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); - let checkIdentifierStart = scanner.getTokenPos(); - let checkIdentifierEnd = scanner.getTextPos(); - const identifierName = parseIdentifierName(); - if (token() === SyntaxKind.AsKeyword) { - node.propertyName = identifierName; - parseExpected(SyntaxKind.AsKeyword); - checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); - checkIdentifierStart = scanner.getTokenPos(); - checkIdentifierEnd = scanner.getTextPos(); - node.name = parseIdentifierName(); - } - else { - node.name = identifierName; - } - if (kind === SyntaxKind.ImportSpecifier && checkIdentifierIsKeyword) { - // Report error identifier expected - parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, Diagnostics.Identifier_expected); - } - return finishNode(node); - } - - function parseExportDeclaration(node: ExportDeclaration): ExportDeclaration { - node.kind = SyntaxKind.ExportDeclaration; - if (parseOptional(SyntaxKind.AsteriskToken)) { - parseExpected(SyntaxKind.FromKeyword); - node.moduleSpecifier = parseModuleSpecifier(); - } - else { - node.exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); - // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, - // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) - // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. - if (token() === SyntaxKind.FromKeyword || (token() === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { - parseExpected(SyntaxKind.FromKeyword); - node.moduleSpecifier = parseModuleSpecifier(); - } - } - parseSemicolon(); - return finishNode(node); - } - - function parseExportAssignment(node: ExportAssignment): ExportAssignment { - node.kind = SyntaxKind.ExportAssignment; - if (parseOptional(SyntaxKind.EqualsToken)) { - node.isExportEquals = true; - } - else { - parseExpected(SyntaxKind.DefaultKeyword); - } - node.expression = parseAssignmentExpressionOrHigher(); - parseSemicolon(); - return finishNode(node); - } - - function processReferenceComments(sourceFile: SourceFile): void { - const triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, LanguageVariant.Standard, sourceText); - const referencedFiles: FileReference[] = []; - const typeReferenceDirectives: FileReference[] = []; - const amdDependencies: { path: string; name: string }[] = []; - let amdModuleName: string; - let checkJsDirective: CheckJsDirective = undefined; - - // Keep scanning all the leading trivia in the file until we get to something that - // isn't trivia. Any single line comment will be analyzed to see if it is a - // reference comment. - while (true) { - const kind = triviaScanner.scan(); - if (kind !== SyntaxKind.SingleLineCommentTrivia) { - if (isTrivia(kind)) { - continue; - } - else { - break; - } - } - - const range = { - kind: triviaScanner.getToken(), - pos: triviaScanner.getTokenPos(), - end: triviaScanner.getTextPos(), - }; - - const comment = sourceText.substring(range.pos, range.end); - const referencePathMatchResult = getFileReferenceFromReferencePath(comment, range); - if (referencePathMatchResult) { - const fileReference = referencePathMatchResult.fileReference; - sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; - const diagnosticMessage = referencePathMatchResult.diagnosticMessage; - if (fileReference) { - if (referencePathMatchResult.isTypeReferenceDirective) { - typeReferenceDirectives.push(fileReference); - } - else { - referencedFiles.push(fileReference); - } - } - if (diagnosticMessage) { - parseDiagnostics.push(createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); - } - } - else { - const amdModuleNameRegEx = /^\/\/\/\s* - hasModifier(node, ModifierFlags.Export) - || node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference - || node.kind === SyntaxKind.ImportDeclaration - || node.kind === SyntaxKind.ExportAssignment - || node.kind === SyntaxKind.ExportDeclaration - ? node - : undefined); - } - - const enum ParsingContext { - SourceElements, // Elements in source file - BlockStatements, // Statements in block - SwitchClauses, // Clauses in switch statement - SwitchClauseStatements, // Statements in switch clause - TypeMembers, // Members in interface or type literal - ClassMembers, // Members in class declaration - EnumMembers, // Members in enum declaration - HeritageClauseElement, // Elements in a heritage clause - VariableDeclarations, // Variable declarations in variable statement - ObjectBindingElements, // Binding elements in object binding list - ArrayBindingElements, // Binding elements in array binding list - ArgumentExpressions, // Expressions in argument list - ObjectLiteralMembers, // Members in object literal - JsxAttributes, // Attributes in jsx element - JsxChildren, // Things between opening and closing JSX tags - ArrayLiteralMembers, // Members in array literal - Parameters, // Parameters in parameter list - RestProperties, // Property names in a rest type list - TypeParameters, // Type parameters in type parameter list - TypeArguments, // Type arguments in type argument list - TupleElementTypes, // Element types in tuple element type list - HeritageClauses, // Heritage clauses for a class or interface declaration. - ImportOrExportSpecifiers, // Named import clause's import specifier list - Count // Number of parsing contexts - } - - const enum Tristate { - False, - True, - Unknown - } - - export namespace JSDocParser { - export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined { - initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); - sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false); - scanner.setText(content, start, length); - currentToken = scanner.scan(); - const jsDocTypeExpression = parseJSDocTypeExpression(); - const diagnostics = parseDiagnostics; - clearState(); - - return jsDocTypeExpression ? { jsDocTypeExpression, diagnostics } : undefined; - } - - // Parses out a JSDoc type expression. - export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression { - const result = createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos()); - - const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken); - result.type = doInsideOfContext(NodeFlags.JSDoc, parseType); - if (!mayOmitBraces || hasBrace) { - parseExpected(SyntaxKind.CloseBraceToken); - } - - fixupParentReferences(result); - return finishNode(result); - } - - export function parseIsolatedJSDocComment(content: string, start: number, length: number): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined { - initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); - sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; // tslint:disable-line no-object-literal-type-assertion - const jsDoc = parseJSDocCommentWorker(start, length); - const diagnostics = parseDiagnostics; - clearState(); - - return jsDoc ? { jsDoc, diagnostics } : undefined; - } - - export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc { - const saveToken = currentToken; - const saveParseDiagnosticsLength = parseDiagnostics.length; - const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; - - const comment = parseJSDocCommentWorker(start, length); - if (comment) { - comment.parent = parent; - } - - if (contextFlags & NodeFlags.JavaScriptFile) { - if (!sourceFile.jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = []; - } - sourceFile.jsDocDiagnostics.push(...parseDiagnostics); - } - currentToken = saveToken; - parseDiagnostics.length = saveParseDiagnosticsLength; - parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; - - return comment; - } - - const enum JSDocState { - BeginningOfLine, - SawAsterisk, - SavingComments, - } - - const enum PropertyLikeParse { - Property, - Parameter, - } - - export function parseJSDocCommentWorker(start: number, length: number): JSDoc { - const content = sourceText; - start = start || 0; - const end = length === undefined ? content.length : start + length; - length = end - start; - - Debug.assert(start >= 0); - Debug.assert(start <= end); - Debug.assert(end <= content.length); - - let tags: JSDocTag[]; - let tagsPos: number; - let tagsEnd: number; - const comments: string[] = []; - let result: JSDoc; - - // Check for /** (JSDoc opening part) - if (!isJsDocStart(content, start)) { - return result; - } - - // + 3 for leading /**, - 5 in total for /** */ - scanner.scanRange(start + 3, length - 5, () => { - // Initially we can parse out a tag. We also have seen a starting asterisk. - // This is so that /** * @type */ doesn't parse. - let state = JSDocState.SawAsterisk; - let margin: number | undefined = undefined; - // + 4 for leading '/** ' - let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; - function pushComment(text: string) { - if (!margin) { - margin = indent; - } - comments.push(text); - indent += text.length; - } - - let t = nextJSDocToken(); - while (t === SyntaxKind.WhitespaceTrivia) { - t = nextJSDocToken(); - } - if (t === SyntaxKind.NewLineTrivia) { - state = JSDocState.BeginningOfLine; - indent = 0; - t = nextJSDocToken(); - } - loop: while (true) { - switch (t) { - case SyntaxKind.AtToken: - if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { - removeTrailingNewlines(comments); - parseTag(indent); - // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. - // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning - // for malformed examples like `/** @param {string} x @returns {number} the length */` - state = JSDocState.BeginningOfLine; - margin = undefined; - indent++; - } - else { - pushComment(scanner.getTokenText()); - } - break; - case SyntaxKind.NewLineTrivia: - comments.push(scanner.getTokenText()); - state = JSDocState.BeginningOfLine; - indent = 0; - break; - case SyntaxKind.AsteriskToken: - const asterisk = scanner.getTokenText(); - if (state === JSDocState.SawAsterisk || state === JSDocState.SavingComments) { - // If we've already seen an asterisk, then we can no longer parse a tag on this line - state = JSDocState.SavingComments; - pushComment(asterisk); - } - else { - // Ignore the first asterisk on a line - state = JSDocState.SawAsterisk; - indent += asterisk.length; - } - break; - case SyntaxKind.Identifier: - // Anything else is doc comment text. We just save it. Because it - // wasn't a tag, we can no longer parse a tag on this line until we hit the next - // line break. - pushComment(scanner.getTokenText()); - state = JSDocState.SavingComments; - break; - case SyntaxKind.WhitespaceTrivia: - // only collect whitespace if we're already saving comments or have just crossed the comment indent margin - const whitespace = scanner.getTokenText(); - if (state === JSDocState.SavingComments) { - comments.push(whitespace); - } - else if (margin !== undefined && indent + whitespace.length > margin) { - comments.push(whitespace.slice(margin - indent - 1)); - } - indent += whitespace.length; - break; - case SyntaxKind.EndOfFileToken: - break loop; - default: - // anything other than whitespace or asterisk at the beginning of the line starts the comment text - state = JSDocState.SavingComments; - pushComment(scanner.getTokenText()); - break; - } - t = nextJSDocToken(); - } - removeLeadingNewlines(comments); - removeTrailingNewlines(comments); - result = createJSDocComment(); - - }); - - return result; - - function removeLeadingNewlines(comments: string[]) { - while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) { - comments.shift(); - } - } - - function removeTrailingNewlines(comments: string[]) { - while (comments.length && (comments[comments.length - 1] === "\n" || comments[comments.length - 1] === "\r")) { - comments.pop(); - } - } - - function isJsDocStart(content: string, start: number) { - return content.charCodeAt(start) === CharacterCodes.slash && - content.charCodeAt(start + 1) === CharacterCodes.asterisk && - content.charCodeAt(start + 2) === CharacterCodes.asterisk && - content.charCodeAt(start + 3) !== CharacterCodes.asterisk; - } - - function createJSDocComment(): JSDoc { - const result = createNode(SyntaxKind.JSDocComment, start); - result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd); - result.comment = comments.length ? comments.join("") : undefined; - return finishNode(result, end); - } - - function skipWhitespace(): void { - while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { - nextJSDocToken(); - } - } - - function parseTag(indent: number) { - Debug.assert(token() === SyntaxKind.AtToken); - const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos()); - atToken.end = scanner.getTextPos(); - nextJSDocToken(); - - const tagName = parseJSDocIdentifierName(); - skipWhitespace(); - if (!tagName) { - return; - } - - let tag: JSDocTag; - if (tagName) { - switch (tagName.escapedText) { - case "augments": - case "extends": - tag = parseAugmentsTag(atToken, tagName); - break; - case "class": - case "constructor": - tag = parseClassTag(atToken, tagName); - break; - case "arg": - case "argument": - case "param": - tag = parseParameterOrPropertyTag(atToken, tagName, PropertyLikeParse.Parameter); - break; - case "return": - case "returns": - tag = parseReturnTag(atToken, tagName); - break; - case "template": - tag = parseTemplateTag(atToken, tagName); - break; - case "type": - tag = parseTypeTag(atToken, tagName); - break; - case "typedef": - tag = parseTypedefTag(atToken, tagName); - break; - default: - tag = parseUnknownTag(atToken, tagName); - break; - } - } - else { - tag = parseUnknownTag(atToken, tagName); - } - - if (!tag) { - // a badly malformed tag should not be added to the list of tags - return; - } - tag.comment = parseTagComments(indent + tag.end - tag.pos); - addTag(tag); - } - - function parseTagComments(indent: number): string | undefined { - const comments: string[] = []; - let state = JSDocState.BeginningOfLine; - let margin: number | undefined; - function pushComment(text: string) { - if (!margin) { - margin = indent; - } - comments.push(text); - indent += text.length; - } - let tok = token() as JsDocSyntaxKind; - loop: while (true) { - switch (tok) { - case SyntaxKind.NewLineTrivia: - if (state >= JSDocState.SawAsterisk) { - state = JSDocState.BeginningOfLine; - comments.push(scanner.getTokenText()); - } - indent = 0; - break; - case SyntaxKind.AtToken: - scanner.setTextPos(scanner.getTextPos() - 1); - // falls through - case SyntaxKind.EndOfFileToken: - // Done - break loop; - case SyntaxKind.WhitespaceTrivia: - if (state === JSDocState.SavingComments) { - pushComment(scanner.getTokenText()); - } - else { - const whitespace = scanner.getTokenText(); - // if the whitespace crosses the margin, take only the whitespace that passes the margin - if (margin !== undefined && indent + whitespace.length > margin) { - comments.push(whitespace.slice(margin - indent - 1)); - } - indent += whitespace.length; - } - break; - case SyntaxKind.AsteriskToken: - if (state === JSDocState.BeginningOfLine) { - // leading asterisks start recording on the *next* (non-whitespace) token - state = JSDocState.SawAsterisk; - indent += 1; - break; - } - // record the * as a comment - // falls through - default: - state = JSDocState.SavingComments; // leading identifiers start recording as well - pushComment(scanner.getTokenText()); - break; - } - tok = nextJSDocToken(); - } - - removeLeadingNewlines(comments); - removeTrailingNewlines(comments); - return comments.length === 0 ? undefined : comments.join(""); - } - - function parseUnknownTag(atToken: AtToken, tagName: Identifier) { - const result = createNode(SyntaxKind.JSDocTag, atToken.pos); - result.atToken = atToken; - result.tagName = tagName; - return finishNode(result); - } - - function addTag(tag: JSDocTag): void { - if (!tags) { - tags = [tag]; - tagsPos = tag.pos; - } - else { - tags.push(tag); - } - tagsEnd = tag.end; - } - - function tryParseTypeExpression(): JSDocTypeExpression | undefined { - skipWhitespace(); - return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; - } - - function parseBracketNameInPropertyAndParamTag(): { name: EntityName, isBracketed: boolean } { - // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar' - const isBracketed = parseOptional(SyntaxKind.OpenBracketToken); - const name = parseJSDocEntityName(); - if (isBracketed) { - skipWhitespace(); - - // May have an optional default, e.g. '[foo = 42]' - if (parseOptionalToken(SyntaxKind.EqualsToken)) { - parseExpression(); - } - - parseExpected(SyntaxKind.CloseBracketToken); - } - - return { name, isBracketed }; - } - - function isObjectOrObjectArrayTypeReference(node: TypeNode): boolean { - switch (node.kind) { - case SyntaxKind.ObjectKeyword: - return true; - case SyntaxKind.ArrayType: - return isObjectOrObjectArrayTypeReference((node as ArrayTypeNode).elementType); - default: - return isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object"; - } - } - - function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse): JSDocParameterTag | JSDocPropertyTag { - let typeExpression = tryParseTypeExpression(); - let isNameFirst = !typeExpression; - skipWhitespace(); - - const { name, isBracketed } = parseBracketNameInPropertyAndParamTag(); - skipWhitespace(); - - if (isNameFirst) { - typeExpression = tryParseTypeExpression(); - } - - const result = target === PropertyLikeParse.Parameter ? - createNode(SyntaxKind.JSDocParameterTag, atToken.pos) : - createNode(SyntaxKind.JSDocPropertyTag, atToken.pos); - const nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name); - if (nestedTypeLiteral) { - typeExpression = nestedTypeLiteral; - isNameFirst = true; - } - result.atToken = atToken; - result.tagName = tagName; - result.typeExpression = typeExpression; - result.name = name; - result.isNameFirst = isNameFirst; - result.isBracketed = isBracketed; - return finishNode(result); - } - - function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression, name: EntityName) { - if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) { - const typeLiteralExpression = createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos()); - let child: JSDocParameterTag | false; - let jsdocTypeLiteral: JSDocTypeLiteral; - const start = scanner.getStartPos(); - let children: JSDocParameterTag[]; - while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Parameter, name))) { - children = append(children, child); - } - if (children) { - jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); - jsdocTypeLiteral.jsDocPropertyTags = children; - if (typeExpression.type.kind === SyntaxKind.ArrayType) { - jsdocTypeLiteral.isArrayType = true; - } - typeLiteralExpression.type = finishNode(jsdocTypeLiteral); - return finishNode(typeLiteralExpression); - } - } - } - - function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag { - if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) { - parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText); - } - - const result = createNode(SyntaxKind.JSDocReturnTag, atToken.pos); - result.atToken = atToken; - result.tagName = tagName; - result.typeExpression = tryParseTypeExpression(); - return finishNode(result); - } - - function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag { - if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) { - parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText); - } - - const result = createNode(SyntaxKind.JSDocTypeTag, atToken.pos); - result.atToken = atToken; - result.tagName = tagName; - result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); - return finishNode(result); - } - - function parseAugmentsTag(atToken: AtToken, tagName: Identifier): JSDocAugmentsTag { - const result = createNode(SyntaxKind.JSDocAugmentsTag, atToken.pos); - result.atToken = atToken; - result.tagName = tagName; - result.class = parseExpressionWithTypeArgumentsForAugments(); - return finishNode(result); - } - - function parseExpressionWithTypeArgumentsForAugments(): ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression } { - const usedBrace = parseOptional(SyntaxKind.OpenBraceToken); - const node = createNode(SyntaxKind.ExpressionWithTypeArguments) as ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; - node.expression = parsePropertyAccessEntityNameExpression(); - node.typeArguments = tryParseTypeArguments(); - const res = finishNode(node); - if (usedBrace) { - parseExpected(SyntaxKind.CloseBraceToken); - } - return res; - } - - function parsePropertyAccessEntityNameExpression() { - let node: Identifier | PropertyAccessEntityNameExpression = parseJSDocIdentifierName(/*createIfMissing*/ true); - while (parseOptional(SyntaxKind.DotToken)) { - const prop: PropertyAccessEntityNameExpression = createNode(SyntaxKind.PropertyAccessExpression, node.pos) as PropertyAccessEntityNameExpression; - prop.expression = node; - prop.name = parseJSDocIdentifierName(); - node = finishNode(prop); - } - return node; - } - - function parseClassTag(atToken: AtToken, tagName: Identifier): JSDocClassTag { - const tag = createNode(SyntaxKind.JSDocClassTag, atToken.pos); - tag.atToken = atToken; - tag.tagName = tagName; - return finishNode(tag); - } - - function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag { - const typeExpression = tryParseTypeExpression(); - skipWhitespace(); - - const typedefTag = createNode(SyntaxKind.JSDocTypedefTag, atToken.pos); - typedefTag.atToken = atToken; - typedefTag.tagName = tagName; - typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0); - if (typedefTag.fullName) { - let rightNode = typedefTag.fullName; - while (true) { - if (rightNode.kind === SyntaxKind.Identifier || !rightNode.body) { - // if node is identifier - use it as name - // otherwise use name of the rightmost part that we were able to parse - typedefTag.name = rightNode.kind === SyntaxKind.Identifier ? rightNode : rightNode.name; - break; - } - rightNode = rightNode.body; - } - } - skipWhitespace(); - - typedefTag.typeExpression = typeExpression; - if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { - let child: JSDocTypeTag | JSDocPropertyTag | false; - let jsdocTypeLiteral: JSDocTypeLiteral; - let childTypeTag: JSDocTypeTag; - const start = scanner.getStartPos(); - while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Property))) { - if (!jsdocTypeLiteral) { - jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); - } - if (child.kind === SyntaxKind.JSDocTypeTag) { - if (childTypeTag) { - break; - } - else { - childTypeTag = child; - } - } - else { - jsdocTypeLiteral.jsDocPropertyTags = append(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray, child); - } - } - if (jsdocTypeLiteral) { - if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) { - jsdocTypeLiteral.isArrayType = true; - } - typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? - childTypeTag.typeExpression : - finishNode(jsdocTypeLiteral); - } - } - - return finishNode(typedefTag); - - function parseJSDocTypeNameWithNamespace(flags: NodeFlags) { - const pos = scanner.getTokenPos(); - const typeNameOrNamespaceName = parseJSDocIdentifierName(); - - if (typeNameOrNamespaceName && parseOptional(SyntaxKind.DotToken)) { - const jsDocNamespaceNode = createNode(SyntaxKind.ModuleDeclaration, pos); - jsDocNamespaceNode.flags |= flags; - jsDocNamespaceNode.name = typeNameOrNamespaceName; - jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(NodeFlags.NestedNamespace); - return finishNode(jsDocNamespaceNode); - } - - if (typeNameOrNamespaceName && flags & NodeFlags.NestedNamespace) { - typeNameOrNamespaceName.isInJSDocNamespace = true; - } - return typeNameOrNamespaceName; - } - } - - function escapedTextsEqual(a: EntityName, b: EntityName): boolean { - while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) { - if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) { - a = a.left; - b = b.left; - } - else { - return false; - } - } - return a.escapedText === b.escapedText; - } - - function parseChildParameterOrPropertyTag(target: PropertyLikeParse.Property): JSDocTypeTag | JSDocPropertyTag | false; - function parseChildParameterOrPropertyTag(target: PropertyLikeParse.Parameter, name: EntityName): JSDocParameterTag | false; - function parseChildParameterOrPropertyTag(target: PropertyLikeParse, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false { - let canParseTag = true; - let seenAsterisk = false; - while (true) { - switch (nextJSDocToken()) { - case SyntaxKind.AtToken: - if (canParseTag) { - const child = tryParseChildTag(target); - if (child && child.kind === SyntaxKind.JSDocParameterTag && - (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) { - return false; - } - return child; - } - seenAsterisk = false; - break; - case SyntaxKind.NewLineTrivia: - canParseTag = true; - seenAsterisk = false; - break; - case SyntaxKind.AsteriskToken: - if (seenAsterisk) { - canParseTag = false; - } - seenAsterisk = true; - break; - case SyntaxKind.Identifier: - canParseTag = false; - break; - case SyntaxKind.EndOfFileToken: - return false; - } - } - } - - function tryParseChildTag(target: PropertyLikeParse): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false { - Debug.assert(token() === SyntaxKind.AtToken); - const atToken = createNode(SyntaxKind.AtToken); - atToken.end = scanner.getTextPos(); - nextJSDocToken(); - - const tagName = parseJSDocIdentifierName(); - skipWhitespace(); - if (!tagName) { - return false; - } - let t: PropertyLikeParse; - switch (tagName.escapedText) { - case "type": - return target === PropertyLikeParse.Property && parseTypeTag(atToken, tagName); - case "prop": - case "property": - t = PropertyLikeParse.Property; - break; - case "arg": - case "argument": - case "param": - t = PropertyLikeParse.Parameter; - break; - default: - return false; - } - if (target !== t) { - return false; - } - const tag = parseParameterOrPropertyTag(atToken, tagName, target); - tag.comment = parseTagComments(tag.end - tag.pos); - return tag; - } - - function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined { - if (some(tags, isJSDocTemplateTag)) { - parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText); - } - - // Type parameter list looks like '@template T,U,V' - const typeParameters = []; - const typeParametersPos = getNodePos(); - - while (true) { - const typeParameter = createNode(SyntaxKind.TypeParameter); - const name = parseJSDocIdentifierNameWithOptionalBraces(); - skipWhitespace(); - if (!name) { - parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected); - return undefined; - } - - typeParameter.name = name; - finishNode(typeParameter); - - typeParameters.push(typeParameter); - - if (token() === SyntaxKind.CommaToken) { - nextJSDocToken(); - skipWhitespace(); - } - else { - break; - } - } - - const result = createNode(SyntaxKind.JSDocTemplateTag, atToken.pos); - result.atToken = atToken; - result.tagName = tagName; - result.typeParameters = createNodeArray(typeParameters, typeParametersPos); - finishNode(result); - return result; - } - - function parseJSDocIdentifierNameWithOptionalBraces(): Identifier | undefined { - const parsedBrace = parseOptional(SyntaxKind.OpenBraceToken); - const res = parseJSDocIdentifierName(); - if (parsedBrace) { - parseExpected(SyntaxKind.CloseBraceToken); - } - return res; - } - - function nextJSDocToken(): JsDocSyntaxKind { - return currentToken = scanner.scanJSDocToken(); - } - - function parseJSDocEntityName(): EntityName { - let entity: EntityName = parseJSDocIdentifierName(/*createIfMissing*/ true); - if (parseOptional(SyntaxKind.OpenBracketToken)) { - parseExpected(SyntaxKind.CloseBracketToken); - // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking. - // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}> - // but it's not worth it to enforce that restriction. - } - while (parseOptional(SyntaxKind.DotToken)) { - const name = parseJSDocIdentifierName(/*createIfMissing*/ true); - if (parseOptional(SyntaxKind.OpenBracketToken)) { - parseExpected(SyntaxKind.CloseBracketToken); - } - entity = createQualifiedName(entity, name); - } - return entity; - } - - function parseJSDocIdentifierName(): Identifier | undefined; - function parseJSDocIdentifierName(createIfMissing: true): Identifier; - function parseJSDocIdentifierName(createIfMissing = false): Identifier | undefined { - if (!tokenIsIdentifierOrKeyword(token())) { - if (createIfMissing) { - return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); - } - else { - parseErrorAtCurrentToken(Diagnostics.Identifier_expected); - return undefined; - } - } - - const pos = scanner.getTokenPos(); - const end = scanner.getTextPos(); - const result = createNode(SyntaxKind.Identifier, pos); - result.escapedText = escapeLeadingUnderscores(content.substring(pos, end)); - finishNode(result, end); - - nextJSDocToken(); - return result; - } - } - } - } - - namespace IncrementalParser { - export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile { - aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive); - - checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks); - if (textChangeRangeIsUnchanged(textChangeRange)) { - // if the text didn't change, then we can just return our current source file as-is. - return sourceFile; - } - - if (sourceFile.statements.length === 0) { - // If we don't have any statements in the current source file, then there's no real - // way to incrementally parse. So just do a full parse instead. - return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind); - } - - // Make sure we're not trying to incrementally update a source file more than once. Once - // we do an update the original source file is considered unusable from that point onwards. - // - // This is because we do incremental parsing in-place. i.e. we take nodes from the old - // tree and give them new positions and parents. From that point on, trusting the old - // tree at all is not possible as far too much of it may violate invariants. - const incrementalSourceFile = sourceFile; - Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed); - incrementalSourceFile.hasBeenIncrementallyParsed = true; - - const oldText = sourceFile.text; - const syntaxCursor = createSyntaxCursor(sourceFile); - - // Make the actual change larger so that we know to reparse anything whose lookahead - // might have intersected the change. - const changeRange = extendToAffectedRange(sourceFile, textChangeRange); - checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks); - - // Ensure that extending the affected range only moved the start of the change range - // earlier in the file. - Debug.assert(changeRange.span.start <= textChangeRange.span.start); - Debug.assert(textSpanEnd(changeRange.span) === textSpanEnd(textChangeRange.span)); - Debug.assert(textSpanEnd(textChangeRangeNewSpan(changeRange)) === textSpanEnd(textChangeRangeNewSpan(textChangeRange))); - - // The is the amount the nodes after the edit range need to be adjusted. It can be - // positive (if the edit added characters), negative (if the edit deleted characters) - // or zero (if this was a pure overwrite with nothing added/removed). - const delta = textChangeRangeNewSpan(changeRange).length - changeRange.span.length; - - // If we added or removed characters during the edit, then we need to go and adjust all - // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they - // may move backward (if we deleted chars). - // - // Doing this helps us out in two ways. First, it means that any nodes/tokens we want - // to reuse are already at the appropriate position in the new text. That way when we - // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes - // it very easy to determine if we can reuse a node. If the node's position is at where - // we are in the text, then we can reuse it. Otherwise we can't. If the node's position - // is ahead of us, then we'll need to rescan tokens. If the node's position is behind - // us, then we'll need to skip it or crumble it as appropriate - // - // We will also adjust the positions of nodes that intersect the change range as well. - // By doing this, we ensure that all the positions in the old tree are consistent, not - // just the positions of nodes entirely before/after the change range. By being - // consistent, we can then easily map from positions to nodes in the old tree easily. - // - // Also, mark any syntax elements that intersect the changed span. We know, up front, - // that we cannot reuse these elements. - updateTokenPositionsAndMarkElements(incrementalSourceFile, - changeRange.span.start, textSpanEnd(changeRange.span), textSpanEnd(textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks); - - // Now that we've set up our internal incremental state just proceed and parse the - // source file in the normal fashion. When possible the parser will retrieve and - // reuse nodes from the old tree. - // - // Note: passing in 'true' for setNodeParents is very important. When incrementally - // parsing, we will be reusing nodes from the old tree, and placing it into new - // parents. If we don't set the parents now, we'll end up with an observably - // inconsistent tree. Setting the parents on the new tree should be very fast. We - // will immediately bail out of walking any subtrees when we can see that their parents - // are already correct. - const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind); - - return result; - } - - function moveElementEntirelyPastChangeRange(element: IncrementalElement, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { - if (isArray) { - visitArray(element); - } - else { - visitNode(element); - } - return; - - function visitNode(node: IncrementalNode) { - let text = ""; - if (aggressiveChecks && shouldCheckNode(node)) { - text = oldText.substring(node.pos, node.end); - } - - // Ditch any existing LS children we may have created. This way we can avoid - // moving them forward. - if (node._children) { - node._children = undefined; - } - - node.pos += delta; - node.end += delta; - - if (aggressiveChecks && shouldCheckNode(node)) { - Debug.assert(text === newText.substring(node.pos, node.end)); - } - - forEachChild(node, visitNode, visitArray); - if (hasJSDocNodes(node)) { - for (const jsDocComment of node.jsDoc) { - forEachChild(jsDocComment, visitNode, visitArray); - } - } - checkNodePositions(node, aggressiveChecks); - } - - function visitArray(array: IncrementalNodeArray) { - array._children = undefined; - array.pos += delta; - array.end += delta; - - for (const node of array) { - visitNode(node); - } - } - } - - function shouldCheckNode(node: Node) { - switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.Identifier: - return true; - } - - return false; - } - - function adjustIntersectingElement(element: IncrementalElement, changeStart: number, changeRangeOldEnd: number, changeRangeNewEnd: number, delta: number) { - Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range"); - Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range"); - Debug.assert(element.pos <= element.end); - - // We have an element that intersects the change range in some way. It may have its - // start, or its end (or both) in the changed range. We want to adjust any part - // that intersects such that the final tree is in a consistent state. i.e. all - // children have spans within the span of their parent, and all siblings are ordered - // properly. - - // We may need to update both the 'pos' and the 'end' of the element. - - // If the 'pos' is before the start of the change, then we don't need to touch it. - // If it isn't, then the 'pos' must be inside the change. How we update it will - // depend if delta is positive or negative. If delta is positive then we have - // something like: - // - // -------------------AAA----------------- - // -------------------BBBCCCCCCC----------------- - // - // In this case, we consider any node that started in the change range to still be - // starting at the same position. - // - // however, if the delta is negative, then we instead have something like this: - // - // -------------------XXXYYYYYYY----------------- - // -------------------ZZZ----------------- - // - // In this case, any element that started in the 'X' range will keep its position. - // However any element that started after that will have their pos adjusted to be - // at the end of the new range. i.e. any node that started in the 'Y' range will - // be adjusted to have their start at the end of the 'Z' range. - // - // The element will keep its position if possible. Or Move backward to the new-end - // if it's in the 'Y' range. - element.pos = Math.min(element.pos, changeRangeNewEnd); - - // If the 'end' is after the change range, then we always adjust it by the delta - // amount. However, if the end is in the change range, then how we adjust it - // will depend on if delta is positive or negative. If delta is positive then we - // have something like: - // - // -------------------AAA----------------- - // -------------------BBBCCCCCCC----------------- - // - // In this case, we consider any node that ended inside the change range to keep its - // end position. - // - // however, if the delta is negative, then we instead have something like this: - // - // -------------------XXXYYYYYYY----------------- - // -------------------ZZZ----------------- - // - // In this case, any element that ended in the 'X' range will keep its position. - // However any element that ended after that will have their pos adjusted to be - // at the end of the new range. i.e. any node that ended in the 'Y' range will - // be adjusted to have their end at the end of the 'Z' range. - if (element.end >= changeRangeOldEnd) { - // Element ends after the change range. Always adjust the end pos. - element.end += delta; - } - else { - // Element ends in the change range. The element will keep its position if - // possible. Or Move backward to the new-end if it's in the 'Y' range. - element.end = Math.min(element.end, changeRangeNewEnd); - } - - Debug.assert(element.pos <= element.end); - if (element.parent) { - Debug.assert(element.pos >= element.parent.pos); - Debug.assert(element.end <= element.parent.end); - } - } - - function checkNodePositions(node: Node, aggressiveChecks: boolean) { - if (aggressiveChecks) { - let pos = node.pos; - forEachChild(node, child => { - Debug.assert(child.pos >= pos); - pos = child.end; - }); - Debug.assert(pos <= node.end); - } - } - - function updateTokenPositionsAndMarkElements( - sourceFile: IncrementalNode, - changeStart: number, - changeRangeOldEnd: number, - changeRangeNewEnd: number, - delta: number, - oldText: string, - newText: string, - aggressiveChecks: boolean): void { - - visitNode(sourceFile); - return; - - function visitNode(child: IncrementalNode) { - Debug.assert(child.pos <= child.end); - if (child.pos > changeRangeOldEnd) { - // Node is entirely past the change range. We need to move both its pos and - // end, forward or backward appropriately. - moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks); - return; - } - - // Check if the element intersects the change range. If it does, then it is not - // reusable. Also, we'll need to recurse to see what constituent portions we may - // be able to use. - const fullEnd = child.end; - if (fullEnd >= changeStart) { - child.intersectsChange = true; - child._children = undefined; - - // Adjust the pos or end (or both) of the intersecting element accordingly. - adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - forEachChild(child, visitNode, visitArray); - - checkNodePositions(child, aggressiveChecks); - return; - } - - // Otherwise, the node is entirely before the change range. No need to do anything with it. - Debug.assert(fullEnd < changeStart); - } - - function visitArray(array: IncrementalNodeArray) { - Debug.assert(array.pos <= array.end); - if (array.pos > changeRangeOldEnd) { - // Array is entirely after the change range. We need to move it, and move any of - // its children. - moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks); - return; - } - - // Check if the element intersects the change range. If it does, then it is not - // reusable. Also, we'll need to recurse to see what constituent portions we may - // be able to use. - const fullEnd = array.end; - if (fullEnd >= changeStart) { - array.intersectsChange = true; - array._children = undefined; - - // Adjust the pos or end (or both) of the intersecting array accordingly. - adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (const node of array) { - visitNode(node); - } - return; - } - - // Otherwise, the array is entirely before the change range. No need to do anything with it. - Debug.assert(fullEnd < changeStart); - } - } - - function extendToAffectedRange(sourceFile: SourceFile, changeRange: TextChangeRange): TextChangeRange { - // Consider the following code: - // void foo() { /; } - // - // If the text changes with an insertion of / just before the semicolon then we end up with: - // void foo() { //; } - // - // If we were to just use the changeRange a is, then we would not rescan the { token - // (as it does not intersect the actual original change range). Because an edit may - // change the token touching it, we actually need to look back *at least* one token so - // that the prior token sees that change. - const maxLookahead = 1; - - let start = changeRange.span.start; - - // the first iteration aligns us with the change start. subsequent iteration move us to - // the left by maxLookahead tokens. We only need to do this as long as we're not at the - // start of the tree. - for (let i = 0; start > 0 && i <= maxLookahead; i++) { - const nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start); - Debug.assert(nearestNode.pos <= start); - const position = nearestNode.pos; - - start = Math.max(0, position - 1); - } - - const finalSpan = createTextSpanFromBounds(start, textSpanEnd(changeRange.span)); - const finalLength = changeRange.newLength + (changeRange.span.start - start); - - return createTextChangeRange(finalSpan, finalLength); - } - - function findNearestNodeStartingBeforeOrAtPosition(sourceFile: SourceFile, position: number): Node { - let bestResult: Node = sourceFile; - let lastNodeEntirelyBeforePosition: Node; - - forEachChild(sourceFile, visit); - - if (lastNodeEntirelyBeforePosition) { - const lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition); - if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) { - bestResult = lastChildOfLastEntireNodeBeforePosition; - } - } - - return bestResult; - - function getLastChild(node: Node): Node { - while (true) { - const lastChild = getLastChildWorker(node); - if (lastChild) { - node = lastChild; - } - else { - return node; - } - } - } - - function getLastChildWorker(node: Node): Node | undefined { - let last: Node = undefined; - forEachChild(node, child => { - if (nodeIsPresent(child)) { - last = child; - } - }); - return last; - } - - function visit(child: Node) { - if (nodeIsMissing(child)) { - // Missing nodes are effectively invisible to us. We never even consider them - // When trying to find the nearest node before us. - return; - } - - // If the child intersects this position, then this node is currently the nearest - // node that starts before the position. - if (child.pos <= position) { - if (child.pos >= bestResult.pos) { - // This node starts before the position, and is closer to the position than - // the previous best node we found. It is now the new best node. - bestResult = child; - } - - // Now, the node may overlap the position, or it may end entirely before the - // position. If it overlaps with the position, then either it, or one of its - // children must be the nearest node before the position. So we can just - // recurse into this child to see if we can find something better. - if (position < child.end) { - // The nearest node is either this child, or one of the children inside - // of it. We've already marked this child as the best so far. Recurse - // in case one of the children is better. - forEachChild(child, visit); - - // Once we look at the children of this node, then there's no need to - // continue any further. - return true; - } - else { - Debug.assert(child.end <= position); - // The child ends entirely before this position. Say you have the following - // (where $ is the position) - // - // ? $ : <...> <...> - // - // We would want to find the nearest preceding node in "complex expr 2". - // To support that, we keep track of this node, and once we're done searching - // for a best node, we recurse down this node to see if we can find a good - // result in it. - // - // This approach allows us to quickly skip over nodes that are entirely - // before the position, while still allowing us to find any nodes in the - // last one that might be what we want. - lastNodeEntirelyBeforePosition = child; - } - } - else { - Debug.assert(child.pos > position); - // We're now at a node that is entirely past the position we're searching for. - // This node (and all following nodes) could never contribute to the result, - // so just skip them by returning 'true' here. - return true; - } - } - } - - function checkChangeRange(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean) { - const oldText = sourceFile.text; - if (textChangeRange) { - Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length); - - if (aggressiveChecks || Debug.shouldAssert(AssertionLevel.VeryAggressive)) { - const oldTextPrefix = oldText.substr(0, textChangeRange.span.start); - const newTextPrefix = newText.substr(0, textChangeRange.span.start); - Debug.assert(oldTextPrefix === newTextPrefix); - - const oldTextSuffix = oldText.substring(textSpanEnd(textChangeRange.span), oldText.length); - const newTextSuffix = newText.substring(textSpanEnd(textChangeRangeNewSpan(textChangeRange)), newText.length); - Debug.assert(oldTextSuffix === newTextSuffix); - } - } - } - - interface IncrementalElement extends TextRange { - parent?: Node; - intersectsChange: boolean; - length?: number; - _children: Node[]; - } - - export interface IncrementalNode extends Node, IncrementalElement { - hasBeenIncrementallyParsed: boolean; - } - - interface IncrementalNodeArray extends NodeArray, IncrementalElement { - length: number; - } - - // Allows finding nodes in the source file at a certain position in an efficient manner. - // The implementation takes advantage of the calling pattern it knows the parser will - // make in order to optimize finding nodes as quickly as possible. - export interface SyntaxCursor { - currentNode(position: number): IncrementalNode; - } - - function createSyntaxCursor(sourceFile: SourceFile): SyntaxCursor { - let currentArray: NodeArray = sourceFile.statements; - let currentArrayIndex = 0; - - Debug.assert(currentArrayIndex < currentArray.length); - let current = currentArray[currentArrayIndex]; - let lastQueriedPosition = InvalidPosition.Value; - - return { - currentNode(position: number) { - // Only compute the current node if the position is different than the last time - // we were asked. The parser commonly asks for the node at the same position - // twice. Once to know if can read an appropriate list element at a certain point, - // and then to actually read and consume the node. - if (position !== lastQueriedPosition) { - // Much of the time the parser will need the very next node in the array that - // we just returned a node from.So just simply check for that case and move - // forward in the array instead of searching for the node again. - if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) { - currentArrayIndex++; - current = currentArray[currentArrayIndex]; - } - - // If we don't have a node, or the node we have isn't in the right position, - // then try to find a viable node at the position requested. - if (!current || current.pos !== position) { - findHighestListElementThatStartsAtPosition(position); - } - } - - // Cache this query so that we don't do any extra work if the parser calls back - // into us. Note: this is very common as the parser will make pairs of calls like - // 'isListElement -> parseListElement'. If we were unable to find a node when - // called with 'isListElement', we don't want to redo the work when parseListElement - // is called immediately after. - lastQueriedPosition = position; - - // Either we don'd have a node, or we have a node at the position being asked for. - Debug.assert(!current || current.pos === position); - return current; - } - }; - - // Finds the highest element in the tree we can find that starts at the provided position. - // The element must be a direct child of some node list in the tree. This way after we - // return it, we can easily return its next sibling in the list. - function findHighestListElementThatStartsAtPosition(position: number) { - // Clear out any cached state about the last node we found. - currentArray = undefined; - currentArrayIndex = InvalidPosition.Value; - current = undefined; - - // Recurse into the source file to find the highest node at this position. - forEachChild(sourceFile, visitNode, visitArray); - return; - - function visitNode(node: Node) { - if (position >= node.pos && position < node.end) { - // Position was within this node. Keep searching deeper to find the node. - forEachChild(node, visitNode, visitArray); - - // don't proceed any further in the search. - return true; - } - - // position wasn't in this node, have to keep searching. - return false; - } - - function visitArray(array: NodeArray) { - if (position >= array.pos && position < array.end) { - // position was in this array. Search through this array to see if we find a - // viable element. - for (let i = 0; i < array.length; i++) { - const child = array[i]; - if (child) { - if (child.pos === position) { - // Found the right node. We're done. - currentArray = array; - currentArrayIndex = i; - current = child; - return true; - } - else { - if (child.pos < position && position < child.end) { - // Position in somewhere within this child. Search in it and - // stop searching in this array. - forEachChild(child, visitNode, visitArray); - return true; - } - } - } - } - } - - // position wasn't in this array, have to keep searching. - return false; - } - } - } - - const enum InvalidPosition { - Value = -1 - } - } - - function isDeclarationFileName(fileName: string): boolean { - return fileExtensionIs(fileName, Extension.Dts); - } -} diff --git a/vendored_parsers/tree-sitter-typescript/package.json b/vendored_parsers/tree-sitter-typescript/package.json deleted file mode 100644 index 5b279cf01..000000000 --- a/vendored_parsers/tree-sitter-typescript/package.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "tree-sitter-typescript", - "version": "0.20.5", - "description": "TypeScript grammar for tree-sitter", - "main": "./bindings/node", - "keywords": [ - "parser", - "tree-sitter", - "typescript", - "tsx" - ], - "repository": { - "type": "git", - "url": "https://github.com/tree-sitter/tree-sitter-typescript.git" - }, - "author": "Max Brunsfeld", - "license": "MIT", - "dependencies": { - "nan": "^2.18.0", - "tree-sitter": "^0.20.6" - }, - "devDependencies": { - "eslint": ">=8.56.0", - "eslint-config-google": "^0.14.0", - "tree-sitter-cli": "^0.20.8", - "tree-sitter-javascript": "^0.20.3" - }, - "scripts": { - "build": "npm run build-typescript && npm run build-tsx", - "build-typescript": "cd typescript && npx tree-sitter generate --no-bindings", - "build-tsx": "cd tsx && npx tree-sitter generate --no-bindings", - "lint": "eslint common/define-grammar.js", - "test-load": "node -e \"console.log(require('./typescript').name, require('./tsx').name)\"", - "test": "npm run test-typescript && npm run test-tsx && npm run test-load && script/parse-examples", - "test-typescript": "cd typescript && npx tree-sitter test", - "test-tsx": "cd tsx && npx tree-sitter test", - "test-windows": "pushd typescript && npx tree-sitter test && popd && pushd tsx && npx tree-sitter test" - }, - "tree-sitter": [ - { - "scope": "source.ts", - "file-types": [ - "ts" - ], - "path": "typescript", - "highlights": [ - "queries/highlights.scm", - "node_modules/tree-sitter-javascript/queries/highlights.scm" - ], - "locals": [ - "queries/locals.scm", - "node_modules/tree-sitter-javascript/queries/locals.scm" - ], - "tags": [ - "queries/tags.scm", - "node_modules/tree-sitter-javascript/queries/tags.scm" - ], - "injections": "node_modules/tree-sitter-javascript/queries/injections.scm", - "injection-regex": "^(ts|typescript)$" - }, - { - "scope": "source.tsx", - "file-types": [ - "tsx" - ], - "path": "tsx", - "highlights": [ - "queries/highlights.scm", - "node_modules/tree-sitter-javascript/queries/highlights-jsx.scm", - "node_modules/tree-sitter-javascript/queries/highlights.scm" - ], - "locals": "node_modules/tree-sitter-javascript/queries/locals.scm", - "tags": [ - "queries/tags.scm", - "node_modules/tree-sitter-javascript/queries/tags.scm" - ], - "injections": "node_modules/tree-sitter-javascript/queries/injections.scm", - "injection-regex": "^(ts|typescript)$" - }, - { - "scope": "source.js.flow", - "file-types": [ - "js" - ], - "path": "tsx", - "highlights": [ - "queries/highlights.scm", - "node_modules/tree-sitter-javascript/queries/highlights-jsx.scm", - "node_modules/tree-sitter-javascript/queries/highlights.scm" - ], - "locals": "node_modules/tree-sitter-javascript/queries/locals.scm", - "tags": [ - "queries/tags.scm", - "node_modules/tree-sitter-javascript/queries/tags.scm" - ], - "injections": "node_modules/tree-sitter-javascript/queries/injections.scm", - "content-regex": "@flow" - } - ] -} diff --git a/vendored_parsers/tree-sitter-typescript/queries/highlights.scm b/vendored_parsers/tree-sitter-typescript/queries/highlights.scm deleted file mode 100644 index c758b516b..000000000 --- a/vendored_parsers/tree-sitter-typescript/queries/highlights.scm +++ /dev/null @@ -1,35 +0,0 @@ -; Types - -(type_identifier) @type -(predefined_type) @type.builtin - -((identifier) @type - (#match? @type "^[A-Z]")) - -(type_arguments - "<" @punctuation.bracket - ">" @punctuation.bracket) - -; Variables - -(required_parameter (identifier) @variable.parameter) -(optional_parameter (identifier) @variable.parameter) - -; Keywords - -[ "abstract" - "declare" - "enum" - "export" - "implements" - "interface" - "keyof" - "namespace" - "private" - "protected" - "public" - "type" - "readonly" - "override" - "satisfies" -] @keyword diff --git a/vendored_parsers/tree-sitter-typescript/queries/locals.scm b/vendored_parsers/tree-sitter-typescript/queries/locals.scm deleted file mode 100644 index aa6d6ffdb..000000000 --- a/vendored_parsers/tree-sitter-typescript/queries/locals.scm +++ /dev/null @@ -1,2 +0,0 @@ -(required_parameter (identifier) @local.definition) -(optional_parameter (identifier) @local.definition) diff --git a/vendored_parsers/tree-sitter-typescript/queries/tags.scm b/vendored_parsers/tree-sitter-typescript/queries/tags.scm deleted file mode 100644 index ccae934e7..000000000 --- a/vendored_parsers/tree-sitter-typescript/queries/tags.scm +++ /dev/null @@ -1,23 +0,0 @@ -(function_signature - name: (identifier) @name) @definition.function - -(method_signature - name: (property_identifier) @name) @definition.method - -(abstract_method_signature - name: (property_identifier) @name) @definition.method - -(abstract_class_declaration - name: (type_identifier) @name) @definition.class - -(module - name: (identifier) @name) @definition.module - -(interface_declaration - name: (type_identifier) @name) @definition.interface - -(type_annotation - (type_identifier) @name) @reference.type - -(new_expression - constructor: (identifier) @name) @reference.class diff --git a/vendored_parsers/tree-sitter-typescript/script/check-generated-files b/vendored_parsers/tree-sitter-typescript/script/check-generated-files deleted file mode 100755 index c1f216dde..000000000 --- a/vendored_parsers/tree-sitter-typescript/script/check-generated-files +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -set -eu - -## Update index to make sure the subsequent diff-index command only reports -## a change if the file content actually changed. Not updating the index can -## give incorrect results when this script is run right after a build. - -git update-index -q --really-refresh - -if ! git diff-index --exit-code --name-status HEAD -- {tsx,typescript}/src/; then - echo "The following files are not up to date in the repository:" 1>&2 - git diff-index --name-status HEAD 1>&2 - echo "Run a build and commit the generated files to resolve this issue." 1>&2 - git diff-index -p HEAD - exit 1 -fi - -exit 0 diff --git a/vendored_parsers/tree-sitter-typescript/script/known-failures.txt b/vendored_parsers/tree-sitter-typescript/script/known-failures.txt deleted file mode 100644 index 63c51c8dd..000000000 --- a/vendored_parsers/tree-sitter-typescript/script/known-failures.txt +++ /dev/null @@ -1 +0,0 @@ -examples/redux/src/types/store.ts diff --git a/vendored_parsers/tree-sitter-typescript/script/parse-examples b/vendored_parsers/tree-sitter-typescript/script/parse-examples deleted file mode 100755 index 68df23973..000000000 --- a/vendored_parsers/tree-sitter-typescript/script/parse-examples +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -set -e - -cd "$(dirname "$0")/.." -root="$PWD" - -clone_repo() { - local owner=$1 - local name=$2 - local sha=$3 - local path="$root/examples/$name" - - if [ -d "$path" ]; then - pushd "$path" >/dev/null - if [ "$(git rev-parse HEAD 2>/dev/null)" == "$sha" ]; then - popd >/dev/null - return - else - popd >/dev/null - rm -rf "$path" - echo "Updating $owner/$name to $sha" - fi - else - echo "Cloning $owner/$name" - fi - - mkdir -p "$path" - pushd "$path" >/dev/null - git init - git remote add origin "https://github.com/$owner/$name" - git pull --ff-only --depth 1 origin "$sha" - popd >/dev/null -} - -clone_repo desktop desktop 7c5111425cab9de911f82dd7e42f92d8f7927bb1 -clone_repo reduxjs redux 936e134b827a2f8022d51f6a42942e935ee2a935 -clone_repo microsoft vscode 4acf2d9fd883d247b903cc9c33221e18e39bffd8 - -known_failures="$(cat script/known-failures.txt)" - -# shellcheck disable=SC2046 -tree-sitter parse -q \ - 'examples/**/*.ts' \ - 'examples/**/*.tsx' \ - $(for failure in $known_failures; do echo "!${failure}"; done) - -example_count=$(find examples -name '*.ts*' -or -name '*.tx' | wc -l) -failure_count=$(wc -w <<<"$known_failures") -success_count=$((example_count - failure_count)) -success_percent=$(bc -l <<<"100*${success_count}/${example_count}") - -printf \ - "Successfully parsed %d of %d example files (%.1f%%)\n" \ - "$success_count" "$example_count" "$success_percent" diff --git a/vendored_parsers/tree-sitter-typescript/tsx/corpus/common b/vendored_parsers/tree-sitter-typescript/tsx/corpus/common deleted file mode 120000 index 3889fcd72..000000000 --- a/vendored_parsers/tree-sitter-typescript/tsx/corpus/common +++ /dev/null @@ -1 +0,0 @@ -../../common/corpus \ No newline at end of file diff --git a/vendored_parsers/tree-sitter-typescript/tsx/corpus/expressions.txt b/vendored_parsers/tree-sitter-typescript/tsx/corpus/expressions.txt deleted file mode 100644 index db87b514c..000000000 --- a/vendored_parsers/tree-sitter-typescript/tsx/corpus/expressions.txt +++ /dev/null @@ -1,25 +0,0 @@ -========================================================== -Type arguments in JSX -========================================================== - ->hi; - />; -<>fragment; - ---- - -(program - (expression_statement - (jsx_element - (jsx_opening_element (identifier) (type_arguments (type_identifier))) - (jsx_text) - (jsx_closing_element (identifier)))) - (expression_statement - (jsx_self_closing_element - (identifier) (type_arguments (type_identifier)))) - (expression_statement - (jsx_element - (jsx_opening_element) - (jsx_text) - (jsx_closing_element))) -) diff --git a/vendored_parsers/tree-sitter-typescript/tsx/grammar.js b/vendored_parsers/tree-sitter-typescript/tsx/grammar.js deleted file mode 100644 index e31c3c6de..000000000 --- a/vendored_parsers/tree-sitter-typescript/tsx/grammar.js +++ /dev/null @@ -1,3 +0,0 @@ -const defineGrammar = require('../common/define-grammar'); - -module.exports = defineGrammar('tsx'); diff --git a/vendored_parsers/tree-sitter-typescript/tsx/package.json b/vendored_parsers/tree-sitter-typescript/tsx/package.json deleted file mode 100644 index 0ed56917f..000000000 --- a/vendored_parsers/tree-sitter-typescript/tsx/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "main": "../bindings/node/tsx" -} diff --git a/vendored_parsers/tree-sitter-typescript/tsx/src/grammar.json b/vendored_parsers/tree-sitter-typescript/tsx/src/grammar.json deleted file mode 100644 index f9cb660a0..000000000 --- a/vendored_parsers/tree-sitter-typescript/tsx/src/grammar.json +++ /dev/null @@ -1,11864 +0,0 @@ -{ - "name": "tsx", - "word": "identifier", - "rules": { - "program": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "hash_bang_line" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - ] - }, - "hash_bang_line": { - "type": "PATTERN", - "value": "#!.*" - }, - "export_statement": { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "export" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "*" - }, - { - "type": "SYMBOL", - "name": "_from_clause" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "namespace_export" - }, - { - "type": "SYMBOL", - "name": "_from_clause" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "export_clause" - }, - { - "type": "SYMBOL", - "name": "_from_clause" - } - ] - }, - { - "type": "SYMBOL", - "name": "export_clause" - } - ] - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "STRING", - "value": "export" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "declaration", - "content": { - "type": "SYMBOL", - "name": "declaration" - } - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "default" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "declaration", - "content": { - "type": "SYMBOL", - "name": "declaration" - } - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "value", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "export" - }, - { - "type": "STRING", - "value": "type" - }, - { - "type": "SYMBOL", - "name": "export_clause" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_from_clause" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "export" - }, - { - "type": "STRING", - "value": "=" - }, - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "export" - }, - { - "type": "STRING", - "value": "as" - }, - { - "type": "STRING", - "value": "namespace" - }, - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - } - ] - }, - "namespace_export": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "*" - }, - { - "type": "STRING", - "value": "as" - }, - { - "type": "SYMBOL", - "name": "_module_export_name" - } - ] - }, - "export_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "export_specifier" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "export_specifier" - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "export_specifier": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "type" - }, - { - "type": "STRING", - "value": "typeof" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_module_export_name" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "as" - }, - { - "type": "FIELD", - "name": "alias", - "content": { - "type": "SYMBOL", - "name": "_module_export_name" - } - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - }, - "_module_export_name": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "string" - } - ] - }, - "declaration": { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "function_declaration" - }, - { - "type": "SYMBOL", - "name": "generator_function_declaration" - }, - { - "type": "SYMBOL", - "name": "class_declaration" - }, - { - "type": "SYMBOL", - "name": "lexical_declaration" - }, - { - "type": "SYMBOL", - "name": "variable_declaration" - } - ] - }, - { - "type": "SYMBOL", - "name": "function_signature" - }, - { - "type": "SYMBOL", - "name": "abstract_class_declaration" - }, - { - "type": "SYMBOL", - "name": "module" - }, - { - "type": "PREC", - "value": "declaration", - "content": { - "type": "SYMBOL", - "name": "internal_module" - } - }, - { - "type": "SYMBOL", - "name": "type_alias_declaration" - }, - { - "type": "SYMBOL", - "name": "enum_declaration" - }, - { - "type": "SYMBOL", - "name": "interface_declaration" - }, - { - "type": "SYMBOL", - "name": "import_alias" - }, - { - "type": "SYMBOL", - "name": "ambient_declaration" - } - ] - }, - "import": { - "type": "TOKEN", - "content": { - "type": "STRING", - "value": "import" - } - }, - "import_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "import" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "type" - }, - { - "type": "STRING", - "value": "typeof" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "import_clause" - }, - { - "type": "SYMBOL", - "name": "_from_clause" - } - ] - }, - { - "type": "SYMBOL", - "name": "import_require_clause" - }, - { - "type": "FIELD", - "name": "source", - "content": { - "type": "SYMBOL", - "name": "string" - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "import_attribute" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "import_clause": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "namespace_import" - }, - { - "type": "SYMBOL", - "name": "named_imports" - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_import_identifier" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "namespace_import" - }, - { - "type": "SYMBOL", - "name": "named_imports" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - }, - "_from_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "from" - }, - { - "type": "FIELD", - "name": "source", - "content": { - "type": "SYMBOL", - "name": "string" - } - } - ] - }, - "namespace_import": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "*" - }, - { - "type": "STRING", - "value": "as" - }, - { - "type": "SYMBOL", - "name": "identifier" - } - ] - }, - "named_imports": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "import_specifier" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "import_specifier" - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "import_specifier": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "type" - }, - { - "type": "STRING", - "value": "typeof" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_import_identifier" - } - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_module_export_name" - }, - { - "type": "ALIAS", - "content": { - "type": "STRING", - "value": "type" - }, - "named": true, - "value": "identifier" - } - ] - } - }, - { - "type": "STRING", - "value": "as" - }, - { - "type": "FIELD", - "name": "alias", - "content": { - "type": "SYMBOL", - "name": "_import_identifier" - } - } - ] - } - ] - } - ] - }, - "import_attribute": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "with" - }, - { - "type": "SYMBOL", - "name": "object" - } - ] - }, - "statement": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "export_statement" - }, - { - "type": "SYMBOL", - "name": "import_statement" - }, - { - "type": "SYMBOL", - "name": "debugger_statement" - }, - { - "type": "SYMBOL", - "name": "expression_statement" - }, - { - "type": "SYMBOL", - "name": "declaration" - }, - { - "type": "SYMBOL", - "name": "statement_block" - }, - { - "type": "SYMBOL", - "name": "if_statement" - }, - { - "type": "SYMBOL", - "name": "switch_statement" - }, - { - "type": "SYMBOL", - "name": "for_statement" - }, - { - "type": "SYMBOL", - "name": "for_in_statement" - }, - { - "type": "SYMBOL", - "name": "while_statement" - }, - { - "type": "SYMBOL", - "name": "do_statement" - }, - { - "type": "SYMBOL", - "name": "try_statement" - }, - { - "type": "SYMBOL", - "name": "with_statement" - }, - { - "type": "SYMBOL", - "name": "break_statement" - }, - { - "type": "SYMBOL", - "name": "continue_statement" - }, - { - "type": "SYMBOL", - "name": "return_statement" - }, - { - "type": "SYMBOL", - "name": "throw_statement" - }, - { - "type": "SYMBOL", - "name": "empty_statement" - }, - { - "type": "SYMBOL", - "name": "labeled_statement" - } - ] - }, - "expression_statement": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_expressions" - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "variable_declaration": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "var" - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "variable_declarator" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "variable_declarator" - } - ] - } - } - ] - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "lexical_declaration": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "kind", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "let" - }, - { - "type": "STRING", - "value": "const" - } - ] - } - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "variable_declarator" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "variable_declarator" - } - ] - } - } - ] - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "variable_declarator": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_destructuring_pattern" - } - ] - } - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_initializer" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "PREC", - "value": "declaration", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "identifier" - } - }, - { - "type": "STRING", - "value": "!" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "SYMBOL", - "name": "type_annotation" - } - } - ] - } - } - ] - }, - "statement_block": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "statement" - } - }, - { - "type": "STRING", - "value": "}" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_automatic_semicolon" - }, - { - "type": "BLANK" - } - ] - } - ] - } - }, - "else_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "else" - }, - { - "type": "SYMBOL", - "name": "statement" - } - ] - }, - "if_statement": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "if" - }, - { - "type": "FIELD", - "name": "condition", - "content": { - "type": "SYMBOL", - "name": "parenthesized_expression" - } - }, - { - "type": "FIELD", - "name": "consequence", - "content": { - "type": "SYMBOL", - "name": "statement" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "alternative", - "content": { - "type": "SYMBOL", - "name": "else_clause" - } - }, - { - "type": "BLANK" - } - ] - } - ] - } - }, - "switch_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "switch" - }, - { - "type": "FIELD", - "name": "value", - "content": { - "type": "SYMBOL", - "name": "parenthesized_expression" - } - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "switch_body" - } - } - ] - }, - "for_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "for" - }, - { - "type": "STRING", - "value": "(" - }, - { - "type": "FIELD", - "name": "initializer", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "lexical_declaration" - }, - { - "type": "SYMBOL", - "name": "variable_declaration" - }, - { - "type": "SYMBOL", - "name": "expression_statement" - }, - { - "type": "SYMBOL", - "name": "empty_statement" - } - ] - } - }, - { - "type": "FIELD", - "name": "condition", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression_statement" - }, - { - "type": "SYMBOL", - "name": "empty_statement" - } - ] - } - }, - { - "type": "FIELD", - "name": "increment", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_expressions" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "STRING", - "value": ")" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - ] - }, - "for_in_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "for" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "await" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_for_header" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - ] - }, - "_for_header": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "(" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_lhs_expression" - }, - { - "type": "SYMBOL", - "name": "parenthesized_expression" - } - ] - } - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "kind", - "content": { - "type": "STRING", - "value": "var" - } - }, - { - "type": "FIELD", - "name": "left", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_destructuring_pattern" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_initializer" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "kind", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "let" - }, - { - "type": "STRING", - "value": "const" - } - ] - } - }, - { - "type": "FIELD", - "name": "left", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_destructuring_pattern" - } - ] - } - } - ] - } - ] - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "in" - }, - { - "type": "STRING", - "value": "of" - } - ] - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "_expressions" - } - }, - { - "type": "STRING", - "value": ")" - } - ] - }, - "while_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "while" - }, - { - "type": "FIELD", - "name": "condition", - "content": { - "type": "SYMBOL", - "name": "parenthesized_expression" - } - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - ] - }, - "do_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "do" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement" - } - }, - { - "type": "STRING", - "value": "while" - }, - { - "type": "FIELD", - "name": "condition", - "content": { - "type": "SYMBOL", - "name": "parenthesized_expression" - } - } - ] - }, - "try_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "try" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "handler", - "content": { - "type": "SYMBOL", - "name": "catch_clause" - } - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "finalizer", - "content": { - "type": "SYMBOL", - "name": "finally_clause" - } - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "with_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "with" - }, - { - "type": "FIELD", - "name": "object", - "content": { - "type": "SYMBOL", - "name": "parenthesized_expression" - } - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - ] - }, - "break_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "break" - }, - { - "type": "FIELD", - "name": "label", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "statement_identifier" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "continue_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "continue" - }, - { - "type": "FIELD", - "name": "label", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "statement_identifier" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "debugger_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "debugger" - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "return_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "return" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_expressions" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "throw_statement": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "throw" - }, - { - "type": "SYMBOL", - "name": "_expressions" - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "empty_statement": { - "type": "STRING", - "value": ";" - }, - "labeled_statement": { - "type": "PREC_DYNAMIC", - "value": -1, - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "label", - "content": { - "type": "ALIAS", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_reserved_identifier" - } - ] - }, - "named": true, - "value": "statement_identifier" - } - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - ] - } - }, - "switch_body": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "switch_case" - }, - { - "type": "SYMBOL", - "name": "switch_default" - } - ] - } - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "switch_case": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "case" - }, - { - "type": "FIELD", - "name": "value", - "content": { - "type": "SYMBOL", - "name": "_expressions" - } - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - } - ] - }, - "switch_default": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "default" - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "statement" - } - } - } - ] - }, - "catch_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "catch" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "(" - }, - { - "type": "FIELD", - "name": "parameter", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_destructuring_pattern" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "type", - "content": { - "type": "SYMBOL", - "name": "type_annotation" - } - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": ")" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - } - ] - }, - "finally_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "finally" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - } - ] - }, - "parenthesized_expression": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "(" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "BLANK" - } - ] - } - } - ] - }, - { - "type": "SYMBOL", - "name": "sequence_expression" - } - ] - }, - { - "type": "STRING", - "value": ")" - } - ] - }, - "_expressions": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "sequence_expression" - } - ] - }, - "expression": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "as_expression" - }, - { - "type": "SYMBOL", - "name": "satisfies_expression" - }, - { - "type": "SYMBOL", - "name": "instantiation_expression" - }, - { - "type": "SYMBOL", - "name": "internal_module" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - }, - { - "type": "SYMBOL", - "name": "glimmer_template" - }, - { - "type": "SYMBOL", - "name": "_jsx_element" - }, - { - "type": "SYMBOL", - "name": "assignment_expression" - }, - { - "type": "SYMBOL", - "name": "augmented_assignment_expression" - }, - { - "type": "SYMBOL", - "name": "await_expression" - }, - { - "type": "SYMBOL", - "name": "unary_expression" - }, - { - "type": "SYMBOL", - "name": "binary_expression" - }, - { - "type": "SYMBOL", - "name": "ternary_expression" - }, - { - "type": "SYMBOL", - "name": "update_expression" - }, - { - "type": "SYMBOL", - "name": "new_expression" - }, - { - "type": "SYMBOL", - "name": "yield_expression" - } - ] - }, - "primary_expression": { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "subscript_expression" - }, - { - "type": "SYMBOL", - "name": "member_expression" - }, - { - "type": "SYMBOL", - "name": "parenthesized_expression" - }, - { - "type": "SYMBOL", - "name": "_identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_reserved_identifier" - }, - "named": true, - "value": "identifier" - }, - { - "type": "SYMBOL", - "name": "this" - }, - { - "type": "SYMBOL", - "name": "super" - }, - { - "type": "SYMBOL", - "name": "number" - }, - { - "type": "SYMBOL", - "name": "string" - }, - { - "type": "SYMBOL", - "name": "template_string" - }, - { - "type": "SYMBOL", - "name": "regex" - }, - { - "type": "SYMBOL", - "name": "true" - }, - { - "type": "SYMBOL", - "name": "false" - }, - { - "type": "SYMBOL", - "name": "null" - }, - { - "type": "SYMBOL", - "name": "object" - }, - { - "type": "SYMBOL", - "name": "array" - }, - { - "type": "SYMBOL", - "name": "function_expression" - }, - { - "type": "SYMBOL", - "name": "arrow_function" - }, - { - "type": "SYMBOL", - "name": "generator_function" - }, - { - "type": "SYMBOL", - "name": "class" - }, - { - "type": "SYMBOL", - "name": "meta_property" - }, - { - "type": "SYMBOL", - "name": "call_expression" - } - ] - }, - { - "type": "SYMBOL", - "name": "non_null_expression" - } - ] - }, - "yield_expression": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "yield" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "*" - }, - { - "type": "SYMBOL", - "name": "expression" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - } - }, - "object": { - "type": "PREC", - "value": "object", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pair" - }, - { - "type": "SYMBOL", - "name": "spread_element" - }, - { - "type": "SYMBOL", - "name": "method_definition" - }, - { - "type": "ALIAS", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_reserved_identifier" - } - ] - }, - "named": true, - "value": "shorthand_property_identifier" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pair" - }, - { - "type": "SYMBOL", - "name": "spread_element" - }, - { - "type": "SYMBOL", - "name": "method_definition" - }, - { - "type": "ALIAS", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_reserved_identifier" - } - ] - }, - "named": true, - "value": "shorthand_property_identifier" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "}" - } - ] - } - }, - "object_pattern": { - "type": "PREC", - "value": "object", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pair_pattern" - }, - { - "type": "SYMBOL", - "name": "rest_pattern" - }, - { - "type": "SYMBOL", - "name": "object_assignment_pattern" - }, - { - "type": "ALIAS", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_reserved_identifier" - } - ] - }, - "named": true, - "value": "shorthand_property_identifier_pattern" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pair_pattern" - }, - { - "type": "SYMBOL", - "name": "rest_pattern" - }, - { - "type": "SYMBOL", - "name": "object_assignment_pattern" - }, - { - "type": "ALIAS", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_reserved_identifier" - } - ] - }, - "named": true, - "value": "shorthand_property_identifier_pattern" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "}" - } - ] - } - }, - "assignment_pattern": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "pattern" - } - }, - { - "type": "STRING", - "value": "=" - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - }, - "object_assignment_pattern": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_reserved_identifier" - }, - { - "type": "SYMBOL", - "name": "identifier" - } - ] - }, - "named": true, - "value": "shorthand_property_identifier_pattern" - }, - { - "type": "SYMBOL", - "name": "_destructuring_pattern" - } - ] - } - }, - { - "type": "STRING", - "value": "=" - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - }, - "array": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "[" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "spread_element" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "spread_element" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - "array_pattern": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "[" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pattern" - }, - { - "type": "SYMBOL", - "name": "assignment_pattern" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pattern" - }, - { - "type": "SYMBOL", - "name": "assignment_pattern" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - "glimmer_template": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "open_tag", - "content": { - "type": "SYMBOL", - "name": "glimmer_opening_tag" - } - }, - { - "type": "FIELD", - "name": "content", - "content": { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "_glimmer_template_content" - } - } - }, - { - "type": "FIELD", - "name": "close_tag", - "content": { - "type": "SYMBOL", - "name": "glimmer_closing_tag" - } - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "open_tag", - "content": { - "type": "SYMBOL", - "name": "glimmer_opening_tag" - } - }, - { - "type": "FIELD", - "name": "close_tag", - "content": { - "type": "SYMBOL", - "name": "glimmer_closing_tag" - } - } - ] - } - ] - }, - "_glimmer_template_content": { - "type": "PATTERN", - "value": ".{1,}" - }, - "glimmer_opening_tag": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "" - } - ] - }, - "_jsx_element": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "jsx_element" - }, - { - "type": "SYMBOL", - "name": "jsx_self_closing_element" - } - ] - }, - "jsx_element": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "open_tag", - "content": { - "type": "SYMBOL", - "name": "jsx_opening_element" - } - }, - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "_jsx_child" - } - }, - { - "type": "FIELD", - "name": "close_tag", - "content": { - "type": "SYMBOL", - "name": "jsx_closing_element" - } - } - ] - }, - "jsx_text": { - "type": "CHOICE", - "members": [ - { - "type": "PATTERN", - "value": "[^{}<>\\n& ]([^{}<>\\n&]*[^{}<>\\n& ])?" - }, - { - "type": "PATTERN", - "value": "\\/\\/[^\\n]*" - } - ] - }, - "html_character_reference": { - "type": "PATTERN", - "value": "&(#([xX][0-9a-fA-F]{1,6}|[0-9]{1,5})|[A-Za-z]{1,30});" - }, - "jsx_expression": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "sequence_expression" - }, - { - "type": "SYMBOL", - "name": "spread_element" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "_jsx_child": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "jsx_text" - }, - { - "type": "SYMBOL", - "name": "html_character_reference" - }, - { - "type": "SYMBOL", - "name": "_jsx_element" - }, - { - "type": "SYMBOL", - "name": "jsx_expression" - } - ] - }, - "jsx_opening_element": { - "type": "PREC_DYNAMIC", - "value": -1, - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_jsx_start_opening_element" - }, - { - "type": "STRING", - "value": ">" - } - ] - } - }, - "jsx_identifier": { - "type": "PATTERN", - "value": "[a-zA-Z_$][a-zA-Z\\d_$]*-[a-zA-Z\\d_$\\-]*" - }, - "_jsx_identifier": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "jsx_identifier" - }, - "named": true, - "value": "identifier" - }, - { - "type": "SYMBOL", - "name": "identifier" - } - ] - }, - "nested_identifier": { - "type": "PREC", - "value": "member", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "object", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "nested_identifier" - }, - "named": true, - "value": "member_expression" - } - ] - } - }, - { - "type": "STRING", - "value": "." - }, - { - "type": "FIELD", - "name": "property", - "content": { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "property_identifier" - } - } - ] - } - }, - "jsx_namespace_name": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_jsx_identifier" - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "SYMBOL", - "name": "_jsx_identifier" - } - ] - }, - "_jsx_element_name": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_jsx_identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "nested_identifier" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "SYMBOL", - "name": "jsx_namespace_name" - } - ] - }, - "jsx_closing_element": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "" - } - ] - }, - "jsx_self_closing_element": { - "type": "PREC_DYNAMIC", - "value": -1, - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_jsx_start_opening_element" - }, - { - "type": "STRING", - "value": "/>" - } - ] - } - }, - "_jsx_attribute": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "jsx_attribute" - }, - { - "type": "SYMBOL", - "name": "jsx_expression" - } - ] - }, - "_jsx_attribute_name": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_jsx_identifier" - }, - "named": true, - "value": "property_identifier" - }, - { - "type": "SYMBOL", - "name": "jsx_namespace_name" - } - ] - }, - "jsx_attribute": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_jsx_attribute_name" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "=" - }, - { - "type": "SYMBOL", - "name": "_jsx_attribute_value" - } - ] - }, - { - "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": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_jsx_string" - }, - "named": true, - "value": "string" - }, - { - "type": "SYMBOL", - "name": "jsx_expression" - }, - { - "type": "SYMBOL", - "name": "_jsx_element" - } - ] - }, - "class": { - "type": "PREC", - "value": "literal", - "content": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "STRING", - "value": "class" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type_identifier" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "class_heritage" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "class_body" - } - } - ] - } - }, - "class_declaration": { - "type": "PREC_LEFT", - "value": "declaration", - "content": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "STRING", - "value": "class" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_type_identifier" - } - }, - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "class_heritage" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "class_body" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_automatic_semicolon" - }, - { - "type": "BLANK" - } - ] - } - ] - } - }, - "class_heritage": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "extends_clause" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "implements_clause" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SYMBOL", - "name": "implements_clause" - } - ] - }, - "function_expression": { - "type": "PREC", - "value": "literal", - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "function" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "_call_signature" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - } - ] - } - }, - "function_declaration": { - "type": "PREC_RIGHT", - "value": "declaration", - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "function" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "identifier" - } - }, - { - "type": "SYMBOL", - "name": "_call_signature" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_automatic_semicolon" - }, - { - "type": "BLANK" - } - ] - } - ] - } - }, - "generator_function": { - "type": "PREC", - "value": "literal", - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "function" - }, - { - "type": "STRING", - "value": "*" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "_call_signature" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - } - ] - } - }, - "generator_function_declaration": { - "type": "PREC_RIGHT", - "value": "declaration", - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "function" - }, - { - "type": "STRING", - "value": "*" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "identifier" - } - }, - { - "type": "SYMBOL", - "name": "_call_signature" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_automatic_semicolon" - }, - { - "type": "BLANK" - } - ] - } - ] - } - }, - "arrow_function": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "parameter", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_reserved_identifier" - }, - "named": true, - "value": "identifier" - }, - { - "type": "SYMBOL", - "name": "identifier" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "_call_signature" - } - ] - }, - { - "type": "STRING", - "value": "=>" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "statement_block" - } - ] - } - } - ] - }, - "_call_signature": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "parameters", - "content": { - "type": "SYMBOL", - "name": "formal_parameters" - } - }, - { - "type": "FIELD", - "name": "return_type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "SYMBOL", - "name": "asserts_annotation" - }, - { - "type": "SYMBOL", - "name": "type_predicate_annotation" - } - ] - }, - { - "type": "BLANK" - } - ] - } - } - ] - }, - "_formal_parameter": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "required_parameter" - }, - { - "type": "SYMBOL", - "name": "optional_parameter" - } - ] - }, - "optional_chain": { - "type": "STRING", - "value": "?." - }, - "call_expression": { - "type": "CHOICE", - "members": [ - { - "type": "PREC", - "value": "call", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "function", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "import" - } - ] - } - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_arguments" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "arguments", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "arguments" - }, - { - "type": "SYMBOL", - "name": "template_string" - } - ] - } - } - ] - } - }, - { - "type": "PREC", - "value": "member", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "function", - "content": { - "type": "SYMBOL", - "name": "primary_expression" - } - }, - { - "type": "STRING", - "value": "?." - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_arguments" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "arguments", - "content": { - "type": "SYMBOL", - "name": "arguments" - } - } - ] - } - } - ] - }, - "new_expression": { - "type": "PREC_RIGHT", - "value": "new", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "new" - }, - { - "type": "FIELD", - "name": "constructor", - "content": { - "type": "SYMBOL", - "name": "primary_expression" - } - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_arguments" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "arguments", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "arguments" - }, - { - "type": "BLANK" - } - ] - } - } - ] - } - }, - "await_expression": { - "type": "PREC", - "value": "unary_void", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "await" - }, - { - "type": "SYMBOL", - "name": "expression" - } - ] - } - }, - "member_expression": { - "type": "PREC", - "value": "member", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "object", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - }, - { - "type": "SYMBOL", - "name": "import" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "." - }, - { - "type": "FIELD", - "name": "optional_chain", - "content": { - "type": "SYMBOL", - "name": "optional_chain" - } - } - ] - }, - { - "type": "FIELD", - "name": "property", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "private_property_identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "property_identifier" - } - ] - } - } - ] - } - }, - "subscript_expression": { - "type": "PREC_RIGHT", - "value": "member", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "object", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "optional_chain", - "content": { - "type": "SYMBOL", - "name": "optional_chain" - } - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "[" - }, - { - "type": "FIELD", - "name": "index", - "content": { - "type": "SYMBOL", - "name": "_expressions" - } - }, - { - "type": "STRING", - "value": "]" - } - ] - } - }, - "_lhs_expression": { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "member_expression" - }, - { - "type": "SYMBOL", - "name": "subscript_expression" - }, - { - "type": "SYMBOL", - "name": "_identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_reserved_identifier" - }, - "named": true, - "value": "identifier" - }, - { - "type": "SYMBOL", - "name": "_destructuring_pattern" - } - ] - }, - { - "type": "SYMBOL", - "name": "non_null_expression" - } - ] - }, - "assignment_expression": { - "type": "PREC_RIGHT", - "value": "assign", - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "using" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "left", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "parenthesized_expression" - }, - { - "type": "SYMBOL", - "name": "_lhs_expression" - } - ] - } - }, - { - "type": "STRING", - "value": "=" - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - "_augmented_assignment_lhs": { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "member_expression" - }, - { - "type": "SYMBOL", - "name": "subscript_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_reserved_identifier" - }, - "named": true, - "value": "identifier" - }, - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "parenthesized_expression" - } - ] - }, - { - "type": "SYMBOL", - "name": "non_null_expression" - } - ] - }, - "augmented_assignment_expression": { - "type": "PREC_RIGHT", - "value": "assign", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "_augmented_assignment_lhs" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "+=" - }, - { - "type": "STRING", - "value": "-=" - }, - { - "type": "STRING", - "value": "*=" - }, - { - "type": "STRING", - "value": "/=" - }, - { - "type": "STRING", - "value": "%=" - }, - { - "type": "STRING", - "value": "^=" - }, - { - "type": "STRING", - "value": "&=" - }, - { - "type": "STRING", - "value": "|=" - }, - { - "type": "STRING", - "value": ">>=" - }, - { - "type": "STRING", - "value": ">>>=" - }, - { - "type": "STRING", - "value": "<<=" - }, - { - "type": "STRING", - "value": "**=" - }, - { - "type": "STRING", - "value": "&&=" - }, - { - "type": "STRING", - "value": "||=" - }, - { - "type": "STRING", - "value": "??=" - } - ] - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - "_initializer": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "=" - }, - { - "type": "FIELD", - "name": "value", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - }, - "_destructuring_pattern": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "object_pattern" - }, - { - "type": "SYMBOL", - "name": "array_pattern" - } - ] - }, - "spread_element": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "..." - }, - { - "type": "SYMBOL", - "name": "expression" - } - ] - }, - "ternary_expression": { - "type": "PREC_RIGHT", - "value": "ternary", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "condition", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_ternary_qmark" - }, - "named": false, - "value": "?" - }, - { - "type": "FIELD", - "name": "consequence", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "alternative", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - "binary_expression": { - "type": "CHOICE", - "members": [ - { - "type": "PREC_LEFT", - "value": "logical_and", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "&&" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "logical_or", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "||" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_shift", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": ">>" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_shift", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": ">>>" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_shift", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "<<" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "bitwise_and", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "&" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "bitwise_xor", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "^" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "bitwise_or", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "|" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_plus", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "+" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_plus", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "-" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_times", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "*" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_times", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "/" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_times", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "%" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_RIGHT", - "value": "binary_exp", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "**" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_relation", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "<" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_relation", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "<=" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_equality", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "==" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_equality", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "===" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_equality", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "!=" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_equality", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "!==" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_relation", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": ">=" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_relation", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": ">" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "ternary", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "??" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_relation", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "instanceof" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - { - "type": "PREC_LEFT", - "value": "binary_relation", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "private_property_identifier" - } - ] - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "STRING", - "value": "in" - } - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - } - ] - }, - "unary_expression": { - "type": "PREC_LEFT", - "value": "unary_void", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "!" - }, - { - "type": "STRING", - "value": "~" - }, - { - "type": "STRING", - "value": "-" - }, - { - "type": "STRING", - "value": "+" - }, - { - "type": "STRING", - "value": "typeof" - }, - { - "type": "STRING", - "value": "void" - }, - { - "type": "STRING", - "value": "delete" - } - ] - } - }, - { - "type": "FIELD", - "name": "argument", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - }, - "update_expression": { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "argument", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "++" - }, - { - "type": "STRING", - "value": "--" - } - ] - } - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "++" - }, - { - "type": "STRING", - "value": "--" - } - ] - } - }, - { - "type": "FIELD", - "name": "argument", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - } - ] - } - }, - "sequence_expression": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "expression" - } - ] - } - } - ] - } - }, - "string": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "\"" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "unescaped_double_string_fragment" - }, - "named": true, - "value": "string_fragment" - }, - { - "type": "SYMBOL", - "name": "escape_sequence" - } - ] - } - }, - { - "type": "STRING", - "value": "\"" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "'" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "unescaped_single_string_fragment" - }, - "named": true, - "value": "string_fragment" - }, - { - "type": "SYMBOL", - "name": "escape_sequence" - } - ] - } - }, - { - "type": "STRING", - "value": "'" - } - ] - } - ] - }, - "unescaped_double_string_fragment": { - "type": "IMMEDIATE_TOKEN", - "content": { - "type": "PREC", - "value": 1, - "content": { - "type": "PATTERN", - "value": "[^\"\\\\\\r\\n]+" - } - } - }, - "unescaped_single_string_fragment": { - "type": "IMMEDIATE_TOKEN", - "content": { - "type": "PREC", - "value": 1, - "content": { - "type": "PATTERN", - "value": "[^'\\\\\\r\\n]+" - } - } - }, - "escape_sequence": { - "type": "IMMEDIATE_TOKEN", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "\\" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "PATTERN", - "value": "[^xu0-7]" - }, - { - "type": "PATTERN", - "value": "[0-7]{1,3}" - }, - { - "type": "PATTERN", - "value": "x[0-9a-fA-F]{2}" - }, - { - "type": "PATTERN", - "value": "u[0-9a-fA-F]{4}" - }, - { - "type": "PATTERN", - "value": "u{[0-9a-fA-F]+}" - }, - { - "type": "PATTERN", - "value": "[\\r?][\\n\\u2028\\u2029]" - } - ] - } - ] - } - }, - "comment": { - "type": "CHOICE", - "members": [ - { - "type": "TOKEN", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "//" - }, - { - "type": "PATTERN", - "value": ".*" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "/*" - }, - { - "type": "PATTERN", - "value": "[^*]*\\*+([^/*][^*]*\\*+)*" - }, - { - "type": "STRING", - "value": "/" - } - ] - } - ] - } - } - ] - }, - "template_string": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "`" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_template_chars" - }, - "named": true, - "value": "string_fragment" - }, - { - "type": "SYMBOL", - "name": "escape_sequence" - }, - { - "type": "SYMBOL", - "name": "template_substitution" - } - ] - } - }, - { - "type": "STRING", - "value": "`" - } - ] - }, - "template_substitution": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "${" - }, - { - "type": "SYMBOL", - "name": "_expressions" - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "regex": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "/" - }, - { - "type": "FIELD", - "name": "pattern", - "content": { - "type": "SYMBOL", - "name": "regex_pattern" - } - }, - { - "type": "IMMEDIATE_TOKEN", - "content": { - "type": "STRING", - "value": "/" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "flags", - "content": { - "type": "SYMBOL", - "name": "regex_flags" - } - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "regex_pattern": { - "type": "IMMEDIATE_TOKEN", - "content": { - "type": "PREC", - "value": -1, - "content": { - "type": "REPEAT1", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "[" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "\\" - }, - { - "type": "PATTERN", - "value": "." - } - ] - }, - { - "type": "PATTERN", - "value": "[^\\]\\n\\\\]" - } - ] - } - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "\\" - }, - { - "type": "PATTERN", - "value": "." - } - ] - }, - { - "type": "PATTERN", - "value": "[^/\\\\\\[\\n]" - } - ] - } - } - } - }, - "regex_flags": { - "type": "IMMEDIATE_TOKEN", - "content": { - "type": "PATTERN", - "value": "[a-z]+" - } - }, - "number": { - "type": "TOKEN", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0x" - }, - { - "type": "STRING", - "value": "0X" - } - ] - }, - { - "type": "PATTERN", - "value": "[\\da-fA-F](_?[\\da-fA-F])*" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0" - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "PATTERN", - "value": "[1-9]" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "_" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - }, - { - "type": "STRING", - "value": "." - }, - { - "type": "CHOICE", - "members": [ - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "e" - }, - { - "type": "STRING", - "value": "E" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "-" - }, - { - "type": "STRING", - "value": "+" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "." - }, - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "e" - }, - { - "type": "STRING", - "value": "E" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "-" - }, - { - "type": "STRING", - "value": "+" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0" - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "PATTERN", - "value": "[1-9]" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "_" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "e" - }, - { - "type": "STRING", - "value": "E" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "-" - }, - { - "type": "STRING", - "value": "+" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - } - ] - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0b" - }, - { - "type": "STRING", - "value": "0B" - } - ] - }, - { - "type": "PATTERN", - "value": "[0-1](_?[0-1])*" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0o" - }, - { - "type": "STRING", - "value": "0O" - } - ] - }, - { - "type": "PATTERN", - "value": "[0-7](_?[0-7])*" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0x" - }, - { - "type": "STRING", - "value": "0X" - } - ] - }, - { - "type": "PATTERN", - "value": "[\\da-fA-F](_?[\\da-fA-F])*" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0b" - }, - { - "type": "STRING", - "value": "0B" - } - ] - }, - { - "type": "PATTERN", - "value": "[0-1](_?[0-1])*" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "0o" - }, - { - "type": "STRING", - "value": "0O" - } - ] - }, - { - "type": "PATTERN", - "value": "[0-7](_?[0-7])*" - } - ] - }, - { - "type": "PATTERN", - "value": "\\d(_?\\d)*" - } - ] - }, - { - "type": "STRING", - "value": "n" - } - ] - } - ] - } - }, - "_identifier": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "undefined" - }, - { - "type": "SYMBOL", - "name": "identifier" - } - ] - }, - "identifier": { - "type": "TOKEN", - "content": { - "type": "SEQ", - "members": [ - { - "type": "PATTERN", - "value": "[^\\x00-\\x1F\\s\\p{Zs}0-9:;`\"'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}" - }, - { - "type": "REPEAT", - "content": { - "type": "PATTERN", - "value": "[^\\x00-\\x1F\\s\\p{Zs}:;`\"'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}" - } - } - ] - } - }, - "private_property_identifier": { - "type": "TOKEN", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "#" - }, - { - "type": "PATTERN", - "value": "[^\\x00-\\x1F\\s\\p{Zs}0-9:;`\"'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}" - }, - { - "type": "REPEAT", - "content": { - "type": "PATTERN", - "value": "[^\\x00-\\x1F\\s\\p{Zs}:;`\"'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}" - } - } - ] - } - }, - "meta_property": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "new" - }, - { - "type": "STRING", - "value": "." - }, - { - "type": "STRING", - "value": "target" - } - ] - }, - "this": { - "type": "STRING", - "value": "this" - }, - "super": { - "type": "STRING", - "value": "super" - }, - "true": { - "type": "STRING", - "value": "true" - }, - "false": { - "type": "STRING", - "value": "false" - }, - "null": { - "type": "STRING", - "value": "null" - }, - "undefined": { - "type": "STRING", - "value": "undefined" - }, - "arguments": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "(" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "spread_element" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "SYMBOL", - "name": "spread_element" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": ")" - } - ] - }, - "decorator": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "@" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "decorator_member_expression" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "decorator_call_expression" - }, - "named": true, - "value": "call_expression" - } - ] - } - ] - }, - "decorator_member_expression": { - "type": "PREC", - "value": "member", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "object", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "decorator_member_expression" - }, - "named": true, - "value": "member_expression" - } - ] - } - }, - { - "type": "STRING", - "value": "." - }, - { - "type": "FIELD", - "name": "property", - "content": { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "property_identifier" - } - } - ] - } - }, - "decorator_call_expression": { - "type": "PREC", - "value": "call", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "function", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "decorator_member_expression" - }, - "named": true, - "value": "member_expression" - } - ] - } - }, - { - "type": "FIELD", - "name": "arguments", - "content": { - "type": "SYMBOL", - "name": "arguments" - } - } - ] - } - }, - "class_body": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "SYMBOL", - "name": "method_definition" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_semicolon" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "method_signature" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_function_signature_automatic_semicolon" - }, - { - "type": "STRING", - "value": "," - } - ] - } - ] - }, - { - "type": "SYMBOL", - "name": "class_static_block" - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "abstract_method_signature" - }, - { - "type": "SYMBOL", - "name": "index_signature" - }, - { - "type": "SYMBOL", - "name": "method_signature" - }, - { - "type": "SYMBOL", - "name": "public_field_definition" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_semicolon" - }, - { - "type": "STRING", - "value": "," - } - ] - } - ] - }, - { - "type": "STRING", - "value": ";" - } - ] - } - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "field_definition": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "static" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "property", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_initializer" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "formal_parameters": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "(" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_formal_parameter" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "_formal_parameter" - } - ] - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": ")" - } - ] - }, - "class_static_block": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "static" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - } - ] - }, - "pattern": { - "type": "PREC_DYNAMIC", - "value": -1, - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_lhs_expression" - }, - { - "type": "SYMBOL", - "name": "rest_pattern" - } - ] - } - }, - "rest_pattern": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "..." - }, - { - "type": "SYMBOL", - "name": "_lhs_expression" - } - ] - } - }, - "method_definition": { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "static" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "override_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "get" - }, - { - "type": "STRING", - "value": "set" - }, - { - "type": "STRING", - "value": "*" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "?" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_call_signature" - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "statement_block" - } - } - ] - } - }, - "pair": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "key", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "value", - "content": { - "type": "SYMBOL", - "name": "expression" - } - } - ] - }, - "pair_pattern": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "key", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "value", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pattern" - }, - { - "type": "SYMBOL", - "name": "assignment_pattern" - } - ] - } - } - ] - }, - "_property_name": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "_reserved_identifier" - } - ] - }, - "named": true, - "value": "property_identifier" - }, - { - "type": "SYMBOL", - "name": "private_property_identifier" - }, - { - "type": "SYMBOL", - "name": "string" - }, - { - "type": "SYMBOL", - "name": "number" - }, - { - "type": "SYMBOL", - "name": "computed_property_name" - } - ] - }, - "computed_property_name": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "[" - }, - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - "_reserved_identifier": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "declare" - }, - { - "type": "STRING", - "value": "namespace" - }, - { - "type": "STRING", - "value": "type" - }, - { - "type": "STRING", - "value": "public" - }, - { - "type": "STRING", - "value": "private" - }, - { - "type": "STRING", - "value": "protected" - }, - { - "type": "STRING", - "value": "override" - }, - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "STRING", - "value": "module" - }, - { - "type": "STRING", - "value": "any" - }, - { - "type": "STRING", - "value": "number" - }, - { - "type": "STRING", - "value": "boolean" - }, - { - "type": "STRING", - "value": "string" - }, - { - "type": "STRING", - "value": "symbol" - }, - { - "type": "STRING", - "value": "export" - }, - { - "type": "STRING", - "value": "object" - }, - { - "type": "STRING", - "value": "new" - }, - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "get" - }, - { - "type": "STRING", - "value": "set" - }, - { - "type": "STRING", - "value": "async" - }, - { - "type": "STRING", - "value": "static" - }, - { - "type": "STRING", - "value": "export" - }, - { - "type": "STRING", - "value": "let" - } - ] - } - ] - }, - "_semicolon": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_automatic_semicolon" - }, - { - "type": "STRING", - "value": ";" - } - ] - }, - "public_field_definition": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "declare" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "declare" - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "static" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "override_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "abstract" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "abstract" - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "?" - }, - { - "type": "STRING", - "value": "!" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_initializer" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "_jsx_start_opening_element": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "<" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_jsx_identifier" - }, - { - "type": "SYMBOL", - "name": "jsx_namespace_name" - } - ] - } - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "nested_identifier" - }, - "named": true, - "value": "member_expression" - } - ] - } - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_arguments" - }, - { - "type": "BLANK" - } - ] - } - } - ] - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "attribute", - "content": { - "type": "SYMBOL", - "name": "_jsx_attribute" - } - } - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "_import_identifier": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "STRING", - "value": "type" - }, - "named": true, - "value": "identifier" - } - ] - }, - "non_null_expression": { - "type": "PREC_LEFT", - "value": "unary", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "STRING", - "value": "!" - } - ] - } - }, - "method_signature": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "static" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "override_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "get" - }, - { - "type": "STRING", - "value": "set" - }, - { - "type": "STRING", - "value": "*" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "?" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_call_signature" - } - ] - }, - "abstract_method_signature": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "abstract" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "override_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "get" - }, - { - "type": "STRING", - "value": "set" - }, - { - "type": "STRING", - "value": "*" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "?" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_call_signature" - } - ] - }, - "function_signature": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "async" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "function" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "identifier" - } - }, - { - "type": "SYMBOL", - "name": "_call_signature" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_semicolon" - }, - { - "type": "SYMBOL", - "name": "_function_signature_automatic_semicolon" - } - ] - } - ] - }, - "type_assertion": { - "type": "PREC_LEFT", - "value": "unary", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "type_arguments" - }, - { - "type": "SYMBOL", - "name": "expression" - } - ] - } - }, - "as_expression": { - "type": "PREC_LEFT", - "value": "binary", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "STRING", - "value": "as" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "const" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - } - ] - } - }, - "satisfies_expression": { - "type": "PREC_LEFT", - "value": "binary", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "STRING", - "value": "satisfies" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - } - }, - "instantiation_expression": { - "type": "PREC", - "value": "instantiation", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "expression" - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "SYMBOL", - "name": "type_arguments" - } - } - ] - } - }, - "import_require_clause": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "STRING", - "value": "=" - }, - { - "type": "STRING", - "value": "require" - }, - { - "type": "STRING", - "value": "(" - }, - { - "type": "FIELD", - "name": "source", - "content": { - "type": "SYMBOL", - "name": "string" - } - }, - { - "type": "STRING", - "value": ")" - } - ] - }, - "extends_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "extends" - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_extends_clause_single" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "_extends_clause_single" - } - ] - } - } - ] - } - ] - }, - "_extends_clause_single": { - "type": "PREC", - "value": "extends", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "value", - "content": { - "type": "SYMBOL", - "name": "expression" - } - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_arguments" - }, - { - "type": "BLANK" - } - ] - } - } - ] - } - }, - "implements_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "implements" - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - } - } - ] - } - ] - }, - "ambient_declaration": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "declare" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "declaration" - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "global" - }, - { - "type": "SYMBOL", - "name": "statement_block" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "module" - }, - { - "type": "STRING", - "value": "." - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "property_identifier" - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - } - ] - } - ] - }, - "abstract_class_declaration": { - "type": "PREC", - "value": "declaration", - "content": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "STRING", - "value": "abstract" - }, - { - "type": "STRING", - "value": "class" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_type_identifier" - } - }, - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "class_heritage" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "class_body" - } - } - ] - } - }, - "module": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "module" - }, - { - "type": "SYMBOL", - "name": "_module" - } - ] - }, - "internal_module": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "namespace" - }, - { - "type": "SYMBOL", - "name": "_module" - } - ] - }, - "_module": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "string" - }, - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "nested_identifier" - } - ] - } - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "statement_block" - }, - { - "type": "BLANK" - } - ] - } - } - ] - } - }, - "import_alias": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "import" - }, - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "STRING", - "value": "=" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "nested_identifier" - } - ] - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "nested_type_identifier": { - "type": "PREC", - "value": "member", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "module", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "nested_identifier" - } - ] - } - }, - { - "type": "STRING", - "value": "." - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_type_identifier" - } - } - ] - } - }, - "interface_declaration": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "interface" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_type_identifier" - } - }, - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "extends_type_clause" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "object_type" - }, - "named": true, - "value": "interface_body" - } - } - ] - }, - "extends_type_clause": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "extends" - }, - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type_identifier" - }, - { - "type": "SYMBOL", - "name": "nested_type_identifier" - }, - { - "type": "SYMBOL", - "name": "generic_type" - } - ] - } - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type_identifier" - }, - { - "type": "SYMBOL", - "name": "nested_type_identifier" - }, - { - "type": "SYMBOL", - "name": "generic_type" - } - ] - } - } - ] - } - } - ] - } - ] - }, - "enum_declaration": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "const" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "enum" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "identifier" - } - }, - { - "type": "FIELD", - "name": "body", - "content": { - "type": "SYMBOL", - "name": "enum_body" - } - } - ] - }, - "enum_body": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "SYMBOL", - "name": "enum_assignment" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "SYMBOL", - "name": "enum_assignment" - } - ] - } - ] - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "enum_assignment": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "SYMBOL", - "name": "_initializer" - } - ] - }, - "type_alias_declaration": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "type" - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_type_identifier" - } - }, - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "STRING", - "value": "=" - }, - { - "type": "FIELD", - "name": "value", - "content": { - "type": "SYMBOL", - "name": "_type" - } - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - "accessibility_modifier": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "public" - }, - { - "type": "STRING", - "value": "private" - }, - { - "type": "STRING", - "value": "protected" - } - ] - }, - "override_modifier": { - "type": "STRING", - "value": "override" - }, - "required_parameter": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_parameter_name" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_initializer" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "optional_parameter": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_parameter_name" - }, - { - "type": "STRING", - "value": "?" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_initializer" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "_parameter_name": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "FIELD", - "name": "decorator", - "content": { - "type": "SYMBOL", - "name": "decorator" - } - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "override_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "pattern", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "pattern" - }, - { - "type": "SYMBOL", - "name": "this" - } - ] - } - } - ] - }, - "omitting_type_annotation": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "-?:" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "adding_type_annotation": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "+?:" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "opting_type_annotation": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "?:" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "type_annotation": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": ":" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression_in_type_annotation" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_call_expression_in_type_annotation" - }, - "named": true, - "value": "call_expression" - } - ] - } - ] - }, - "_type_query_member_expression_in_type_annotation": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "object", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "import" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression_in_type_annotation" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_call_expression_in_type_annotation" - }, - "named": true, - "value": "call_expression" - } - ] - } - }, - { - "type": "STRING", - "value": "." - }, - { - "type": "FIELD", - "name": "property", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "private_property_identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "property_identifier" - } - ] - } - } - ] - }, - "_type_query_call_expression_in_type_annotation": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "function", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "import" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression_in_type_annotation" - }, - "named": true, - "value": "member_expression" - } - ] - } - }, - { - "type": "FIELD", - "name": "arguments", - "content": { - "type": "SYMBOL", - "name": "arguments" - } - } - ] - }, - "asserts": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "asserts" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_predicate" - }, - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "this" - } - ] - } - ] - }, - "asserts_annotation": { - "type": "SEQ", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": ":" - }, - { - "type": "SYMBOL", - "name": "asserts" - } - ] - } - ] - }, - "_type": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_primary_type" - }, - { - "type": "SYMBOL", - "name": "function_type" - }, - { - "type": "SYMBOL", - "name": "readonly_type" - }, - { - "type": "SYMBOL", - "name": "constructor_type" - }, - { - "type": "SYMBOL", - "name": "infer_type" - } - ] - }, - "tuple_parameter": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "rest_pattern" - } - ] - } - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "SYMBOL", - "name": "type_annotation" - } - } - ] - }, - "optional_tuple_parameter": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "identifier" - } - }, - { - "type": "STRING", - "value": "?" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "SYMBOL", - "name": "type_annotation" - } - } - ] - }, - "optional_type": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "STRING", - "value": "?" - } - ] - }, - "rest_type": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "..." - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "_tuple_type_member": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "tuple_parameter" - }, - "named": true, - "value": "required_parameter" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "optional_tuple_parameter" - }, - "named": true, - "value": "optional_parameter" - }, - { - "type": "SYMBOL", - "name": "optional_type" - }, - { - "type": "SYMBOL", - "name": "rest_type" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "constructor_type": { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "abstract" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "new" - }, - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "parameters", - "content": { - "type": "SYMBOL", - "name": "formal_parameters" - } - }, - { - "type": "STRING", - "value": "=>" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "SYMBOL", - "name": "_type" - } - } - ] - } - }, - "_primary_type": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "parenthesized_type" - }, - { - "type": "SYMBOL", - "name": "predefined_type" - }, - { - "type": "SYMBOL", - "name": "_type_identifier" - }, - { - "type": "SYMBOL", - "name": "nested_type_identifier" - }, - { - "type": "SYMBOL", - "name": "generic_type" - }, - { - "type": "SYMBOL", - "name": "object_type" - }, - { - "type": "SYMBOL", - "name": "array_type" - }, - { - "type": "SYMBOL", - "name": "tuple_type" - }, - { - "type": "SYMBOL", - "name": "flow_maybe_type" - }, - { - "type": "SYMBOL", - "name": "type_query" - }, - { - "type": "SYMBOL", - "name": "index_type_query" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "this" - }, - "named": true, - "value": "this_type" - }, - { - "type": "SYMBOL", - "name": "existential_type" - }, - { - "type": "SYMBOL", - "name": "literal_type" - }, - { - "type": "SYMBOL", - "name": "lookup_type" - }, - { - "type": "SYMBOL", - "name": "conditional_type" - }, - { - "type": "SYMBOL", - "name": "template_literal_type" - }, - { - "type": "SYMBOL", - "name": "intersection_type" - }, - { - "type": "SYMBOL", - "name": "union_type" - }, - { - "type": "STRING", - "value": "const" - } - ] - }, - "template_type": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "${" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_primary_type" - }, - { - "type": "SYMBOL", - "name": "infer_type" - } - ] - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "template_literal_type": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "`" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_template_chars" - }, - { - "type": "SYMBOL", - "name": "template_type" - } - ] - } - }, - { - "type": "STRING", - "value": "`" - } - ] - }, - "infer_type": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "infer" - }, - { - "type": "SYMBOL", - "name": "_type_identifier" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "extends" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - } - }, - "conditional_type": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "left", - "content": { - "type": "SYMBOL", - "name": "_type" - } - }, - { - "type": "STRING", - "value": "extends" - }, - { - "type": "FIELD", - "name": "right", - "content": { - "type": "SYMBOL", - "name": "_type" - } - }, - { - "type": "STRING", - "value": "?" - }, - { - "type": "FIELD", - "name": "consequence", - "content": { - "type": "SYMBOL", - "name": "_type" - } - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "alternative", - "content": { - "type": "SYMBOL", - "name": "_type" - } - } - ] - } - }, - "generic_type": { - "type": "PREC", - "value": "call", - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type_identifier" - }, - { - "type": "SYMBOL", - "name": "nested_type_identifier" - } - ] - } - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "SYMBOL", - "name": "type_arguments" - } - } - ] - } - }, - "type_predicate": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "SYMBOL", - "name": "this" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "predefined_type" - }, - "named": true, - "value": "identifier" - } - ] - } - }, - { - "type": "STRING", - "value": "is" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "SYMBOL", - "name": "_type" - } - } - ] - }, - "type_predicate_annotation": { - "type": "SEQ", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": ":" - }, - { - "type": "SYMBOL", - "name": "type_predicate" - } - ] - } - ] - }, - "_type_query_member_expression": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "object", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - }, - "named": true, - "value": "subscript_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_call_expression" - }, - "named": true, - "value": "call_expression" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "." - }, - { - "type": "STRING", - "value": "?." - } - ] - }, - { - "type": "FIELD", - "name": "property", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "private_property_identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "property_identifier" - } - ] - } - } - ] - }, - "_type_query_subscript_expression": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "object", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - }, - "named": true, - "value": "subscript_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_call_expression" - }, - "named": true, - "value": "call_expression" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "?." - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "[" - }, - { - "type": "FIELD", - "name": "index", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "predefined_type" - }, - { - "type": "SYMBOL", - "name": "string" - }, - { - "type": "SYMBOL", - "name": "number" - } - ] - } - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - "_type_query_call_expression": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "function", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "import" - }, - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - }, - "named": true, - "value": "subscript_expression" - } - ] - } - }, - { - "type": "FIELD", - "name": "arguments", - "content": { - "type": "SYMBOL", - "name": "arguments" - } - } - ] - }, - "_type_query_instantiation_expression": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "function", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "import" - }, - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - }, - "named": true, - "value": "subscript_expression" - } - ] - } - }, - { - "type": "FIELD", - "name": "type_arguments", - "content": { - "type": "SYMBOL", - "name": "type_arguments" - } - } - ] - }, - "type_query": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "typeof" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - }, - "named": true, - "value": "subscript_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_call_expression" - }, - "named": true, - "value": "call_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_instantiation_expression" - }, - "named": true, - "value": "instantiation_expression" - }, - { - "type": "SYMBOL", - "name": "identifier" - } - ] - } - ] - } - }, - "index_type_query": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "keyof" - }, - { - "type": "SYMBOL", - "name": "_primary_type" - } - ] - }, - "lookup_type": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_primary_type" - }, - { - "type": "STRING", - "value": "[" - }, - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - "mapped_type_clause": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_type_identifier" - } - }, - { - "type": "STRING", - "value": "in" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "SYMBOL", - "name": "_type" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "as" - }, - { - "type": "FIELD", - "name": "alias", - "content": { - "type": "SYMBOL", - "name": "_type" - } - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - }, - "literal_type": { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_number" - }, - "named": true, - "value": "unary_expression" - }, - { - "type": "SYMBOL", - "name": "number" - }, - { - "type": "SYMBOL", - "name": "string" - }, - { - "type": "SYMBOL", - "name": "true" - }, - { - "type": "SYMBOL", - "name": "false" - }, - { - "type": "SYMBOL", - "name": "null" - }, - { - "type": "SYMBOL", - "name": "undefined" - } - ] - }, - "_number": { - "type": "PREC_LEFT", - "value": 1, - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "operator", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "-" - }, - { - "type": "STRING", - "value": "+" - } - ] - } - }, - { - "type": "FIELD", - "name": "argument", - "content": { - "type": "SYMBOL", - "name": "number" - } - } - ] - } - }, - "existential_type": { - "type": "STRING", - "value": "*" - }, - "flow_maybe_type": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "?" - }, - { - "type": "SYMBOL", - "name": "_primary_type" - } - ] - } - }, - "parenthesized_type": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "(" - }, - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "STRING", - "value": ")" - } - ] - }, - "predefined_type": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "any" - }, - { - "type": "STRING", - "value": "number" - }, - { - "type": "STRING", - "value": "boolean" - }, - { - "type": "STRING", - "value": "string" - }, - { - "type": "STRING", - "value": "symbol" - }, - { - "type": "ALIAS", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "unique" - }, - { - "type": "STRING", - "value": "symbol" - } - ] - }, - "named": false, - "value": "unique symbol" - }, - { - "type": "STRING", - "value": "void" - }, - { - "type": "STRING", - "value": "unknown" - }, - { - "type": "STRING", - "value": "string" - }, - { - "type": "STRING", - "value": "never" - }, - { - "type": "STRING", - "value": "object" - } - ] - }, - "type_arguments": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "<" - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression_in_type_annotation" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_call_expression_in_type_annotation" - }, - "named": true, - "value": "call_expression" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_member_expression_in_type_annotation" - }, - "named": true, - "value": "member_expression" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_type_query_call_expression_in_type_annotation" - }, - "named": true, - "value": "call_expression" - } - ] - } - ] - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": ">" - } - ] - }, - "object_type": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "{" - }, - { - "type": "STRING", - "value": "{|" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "STRING", - "value": ";" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "export_statement" - }, - { - "type": "SYMBOL", - "name": "property_signature" - }, - { - "type": "SYMBOL", - "name": "call_signature" - }, - { - "type": "SYMBOL", - "name": "construct_signature" - }, - { - "type": "SYMBOL", - "name": "index_signature" - }, - { - "type": "SYMBOL", - "name": "method_signature" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "export_statement" - }, - { - "type": "SYMBOL", - "name": "property_signature" - }, - { - "type": "SYMBOL", - "name": "call_signature" - }, - { - "type": "SYMBOL", - "name": "construct_signature" - }, - { - "type": "SYMBOL", - "name": "index_signature" - }, - { - "type": "SYMBOL", - "name": "method_signature" - } - ] - } - ] - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "_semicolon" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "}" - }, - { - "type": "STRING", - "value": "|}" - } - ] - } - ] - }, - "call_signature": { - "type": "SYMBOL", - "name": "_call_signature" - }, - "property_signature": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "static" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "override_modifier" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_property_name" - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "?" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "BLANK" - } - ] - } - } - ] - }, - "type_parameters": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "<" - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameter" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "type_parameter" - } - ] - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": ">" - } - ] - }, - "type_parameter": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "const" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "FIELD", - "name": "name", - "content": { - "type": "SYMBOL", - "name": "_type_identifier" - } - }, - { - "type": "FIELD", - "name": "constraint", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "constraint" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "value", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "default_type" - }, - { - "type": "BLANK" - } - ] - } - } - ] - }, - "default_type": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "=" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "constraint": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "extends" - }, - { - "type": "STRING", - "value": ":" - } - ] - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "construct_signature": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "abstract" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "new" - }, - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "parameters", - "content": { - "type": "SYMBOL", - "name": "formal_parameters" - } - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "BLANK" - } - ] - } - } - ] - }, - "index_signature": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "sign", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "-" - }, - { - "type": "STRING", - "value": "+" - } - ] - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "STRING", - "value": "readonly" - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "[" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "name", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "identifier" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_reserved_identifier" - }, - "named": true, - "value": "identifier" - } - ] - } - }, - { - "type": "STRING", - "value": ":" - }, - { - "type": "FIELD", - "name": "index_type", - "content": { - "type": "SYMBOL", - "name": "_type" - } - } - ] - }, - { - "type": "SYMBOL", - "name": "mapped_type_clause" - } - ] - }, - { - "type": "STRING", - "value": "]" - }, - { - "type": "FIELD", - "name": "type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_annotation" - }, - { - "type": "SYMBOL", - "name": "omitting_type_annotation" - }, - { - "type": "SYMBOL", - "name": "adding_type_annotation" - }, - { - "type": "SYMBOL", - "name": "opting_type_annotation" - } - ] - } - } - ] - }, - "array_type": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_primary_type" - }, - { - "type": "STRING", - "value": "[" - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - "tuple_type": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "[" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_tuple_type_member" - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "SYMBOL", - "name": "_tuple_type_member" - } - ] - } - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "," - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "]" - } - ] - }, - "readonly_type": { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "readonly" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - }, - "union_type": { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "|" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - } - }, - "intersection_type": { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "STRING", - "value": "&" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ] - } - }, - "function_type": { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "FIELD", - "name": "type_parameters", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "type_parameters" - }, - { - "type": "BLANK" - } - ] - } - }, - { - "type": "FIELD", - "name": "parameters", - "content": { - "type": "SYMBOL", - "name": "formal_parameters" - } - }, - { - "type": "STRING", - "value": "=>" - }, - { - "type": "FIELD", - "name": "return_type", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "SYMBOL", - "name": "asserts" - }, - { - "type": "SYMBOL", - "name": "type_predicate" - } - ] - } - } - ] - } - }, - "_type_identifier": { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "identifier" - }, - "named": true, - "value": "type_identifier" - } - }, - "extras": [ - { - "type": "SYMBOL", - "name": "comment" - }, - { - "type": "SYMBOL", - "name": "html_comment" - }, - { - "type": "PATTERN", - "value": "[\\s\\p{Zs}\\uFEFF\\u2028\\u2029\\u2060\\u200B]" - } - ], - "conflicts": [ - [ - "primary_expression", - "_property_name" - ], - [ - "primary_expression", - "_property_name", - "arrow_function" - ], - [ - "primary_expression", - "arrow_function" - ], - [ - "primary_expression", - "method_definition" - ], - [ - "primary_expression", - "rest_pattern" - ], - [ - "primary_expression", - "pattern" - ], - [ - "primary_expression", - "_for_header" - ], - [ - "array", - "array_pattern" - ], - [ - "object", - "object_pattern" - ], - [ - "assignment_expression", - "pattern" - ], - [ - "assignment_expression", - "object_assignment_pattern" - ], - [ - "labeled_statement", - "_property_name" - ], - [ - "computed_property_name", - "array" - ], - [ - "binary_expression", - "_initializer" - ], - [ - "call_expression", - "instantiation_expression", - "binary_expression" - ], - [ - "call_expression", - "instantiation_expression", - "binary_expression", - "unary_expression" - ], - [ - "call_expression", - "instantiation_expression", - "binary_expression", - "update_expression" - ], - [ - "call_expression", - "instantiation_expression", - "binary_expression", - "await_expression" - ], - [ - "class" - ], - [ - "nested_identifier", - "nested_type_identifier", - "primary_expression" - ], - [ - "nested_identifier", - "nested_type_identifier" - ], - [ - "_call_signature", - "function_type" - ], - [ - "_call_signature", - "constructor_type" - ], - [ - "_primary_type", - "type_parameter" - ], - [ - "jsx_opening_element", - "type_parameter" - ], - [ - "jsx_namespace_name", - "_primary_type" - ], - [ - "primary_expression", - "_parameter_name" - ], - [ - "primary_expression", - "_parameter_name", - "_primary_type" - ], - [ - "primary_expression", - "literal_type" - ], - [ - "primary_expression", - "literal_type", - "rest_pattern" - ], - [ - "primary_expression", - "predefined_type", - "rest_pattern" - ], - [ - "primary_expression", - "_primary_type" - ], - [ - "primary_expression", - "generic_type" - ], - [ - "primary_expression", - "predefined_type" - ], - [ - "primary_expression", - "pattern", - "_primary_type" - ], - [ - "_parameter_name", - "_primary_type" - ], - [ - "pattern", - "_primary_type" - ], - [ - "optional_tuple_parameter", - "_primary_type" - ], - [ - "rest_pattern", - "_primary_type", - "primary_expression" - ], - [ - "object", - "object_type" - ], - [ - "object", - "object_pattern", - "object_type" - ], - [ - "object", - "object_pattern", - "_property_name" - ], - [ - "object_pattern", - "object_type" - ], - [ - "object_pattern", - "object_type" - ], - [ - "array", - "tuple_type" - ], - [ - "array", - "array_pattern", - "tuple_type" - ], - [ - "array_pattern", - "tuple_type" - ], - [ - "template_literal_type", - "template_string" - ] - ], - "precedences": [ - [ - { - "type": "STRING", - "value": "member" - }, - { - "type": "STRING", - "value": "call" - }, - { - "type": "SYMBOL", - "name": "update_expression" - }, - { - "type": "STRING", - "value": "unary_void" - }, - { - "type": "STRING", - "value": "binary_exp" - }, - { - "type": "STRING", - "value": "binary_times" - }, - { - "type": "STRING", - "value": "binary_plus" - }, - { - "type": "STRING", - "value": "binary_shift" - }, - { - "type": "STRING", - "value": "binary_compare" - }, - { - "type": "STRING", - "value": "binary_relation" - }, - { - "type": "STRING", - "value": "binary_equality" - }, - { - "type": "STRING", - "value": "bitwise_and" - }, - { - "type": "STRING", - "value": "bitwise_xor" - }, - { - "type": "STRING", - "value": "bitwise_or" - }, - { - "type": "STRING", - "value": "logical_and" - }, - { - "type": "STRING", - "value": "logical_or" - }, - { - "type": "STRING", - "value": "ternary" - }, - { - "type": "SYMBOL", - "name": "sequence_expression" - }, - { - "type": "SYMBOL", - "name": "arrow_function" - } - ], - [ - { - "type": "STRING", - "value": "assign" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "STRING", - "value": "member" - }, - { - "type": "STRING", - "value": "new" - }, - { - "type": "STRING", - "value": "call" - }, - { - "type": "SYMBOL", - "name": "expression" - } - ], - [ - { - "type": "STRING", - "value": "declaration" - }, - { - "type": "STRING", - "value": "literal" - } - ], - [ - { - "type": "SYMBOL", - "name": "primary_expression" - }, - { - "type": "SYMBOL", - "name": "statement_block" - }, - { - "type": "STRING", - "value": "object" - } - ], - [ - { - "type": "SYMBOL", - "name": "import_statement" - }, - { - "type": "SYMBOL", - "name": "import" - } - ], - [ - { - "type": "SYMBOL", - "name": "export_statement" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "lexical_declaration" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "STRING", - "value": "call" - }, - { - "type": "STRING", - "value": "instantiation" - }, - { - "type": "STRING", - "value": "unary" - }, - { - "type": "STRING", - "value": "binary" - }, - { - "type": "SYMBOL", - "name": "await_expression" - }, - { - "type": "SYMBOL", - "name": "arrow_function" - } - ], - [ - { - "type": "STRING", - "value": "extends" - }, - { - "type": "STRING", - "value": "instantiation" - } - ], - [ - { - "type": "SYMBOL", - "name": "intersection_type" - }, - { - "type": "SYMBOL", - "name": "union_type" - }, - { - "type": "SYMBOL", - "name": "conditional_type" - }, - { - "type": "SYMBOL", - "name": "function_type" - }, - { - "type": "STRING", - "value": "binary" - }, - { - "type": "SYMBOL", - "name": "type_predicate" - }, - { - "type": "SYMBOL", - "name": "readonly_type" - } - ], - [ - { - "type": "SYMBOL", - "name": "mapped_type_clause" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "accessibility_modifier" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "STRING", - "value": "unary_void" - }, - { - "type": "SYMBOL", - "name": "expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "extends_clause" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "STRING", - "value": "unary" - }, - { - "type": "STRING", - "value": "assign" - } - ], - [ - { - "type": "STRING", - "value": "declaration" - }, - { - "type": "SYMBOL", - "name": "expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "predefined_type" - }, - { - "type": "SYMBOL", - "name": "unary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "_type" - }, - { - "type": "SYMBOL", - "name": "flow_maybe_type" - } - ], - [ - { - "type": "SYMBOL", - "name": "tuple_type" - }, - { - "type": "SYMBOL", - "name": "array_type" - }, - { - "type": "SYMBOL", - "name": "pattern" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ], - [ - { - "type": "SYMBOL", - "name": "readonly_type" - }, - { - "type": "SYMBOL", - "name": "pattern" - } - ], - [ - { - "type": "SYMBOL", - "name": "readonly_type" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "type_query" - }, - { - "type": "SYMBOL", - "name": "subscript_expression" - }, - { - "type": "SYMBOL", - "name": "expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "type_query" - }, - { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "nested_type_identifier" - }, - { - "type": "SYMBOL", - "name": "generic_type" - }, - { - "type": "SYMBOL", - "name": "_primary_type" - }, - { - "type": "SYMBOL", - "name": "lookup_type" - }, - { - "type": "SYMBOL", - "name": "index_type_query" - }, - { - "type": "SYMBOL", - "name": "_type" - } - ], - [ - { - "type": "SYMBOL", - "name": "as_expression" - }, - { - "type": "SYMBOL", - "name": "satisfies_expression" - }, - { - "type": "SYMBOL", - "name": "_primary_type" - } - ], - [ - { - "type": "SYMBOL", - "name": "_type_query_member_expression" - }, - { - "type": "SYMBOL", - "name": "member_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "member_expression" - }, - { - "type": "SYMBOL", - "name": "_type_query_member_expression_in_type_annotation" - } - ], - [ - { - "type": "SYMBOL", - "name": "_type_query_member_expression" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - }, - { - "type": "SYMBOL", - "name": "subscript_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "_type_query_subscript_expression" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "_type_query_call_expression" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "_type_query_instantiation_expression" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "type_query" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "override_modifier" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "decorator_call_expression" - }, - { - "type": "SYMBOL", - "name": "decorator" - } - ], - [ - { - "type": "SYMBOL", - "name": "literal_type" - }, - { - "type": "SYMBOL", - "name": "pattern" - } - ], - [ - { - "type": "SYMBOL", - "name": "predefined_type" - }, - { - "type": "SYMBOL", - "name": "pattern" - } - ], - [ - { - "type": "SYMBOL", - "name": "call_expression" - }, - { - "type": "SYMBOL", - "name": "_type_query_call_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "call_expression" - }, - { - "type": "SYMBOL", - "name": "_type_query_call_expression_in_type_annotation" - } - ], - [ - { - "type": "SYMBOL", - "name": "new_expression" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "meta_property" - }, - { - "type": "SYMBOL", - "name": "primary_expression" - } - ], - [ - { - "type": "SYMBOL", - "name": "construct_signature" - }, - { - "type": "SYMBOL", - "name": "_property_name" - } - ] - ], - "externals": [ - { - "type": "SYMBOL", - "name": "_automatic_semicolon" - }, - { - "type": "SYMBOL", - "name": "_template_chars" - }, - { - "type": "SYMBOL", - "name": "_ternary_qmark" - }, - { - "type": "SYMBOL", - "name": "html_comment" - }, - { - "type": "STRING", - "value": "||" - }, - { - "type": "SYMBOL", - "name": "escape_sequence" - }, - { - "type": "SYMBOL", - "name": "_function_signature_automatic_semicolon" - } - ], - "inline": [ - "statement", - "_expressions", - "_semicolon", - "_identifier", - "_reserved_identifier", - "_jsx_attribute", - "_jsx_element_name", - "_jsx_child", - "_jsx_element", - "_jsx_attribute_name", - "_jsx_attribute_value", - "_jsx_identifier", - "_lhs_expression", - "_type_identifier", - "_jsx_start_opening_element" - ], - "supertypes": [ - "statement", - "declaration", - "expression", - "primary_expression", - "pattern", - "_primary_type" - ] -} - diff --git a/vendored_parsers/tree-sitter-typescript/tsx/src/node-types.json b/vendored_parsers/tree-sitter-typescript/tsx/src/node-types.json deleted file mode 100644 index 096e181d0..000000000 --- a/vendored_parsers/tree-sitter-typescript/tsx/src/node-types.json +++ /dev/null @@ -1,6763 +0,0 @@ -[ - { - "type": "_primary_type", - "named": true, - "subtypes": [ - { - "type": "array_type", - "named": true - }, - { - "type": "conditional_type", - "named": true - }, - { - "type": "const", - "named": false - }, - { - "type": "existential_type", - "named": true - }, - { - "type": "flow_maybe_type", - "named": true - }, - { - "type": "generic_type", - "named": true - }, - { - "type": "index_type_query", - "named": true - }, - { - "type": "intersection_type", - "named": true - }, - { - "type": "literal_type", - "named": true - }, - { - "type": "lookup_type", - "named": true - }, - { - "type": "nested_type_identifier", - "named": true - }, - { - "type": "object_type", - "named": true - }, - { - "type": "parenthesized_type", - "named": true - }, - { - "type": "predefined_type", - "named": true - }, - { - "type": "template_literal_type", - "named": true - }, - { - "type": "this_type", - "named": true - }, - { - "type": "tuple_type", - "named": true - }, - { - "type": "type_identifier", - "named": true - }, - { - "type": "type_query", - "named": true - }, - { - "type": "union_type", - "named": true - } - ] - }, - { - "type": "declaration", - "named": true, - "subtypes": [ - { - "type": "abstract_class_declaration", - "named": true - }, - { - "type": "ambient_declaration", - "named": true - }, - { - "type": "class_declaration", - "named": true - }, - { - "type": "enum_declaration", - "named": true - }, - { - "type": "function_declaration", - "named": true - }, - { - "type": "function_signature", - "named": true - }, - { - "type": "generator_function_declaration", - "named": true - }, - { - "type": "import_alias", - "named": true - }, - { - "type": "interface_declaration", - "named": true - }, - { - "type": "internal_module", - "named": true - }, - { - "type": "lexical_declaration", - "named": true - }, - { - "type": "module", - "named": true - }, - { - "type": "type_alias_declaration", - "named": true - }, - { - "type": "variable_declaration", - "named": true - } - ] - }, - { - "type": "expression", - "named": true, - "subtypes": [ - { - "type": "as_expression", - "named": true - }, - { - "type": "assignment_expression", - "named": true - }, - { - "type": "augmented_assignment_expression", - "named": true - }, - { - "type": "await_expression", - "named": true - }, - { - "type": "binary_expression", - "named": true - }, - { - "type": "glimmer_template", - "named": true - }, - { - "type": "instantiation_expression", - "named": true - }, - { - "type": "internal_module", - "named": true - }, - { - "type": "jsx_element", - "named": true - }, - { - "type": "jsx_self_closing_element", - "named": true - }, - { - "type": "new_expression", - "named": true - }, - { - "type": "primary_expression", - "named": true - }, - { - "type": "satisfies_expression", - "named": true - }, - { - "type": "ternary_expression", - "named": true - }, - { - "type": "unary_expression", - "named": true - }, - { - "type": "update_expression", - "named": true - }, - { - "type": "yield_expression", - "named": true - } - ] - }, - { - "type": "pattern", - "named": true, - "subtypes": [ - { - "type": "array_pattern", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "non_null_expression", - "named": true - }, - { - "type": "object_pattern", - "named": true - }, - { - "type": "rest_pattern", - "named": true - }, - { - "type": "subscript_expression", - "named": true - }, - { - "type": "undefined", - "named": true - } - ] - }, - { - "type": "primary_expression", - "named": true, - "subtypes": [ - { - "type": "array", - "named": true - }, - { - "type": "arrow_function", - "named": true - }, - { - "type": "call_expression", - "named": true - }, - { - "type": "class", - "named": true - }, - { - "type": "false", - "named": true - }, - { - "type": "function_expression", - "named": true - }, - { - "type": "generator_function", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "meta_property", - "named": true - }, - { - "type": "non_null_expression", - "named": true - }, - { - "type": "null", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "object", - "named": true - }, - { - "type": "parenthesized_expression", - "named": true - }, - { - "type": "regex", - "named": true - }, - { - "type": "string", - "named": true - }, - { - "type": "subscript_expression", - "named": true - }, - { - "type": "super", - "named": true - }, - { - "type": "template_string", - "named": true - }, - { - "type": "this", - "named": true - }, - { - "type": "true", - "named": true - }, - { - "type": "undefined", - "named": true - } - ] - }, - { - "type": "statement", - "named": true, - "subtypes": [ - { - "type": "break_statement", - "named": true - }, - { - "type": "continue_statement", - "named": true - }, - { - "type": "debugger_statement", - "named": true - }, - { - "type": "declaration", - "named": true - }, - { - "type": "do_statement", - "named": true - }, - { - "type": "empty_statement", - "named": true - }, - { - "type": "export_statement", - "named": true - }, - { - "type": "expression_statement", - "named": true - }, - { - "type": "for_in_statement", - "named": true - }, - { - "type": "for_statement", - "named": true - }, - { - "type": "if_statement", - "named": true - }, - { - "type": "import_statement", - "named": true - }, - { - "type": "labeled_statement", - "named": true - }, - { - "type": "return_statement", - "named": true - }, - { - "type": "statement_block", - "named": true - }, - { - "type": "switch_statement", - "named": true - }, - { - "type": "throw_statement", - "named": true - }, - { - "type": "try_statement", - "named": true - }, - { - "type": "while_statement", - "named": true - }, - { - "type": "with_statement", - "named": true - } - ] - }, - { - "type": "abstract_class_declaration", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "class_body", - "named": true - } - ] - }, - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "class_heritage", - "named": true - } - ] - } - }, - { - "type": "abstract_method_signature", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "accessibility_modifier", - "named": true - }, - { - "type": "override_modifier", - "named": true - } - ] - } - }, - { - "type": "accessibility_modifier", - "named": true, - "fields": {} - }, - { - "type": "adding_type_annotation", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "ambient_declaration", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "declaration", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "readonly_type", - "named": true - }, - { - "type": "statement_block", - "named": true - } - ] - } - }, - { - "type": "arguments", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "spread_element", - "named": true - } - ] - } - }, - { - "type": "array", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "spread_element", - "named": true - } - ] - } - }, - { - "type": "array_pattern", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "assignment_pattern", - "named": true - }, - { - "type": "pattern", - "named": true - } - ] - } - }, - { - "type": "array_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - } - ] - } - }, - { - "type": "arrow_function", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "statement_block", - "named": true - } - ] - }, - "parameter": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "as_expression", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "expression", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "asserts", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "this", - "named": true - }, - { - "type": "type_predicate", - "named": true - } - ] - } - }, - { - "type": "asserts_annotation", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "asserts", - "named": true - } - ] - } - }, - { - "type": "assignment_expression", - "named": true, - "fields": { - "left": { - "multiple": false, - "required": true, - "types": [ - { - "type": "array_pattern", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "non_null_expression", - "named": true - }, - { - "type": "object_pattern", - "named": true - }, - { - "type": "parenthesized_expression", - "named": true - }, - { - "type": "subscript_expression", - "named": true - }, - { - "type": "undefined", - "named": true - } - ] - }, - "right": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "assignment_pattern", - "named": true, - "fields": { - "left": { - "multiple": false, - "required": true, - "types": [ - { - "type": "pattern", - "named": true - } - ] - }, - "right": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "augmented_assignment_expression", - "named": true, - "fields": { - "left": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "non_null_expression", - "named": true - }, - { - "type": "parenthesized_expression", - "named": true - }, - { - "type": "subscript_expression", - "named": true - } - ] - }, - "operator": { - "multiple": false, - "required": true, - "types": [ - { - "type": "%=", - "named": false - }, - { - "type": "&&=", - "named": false - }, - { - "type": "&=", - "named": false - }, - { - "type": "**=", - "named": false - }, - { - "type": "*=", - "named": false - }, - { - "type": "+=", - "named": false - }, - { - "type": "-=", - "named": false - }, - { - "type": "/=", - "named": false - }, - { - "type": "<<=", - "named": false - }, - { - "type": ">>=", - "named": false - }, - { - "type": ">>>=", - "named": false - }, - { - "type": "??=", - "named": false - }, - { - "type": "^=", - "named": false - }, - { - "type": "|=", - "named": false - }, - { - "type": "||=", - "named": false - } - ] - }, - "right": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "await_expression", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - { - "type": "binary_expression", - "named": true, - "fields": { - "left": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - } - ] - }, - "operator": { - "multiple": false, - "required": true, - "types": [ - { - "type": "!=", - "named": false - }, - { - "type": "!==", - "named": false - }, - { - "type": "%", - "named": false - }, - { - "type": "&", - "named": false - }, - { - "type": "&&", - "named": false - }, - { - "type": "*", - "named": false - }, - { - "type": "**", - "named": false - }, - { - "type": "+", - "named": false - }, - { - "type": "-", - "named": false - }, - { - "type": "/", - "named": false - }, - { - "type": "<", - "named": false - }, - { - "type": "<<", - "named": false - }, - { - "type": "<=", - "named": false - }, - { - "type": "==", - "named": false - }, - { - "type": "===", - "named": false - }, - { - "type": ">", - "named": false - }, - { - "type": ">=", - "named": false - }, - { - "type": ">>", - "named": false - }, - { - "type": ">>>", - "named": false - }, - { - "type": "??", - "named": false - }, - { - "type": "^", - "named": false - }, - { - "type": "in", - "named": false - }, - { - "type": "instanceof", - "named": false - }, - { - "type": "|", - "named": false - }, - { - "type": "||", - "named": false - } - ] - }, - "right": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "break_statement", - "named": true, - "fields": { - "label": { - "multiple": false, - "required": false, - "types": [ - { - "type": "statement_identifier", - "named": true - } - ] - } - } - }, - { - "type": "call_expression", - "named": true, - "fields": { - "arguments": { - "multiple": false, - "required": true, - "types": [ - { - "type": "arguments", - "named": true - }, - { - "type": "template_string", - "named": true - } - ] - }, - "function": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "import", - "named": true - } - ] - }, - "type_arguments": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_arguments", - "named": true - } - ] - } - } - }, - { - "type": "call_signature", - "named": true, - "fields": { - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "catch_clause", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "parameter": { - "multiple": false, - "required": false, - "types": [ - { - "type": "array_pattern", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "object_pattern", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - } - } - }, - { - "type": "class", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "class_body", - "named": true - } - ] - }, - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "class_heritage", - "named": true - } - ] - } - }, - { - "type": "class_body", - "named": true, - "fields": { - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "abstract_method_signature", - "named": true - }, - { - "type": "class_static_block", - "named": true - }, - { - "type": "index_signature", - "named": true - }, - { - "type": "method_definition", - "named": true - }, - { - "type": "method_signature", - "named": true - }, - { - "type": "public_field_definition", - "named": true - } - ] - } - }, - { - "type": "class_declaration", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "class_body", - "named": true - } - ] - }, - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "class_heritage", - "named": true - } - ] - } - }, - { - "type": "class_heritage", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "extends_clause", - "named": true - }, - { - "type": "implements_clause", - "named": true - } - ] - } - }, - { - "type": "class_static_block", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - } - } - }, - { - "type": "comment", - "named": true, - "fields": {} - }, - { - "type": "computed_property_name", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - { - "type": "conditional_type", - "named": true, - "fields": { - "alternative": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - }, - "consequence": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - }, - "left": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - }, - "right": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - } - }, - { - "type": "constraint", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "construct_signature", - "named": true, - "fields": { - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "constructor_type", - "named": true, - "fields": { - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "continue_statement", - "named": true, - "fields": { - "label": { - "multiple": false, - "required": false, - "types": [ - { - "type": "statement_identifier", - "named": true - } - ] - } - } - }, - { - "type": "debugger_statement", - "named": true, - "fields": {} - }, - { - "type": "decorator", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "call_expression", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - } - ] - } - }, - { - "type": "default_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "do_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - }, - "condition": { - "multiple": false, - "required": true, - "types": [ - { - "type": "parenthesized_expression", - "named": true - } - ] - } - } - }, - { - "type": "else_clause", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - } - }, - { - "type": "empty_statement", - "named": true, - "fields": {} - }, - { - "type": "enum_assignment", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "enum_body", - "named": true, - "fields": { - "name": { - "multiple": true, - "required": false, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "enum_assignment", - "named": true - } - ] - } - }, - { - "type": "enum_declaration", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "enum_body", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - } - ] - } - } - }, - { - "type": "existential_type", - "named": true, - "fields": {} - }, - { - "type": "export_clause", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "export_specifier", - "named": true - } - ] - } - }, - { - "type": "export_specifier", - "named": true, - "fields": { - "alias": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - } - } - }, - { - "type": "export_statement", - "named": true, - "fields": { - "declaration": { - "multiple": false, - "required": false, - "types": [ - { - "type": "declaration", - "named": true - } - ] - }, - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - }, - "source": { - "multiple": false, - "required": false, - "types": [ - { - "type": "string", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "export_clause", - "named": true - }, - { - "type": "expression", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "namespace_export", - "named": true - } - ] - } - }, - { - "type": "expression_statement", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - } - }, - { - "type": "extends_clause", - "named": true, - "fields": { - "type_arguments": { - "multiple": true, - "required": false, - "types": [ - { - "type": "type_arguments", - "named": true - } - ] - }, - "value": { - "multiple": true, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "extends_type_clause", - "named": true, - "fields": { - "type": { - "multiple": true, - "required": true, - "types": [ - { - "type": "generic_type", - "named": true - }, - { - "type": "nested_type_identifier", - "named": true - }, - { - "type": "type_identifier", - "named": true - } - ] - } - } - }, - { - "type": "finally_clause", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - } - } - }, - { - "type": "flow_maybe_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - } - ] - } - }, - { - "type": "for_in_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - }, - "kind": { - "multiple": false, - "required": false, - "types": [ - { - "type": "const", - "named": false - }, - { - "type": "let", - "named": false - }, - { - "type": "var", - "named": false - } - ] - }, - "left": { - "multiple": false, - "required": true, - "types": [ - { - "type": "array_pattern", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "non_null_expression", - "named": true - }, - { - "type": "object_pattern", - "named": true - }, - { - "type": "parenthesized_expression", - "named": true - }, - { - "type": "subscript_expression", - "named": true - }, - { - "type": "undefined", - "named": true - } - ] - }, - "operator": { - "multiple": false, - "required": true, - "types": [ - { - "type": "in", - "named": false - }, - { - "type": "of", - "named": false - } - ] - }, - "right": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "for_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - }, - "condition": { - "multiple": false, - "required": true, - "types": [ - { - "type": "empty_statement", - "named": true - }, - { - "type": "expression_statement", - "named": true - } - ] - }, - "increment": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - }, - "initializer": { - "multiple": false, - "required": true, - "types": [ - { - "type": "empty_statement", - "named": true - }, - { - "type": "expression_statement", - "named": true - }, - { - "type": "lexical_declaration", - "named": true - }, - { - "type": "variable_declaration", - "named": true - } - ] - } - } - }, - { - "type": "formal_parameters", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "optional_parameter", - "named": true - }, - { - "type": "required_parameter", - "named": true - } - ] - } - }, - { - "type": "function_declaration", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "function_expression", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "function_signature", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "function_type", - "named": true, - "fields": { - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "asserts", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - }, - { - "type": "type_predicate", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "generator_function", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "generator_function_declaration", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - } - }, - { - "type": "generic_type", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "nested_type_identifier", - "named": true - }, - { - "type": "type_identifier", - "named": true - } - ] - }, - "type_arguments": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_arguments", - "named": true - } - ] - } - } - }, - { - "type": "glimmer_closing_tag", - "named": true, - "fields": {} - }, - { - "type": "glimmer_opening_tag", - "named": true, - "fields": {} - }, - { - "type": "glimmer_template", - "named": true, - "fields": { - "close_tag": { - "multiple": false, - "required": true, - "types": [ - { - "type": "glimmer_closing_tag", - "named": true - } - ] - }, - "open_tag": { - "multiple": false, - "required": true, - "types": [ - { - "type": "glimmer_opening_tag", - "named": true - } - ] - } - } - }, - { - "type": "identifier", - "named": true, - "fields": {} - }, - { - "type": "if_statement", - "named": true, - "fields": { - "alternative": { - "multiple": false, - "required": false, - "types": [ - { - "type": "else_clause", - "named": true - } - ] - }, - "condition": { - "multiple": false, - "required": true, - "types": [ - { - "type": "parenthesized_expression", - "named": true - } - ] - }, - "consequence": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - } - } - }, - { - "type": "implements_clause", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "import", - "named": true, - "fields": {} - }, - { - "type": "import_alias", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "nested_identifier", - "named": true - } - ] - } - }, - { - "type": "import_attribute", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "object", - "named": true - } - ] - } - }, - { - "type": "import_clause", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "named_imports", - "named": true - }, - { - "type": "namespace_import", - "named": true - } - ] - } - }, - { - "type": "import_require_clause", - "named": true, - "fields": { - "source": { - "multiple": false, - "required": true, - "types": [ - { - "type": "string", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - } - ] - } - }, - { - "type": "import_specifier", - "named": true, - "fields": { - "alias": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - } - } - }, - { - "type": "import_statement", - "named": true, - "fields": { - "source": { - "multiple": false, - "required": false, - "types": [ - { - "type": "string", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "import_attribute", - "named": true - }, - { - "type": "import_clause", - "named": true - }, - { - "type": "import_require_clause", - "named": true - } - ] - } - }, - { - "type": "index_signature", - "named": true, - "fields": { - "index_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "sign": { - "multiple": false, - "required": false, - "types": [ - { - "type": "+", - "named": false - }, - { - "type": "-", - "named": false - } - ] - }, - "type": { - "multiple": false, - "required": true, - "types": [ - { - "type": "adding_type_annotation", - "named": true - }, - { - "type": "omitting_type_annotation", - "named": true - }, - { - "type": "opting_type_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "mapped_type_clause", - "named": true - } - ] - } - }, - { - "type": "index_type_query", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - } - ] - } - }, - { - "type": "infer_type", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "instantiation_expression", - "named": true, - "fields": { - "function": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "import", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "subscript_expression", - "named": true - } - ] - }, - "type_arguments": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_arguments", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - { - "type": "interface_body", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "call_signature", - "named": true - }, - { - "type": "construct_signature", - "named": true - }, - { - "type": "export_statement", - "named": true - }, - { - "type": "index_signature", - "named": true - }, - { - "type": "method_signature", - "named": true - }, - { - "type": "property_signature", - "named": true - } - ] - } - }, - { - "type": "interface_declaration", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "interface_body", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "extends_type_clause", - "named": true - } - ] - } - }, - { - "type": "internal_module", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": false, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "nested_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - } - } - }, - { - "type": "intersection_type", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "jsx_attribute", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "jsx_element", - "named": true - }, - { - "type": "jsx_expression", - "named": true - }, - { - "type": "jsx_namespace_name", - "named": true - }, - { - "type": "jsx_self_closing_element", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - } - }, - { - "type": "jsx_closing_element", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "jsx_namespace_name", - "named": true - }, - { - "type": "member_expression", - "named": true - } - ] - } - } - }, - { - "type": "jsx_element", - "named": true, - "fields": { - "close_tag": { - "multiple": false, - "required": true, - "types": [ - { - "type": "jsx_closing_element", - "named": true - } - ] - }, - "open_tag": { - "multiple": false, - "required": true, - "types": [ - { - "type": "jsx_opening_element", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "html_character_reference", - "named": true - }, - { - "type": "jsx_element", - "named": true - }, - { - "type": "jsx_expression", - "named": true - }, - { - "type": "jsx_self_closing_element", - "named": true - }, - { - "type": "jsx_text", - "named": true - } - ] - } - }, - { - "type": "jsx_expression", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - }, - { - "type": "spread_element", - "named": true - } - ] - } - }, - { - "type": "jsx_namespace_name", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - } - ] - } - }, - { - "type": "jsx_opening_element", - "named": true, - "fields": { - "attribute": { - "multiple": true, - "required": false, - "types": [ - { - "type": "jsx_attribute", - "named": true - }, - { - "type": "jsx_expression", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "jsx_namespace_name", - "named": true - }, - { - "type": "member_expression", - "named": true - } - ] - }, - "type_arguments": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_arguments", - "named": true - } - ] - } - } - }, - { - "type": "jsx_self_closing_element", - "named": true, - "fields": { - "attribute": { - "multiple": true, - "required": false, - "types": [ - { - "type": "jsx_attribute", - "named": true - }, - { - "type": "jsx_expression", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "jsx_namespace_name", - "named": true - }, - { - "type": "member_expression", - "named": true - } - ] - }, - "type_arguments": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_arguments", - "named": true - } - ] - } - } - }, - { - "type": "jsx_text", - "named": true, - "fields": {} - }, - { - "type": "labeled_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - }, - "label": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_identifier", - "named": true - } - ] - } - } - }, - { - "type": "lexical_declaration", - "named": true, - "fields": { - "kind": { - "multiple": false, - "required": true, - "types": [ - { - "type": "const", - "named": false - }, - { - "type": "let", - "named": false - } - ] - } - }, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "variable_declarator", - "named": true - } - ] - } - }, - { - "type": "literal_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "false", - "named": true - }, - { - "type": "null", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "string", - "named": true - }, - { - "type": "true", - "named": true - }, - { - "type": "unary_expression", - "named": true - }, - { - "type": "undefined", - "named": true - } - ] - } - }, - { - "type": "lookup_type", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "mapped_type_clause", - "named": true, - "fields": { - "alias": { - "multiple": false, - "required": false, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - } - }, - { - "type": "member_expression", - "named": true, - "fields": { - "object": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "import", - "named": true - } - ] - }, - "optional_chain": { - "multiple": false, - "required": false, - "types": [ - { - "type": "optional_chain", - "named": true - } - ] - }, - "property": { - "multiple": false, - "required": true, - "types": [ - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - } - ] - } - } - }, - { - "type": "meta_property", - "named": true, - "fields": {} - }, - { - "type": "method_definition", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "accessibility_modifier", - "named": true - }, - { - "type": "override_modifier", - "named": true - } - ] - } - }, - { - "type": "method_signature", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "parameters": { - "multiple": false, - "required": true, - "types": [ - { - "type": "formal_parameters", - "named": true - } - ] - }, - "return_type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "asserts_annotation", - "named": true - }, - { - "type": "type_annotation", - "named": true - }, - { - "type": "type_predicate_annotation", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "accessibility_modifier", - "named": true - }, - { - "type": "override_modifier", - "named": true - } - ] - } - }, - { - "type": "module", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": false, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "nested_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - } - } - }, - { - "type": "named_imports", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "import_specifier", - "named": true - } - ] - } - }, - { - "type": "namespace_export", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - } - }, - { - "type": "namespace_import", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - } - ] - } - }, - { - "type": "nested_identifier", - "named": true, - "fields": { - "object": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - } - ] - }, - "property": { - "multiple": false, - "required": true, - "types": [ - { - "type": "property_identifier", - "named": true - } - ] - } - } - }, - { - "type": "nested_type_identifier", - "named": true, - "fields": { - "module": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "nested_identifier", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - } - } - }, - { - "type": "new_expression", - "named": true, - "fields": { - "arguments": { - "multiple": false, - "required": false, - "types": [ - { - "type": "arguments", - "named": true - } - ] - }, - "constructor": { - "multiple": false, - "required": true, - "types": [ - { - "type": "primary_expression", - "named": true - } - ] - }, - "type_arguments": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_arguments", - "named": true - } - ] - } - } - }, - { - "type": "non_null_expression", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - { - "type": "object", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "method_definition", - "named": true - }, - { - "type": "pair", - "named": true - }, - { - "type": "shorthand_property_identifier", - "named": true - }, - { - "type": "spread_element", - "named": true - } - ] - } - }, - { - "type": "object_assignment_pattern", - "named": true, - "fields": { - "left": { - "multiple": false, - "required": true, - "types": [ - { - "type": "array_pattern", - "named": true - }, - { - "type": "object_pattern", - "named": true - }, - { - "type": "shorthand_property_identifier_pattern", - "named": true - } - ] - }, - "right": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "object_pattern", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "object_assignment_pattern", - "named": true - }, - { - "type": "pair_pattern", - "named": true - }, - { - "type": "rest_pattern", - "named": true - }, - { - "type": "shorthand_property_identifier_pattern", - "named": true - } - ] - } - }, - { - "type": "object_type", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "call_signature", - "named": true - }, - { - "type": "construct_signature", - "named": true - }, - { - "type": "export_statement", - "named": true - }, - { - "type": "index_signature", - "named": true - }, - { - "type": "method_signature", - "named": true - }, - { - "type": "property_signature", - "named": true - } - ] - } - }, - { - "type": "omitting_type_annotation", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "opting_type_annotation", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "optional_chain", - "named": true, - "fields": {} - }, - { - "type": "optional_parameter", - "named": true, - "fields": { - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - } - ] - }, - "pattern": { - "multiple": false, - "required": false, - "types": [ - { - "type": "pattern", - "named": true - }, - { - "type": "this", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "accessibility_modifier", - "named": true - }, - { - "type": "override_modifier", - "named": true - } - ] - } - }, - { - "type": "optional_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "override_modifier", - "named": true, - "fields": {} - }, - { - "type": "pair", - "named": true, - "fields": { - "key": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "pair_pattern", - "named": true, - "fields": { - "key": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": true, - "types": [ - { - "type": "assignment_pattern", - "named": true - }, - { - "type": "pattern", - "named": true - } - ] - } - } - }, - { - "type": "parenthesized_expression", - "named": true, - "fields": { - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - } - }, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - } - }, - { - "type": "parenthesized_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "predefined_type", - "named": true, - "fields": {} - }, - { - "type": "program", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "hash_bang_line", - "named": true - }, - { - "type": "statement", - "named": true - } - ] - } - }, - { - "type": "property_signature", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "accessibility_modifier", - "named": true - }, - { - "type": "override_modifier", - "named": true - } - ] - } - }, - { - "type": "public_field_definition", - "named": true, - "fields": { - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "computed_property_name", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "private_property_identifier", - "named": true - }, - { - "type": "property_identifier", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "accessibility_modifier", - "named": true - }, - { - "type": "override_modifier", - "named": true - } - ] - } - }, - { - "type": "readonly_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "regex", - "named": true, - "fields": { - "flags": { - "multiple": false, - "required": false, - "types": [ - { - "type": "regex_flags", - "named": true - } - ] - }, - "pattern": { - "multiple": false, - "required": true, - "types": [ - { - "type": "regex_pattern", - "named": true - } - ] - } - } - }, - { - "type": "required_parameter", - "named": true, - "fields": { - "decorator": { - "multiple": true, - "required": false, - "types": [ - { - "type": "decorator", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": false, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "rest_pattern", - "named": true - } - ] - }, - "pattern": { - "multiple": false, - "required": false, - "types": [ - { - "type": "pattern", - "named": true - }, - { - "type": "this", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "accessibility_modifier", - "named": true - }, - { - "type": "override_modifier", - "named": true - } - ] - } - }, - { - "type": "rest_pattern", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "array_pattern", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "non_null_expression", - "named": true - }, - { - "type": "object_pattern", - "named": true - }, - { - "type": "subscript_expression", - "named": true - }, - { - "type": "undefined", - "named": true - } - ] - } - }, - { - "type": "rest_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "return_statement", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - } - }, - { - "type": "satisfies_expression", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "expression", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "sequence_expression", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - { - "type": "spread_element", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - { - "type": "statement_block", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "statement", - "named": true - } - ] - } - }, - { - "type": "string", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "escape_sequence", - "named": true - }, - { - "type": "html_character_reference", - "named": true - }, - { - "type": "string_fragment", - "named": true - } - ] - } - }, - { - "type": "subscript_expression", - "named": true, - "fields": { - "index": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "number", - "named": true - }, - { - "type": "predefined_type", - "named": true - }, - { - "type": "sequence_expression", - "named": true - }, - { - "type": "string", - "named": true - } - ] - }, - "object": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - }, - "optional_chain": { - "multiple": false, - "required": false, - "types": [ - { - "type": "optional_chain", - "named": true - } - ] - } - } - }, - { - "type": "switch_body", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "switch_case", - "named": true - }, - { - "type": "switch_default", - "named": true - } - ] - } - }, - { - "type": "switch_case", - "named": true, - "fields": { - "body": { - "multiple": true, - "required": false, - "types": [ - { - "type": "statement", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - } - } - }, - { - "type": "switch_default", - "named": true, - "fields": { - "body": { - "multiple": true, - "required": false, - "types": [ - { - "type": "statement", - "named": true - } - ] - } - } - }, - { - "type": "switch_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "switch_body", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": true, - "types": [ - { - "type": "parenthesized_expression", - "named": true - } - ] - } - } - }, - { - "type": "template_literal_type", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "template_type", - "named": true - } - ] - } - }, - { - "type": "template_string", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "escape_sequence", - "named": true - }, - { - "type": "string_fragment", - "named": true - }, - { - "type": "template_substitution", - "named": true - } - ] - } - }, - { - "type": "template_substitution", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - } - }, - { - "type": "template_type", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "infer_type", - "named": true - } - ] - } - }, - { - "type": "ternary_expression", - "named": true, - "fields": { - "alternative": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - }, - "condition": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - }, - "consequence": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "throw_statement", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "sequence_expression", - "named": true - } - ] - } - }, - { - "type": "try_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement_block", - "named": true - } - ] - }, - "finalizer": { - "multiple": false, - "required": false, - "types": [ - { - "type": "finally_clause", - "named": true - } - ] - }, - "handler": { - "multiple": false, - "required": false, - "types": [ - { - "type": "catch_clause", - "named": true - } - ] - } - } - }, - { - "type": "tuple_type", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "optional_parameter", - "named": true - }, - { - "type": "optional_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - }, - { - "type": "required_parameter", - "named": true - }, - { - "type": "rest_type", - "named": true - } - ] - } - }, - { - "type": "type_alias_declaration", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - }, - "type_parameters": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_parameters", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - } - }, - { - "type": "type_annotation", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "call_expression", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "type_arguments", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "call_expression", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "type_parameter", - "named": true, - "fields": { - "constraint": { - "multiple": false, - "required": false, - "types": [ - { - "type": "constraint", - "named": true - } - ] - }, - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_identifier", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": false, - "types": [ - { - "type": "default_type", - "named": true - } - ] - } - } - }, - { - "type": "type_parameters", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "type_parameter", - "named": true - } - ] - } - }, - { - "type": "type_predicate", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "identifier", - "named": true - }, - { - "type": "this", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - } - }, - { - "type": "type_predicate_annotation", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "type_predicate", - "named": true - } - ] - } - }, - { - "type": "type_query", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": true, - "types": [ - { - "type": "call_expression", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "instantiation_expression", - "named": true - }, - { - "type": "member_expression", - "named": true - }, - { - "type": "subscript_expression", - "named": true - } - ] - } - }, - { - "type": "unary_expression", - "named": true, - "fields": { - "argument": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - }, - { - "type": "number", - "named": true - } - ] - }, - "operator": { - "multiple": false, - "required": true, - "types": [ - { - "type": "!", - "named": false - }, - { - "type": "+", - "named": false - }, - { - "type": "-", - "named": false - }, - { - "type": "delete", - "named": false - }, - { - "type": "typeof", - "named": false - }, - { - "type": "void", - "named": false - }, - { - "type": "~", - "named": false - } - ] - } - } - }, - { - "type": "union_type", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "_primary_type", - "named": true - }, - { - "type": "constructor_type", - "named": true - }, - { - "type": "function_type", - "named": true - }, - { - "type": "infer_type", - "named": true - }, - { - "type": "readonly_type", - "named": true - } - ] - } - }, - { - "type": "update_expression", - "named": true, - "fields": { - "argument": { - "multiple": false, - "required": true, - "types": [ - { - "type": "expression", - "named": true - } - ] - }, - "operator": { - "multiple": false, - "required": true, - "types": [ - { - "type": "++", - "named": false - }, - { - "type": "--", - "named": false - } - ] - } - } - }, - { - "type": "variable_declaration", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "variable_declarator", - "named": true - } - ] - } - }, - { - "type": "variable_declarator", - "named": true, - "fields": { - "name": { - "multiple": false, - "required": true, - "types": [ - { - "type": "array_pattern", - "named": true - }, - { - "type": "identifier", - "named": true - }, - { - "type": "object_pattern", - "named": true - } - ] - }, - "type": { - "multiple": false, - "required": false, - "types": [ - { - "type": "type_annotation", - "named": true - } - ] - }, - "value": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - } - }, - { - "type": "while_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - }, - "condition": { - "multiple": false, - "required": true, - "types": [ - { - "type": "parenthesized_expression", - "named": true - } - ] - } - } - }, - { - "type": "with_statement", - "named": true, - "fields": { - "body": { - "multiple": false, - "required": true, - "types": [ - { - "type": "statement", - "named": true - } - ] - }, - "object": { - "multiple": false, - "required": true, - "types": [ - { - "type": "parenthesized_expression", - "named": true - } - ] - } - } - }, - { - "type": "yield_expression", - "named": true, - "fields": {}, - "children": { - "multiple": false, - "required": false, - "types": [ - { - "type": "expression", - "named": true - } - ] - } - }, - { - "type": "!", - "named": false - }, - { - "type": "!=", - "named": false - }, - { - "type": "!==", - "named": false - }, - { - "type": "\"", - "named": false - }, - { - "type": "${", - "named": false - }, - { - "type": "%", - "named": false - }, - { - "type": "%=", - "named": false - }, - { - "type": "&", - "named": false - }, - { - "type": "&&", - "named": false - }, - { - "type": "&&=", - "named": false - }, - { - "type": "&=", - "named": false - }, - { - "type": "'", - "named": false - }, - { - "type": "(", - "named": false - }, - { - "type": ")", - "named": false - }, - { - "type": "*", - "named": false - }, - { - "type": "**", - "named": false - }, - { - "type": "**=", - "named": false - }, - { - "type": "*=", - "named": false - }, - { - "type": "+", - "named": false - }, - { - "type": "++", - "named": false - }, - { - "type": "+=", - "named": false - }, - { - "type": "+?:", - "named": false - }, - { - "type": ",", - "named": false - }, - { - "type": "-", - "named": false - }, - { - "type": "--", - "named": false - }, - { - "type": "-=", - "named": false - }, - { - "type": "-?:", - "named": false - }, - { - "type": ".", - "named": false - }, - { - "type": "...", - "named": false - }, - { - "type": "/", - "named": false - }, - { - "type": "/=", - "named": false - }, - { - "type": "/>", - "named": false - }, - { - "type": ":", - "named": false - }, - { - "type": ";", - "named": false - }, - { - "type": "<", - "named": false - }, - { - "type": "", - "named": false - }, - { - "type": "<<", - "named": false - }, - { - "type": "<<=", - "named": false - }, - { - "type": "<=", - "named": false - }, - { - "type": "