├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml └── workflows │ ├── ci.yml │ ├── fuzz.yml │ ├── lint.yml │ └── publish.yml ├── .gitignore ├── CMakeLists.txt ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.resolved ├── Package.swift ├── README.md ├── binding.gyp ├── bindings ├── c │ ├── tree-sitter-tsx.h │ ├── tree-sitter-tsx.pc.in │ ├── tree-sitter-typescript.h │ └── tree-sitter-typescript.pc.in ├── go │ ├── binding_test.go │ ├── tsx.go │ └── typescript.go ├── node │ ├── binding.cc │ ├── binding_test.js │ ├── index.d.ts │ ├── index.js │ ├── tsx.js │ └── typescript.js ├── python │ ├── tests │ │ └── test_binding.py │ └── tree_sitter_typescript │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed ├── rust │ ├── build.rs │ └── lib.rs └── swift │ ├── TreeSitterTypeScriptTests │ └── TreeSitterTypeScriptTests.swift │ ├── tsx │ └── TreeSitterTSX │ │ └── tsx.h │ └── typescript │ └── TreeSitterTypeScript │ └── typescript.h ├── common ├── common.mak ├── define-grammar.js └── scanner.h ├── eslint.config.mjs ├── examples └── parser.ts ├── go.mod ├── go.sum ├── package-lock.json ├── package.json ├── pyproject.toml ├── queries ├── highlights.scm ├── locals.scm └── tags.scm ├── setup.py ├── test └── corpus │ ├── declarations.txt │ ├── expressions.txt │ ├── functions.txt │ └── types.txt ├── tree-sitter.json ├── tsx ├── CMakeLists.txt ├── Makefile ├── grammar.js ├── package.json └── src │ ├── grammar.json │ ├── node-types.json │ ├── parser.c │ ├── scanner.c │ └── tree_sitter │ ├── alloc.h │ ├── array.h │ └── parser.h └── typescript ├── CMakeLists.txt ├── Makefile ├── grammar.js ├── package.json └── src ├── grammar.json ├── node-types.json ├── parser.c ├── scanner.c └── tree_sitter ├── alloc.h ├── array.h └── parser.h /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | 6 | [*.{json,toml,yml,gyp}] 7 | indent_style = space 8 | indent_size = 2 9 | 10 | [*.js] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.scm] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [*.{c,cc,h}] 19 | indent_style = space 20 | indent_size = 4 21 | 22 | [*.rs] 23 | indent_style = space 24 | indent_size = 4 25 | 26 | [*.{py,pyi}] 27 | indent_style = space 28 | indent_size = 4 29 | 30 | [*.swift] 31 | indent_style = space 32 | indent_size = 4 33 | 34 | [*.go] 35 | indent_style = tab 36 | indent_size = 8 37 | 38 | [Makefile] 39 | indent_style = tab 40 | indent_size = 8 41 | 42 | [parser.c] 43 | indent_size = 2 44 | 45 | [{alloc,array,parser}.h] 46 | indent_size = 2 47 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | 3 | # Generated source files 4 | typescript/src/*.json linguist-generated 5 | typescript/src/parser.c linguist-generated 6 | typescript/src/tree_sitter/* linguist-generated 7 | 8 | tsx/src/*.json linguist-generated 9 | tsx/src/parser.c linguist-generated 10 | tsx/src/tree_sitter/* linguist-generated 11 | 12 | # C bindings 13 | bindings/c/* linguist-generated 14 | CMakeLists.txt linguist-generated 15 | Makefile linguist-generated 16 | 17 | # Rust bindings 18 | bindings/rust/* linguist-generated 19 | Cargo.toml linguist-generated 20 | Cargo.lock linguist-generated 21 | 22 | # Node.js bindings 23 | bindings/node/* linguist-generated 24 | binding.gyp linguist-generated 25 | package.json linguist-generated 26 | package-lock.json linguist-generated 27 | 28 | # Python bindings 29 | bindings/python/** linguist-generated 30 | setup.py linguist-generated 31 | pyproject.toml linguist-generated 32 | 33 | # Go bindings 34 | bindings/go/* linguist-generated 35 | go.mod linguist-generated 36 | go.sum linguist-generated 37 | 38 | # Swift bindings 39 | bindings/swift/** linguist-generated 40 | Package.swift linguist-generated 41 | Package.resolved linguist-generated 42 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: tree-sitter 4 | patreon: # Replace with a single Patreon username 5 | open_collective: tree-sitter # Replace with a single Open Collective username 6 | ko_fi: amaanq 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug or issue 3 | title: "bug: " 4 | labels: [bug] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | **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. 10 | 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. 11 | - type: checkboxes 12 | attributes: 13 | label: Did you check existing issues? 14 | description: Make sure you've checked all of the below before submitting an issue 15 | options: 16 | - 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 17 | required: false 18 | - label: I have searched the existing issues of tree-sitter-typescript 19 | required: true 20 | - type: input 21 | attributes: 22 | label: "Tree-Sitter CLI Version, if relevant (output of `tree-sitter --version`)" 23 | placeholder: "tree-sitter 0.20.8 (6bbb50bef8249e6460e7d69e42cc8146622fa4fd)" 24 | validations: 25 | required: false 26 | - type: textarea 27 | attributes: 28 | label: Describe the bug 29 | 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. 30 | validations: 31 | required: true 32 | - type: textarea 33 | attributes: 34 | label: Steps To Reproduce/Bad Parse Tree 35 | 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. 36 | placeholder: | 37 | 1. 38 | 2. 39 | 3. 40 | validations: 41 | required: true 42 | - type: textarea 43 | attributes: 44 | label: Expected Behavior/Parse Tree 45 | description: A concise description of what you expected to happen, or in the case of a bad parse tree, the expected parse tree. 46 | validations: 47 | required: true 48 | - type: textarea 49 | attributes: 50 | label: Repro 51 | 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) 52 | value: | 53 | // Example code that causes the issue 54 | function foo() { 55 | // Code that fails to parse, or causes an error 56 | } 57 | render: TypeScript 58 | validations: 59 | required: false 60 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest a new feature 3 | title: "feature: " 4 | labels: [enhancement] 5 | body: 6 | - type: checkboxes 7 | attributes: 8 | label: Did you check the tree-sitter docs? 9 | description: Make sure you read all the docs before submitting a feature request 10 | options: 11 | - 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 12 | required: false 13 | - type: textarea 14 | validations: 15 | required: true 16 | attributes: 17 | label: Is your feature request related to a problem? Please describe. 18 | 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. 19 | - type: textarea 20 | validations: 21 | required: true 22 | attributes: 23 | label: Describe the solution you'd like 24 | description: A clear and concise description of what you want to happen. 25 | - type: textarea 26 | validations: 27 | required: true 28 | attributes: 29 | label: Describe alternatives you've considered 30 | description: A clear and concise description of any alternative solutions or features you've considered. 31 | - type: textarea 32 | validations: 33 | required: false 34 | attributes: 35 | label: Additional context 36 | 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. 37 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - "scripts.js" 8 | - "common/*" 9 | - "*/grammar.js" 10 | - "*/src/**" 11 | - "bindings/**" 12 | - "binding.gyp" 13 | pull_request: 14 | paths: 15 | - "scripts.js" 16 | - "common/*" 17 | - "*/grammar.js" 18 | - "*/src/**" 19 | - "bindings/**" 20 | - "binding.gyp" 21 | 22 | concurrency: 23 | group: ${{github.workflow}}-${{github.ref}} 24 | cancel-in-progress: true 25 | 26 | jobs: 27 | test: 28 | name: Test parsers 29 | runs-on: ${{matrix.os}} 30 | strategy: 31 | fail-fast: false 32 | matrix: 33 | os: [ubuntu-latest, windows-latest, macos-14] 34 | steps: 35 | - name: Checkout repository 36 | uses: actions/checkout@v4 37 | - name: Set up tree-sitter 38 | uses: tree-sitter/setup-action/cli@v1 39 | - name: Set up examples 40 | run: |- 41 | git clone https://github.com/desktop/desktop examples/desktop --single-branch --depth=1 --filter=blob:none 42 | git clone https://github.com/reduxjs/redux examples/redux --single-branch --depth=1 --filter=blob:none 43 | git clone https://github.com/microsoft/vscode examples/vscode --single-branch --depth=1 --filter=blob:none 44 | - name: Run tests 45 | uses: tree-sitter/parser-test-action@v2 46 | with: 47 | test-rust: true 48 | test-node: true 49 | test-python: true 50 | test-go: true 51 | test-swift: true 52 | - name: Parse examples 53 | id: test 54 | uses: tree-sitter/parse-action@v4 55 | with: 56 | files: | 57 | examples/**/*.ts 58 | examples/**/*.tsx 59 | !examples/redux/src/types/store.ts 60 | !examples/vscode/src/bootstrap-window.ts 61 | !examples/vscode/extensions/vscode-colorize-perf-tests/test/colorize-fixtures/test-checker.ts 62 | -------------------------------------------------------------------------------- /.github/workflows/fuzz.yml: -------------------------------------------------------------------------------- 1 | name: Fuzz Parser 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - typescript/src/scanner.c 8 | - tsx/src/scanner.c 9 | - common/scanner.h 10 | pull_request: 11 | paths: 12 | - typescript/src/scanner.c 13 | - tsx/src/scanner.c 14 | - common/scanner.h 15 | 16 | jobs: 17 | fuzz: 18 | runs-on: ubuntu-latest 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | language: [typescript, tsx] 23 | steps: 24 | - name: Checkout repository 25 | uses: actions/checkout@v4 26 | - name: Fuzz ${{matrix.language}} parser 27 | uses: tree-sitter/fuzz-action@v4 28 | with: 29 | directory: ${{matrix.language}} 30 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - common/define-grammar.js 8 | pull_request: 9 | paths: 10 | - common/define-grammar.js 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | - name: Set up Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | cache: npm 22 | node-version: ${{vars.NODE_VERSION}} 23 | - name: Install modules 24 | run: npm ci --legacy-peer-deps 25 | - name: Run ESLint 26 | run: npm run lint 27 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish packages 2 | 3 | on: 4 | push: 5 | tags: ["*"] 6 | 7 | permissions: 8 | contents: write 9 | id-token: write 10 | attestations: write 11 | 12 | jobs: 13 | github: 14 | uses: tree-sitter/workflows/.github/workflows/release.yml@main 15 | with: 16 | generate: true 17 | attestations: true 18 | npm: 19 | uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main 20 | secrets: 21 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 22 | with: 23 | generate: true 24 | crates: 25 | uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main 26 | secrets: 27 | CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_REGISTRY_TOKEN}} 28 | with: 29 | generate: true 30 | pypi: 31 | uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main 32 | secrets: 33 | PYPI_API_TOKEN: ${{secrets.PYPI_API_TOKEN}} 34 | with: 35 | generate: true 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Rust artifacts 2 | target/ 3 | 4 | # Node artifacts 5 | build/ 6 | prebuilds/ 7 | node_modules/ 8 | 9 | # Swift artifacts 10 | .build/ 11 | 12 | # Go artifacts 13 | _obj/ 14 | 15 | # Python artifacts 16 | .venv/ 17 | dist/ 18 | *.egg-info 19 | *.whl 20 | 21 | # C artifacts 22 | *.a 23 | *.so 24 | *.so.* 25 | *.dylib 26 | *.dll 27 | *.pc 28 | 29 | # Example dirs 30 | /examples/*/ 31 | 32 | # Grammar volatiles 33 | *.wasm 34 | *.obj 35 | *.o 36 | 37 | # Archives 38 | *.tar.gz 39 | *.tgz 40 | *.zip 41 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | project(tree-sitter-typescript 4 | VERSION "0.23.2" 5 | DESCRIPTION "TypeScript and TSX grammars for tree-sitter" 6 | HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-typescript" 7 | LANGUAGES C) 8 | 9 | option(BUILD_SHARED_LIBS "Build using shared libraries" ON) 10 | option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the library allocator" OFF) 11 | 12 | set(TREE_SITTER_ABI_VERSION 14 CACHE STRING "Tree-sitter ABI version") 13 | if(NOT ${TREE_SITTER_ABI_VERSION} MATCHES "^[0-9]+$") 14 | unset(TREE_SITTER_ABI_VERSION CACHE) 15 | message(FATAL_ERROR "TREE_SITTER_ABI_VERSION must be an integer") 16 | endif() 17 | 18 | find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI") 19 | 20 | include(GNUInstallDirs) 21 | 22 | macro(add_parser name) 23 | add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" 24 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" 25 | COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json 26 | --abi=${TREE_SITTER_ABI_VERSION} 27 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 28 | COMMENT "Generating parser.c") 29 | 30 | add_library(tree-sitter-${name} 31 | "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" 32 | "${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c") 33 | target_include_directories(tree-sitter-${name} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src") 34 | 35 | target_compile_definitions(tree-sitter-${name} PRIVATE 36 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 37 | $<$:TREE_SITTER_DEBUG>) 38 | 39 | set_target_properties(tree-sitter-${name} 40 | PROPERTIES 41 | C_STANDARD 11 42 | POSITION_INDEPENDENT_CODE ON 43 | SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}" 44 | DEFINE_SYMBOL "") 45 | 46 | configure_file("${CMAKE_SOURCE_DIR}/bindings/c/tree-sitter-${name}.pc.in" 47 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-${name}.pc" @ONLY) 48 | 49 | install(FILES "${CMAKE_SOURCE_DIR}/bindings/c/tree-sitter-${name}.h" 50 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tree_sitter") 51 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-${name}.pc" 52 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") 53 | install(TARGETS tree-sitter-${name} 54 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 55 | endmacro() 56 | 57 | add_subdirectory(typescript tree-sitter-typescript) 58 | 59 | add_subdirectory(tsx tree-sitter-tsx) 60 | 61 | add_custom_target(ts-test "${TREE_SITTER_CLI}" test 62 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 63 | COMMENT "tree-sitter test") 64 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "cc" 16 | version = "1.1.37" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" 19 | dependencies = [ 20 | "shlex", 21 | ] 22 | 23 | [[package]] 24 | name = "memchr" 25 | version = "2.7.4" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 28 | 29 | [[package]] 30 | name = "regex" 31 | version = "1.11.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 34 | dependencies = [ 35 | "aho-corasick", 36 | "memchr", 37 | "regex-automata", 38 | "regex-syntax", 39 | ] 40 | 41 | [[package]] 42 | name = "regex-automata" 43 | version = "0.4.8" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" 46 | dependencies = [ 47 | "aho-corasick", 48 | "memchr", 49 | "regex-syntax", 50 | ] 51 | 52 | [[package]] 53 | name = "regex-syntax" 54 | version = "0.8.5" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 57 | 58 | [[package]] 59 | name = "shlex" 60 | version = "1.3.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 63 | 64 | [[package]] 65 | name = "streaming-iterator" 66 | version = "0.1.9" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" 69 | 70 | [[package]] 71 | name = "tree-sitter" 72 | version = "0.24.4" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "b67baf55e7e1b6806063b1e51041069c90afff16afcbbccd278d899f9d84bca4" 75 | dependencies = [ 76 | "cc", 77 | "regex", 78 | "regex-syntax", 79 | "streaming-iterator", 80 | "tree-sitter-language", 81 | ] 82 | 83 | [[package]] 84 | name = "tree-sitter-language" 85 | version = "0.1.2" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "e8ddffe35a0e5eeeadf13ff7350af564c6e73993a24db62caee1822b185c2600" 88 | 89 | [[package]] 90 | name = "tree-sitter-typescript" 91 | version = "0.23.2" 92 | dependencies = [ 93 | "cc", 94 | "tree-sitter", 95 | "tree-sitter-language", 96 | ] 97 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-typescript" 3 | description = "TypeScript and TSX grammars for tree-sitter" 4 | version = "0.23.2" 5 | authors = [ 6 | "Max Brunsfeld ", 7 | "Amaan Qureshi ", 8 | ] 9 | license = "MIT" 10 | readme = "README.md" 11 | keywords = ["incremental", "parsing", "tree-sitter", "typescript", "tsx"] 12 | categories = ["parsing", "text-editors"] 13 | repository = "https://github.com/tree-sitter/tree-sitter-typescript" 14 | edition = "2021" 15 | autoexamples = false 16 | 17 | build = "bindings/rust/build.rs" 18 | include = [ 19 | "LICENSE", 20 | "common", 21 | "bindings/rust", 22 | "typescript/grammar.js", 23 | "typescript/src", 24 | "tsx/grammar.js", 25 | "tsx/src", 26 | "queries/*", 27 | "./tree-sitter.json", 28 | ] 29 | 30 | [lib] 31 | path = "bindings/rust/lib.rs" 32 | 33 | [dependencies] 34 | tree-sitter-language = "0.1" 35 | 36 | [build-dependencies] 37 | cc = "1.1" 38 | 39 | [dev-dependencies] 40 | tree-sitter = "0.24" 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Max Brunsfeld 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TS ?= tree-sitter 2 | 3 | all install uninstall clean: 4 | $(MAKE) -C typescript $@ 5 | $(MAKE) -C tsx $@ 6 | 7 | test: 8 | $(TS) test 9 | $(TS) parse examples/* --quiet --time 10 | 11 | .PHONY: all install uninstall clean test update 12 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "SwiftTreeSitter", 6 | "repositoryURL": "https://github.com/ChimeHQ/SwiftTreeSitter", 7 | "state": { 8 | "branch": null, 9 | "revision": "2599e95310b3159641469d8a21baf2d3d200e61f", 10 | "version": "0.8.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "TreeSitterTypeScript", 6 | products: [ 7 | .library(name: "TreeSitterTypeScript", targets: ["TreeSitterTypeScript", "TreeSitterTSX"]), 8 | ], 9 | dependencies: [ 10 | .package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"), 11 | ], 12 | targets: [ 13 | .target( 14 | name: "TreeSitterTypeScript", 15 | path: ".", 16 | sources: [ 17 | "typescript/src/parser.c", 18 | "typescript/src/scanner.c", 19 | ], 20 | resources: [ 21 | .copy("queries") 22 | ], 23 | publicHeadersPath: "bindings/swift/typescript", 24 | cSettings: [.headerSearchPath("typescript/src")] 25 | ), 26 | .target( 27 | name: "TreeSitterTSX", 28 | path: ".", 29 | sources: [ 30 | "tsx/src/parser.c", 31 | "tsx/src/scanner.c", 32 | ], 33 | resources: [ 34 | .copy("queries") 35 | ], 36 | publicHeadersPath: "bindings/swift/tsx", 37 | cSettings: [.headerSearchPath("tsx/src")] 38 | ), 39 | .testTarget( 40 | name: "TreeSitterTypeScriptTests", 41 | dependencies: [ 42 | "SwiftTreeSitter", 43 | "TreeSitterTypeScript", 44 | "TreeSitterTSX", 45 | ], 46 | path: "bindings/swift/TreeSitterTypeScriptTests" 47 | ) 48 | ] 49 | ) 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-typescript 2 | 3 | [![CI][ci]](https://github.com/tree-sitter/tree-sitter-typescript/actions/workflows/ci.yml) 4 | [![discord][discord]](https://discord.gg/w7nTvsVJhm) 5 | [![matrix][matrix]](https://matrix.to/#/#tree-sitter-chat:matrix.org) 6 | [![crates][crates]](https://crates.io/crates/tree-sitter-typescript) 7 | [![npm][npm]](https://www.npmjs.com/package/tree-sitter-typescript) 8 | [![pypi][pypi]](https://pypi.org/project/tree-sitter-typescript) 9 | 10 | TypeScript and TSX grammars for [tree-sitter][]. 11 | 12 | Because TSX and TypeScript are actually two different dialects, this module defines two grammars. Require them as follows: 13 | 14 | ```js 15 | require("tree-sitter-typescript").typescript; // TypeScript grammar 16 | require("tree-sitter-typescript").tsx; // TSX grammar 17 | ``` 18 | 19 | For Javascript files with [flow] type annotations you can use the `tsx` parser. 20 | 21 | [tree-sitter]: https://github.com/tree-sitter/tree-sitter 22 | [flow]: https://flow.org/en/ 23 | 24 | References 25 | 26 | - [TypeScript Language Spec](https://github.com/microsoft/TypeScript/blob/30cb20434a6b117e007a4959b2a7c16489f86069/doc/spec-ARCHIVED.md) 27 | 28 | [ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-typescript/ci.yml?logo=github&label=CI 29 | [discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord 30 | [matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix 31 | [npm]: https://img.shields.io/npm/v/tree-sitter-typescript?logo=npm 32 | [crates]: https://img.shields.io/crates/v/tree-sitter-typescript?logo=rust 33 | [pypi]: https://img.shields.io/pypi/v/tree-sitter-typescript?logo=pypi&logoColor=ffd242 34 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_typescript_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_typescript(); 6 | extern "C" TSLanguage *tree_sitter_tsx(); 7 | 8 | // "tree-sitter", "language" hashed with BLAKE2 9 | const napi_type_tag LANGUAGE_TYPE_TAG = { 10 | 0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16 11 | }; 12 | 13 | Napi::Object Init(Napi::Env env, Napi::Object exports) { 14 | auto typescript = Napi::Object::New(env); 15 | typescript["name"] = Napi::String::New(env, "typescript"); 16 | auto typescript_language = Napi::External::New(env, tree_sitter_typescript()); 17 | typescript_language.TypeTag(&LANGUAGE_TYPE_TAG); 18 | typescript["language"] = typescript_language; 19 | 20 | auto tsx = Napi::Object::New(env); 21 | tsx["name"] = Napi::String::New(env, "tsx"); 22 | auto tsx_language = Napi::External::New(env, tree_sitter_tsx()); 23 | tsx_language.TypeTag(&LANGUAGE_TYPE_TAG); 24 | tsx["language"] = tsx_language; 25 | 26 | exports["typescript"] = typescript; 27 | exports["tsx"] = tsx; 28 | return exports; 29 | } 30 | 31 | NODE_API_MODULE(tree_sitter_typescript_binding, Init) 32 | -------------------------------------------------------------------------------- /bindings/node/binding_test.js: -------------------------------------------------------------------------------- 1 | const assert = require('node:assert'); 2 | const { test } = require('node:test'); 3 | 4 | const Parser = require('tree-sitter'); 5 | 6 | test('can load TypeScript grammar', () => { 7 | const parser = new Parser(); 8 | assert.doesNotThrow(() => parser.setLanguage(require('./typescript'))); 9 | }); 10 | 11 | test('can load TSX grammar', () => { 12 | const parser = new Parser(); 13 | assert.doesNotThrow(() => parser.setLanguage(require('./tsx'))); 14 | }); 15 | -------------------------------------------------------------------------------- /bindings/node/index.d.ts: -------------------------------------------------------------------------------- 1 | type BaseNode = { 2 | type: string; 3 | named: boolean; 4 | }; 5 | 6 | type ChildNode = { 7 | multiple: boolean; 8 | required: boolean; 9 | types: BaseNode[]; 10 | }; 11 | 12 | type NodeInfo = 13 | | (BaseNode & { 14 | subtypes: BaseNode[]; 15 | }) 16 | | (BaseNode & { 17 | fields: { [name: string]: ChildNode }; 18 | children: ChildNode[]; 19 | }); 20 | 21 | type Language = { 22 | name: string; 23 | language: unknown; 24 | nodeTypeInfo: NodeInfo[]; 25 | }; 26 | 27 | declare const typescript: Language; 28 | declare const tsx: Language; 29 | export = {typescript, tsx} 30 | -------------------------------------------------------------------------------- /bindings/node/index.js: -------------------------------------------------------------------------------- 1 | const root = require("path").join(__dirname, "..", ".."); 2 | 3 | module.exports = 4 | typeof process.versions.bun === "string" 5 | // Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time 6 | ? require(`../../prebuilds/${process.platform}-${process.arch}/tree-sitter-typescript.node`) 7 | : require("node-gyp-build")(root); 8 | 9 | try { 10 | module.exports.typescript.nodeTypeInfo = require("../../typescript/src/node-types.json"); 11 | module.exports.tsx.nodeTypeInfo = require("../../tsx/src/node-types.json"); 12 | } catch (_) { } 13 | -------------------------------------------------------------------------------- /bindings/node/tsx.js: -------------------------------------------------------------------------------- 1 | module.exports = require('.').tsx; 2 | -------------------------------------------------------------------------------- /bindings/node/typescript.js: -------------------------------------------------------------------------------- 1 | module.exports = require('.').typescript; 2 | -------------------------------------------------------------------------------- /bindings/python/tests/test_binding.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import tree_sitter, tree_sitter_typescript 4 | 5 | 6 | class TestLanguage(TestCase): 7 | def test_can_load_typescript_grammar(self): 8 | try: 9 | tree_sitter.Language(tree_sitter_typescript.language_typescript()) 10 | except Exception: 11 | self.fail("Error loading TypeScript grammar") 12 | 13 | def test_can_load_tsx_grammar(self): 14 | try: 15 | tree_sitter.Language(tree_sitter_typescript.language_tsx()) 16 | except Exception: 17 | self.fail("Error loading TSX grammar") 18 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_typescript/__init__.py: -------------------------------------------------------------------------------- 1 | "TypeScript and TSX grammars for tree-sitter" 2 | 3 | from importlib.resources import files as _files 4 | 5 | from ._binding import language_typescript, language_tsx 6 | 7 | def _get_query(name, file): 8 | query = _files(f"{__package__}.queries") / file 9 | globals()[name] = query.read_text() 10 | return globals()[name] 11 | 12 | def __getattr__(name): 13 | if name == "HIGHLIGHTS_QUERY": 14 | return _get_query("HIGHLIGHTS_QUERY", "highlights.scm") 15 | if name == "LOCALS_QUERY": 16 | return _get_query("LOCALS_QUERY", "locals.scm") 17 | if name == "TAGS_QUERY": 18 | return _get_query("TAGS_QUERY", "tags.scm") 19 | 20 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 21 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_typescript/__init__.pyi: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | HIGHLIGHTS_QUERY: Final[str] 4 | LOCALS_QUERY: Final[str] 5 | TAGS_QUERY: Final[str] 6 | 7 | def language_typescript() -> object: ... 8 | 9 | def language_tsx() -> object: ... 10 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_typescript/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_typescript(void); 6 | TSLanguage *tree_sitter_tsx(void); 7 | 8 | static PyObject* _binding_language_typescript(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 9 | return PyCapsule_New(tree_sitter_typescript(), "tree_sitter.Language", NULL); 10 | } 11 | 12 | static PyObject* _binding_language_tsx(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 13 | return PyCapsule_New(tree_sitter_tsx(), "tree_sitter.Language", NULL); 14 | } 15 | 16 | static PyMethodDef methods[] = { 17 | {"language_typescript", _binding_language_typescript, METH_NOARGS, 18 | "Get the tree-sitter language for TypeScript."}, 19 | {"language_tsx", _binding_language_tsx, METH_NOARGS, 20 | "Get the tree-sitter language for TSX."}, 21 | {NULL, NULL, 0, NULL} 22 | }; 23 | 24 | static struct PyModuleDef module = { 25 | .m_base = PyModuleDef_HEAD_INIT, 26 | .m_name = "_binding", 27 | .m_doc = NULL, 28 | .m_size = -1, 29 | .m_methods = methods 30 | }; 31 | 32 | PyMODINIT_FUNC PyInit__binding(void) { 33 | return PyModule_Create(&module); 34 | } 35 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_typescript/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tree-sitter/tree-sitter-typescript/75b3874edb2dc714fb1fd77a32013d0f8699989f/bindings/python/tree_sitter_typescript/py.typed -------------------------------------------------------------------------------- /bindings/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let root_dir = std::path::Path::new("."); 3 | let typescript_dir = root_dir.join("typescript").join("src"); 4 | let tsx_dir = root_dir.join("tsx").join("src"); 5 | let common_dir = root_dir.join("common"); 6 | 7 | let mut config = cc::Build::new(); 8 | config.include(&typescript_dir); 9 | config 10 | .flag_if_supported("-std=c11") 11 | .flag_if_supported("-Wno-unused-parameter"); 12 | 13 | for path in &[ 14 | typescript_dir.join("parser.c"), 15 | typescript_dir.join("scanner.c"), 16 | tsx_dir.join("parser.c"), 17 | tsx_dir.join("scanner.c"), 18 | ] { 19 | config.file(path); 20 | println!("cargo:rerun-if-changed={}", path.to_str().unwrap()); 21 | } 22 | 23 | println!( 24 | "cargo:rerun-if-changed={}", 25 | common_dir.join("scanner.h").to_str().unwrap() 26 | ); 27 | 28 | config.compile("tree-sitter-typescript"); 29 | } 30 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides TypeScript and TSX language support for the [tree-sitter][] parsing library. 2 | //! 3 | //! Typically, you will use the [LANGUAGE_TYPESCRIPT] constant to add this language to a 4 | //! tree-sitter [Parser][], and then use the parser to parse some code: 5 | //! 6 | //! ``` 7 | //! use tree_sitter::Parser; 8 | //! 9 | //! let code = r#" 10 | //! function double(x: number): number { 11 | //! return x * 2; 12 | //! } 13 | //! "#; 14 | //! let mut parser = Parser::new(); 15 | //! let language = tree_sitter_typescript::LANGUAGE_TYPESCRIPT; 16 | //! parser 17 | //! .set_language(&language.into()) 18 | //! .expect("Error loading TypeScript parser"); 19 | //! let tree = parser.parse(code, None).unwrap(); 20 | //! assert!(!tree.root_node().has_error()); 21 | //! ``` 22 | //! 23 | //! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html 24 | //! [tree-sitter]: https://tree-sitter.github.io/ 25 | 26 | use tree_sitter_language::LanguageFn; 27 | 28 | extern "C" { 29 | fn tree_sitter_typescript() -> *const (); 30 | fn tree_sitter_tsx() -> *const (); 31 | } 32 | 33 | /// The tree-sitter [`LanguageFn`] for TypeScript. 34 | /// 35 | /// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html 36 | pub const LANGUAGE_TYPESCRIPT: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_typescript) }; 37 | 38 | /// The tree-sitter [`LanguageFn`] for TSX. 39 | /// 40 | /// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html 41 | pub const LANGUAGE_TSX: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_tsx) }; 42 | 43 | /// The content of the [`node-types.json`][] file for TypeScript. 44 | /// 45 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types 46 | pub const TYPESCRIPT_NODE_TYPES: &str = include_str!("../../typescript/src/node-types.json"); 47 | 48 | /// The content of the [`node-types.json`][] file for TSX. 49 | /// 50 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types 51 | pub const TSX_NODE_TYPES: &str = include_str!("../../tsx/src/node-types.json"); 52 | 53 | /// The syntax highlighting query for TypeScript. 54 | pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); 55 | 56 | /// The local-variable syntax highlighting query for TypeScript. 57 | pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); 58 | 59 | /// The symbol tagging query for TypeScript. 60 | pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); 61 | 62 | #[cfg(test)] 63 | mod tests { 64 | #[test] 65 | fn test_can_load_typescript_grammar() { 66 | let mut parser = tree_sitter::Parser::new(); 67 | parser 68 | .set_language(&super::LANGUAGE_TYPESCRIPT.into()) 69 | .expect("Error loading TypeScript parser"); 70 | } 71 | 72 | #[test] 73 | fn test_can_load_tsx_grammar() { 74 | let mut parser = tree_sitter::Parser::new(); 75 | parser 76 | .set_language(&super::LANGUAGE_TSX.into()) 77 | .expect("Error loading TSX parser"); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterTypeScriptTests/TreeSitterTypeScriptTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterTypeScript 4 | import TreeSitterTSX 5 | 6 | final class TreeSitterTypeScriptTests: XCTestCase { 7 | func testCanLoadTypeScriptGrammar() throws { 8 | let parser = Parser() 9 | let language = Language(language: tree_sitter_typescript()) 10 | XCTAssertNoThrow(try parser.setLanguage(language), 11 | "Error loading TypeScript grammar") 12 | } 13 | 14 | func testCanLoadTSXGrammar() throws { 15 | let parser = Parser() 16 | let language = Language(language: tree_sitter_tsx()) 17 | XCTAssertNoThrow(try parser.setLanguage(language), 18 | "Error loading TSX grammar") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /bindings/swift/tsx/TreeSitterTSX/tsx.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_TSX_H_ 2 | #define TREE_SITTER_TSX_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_tsx(); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_TSX_H_ 17 | -------------------------------------------------------------------------------- /bindings/swift/typescript/TreeSitterTypeScript/typescript.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_TYPESCRIPT_H_ 2 | #define TREE_SITTER_TYPESCRIPT_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_typescript(); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_TYPESCRIPT_H_ 17 | -------------------------------------------------------------------------------- /common/common.mak: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | $(error "Windows is not supported") 3 | endif 4 | 5 | HOMEPAGE_URL := https://github.com/tree-sitter/tree-sitter-typescript 6 | VERSION := 0.23.2 7 | 8 | # repository 9 | SRC_DIR := src 10 | 11 | TS ?= tree-sitter 12 | 13 | # install directory layout 14 | PREFIX ?= /usr/local 15 | INCLUDEDIR ?= $(PREFIX)/include 16 | LIBDIR ?= $(PREFIX)/lib 17 | PCLIBDIR ?= $(LIBDIR)/pkgconfig 18 | 19 | # source/object files 20 | PARSER := $(SRC_DIR)/parser.c 21 | EXTRAS := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c)) 22 | OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS)) 23 | 24 | # flags 25 | ARFLAGS ?= rcs 26 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC 27 | 28 | # ABI versioning 29 | SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER)) 30 | SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION))) 31 | 32 | # OS-specific bits 33 | ifeq ($(shell uname),Darwin) 34 | SOEXT = dylib 35 | SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT) 36 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT) 37 | LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks 38 | else 39 | SOEXT = so 40 | SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR) 41 | SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR) 42 | LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER) 43 | endif 44 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 45 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 46 | endif 47 | 48 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 49 | 50 | lib$(LANGUAGE_NAME).a: $(OBJS) 51 | $(AR) $(ARFLAGS) $@ $^ 52 | 53 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 54 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 55 | ifneq ($(STRIP),) 56 | $(STRIP) $@ 57 | endif 58 | 59 | $(LANGUAGE_NAME).pc: ../bindings/c/$(LANGUAGE_NAME).pc.in 60 | sed -e 's|@CMAKE_PROJECT_VERSION@|$(VERSION)|' \ 61 | -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \ 62 | -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \ 63 | -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \ 64 | -e 's|@CMAKE_PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \ 65 | -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ 66 | 67 | $(PARSER): $(SRC_DIR)/grammar.json 68 | $(TS) generate $^ 69 | 70 | install: all 71 | install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' 72 | install -m644 ../bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 73 | install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 74 | install -m755 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 75 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 76 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 77 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 78 | 79 | uninstall: 80 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 81 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 82 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 83 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 84 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 85 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 86 | 87 | clean: 88 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 89 | 90 | .PHONY: all install uninstall clean 91 | -------------------------------------------------------------------------------- /common/define-grammar.js: -------------------------------------------------------------------------------- 1 | const JavaScript = require('tree-sitter-javascript/grammar'); 2 | 3 | module.exports = function defineGrammar(dialect) { 4 | return grammar(JavaScript, { 5 | name: dialect, 6 | 7 | externals: ($, previous) => previous.concat([ 8 | $._function_signature_automatic_semicolon, 9 | $.__error_recovery, 10 | ]), 11 | 12 | supertypes: ($, previous) => previous.concat([ 13 | $.type, 14 | $.primary_type, 15 | ]), 16 | 17 | precedences: ($, previous) => previous.concat([ 18 | [ 19 | 'call', 20 | 'instantiation', 21 | 'unary', 22 | 'binary', 23 | $.await_expression, 24 | $.arrow_function, 25 | ], 26 | [ 27 | 'extends', 28 | 'instantiation', 29 | ], 30 | [ 31 | $.intersection_type, 32 | $.union_type, 33 | $.conditional_type, 34 | $.function_type, 35 | 'binary', 36 | $.type_predicate, 37 | $.readonly_type, 38 | ], 39 | [$.mapped_type_clause, $.primary_expression], 40 | [$.accessibility_modifier, $.primary_expression], 41 | ['unary_void', $.expression], 42 | [$.extends_clause, $.primary_expression], 43 | ['unary', 'assign'], 44 | ['declaration', $.expression], 45 | [$.predefined_type, $.unary_expression], 46 | [$.type, $.flow_maybe_type], 47 | [$.tuple_type, $.array_type, $.pattern, $.type], 48 | [$.readonly_type, $.pattern], 49 | [$.readonly_type, $.primary_expression], 50 | [$.type_query, $.subscript_expression, $.expression], 51 | [$.type_query, $._type_query_subscript_expression], 52 | [$.nested_type_identifier, $.generic_type, $.primary_type, $.lookup_type, $.index_type_query, $.type], 53 | [$.as_expression, $.satisfies_expression, $.primary_type], 54 | [$._type_query_member_expression, $.member_expression], 55 | [$.member_expression, $._type_query_member_expression_in_type_annotation], 56 | [$._type_query_member_expression, $.primary_expression], 57 | [$._type_query_subscript_expression, $.subscript_expression], 58 | [$._type_query_subscript_expression, $.primary_expression], 59 | [$._type_query_call_expression, $.primary_expression], 60 | [$._type_query_instantiation_expression, $.primary_expression], 61 | [$.type_query, $.primary_expression], 62 | [$.override_modifier, $.primary_expression], 63 | [$.decorator_call_expression, $.decorator], 64 | [$.literal_type, $.pattern], 65 | [$.predefined_type, $.pattern], 66 | [$.call_expression, $._type_query_call_expression], 67 | [$.call_expression, $._type_query_call_expression_in_type_annotation], 68 | [$.new_expression, $.primary_expression], 69 | [$.meta_property, $.primary_expression], 70 | [$.construct_signature, $._property_name], 71 | ]), 72 | 73 | conflicts: ($, previous) => previous.concat([ 74 | [$.call_expression, $.instantiation_expression, $.binary_expression], 75 | [$.call_expression, $.instantiation_expression, $.binary_expression, $.unary_expression], 76 | [$.call_expression, $.instantiation_expression, $.binary_expression, $.update_expression], 77 | [$.call_expression, $.instantiation_expression, $.binary_expression, $.await_expression], 78 | 79 | // This appears to be necessary to parse a parenthesized class expression 80 | [$.class], 81 | 82 | [$.nested_identifier, $.nested_type_identifier, $.primary_expression], 83 | [$.nested_identifier, $.nested_type_identifier], 84 | 85 | [$._call_signature, $.function_type], 86 | [$._call_signature, $.constructor_type], 87 | 88 | [$.primary_expression, $._parameter_name], 89 | [$.primary_expression, $._parameter_name, $.primary_type], 90 | [$.primary_expression, $.literal_type], 91 | [$.primary_expression, $.literal_type, $.rest_pattern], 92 | [$.primary_expression, $.predefined_type, $.rest_pattern], 93 | [$.primary_expression, $.primary_type], 94 | [$.primary_expression, $.generic_type], 95 | [$.primary_expression, $.predefined_type], 96 | [$.primary_expression, $.pattern, $.primary_type], 97 | [$._parameter_name, $.primary_type], 98 | [$.pattern, $.primary_type], 99 | 100 | [$.optional_tuple_parameter, $.primary_type], 101 | [$.rest_pattern, $.primary_type, $.primary_expression], 102 | 103 | [$.object, $.object_type], 104 | [$.object, $.object_pattern, $.object_type], 105 | [$.object, $.object_pattern, $._property_name], 106 | [$.object_pattern, $.object_type], 107 | [$.object_pattern, $.object_type], 108 | 109 | [$.array, $.tuple_type], 110 | [$.array, $.array_pattern, $.tuple_type], 111 | [$.array_pattern, $.tuple_type], 112 | 113 | [$.template_literal_type, $.template_string], 114 | ]).concat( 115 | dialect === 'typescript' ? [ 116 | [$.primary_type, $.type_parameter], 117 | ] : [ 118 | [$.jsx_opening_element, $.type_parameter], 119 | [$.jsx_namespace_name, $.primary_type], 120 | ], 121 | ), 122 | 123 | inline: ($, previous) => previous 124 | .filter((rule) => ![ 125 | '_formal_parameter', 126 | '_call_signature', 127 | ].includes(rule.name)) 128 | .concat([ 129 | $._type_identifier, 130 | $._jsx_start_opening_element, 131 | ]), 132 | 133 | rules: { 134 | public_field_definition: $ => seq( 135 | repeat(field('decorator', $.decorator)), 136 | optional(choice( 137 | seq('declare', optional($.accessibility_modifier)), 138 | seq($.accessibility_modifier, optional('declare')), 139 | )), 140 | choice( 141 | seq(optional('static'), optional($.override_modifier), optional('readonly')), 142 | seq(optional('abstract'), optional('readonly')), 143 | seq(optional('readonly'), optional('abstract')), 144 | optional('accessor'), 145 | ), 146 | field('name', $._property_name), 147 | optional(choice('?', '!')), 148 | field('type', optional($.type_annotation)), 149 | optional($._initializer), 150 | ), 151 | 152 | // override original catch_clause, add optional type annotation 153 | catch_clause: $ => seq( 154 | 'catch', 155 | optional( 156 | seq( 157 | '(', 158 | field( 159 | 'parameter', 160 | choice($.identifier, $._destructuring_pattern), 161 | ), 162 | optional( 163 | // only types that resolve to 'any' or 'unknown' are supported 164 | // by the language but it's simpler to accept any type here. 165 | field('type', $.type_annotation), 166 | ), 167 | ')', 168 | ), 169 | ), 170 | field('body', $.statement_block), 171 | ), 172 | 173 | call_expression: $ => choice( 174 | prec('call', seq( 175 | field('function', choice($.expression, $.import)), 176 | field('type_arguments', optional($.type_arguments)), 177 | field('arguments', $.arguments), 178 | )), 179 | prec('template_call', seq( 180 | field('function', choice($.primary_expression, $.new_expression)), 181 | field('arguments', $.template_string), 182 | )), 183 | prec('member', seq( 184 | field('function', $.primary_expression), 185 | '?.', 186 | field('type_arguments', optional($.type_arguments)), 187 | field('arguments', $.arguments), 188 | )), 189 | ), 190 | 191 | new_expression: $ => prec.right('new', seq( 192 | 'new', 193 | field('constructor', $.primary_expression), 194 | field('type_arguments', optional($.type_arguments)), 195 | field('arguments', optional($.arguments)), 196 | )), 197 | 198 | assignment_expression: $ => prec.right('assign', seq( 199 | optional('using'), 200 | field('left', choice($.parenthesized_expression, $._lhs_expression)), 201 | '=', 202 | field('right', $.expression), 203 | )), 204 | 205 | _augmented_assignment_lhs: ($, previous) => choice(previous, $.non_null_expression), 206 | 207 | _lhs_expression: ($, previous) => choice(previous, $.non_null_expression), 208 | 209 | primary_expression: ($, previous) => choice( 210 | previous, 211 | $.non_null_expression, 212 | ), 213 | 214 | // If the dialect is regular typescript, we exclude JSX expressions and 215 | // include type assertions. If the dialect is TSX, we do the opposite. 216 | expression: ($, previous) => { 217 | const choices = [ 218 | $.as_expression, 219 | $.satisfies_expression, 220 | $.instantiation_expression, 221 | $.internal_module, 222 | ]; 223 | 224 | if (dialect === 'typescript') { 225 | choices.push($.type_assertion); 226 | choices.push(...previous.members.filter((member) => 227 | member.name !== '_jsx_element', 228 | )); 229 | } else if (dialect === 'tsx') { 230 | choices.push(...previous.members); 231 | } else { 232 | throw new Error(`Unknown dialect ${dialect}`); 233 | } 234 | 235 | return choice(...choices); 236 | }, 237 | 238 | _jsx_start_opening_element: $ => seq( 239 | '<', 240 | optional( 241 | seq( 242 | choice( 243 | field('name', choice( 244 | $._jsx_identifier, 245 | $.jsx_namespace_name, 246 | )), 247 | seq( 248 | field('name', choice( 249 | $.identifier, 250 | alias($.nested_identifier, $.member_expression), 251 | )), 252 | field('type_arguments', optional($.type_arguments)), 253 | ), 254 | ), 255 | repeat(field('attribute', $._jsx_attribute)), 256 | ), 257 | ), 258 | ), 259 | 260 | // This rule is only referenced by expression when the dialect is 'tsx' 261 | jsx_opening_element: $ => prec.dynamic(-1, seq( 262 | $._jsx_start_opening_element, 263 | '>', 264 | )), 265 | 266 | // tsx only. See jsx_opening_element. 267 | jsx_self_closing_element: $ => prec.dynamic(-1, seq( 268 | $._jsx_start_opening_element, 269 | '/>', 270 | )), 271 | 272 | export_specifier: (_, previous) => seq( 273 | optional(choice('type', 'typeof')), 274 | previous, 275 | ), 276 | 277 | _import_identifier: $ => choice($.identifier, alias('type', $.identifier)), 278 | 279 | import_specifier: $ => seq( 280 | optional(choice('type', 'typeof')), 281 | choice( 282 | field('name', $._import_identifier), 283 | seq( 284 | field('name', choice($._module_export_name, alias('type', $.identifier))), 285 | 'as', 286 | field('alias', $._import_identifier), 287 | ), 288 | ), 289 | ), 290 | 291 | import_attribute: $ => seq(choice('with', 'assert'), $.object), 292 | 293 | import_clause: $ => choice( 294 | $.namespace_import, 295 | $.named_imports, 296 | seq( 297 | $._import_identifier, 298 | optional(seq( 299 | ',', 300 | choice( 301 | $.namespace_import, 302 | $.named_imports, 303 | ), 304 | )), 305 | ), 306 | ), 307 | 308 | import_statement: $ => seq( 309 | 'import', 310 | optional(choice('type', 'typeof')), 311 | choice( 312 | seq($.import_clause, $._from_clause), 313 | $.import_require_clause, 314 | field('source', $.string), 315 | ), 316 | optional($.import_attribute), 317 | $._semicolon, 318 | ), 319 | 320 | export_statement: ($, previous) => choice( 321 | previous, 322 | seq( 323 | 'export', 324 | 'type', 325 | $.export_clause, 326 | optional($._from_clause), 327 | $._semicolon, 328 | ), 329 | seq('export', '=', $.expression, $._semicolon), 330 | seq('export', 'as', 'namespace', $.identifier, $._semicolon), 331 | ), 332 | 333 | non_null_expression: $ => prec.left('unary', seq( 334 | $.expression, '!', 335 | )), 336 | 337 | variable_declarator: $ => choice( 338 | seq( 339 | field('name', choice($.identifier, $._destructuring_pattern)), 340 | field('type', optional($.type_annotation)), 341 | optional($._initializer), 342 | ), 343 | prec('declaration', seq( 344 | field('name', $.identifier), 345 | '!', 346 | field('type', $.type_annotation), 347 | )), 348 | ), 349 | 350 | method_signature: $ => seq( 351 | optional($.accessibility_modifier), 352 | optional('static'), 353 | optional($.override_modifier), 354 | optional('readonly'), 355 | optional('async'), 356 | optional(choice('get', 'set', '*')), 357 | field('name', $._property_name), 358 | optional('?'), 359 | $._call_signature, 360 | ), 361 | 362 | abstract_method_signature: $ => seq( 363 | optional($.accessibility_modifier), 364 | 'abstract', 365 | optional($.override_modifier), 366 | optional(choice('get', 'set', '*')), 367 | field('name', $._property_name), 368 | optional('?'), 369 | $._call_signature, 370 | ), 371 | 372 | parenthesized_expression: $ => seq( 373 | '(', 374 | choice( 375 | seq($.expression, field('type', optional($.type_annotation))), 376 | $.sequence_expression, 377 | ), 378 | ')', 379 | ), 380 | 381 | _formal_parameter: $ => choice( 382 | $.required_parameter, 383 | $.optional_parameter, 384 | ), 385 | 386 | function_signature: $ => seq( 387 | optional('async'), 388 | 'function', 389 | field('name', $.identifier), 390 | $._call_signature, 391 | choice($._semicolon, $._function_signature_automatic_semicolon), 392 | ), 393 | 394 | decorator: $ => seq( 395 | '@', 396 | choice( 397 | $.identifier, 398 | alias($.decorator_member_expression, $.member_expression), 399 | alias($.decorator_call_expression, $.call_expression), 400 | alias($.decorator_parenthesized_expression, $.parenthesized_expression), 401 | ), 402 | ), 403 | 404 | decorator_call_expression: $ => prec('call', seq( 405 | field('function', choice( 406 | $.identifier, 407 | alias($.decorator_member_expression, $.member_expression), 408 | )), 409 | optional(field('type_arguments', $.type_arguments)), 410 | field('arguments', $.arguments), 411 | )), 412 | 413 | decorator_parenthesized_expression: $ => seq( 414 | '(', 415 | choice( 416 | $.identifier, 417 | alias($.decorator_member_expression, $.member_expression), 418 | alias($.decorator_call_expression, $.call_expression), 419 | ), 420 | ')', 421 | ), 422 | 423 | class_body: $ => seq( 424 | '{', 425 | repeat(choice( 426 | seq( 427 | repeat(field('decorator', $.decorator)), 428 | $.method_definition, 429 | optional($._semicolon), 430 | ), 431 | // As it happens for functions, the semicolon insertion should not 432 | // happen if a block follows the closing paren, because then it's a 433 | // *definition*, not a declaration. Example: 434 | // public foo() 435 | // { <--- this brace made the method signature become a definition 436 | // } 437 | // The same rule applies for functions and that's why we use 438 | // "_function_signature_automatic_semicolon". 439 | seq($.method_signature, choice($._function_signature_automatic_semicolon, ',')), 440 | $.class_static_block, 441 | seq( 442 | choice( 443 | $.abstract_method_signature, 444 | $.index_signature, 445 | $.method_signature, 446 | $.public_field_definition, 447 | ), 448 | choice($._semicolon, ','), 449 | ), 450 | ';', 451 | )), 452 | '}', 453 | ), 454 | 455 | method_definition: $ => prec.left(seq( 456 | optional($.accessibility_modifier), 457 | optional('static'), 458 | optional($.override_modifier), 459 | optional('readonly'), 460 | optional('async'), 461 | optional(choice('get', 'set', '*')), 462 | field('name', $._property_name), 463 | optional('?'), 464 | $._call_signature, 465 | field('body', $.statement_block), 466 | )), 467 | 468 | declaration: ($, previous) => choice( 469 | previous, 470 | $.function_signature, 471 | $.abstract_class_declaration, 472 | $.module, 473 | prec('declaration', $.internal_module), 474 | $.type_alias_declaration, 475 | $.enum_declaration, 476 | $.interface_declaration, 477 | $.import_alias, 478 | $.ambient_declaration, 479 | ), 480 | 481 | type_assertion: $ => prec.left('unary', seq( 482 | $.type_arguments, 483 | $.expression, 484 | )), 485 | 486 | as_expression: $ => prec.left('binary', seq( 487 | $.expression, 488 | 'as', 489 | choice('const', $.type), 490 | )), 491 | 492 | satisfies_expression: $ => prec.left('binary', seq( 493 | $.expression, 494 | 'satisfies', 495 | $.type, 496 | )), 497 | 498 | instantiation_expression: $ => prec('instantiation', seq( 499 | $.expression, 500 | field('type_arguments', $.type_arguments), 501 | )), 502 | 503 | class_heritage: $ => choice( 504 | seq($.extends_clause, optional($.implements_clause)), 505 | $.implements_clause, 506 | ), 507 | 508 | import_require_clause: $ => seq( 509 | $.identifier, 510 | '=', 511 | 'require', 512 | '(', 513 | field('source', $.string), 514 | ')', 515 | ), 516 | 517 | extends_clause: $ => seq( 518 | 'extends', 519 | commaSep1($._extends_clause_single), 520 | ), 521 | 522 | _extends_clause_single: $ => prec('extends', seq( 523 | field('value', $.expression), 524 | field('type_arguments', optional($.type_arguments)), 525 | )), 526 | 527 | implements_clause: $ => seq( 528 | 'implements', 529 | commaSep1($.type), 530 | ), 531 | 532 | ambient_declaration: $ => seq( 533 | 'declare', 534 | choice( 535 | $.declaration, 536 | seq('global', $.statement_block), 537 | seq('module', '.', alias($.identifier, $.property_identifier), ':', $.type, $._semicolon), 538 | ), 539 | ), 540 | 541 | class: $ => prec('literal', seq( 542 | repeat(field('decorator', $.decorator)), 543 | 'class', 544 | field('name', optional($._type_identifier)), 545 | field('type_parameters', optional($.type_parameters)), 546 | optional($.class_heritage), 547 | field('body', $.class_body), 548 | )), 549 | 550 | abstract_class_declaration: $ => prec('declaration', seq( 551 | repeat(field('decorator', $.decorator)), 552 | 'abstract', 553 | 'class', 554 | field('name', $._type_identifier), 555 | field('type_parameters', optional($.type_parameters)), 556 | optional($.class_heritage), 557 | field('body', $.class_body), 558 | )), 559 | 560 | class_declaration: $ => prec.left('declaration', seq( 561 | repeat(field('decorator', $.decorator)), 562 | 'class', 563 | field('name', $._type_identifier), 564 | field('type_parameters', optional($.type_parameters)), 565 | optional($.class_heritage), 566 | field('body', $.class_body), 567 | optional($._automatic_semicolon), 568 | )), 569 | 570 | module: $ => seq( 571 | 'module', 572 | $._module, 573 | ), 574 | 575 | internal_module: $ => seq( 576 | 'namespace', 577 | $._module, 578 | ), 579 | 580 | _module: $ => prec.right(seq( 581 | field('name', choice($.string, $.identifier, $.nested_identifier)), 582 | // On .d.ts files "declare module foo" desugars to "declare module foo {}", 583 | // hence why it is optional here 584 | field('body', optional($.statement_block)), 585 | )), 586 | 587 | import_alias: $ => seq( 588 | 'import', 589 | $.identifier, 590 | '=', 591 | choice($.identifier, $.nested_identifier), 592 | $._semicolon, 593 | ), 594 | 595 | nested_type_identifier: $ => prec('member', seq( 596 | field('module', choice($.identifier, $.nested_identifier)), 597 | '.', 598 | field('name', $._type_identifier), 599 | )), 600 | 601 | interface_declaration: $ => seq( 602 | 'interface', 603 | field('name', $._type_identifier), 604 | field('type_parameters', optional($.type_parameters)), 605 | optional($.extends_type_clause), 606 | field('body', alias($.object_type, $.interface_body)), 607 | ), 608 | 609 | extends_type_clause: $ => seq( 610 | 'extends', 611 | commaSep1(field('type', choice( 612 | $._type_identifier, 613 | $.nested_type_identifier, 614 | $.generic_type, 615 | ))), 616 | ), 617 | 618 | enum_declaration: $ => seq( 619 | optional('const'), 620 | 'enum', 621 | field('name', $.identifier), 622 | field('body', $.enum_body), 623 | ), 624 | 625 | enum_body: $ => seq( 626 | '{', 627 | optional(seq( 628 | sepBy1(',', choice( 629 | field('name', $._property_name), 630 | $.enum_assignment, 631 | )), 632 | optional(','), 633 | )), 634 | '}', 635 | ), 636 | 637 | enum_assignment: $ => seq( 638 | field('name', $._property_name), 639 | $._initializer, 640 | ), 641 | 642 | type_alias_declaration: $ => seq( 643 | 'type', 644 | field('name', $._type_identifier), 645 | field('type_parameters', optional($.type_parameters)), 646 | '=', 647 | field('value', $.type), 648 | $._semicolon, 649 | ), 650 | 651 | accessibility_modifier: _ => choice( 652 | 'public', 653 | 'private', 654 | 'protected', 655 | ), 656 | 657 | override_modifier: _ => 'override', 658 | 659 | required_parameter: $ => seq( 660 | $._parameter_name, 661 | field('type', optional($.type_annotation)), 662 | optional($._initializer), 663 | ), 664 | 665 | optional_parameter: $ => seq( 666 | $._parameter_name, 667 | '?', 668 | field('type', optional($.type_annotation)), 669 | optional($._initializer), 670 | ), 671 | 672 | _parameter_name: $ => seq( 673 | repeat(field('decorator', $.decorator)), 674 | optional($.accessibility_modifier), 675 | optional($.override_modifier), 676 | optional('readonly'), 677 | field('pattern', choice($.pattern, $.this)), 678 | ), 679 | 680 | omitting_type_annotation: $ => seq('-?:', $.type), 681 | adding_type_annotation: $ => seq('+?:', $.type), 682 | opting_type_annotation: $ => seq('?:', $.type), 683 | type_annotation: $ => seq( 684 | ':', 685 | $.type, 686 | ), 687 | 688 | // Oh boy 689 | // The issue is these special type queries need a lower relative precedence than the normal ones, 690 | // since these are used in type annotations whereas the other ones are used where `typeof` is 691 | // required beforehand. This allows for parsing of annotations such as 692 | // foo: import('x').y.z; 693 | // but was a nightmare to get working. 694 | _type_query_member_expression_in_type_annotation: $ => seq( 695 | field('object', choice( 696 | $.import, 697 | alias($._type_query_member_expression_in_type_annotation, $.member_expression), 698 | alias($._type_query_call_expression_in_type_annotation, $.call_expression), 699 | )), 700 | '.', 701 | field('property', choice( 702 | $.private_property_identifier, 703 | alias($.identifier, $.property_identifier), 704 | )), 705 | ), 706 | _type_query_call_expression_in_type_annotation: $ => seq( 707 | field('function', choice( 708 | $.import, 709 | alias($._type_query_member_expression_in_type_annotation, $.member_expression), 710 | )), 711 | field('arguments', $.arguments), 712 | ), 713 | 714 | asserts: $ => seq( 715 | 'asserts', 716 | choice($.type_predicate, $.identifier, $.this), 717 | ), 718 | 719 | asserts_annotation: $ => seq( 720 | seq(':', $.asserts), 721 | ), 722 | 723 | type: $ => choice( 724 | $.primary_type, 725 | $.function_type, 726 | $.readonly_type, 727 | $.constructor_type, 728 | $.infer_type, 729 | prec(-1, alias($._type_query_member_expression_in_type_annotation, $.member_expression)), 730 | prec(-1, alias($._type_query_call_expression_in_type_annotation, $.call_expression)), 731 | ), 732 | 733 | tuple_parameter: $ => seq( 734 | field('name', choice($.identifier, $.rest_pattern)), 735 | field('type', $.type_annotation), 736 | ), 737 | 738 | optional_tuple_parameter: $ => seq( 739 | field('name', $.identifier), 740 | '?', 741 | field('type', $.type_annotation), 742 | ), 743 | 744 | optional_type: $ => seq($.type, '?'), 745 | rest_type: $ => seq('...', $.type), 746 | 747 | _tuple_type_member: $ => choice( 748 | alias($.tuple_parameter, $.required_parameter), 749 | alias($.optional_tuple_parameter, $.optional_parameter), 750 | $.optional_type, 751 | $.rest_type, 752 | $.type, 753 | ), 754 | 755 | constructor_type: $ => prec.left(seq( 756 | optional('abstract'), 757 | 'new', 758 | field('type_parameters', optional($.type_parameters)), 759 | field('parameters', $.formal_parameters), 760 | '=>', 761 | field('type', $.type), 762 | )), 763 | 764 | primary_type: $ => choice( 765 | $.parenthesized_type, 766 | $.predefined_type, 767 | $._type_identifier, 768 | $.nested_type_identifier, 769 | $.generic_type, 770 | $.object_type, 771 | $.array_type, 772 | $.tuple_type, 773 | $.flow_maybe_type, 774 | $.type_query, 775 | $.index_type_query, 776 | alias($.this, $.this_type), 777 | $.existential_type, 778 | $.literal_type, 779 | $.lookup_type, 780 | $.conditional_type, 781 | $.template_literal_type, 782 | $.intersection_type, 783 | $.union_type, 784 | 'const', 785 | ), 786 | 787 | template_type: $ => seq('${', choice($.primary_type, $.infer_type), '}'), 788 | 789 | template_literal_type: $ => seq( 790 | '`', 791 | repeat(choice( 792 | alias($._template_chars, $.string_fragment), 793 | $.template_type, 794 | )), 795 | '`', 796 | ), 797 | 798 | infer_type: $ => prec.right(seq( 799 | 'infer', 800 | $._type_identifier, 801 | optional(seq( 802 | 'extends', 803 | $.type, 804 | )), 805 | )), 806 | 807 | conditional_type: $ => prec.right(seq( 808 | field('left', $.type), 809 | 'extends', 810 | field('right', $.type), 811 | '?', 812 | field('consequence', $.type), 813 | ':', 814 | field('alternative', $.type), 815 | )), 816 | 817 | generic_type: $ => prec('call', seq( 818 | field('name', choice( 819 | $._type_identifier, 820 | $.nested_type_identifier, 821 | )), 822 | field('type_arguments', $.type_arguments), 823 | )), 824 | 825 | type_predicate: $ => seq( 826 | field('name', choice( 827 | $.identifier, 828 | $.this, 829 | // Sometimes tree-sitter contextual lexing is not good enough to know 830 | // that 'object' in ':object is foo' is really an identifier and not 831 | // a predefined_type, so we must explicitely list all possibilities. 832 | // TODO: should we use '_reserved_identifier'? Should all the element in 833 | // 'predefined_type' be added to '_reserved_identifier'? 834 | alias($.predefined_type, $.identifier), 835 | )), 836 | 'is', 837 | field('type', $.type), 838 | ), 839 | 840 | type_predicate_annotation: $ => seq( 841 | seq(':', $.type_predicate), 842 | ), 843 | 844 | // Type query expressions are more restrictive than regular expressions 845 | _type_query_member_expression: $ => seq( 846 | field('object', choice( 847 | $.identifier, 848 | $.this, 849 | alias($._type_query_subscript_expression, $.subscript_expression), 850 | alias($._type_query_member_expression, $.member_expression), 851 | alias($._type_query_call_expression, $.call_expression), 852 | )), 853 | choice('.', '?.'), 854 | field('property', choice( 855 | $.private_property_identifier, 856 | alias($.identifier, $.property_identifier), 857 | )), 858 | ), 859 | _type_query_subscript_expression: $ => seq( 860 | field('object', choice( 861 | $.identifier, 862 | $.this, 863 | alias($._type_query_subscript_expression, $.subscript_expression), 864 | alias($._type_query_member_expression, $.member_expression), 865 | alias($._type_query_call_expression, $.call_expression), 866 | )), 867 | optional('?.'), 868 | '[', field('index', choice($.predefined_type, $.string, $.number)), ']', 869 | ), 870 | _type_query_call_expression: $ => seq( 871 | field('function', choice( 872 | $.import, 873 | $.identifier, 874 | alias($._type_query_member_expression, $.member_expression), 875 | alias($._type_query_subscript_expression, $.subscript_expression), 876 | )), 877 | field('arguments', $.arguments), 878 | ), 879 | _type_query_instantiation_expression: $ => seq( 880 | field('function', choice( 881 | $.import, 882 | $.identifier, 883 | alias($._type_query_member_expression, $.member_expression), 884 | alias($._type_query_subscript_expression, $.subscript_expression), 885 | )), 886 | field('type_arguments', $.type_arguments), 887 | ), 888 | type_query: $ => prec.right(seq( 889 | 'typeof', 890 | choice( 891 | alias($._type_query_subscript_expression, $.subscript_expression), 892 | alias($._type_query_member_expression, $.member_expression), 893 | alias($._type_query_call_expression, $.call_expression), 894 | alias($._type_query_instantiation_expression, $.instantiation_expression), 895 | $.identifier, 896 | $.this, 897 | ), 898 | )), 899 | 900 | index_type_query: $ => seq( 901 | 'keyof', 902 | $.primary_type, 903 | ), 904 | 905 | lookup_type: $ => seq( 906 | $.primary_type, 907 | '[', 908 | $.type, 909 | ']', 910 | ), 911 | 912 | mapped_type_clause: $ => seq( 913 | field('name', $._type_identifier), 914 | 'in', 915 | field('type', $.type), 916 | optional(seq('as', field('alias', $.type))), 917 | ), 918 | 919 | literal_type: $ => choice( 920 | alias($._number, $.unary_expression), 921 | $.number, 922 | $.string, 923 | $.true, 924 | $.false, 925 | $.null, 926 | $.undefined, 927 | ), 928 | 929 | _number: $ => prec.left(1, seq( 930 | field('operator', choice('-', '+')), 931 | field('argument', $.number), 932 | )), 933 | 934 | existential_type: _ => '*', 935 | 936 | flow_maybe_type: $ => prec.right(seq('?', $.primary_type)), 937 | 938 | parenthesized_type: $ => seq('(', $.type, ')'), 939 | 940 | predefined_type: _ => choice( 941 | 'any', 942 | 'number', 943 | 'boolean', 944 | 'string', 945 | 'symbol', 946 | alias(seq('unique', 'symbol'), 'unique symbol'), 947 | 'void', 948 | 'unknown', 949 | 'string', 950 | 'never', 951 | 'object', 952 | ), 953 | 954 | type_arguments: $ => seq( 955 | '<', 956 | commaSep1($.type), 957 | optional(','), 958 | '>', 959 | ), 960 | 961 | object_type: $ => seq( 962 | choice('{', '{|'), 963 | optional(seq( 964 | optional(choice(',', ';')), 965 | sepBy1( 966 | choice(',', $._semicolon), 967 | choice( 968 | $.export_statement, 969 | $.property_signature, 970 | $.call_signature, 971 | $.construct_signature, 972 | $.index_signature, 973 | $.method_signature, 974 | ), 975 | ), 976 | optional(choice(',', $._semicolon)), 977 | )), 978 | choice('}', '|}'), 979 | ), 980 | 981 | call_signature: $ => $._call_signature, 982 | 983 | property_signature: $ => seq( 984 | optional($.accessibility_modifier), 985 | optional('static'), 986 | optional($.override_modifier), 987 | optional('readonly'), 988 | field('name', $._property_name), 989 | optional('?'), 990 | field('type', optional($.type_annotation)), 991 | ), 992 | 993 | _call_signature: $ => seq( 994 | field('type_parameters', optional($.type_parameters)), 995 | field('parameters', $.formal_parameters), 996 | field('return_type', optional( 997 | choice($.type_annotation, $.asserts_annotation, $.type_predicate_annotation), 998 | )), 999 | ), 1000 | 1001 | type_parameters: $ => seq( 1002 | '<', commaSep1($.type_parameter), optional(','), '>', 1003 | ), 1004 | 1005 | type_parameter: $ => seq( 1006 | optional('const'), 1007 | field('name', $._type_identifier), 1008 | field('constraint', optional($.constraint)), 1009 | field('value', optional($.default_type)), 1010 | ), 1011 | 1012 | default_type: $ => seq( 1013 | '=', 1014 | $.type, 1015 | ), 1016 | 1017 | constraint: $ => seq( 1018 | choice('extends', ':'), 1019 | $.type, 1020 | ), 1021 | 1022 | construct_signature: $ => seq( 1023 | optional('abstract'), 1024 | 'new', 1025 | field('type_parameters', optional($.type_parameters)), 1026 | field('parameters', $.formal_parameters), 1027 | field('type', optional($.type_annotation)), 1028 | ), 1029 | 1030 | index_signature: $ => seq( 1031 | optional( 1032 | seq( 1033 | field('sign', optional(choice('-', '+'))), 1034 | 'readonly', 1035 | ), 1036 | ), 1037 | '[', 1038 | choice( 1039 | seq( 1040 | field('name', choice( 1041 | $.identifier, 1042 | alias($._reserved_identifier, $.identifier), 1043 | )), 1044 | ':', 1045 | field('index_type', $.type), 1046 | ), 1047 | $.mapped_type_clause, 1048 | ), 1049 | ']', 1050 | field('type', choice( 1051 | $.type_annotation, 1052 | $.omitting_type_annotation, 1053 | $.adding_type_annotation, 1054 | $.opting_type_annotation, 1055 | )), 1056 | ), 1057 | 1058 | array_type: $ => seq($.primary_type, '[', ']'), 1059 | tuple_type: $ => seq( 1060 | '[', commaSep($._tuple_type_member), optional(','), ']', 1061 | ), 1062 | readonly_type: $ => seq('readonly', $.type), 1063 | 1064 | union_type: $ => prec.left(seq(optional($.type), '|', $.type)), 1065 | intersection_type: $ => prec.left(seq(optional($.type), '&', $.type)), 1066 | 1067 | function_type: $ => prec.left(seq( 1068 | field('type_parameters', optional($.type_parameters)), 1069 | field('parameters', $.formal_parameters), 1070 | '=>', 1071 | field('return_type', choice($.type, $.asserts, $.type_predicate)), 1072 | )), 1073 | 1074 | _type_identifier: $ => alias($.identifier, $.type_identifier), 1075 | 1076 | _reserved_identifier: (_, previous) => choice( 1077 | 'declare', 1078 | 'namespace', 1079 | 'type', 1080 | 'public', 1081 | 'private', 1082 | 'protected', 1083 | 'override', 1084 | 'readonly', 1085 | 'module', 1086 | 'any', 1087 | 'number', 1088 | 'boolean', 1089 | 'string', 1090 | 'symbol', 1091 | 'export', 1092 | 'object', 1093 | 'new', 1094 | 'readonly', 1095 | previous, 1096 | ), 1097 | }, 1098 | }); 1099 | }; 1100 | 1101 | /** 1102 | * Creates a rule to match one or more of the rules separated by a comma 1103 | * 1104 | * @param {RuleOrLiteral} rule 1105 | * 1106 | * @return {SeqRule} 1107 | * 1108 | */ 1109 | function commaSep1(rule) { 1110 | return sepBy1(',', rule); 1111 | } 1112 | 1113 | /** 1114 | * Creates a rule to optionally match one or more of the rules separated by a comma 1115 | * 1116 | * @param {RuleOrLiteral} rule 1117 | * 1118 | * @return {SeqRule} 1119 | * 1120 | */ 1121 | function commaSep(rule) { 1122 | return sepBy(',', rule); 1123 | } 1124 | 1125 | /** 1126 | * Creates a rule to optionally match one or more of the rules separated by a separator 1127 | * 1128 | * @param {RuleOrLiteral} sep 1129 | * 1130 | * @param {RuleOrLiteral} rule 1131 | * 1132 | * @return {ChoiceRule} 1133 | */ 1134 | function sepBy(sep, rule) { 1135 | return optional(sepBy1(sep, rule)); 1136 | } 1137 | 1138 | /** 1139 | * Creates a rule to match one or more of the rules separated by a separator 1140 | * 1141 | * @param {RuleOrLiteral} sep 1142 | * 1143 | * @param {RuleOrLiteral} rule 1144 | * 1145 | * @return {SeqRule} 1146 | */ 1147 | function sepBy1(sep, rule) { 1148 | return seq(rule, repeat(seq(sep, rule))); 1149 | } 1150 | -------------------------------------------------------------------------------- /common/scanner.h: -------------------------------------------------------------------------------- 1 | #include "tree_sitter/parser.h" 2 | 3 | #include 4 | 5 | enum TokenType { 6 | AUTOMATIC_SEMICOLON, 7 | TEMPLATE_CHARS, 8 | TERNARY_QMARK, 9 | HTML_COMMENT, 10 | LOGICAL_OR, 11 | ESCAPE_SEQUENCE, 12 | REGEX_PATTERN, 13 | JSX_TEXT, 14 | FUNCTION_SIGNATURE_AUTOMATIC_SEMICOLON, 15 | ERROR_RECOVERY, 16 | }; 17 | 18 | static void advance(TSLexer *lexer) { lexer->advance(lexer, false); } 19 | 20 | static void skip(TSLexer *lexer) { lexer->advance(lexer, true); } 21 | 22 | static bool scan_template_chars(TSLexer *lexer) { 23 | lexer->result_symbol = TEMPLATE_CHARS; 24 | for (bool has_content = false;; has_content = true) { 25 | lexer->mark_end(lexer); 26 | switch (lexer->lookahead) { 27 | case '`': 28 | return has_content; 29 | case '\0': 30 | return false; 31 | case '$': 32 | advance(lexer); 33 | if (lexer->lookahead == '{') { 34 | return has_content; 35 | } 36 | break; 37 | case '\\': 38 | return has_content; 39 | default: 40 | advance(lexer); 41 | } 42 | } 43 | } 44 | 45 | static bool scan_whitespace_and_comments(TSLexer *lexer, bool *scanned_comment) { 46 | for (;;) { 47 | while (iswspace(lexer->lookahead)) { 48 | skip(lexer); 49 | } 50 | 51 | if (lexer->lookahead == '/') { 52 | skip(lexer); 53 | 54 | if (lexer->lookahead == '/') { 55 | skip(lexer); 56 | while (lexer->lookahead != 0 && lexer->lookahead != '\n') { 57 | skip(lexer); 58 | } 59 | *scanned_comment = true; 60 | } else if (lexer->lookahead == '*') { 61 | skip(lexer); 62 | while (lexer->lookahead != 0) { 63 | if (lexer->lookahead == '*') { 64 | skip(lexer); 65 | if (lexer->lookahead == '/') { 66 | skip(lexer); 67 | break; 68 | } 69 | } else { 70 | skip(lexer); 71 | } 72 | } 73 | } else { 74 | return false; 75 | } 76 | } else { 77 | return true; 78 | } 79 | } 80 | } 81 | 82 | static bool scan_automatic_semicolon(TSLexer *lexer, const bool *valid_symbols, bool *scanned_comment) { 83 | lexer->result_symbol = AUTOMATIC_SEMICOLON; 84 | lexer->mark_end(lexer); 85 | 86 | for (;;) { 87 | if (lexer->lookahead == 0) { 88 | return true; 89 | } 90 | if (lexer->lookahead == '}') { 91 | // Automatic semicolon insertion breaks detection of object patterns 92 | // in a typed context: 93 | // type F = ({a}: {a: number}) => number; 94 | // Therefore, disable automatic semicolons when followed by typing 95 | do { 96 | skip(lexer); 97 | } while (iswspace(lexer->lookahead)); 98 | if (lexer->lookahead == ':') { 99 | return valid_symbols[LOGICAL_OR]; // Don't return false if we're in a ternary by checking if || is valid 100 | } 101 | return true; 102 | } 103 | if (!iswspace(lexer->lookahead)) { 104 | return false; 105 | } 106 | if (lexer->lookahead == '\n') { 107 | break; 108 | } 109 | skip(lexer); 110 | } 111 | 112 | skip(lexer); 113 | 114 | if (!scan_whitespace_and_comments(lexer, scanned_comment)) { 115 | return false; 116 | } 117 | 118 | switch (lexer->lookahead) { 119 | case '`': 120 | case ',': 121 | case '.': 122 | case ';': 123 | case '*': 124 | case '%': 125 | case '>': 126 | case '<': 127 | case '=': 128 | case '?': 129 | case '^': 130 | case '|': 131 | case '&': 132 | case '/': 133 | case ':': 134 | return false; 135 | 136 | case '{': 137 | if (valid_symbols[FUNCTION_SIGNATURE_AUTOMATIC_SEMICOLON]) { 138 | return false; 139 | } 140 | break; 141 | 142 | // Don't insert a semicolon before a '[' or '(', unless we're parsing 143 | // a type. Detect whether we're parsing a type or an expression using 144 | // the validity of a binary operator token. 145 | case '(': 146 | case '[': 147 | if (valid_symbols[LOGICAL_OR]) { 148 | return false; 149 | } 150 | break; 151 | 152 | // Insert a semicolon before `--` and `++`, but not before binary `+` or `-`. 153 | case '+': 154 | skip(lexer); 155 | return lexer->lookahead == '+'; 156 | case '-': 157 | skip(lexer); 158 | return lexer->lookahead == '-'; 159 | 160 | // Don't insert a semicolon before `!=`, but do insert one before a unary `!`. 161 | case '!': 162 | skip(lexer); 163 | return lexer->lookahead != '='; 164 | 165 | // Don't insert a semicolon before `in` or `instanceof`, but do insert one 166 | // before an identifier. 167 | case 'i': 168 | skip(lexer); 169 | 170 | if (lexer->lookahead != 'n') { 171 | return true; 172 | } 173 | skip(lexer); 174 | 175 | if (!iswalpha(lexer->lookahead)) { 176 | return false; 177 | } 178 | 179 | for (unsigned i = 0; i < 8; i++) { 180 | if (lexer->lookahead != "stanceof"[i]) { 181 | return true; 182 | } 183 | skip(lexer); 184 | } 185 | 186 | if (!iswalpha(lexer->lookahead)) { 187 | return false; 188 | } 189 | break; 190 | } 191 | 192 | return true; 193 | } 194 | 195 | static bool scan_ternary_qmark(TSLexer *lexer) { 196 | for (;;) { 197 | if (!iswspace(lexer->lookahead)) { 198 | break; 199 | } 200 | skip(lexer); 201 | } 202 | 203 | if (lexer->lookahead == '?') { 204 | advance(lexer); 205 | 206 | /* Optional chaining. */ 207 | if (lexer->lookahead == '?' || lexer->lookahead == '.') { 208 | return false; 209 | } 210 | 211 | lexer->mark_end(lexer); 212 | lexer->result_symbol = TERNARY_QMARK; 213 | 214 | /* TypeScript optional arguments contain the ?: sequence, possibly 215 | with whitespace. */ 216 | for (;;) { 217 | if (!iswspace(lexer->lookahead)) { 218 | break; 219 | } 220 | advance(lexer); 221 | } 222 | 223 | if (lexer->lookahead == ':' || lexer->lookahead == ')' || lexer->lookahead == ',') { 224 | return false; 225 | } 226 | 227 | if (lexer->lookahead == '.') { 228 | advance(lexer); 229 | if (iswdigit(lexer->lookahead)) { 230 | return true; 231 | } 232 | return false; 233 | } 234 | return true; 235 | } 236 | return false; 237 | } 238 | 239 | static bool scan_closing_comment(TSLexer *lexer) { 240 | while (iswspace(lexer->lookahead) || lexer->lookahead == 0x2028 || lexer->lookahead == 0x2029) { 241 | skip(lexer); 242 | } 243 | 244 | const char *comment_start = ""; 246 | 247 | if (lexer->lookahead == '<') { 248 | for (unsigned i = 0; i < 4; i++) { 249 | if (lexer->lookahead != comment_start[i]) { 250 | return false; 251 | } 252 | advance(lexer); 253 | } 254 | } else if (lexer->lookahead == '-') { 255 | for (unsigned i = 0; i < 3; i++) { 256 | if (lexer->lookahead != comment_end[i]) { 257 | return false; 258 | } 259 | advance(lexer); 260 | } 261 | } else { 262 | return false; 263 | } 264 | 265 | while (lexer->lookahead != 0 && lexer->lookahead != '\n' && lexer->lookahead != 0x2028 && 266 | lexer->lookahead != 0x2029) { 267 | advance(lexer); 268 | } 269 | 270 | lexer->result_symbol = HTML_COMMENT; 271 | lexer->mark_end(lexer); 272 | 273 | return true; 274 | } 275 | 276 | static bool scan_jsx_text(TSLexer *lexer) { 277 | // saw_text will be true if we see any non-whitespace content, or any whitespace content that is not a newline and 278 | // does not immediately follow a newline. 279 | bool saw_text = false; 280 | // at_newline will be true if we are currently at a newline, or if we are at whitespace that is not a newline but 281 | // immediately follows a newline. 282 | bool at_newline = false; 283 | 284 | while (lexer->lookahead != 0 && lexer->lookahead != '<' && lexer->lookahead != '>' && lexer->lookahead != '{' && 285 | lexer->lookahead != '}' && lexer->lookahead != '&') { 286 | bool is_wspace = iswspace(lexer->lookahead); 287 | if (lexer->lookahead == '\n') { 288 | at_newline = true; 289 | } else { 290 | // If at_newline is already true, and we see some whitespace, then it must stay true. 291 | // Otherwise, it should be false. 292 | // 293 | // See the table below to determine the logic for computing `saw_text`. 294 | // 295 | // |------------------------------------| 296 | // | at_newline | is_wspace | saw_text | 297 | // |------------|-----------|-----------| 298 | // | false (0) | false (0) | true (1) | 299 | // | false (0) | true (1) | true (1) | 300 | // | true (1) | false (0) | true (1) | 301 | // | true (1) | true (1) | false (0) | 302 | // |------------------------------------| 303 | 304 | at_newline &= is_wspace; 305 | if (!at_newline) { 306 | saw_text = true; 307 | } 308 | } 309 | 310 | advance(lexer); 311 | } 312 | 313 | lexer->result_symbol = JSX_TEXT; 314 | return saw_text; 315 | } 316 | 317 | static inline bool external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) { 318 | if (valid_symbols[TEMPLATE_CHARS]) { 319 | if (valid_symbols[AUTOMATIC_SEMICOLON]) { 320 | return false; 321 | } 322 | return scan_template_chars(lexer); 323 | } 324 | 325 | if (valid_symbols[JSX_TEXT] && scan_jsx_text(lexer)) { 326 | return true; 327 | } 328 | 329 | if (valid_symbols[AUTOMATIC_SEMICOLON] || valid_symbols[FUNCTION_SIGNATURE_AUTOMATIC_SEMICOLON]) { 330 | bool scanned_comment = false; 331 | bool ret = scan_automatic_semicolon(lexer, valid_symbols, &scanned_comment); 332 | if (!ret && !scanned_comment && valid_symbols[TERNARY_QMARK] && lexer->lookahead == '?') { 333 | return scan_ternary_qmark(lexer); 334 | } 335 | return ret; 336 | } 337 | if (valid_symbols[TERNARY_QMARK]) { 338 | return scan_ternary_qmark(lexer); 339 | } 340 | 341 | if (valid_symbols[HTML_COMMENT] && !valid_symbols[LOGICAL_OR] && !valid_symbols[ESCAPE_SEQUENCE] && 342 | !valid_symbols[REGEX_PATTERN]) { 343 | return scan_closing_comment(lexer); 344 | } 345 | 346 | return false; 347 | } 348 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import treesitter from 'eslint-config-treesitter'; 2 | 3 | export default [ 4 | ...treesitter, 5 | ]; 6 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tree-sitter/tree-sitter-typescript 2 | 3 | go 1.22.0 4 | 5 | require github.com/tree-sitter/go-tree-sitter v0.24.0 6 | 7 | require github.com/mattn/go-pointer v0.0.1 // indirect 8 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= 4 | github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 8 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 9 | github.com/tree-sitter/go-tree-sitter v0.24.0 h1:kRZb6aBNfcI/u0Qh8XEt3zjNVnmxTisDBN+kXK0xRYQ= 10 | github.com/tree-sitter/go-tree-sitter v0.24.0/go.mod h1:x681iFVoLMEwOSIHA1chaLkXlroXEN7WY+VHGFaoDbk= 11 | github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb h1:A8425heRM8mylnv4H58FPUiH+aYivyitre0PzxrfmWs= 12 | github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb/go.mod h1:dOF6gtQiF9UwNh995T5OphYmtIypkjsp3ap7r9AN/iA= 13 | github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148 h1:AfFPZwtwGN01BW1jDdqBVqscTwetvMpydqYZz57RSlc= 14 | github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148/go.mod h1:Bh6U3viD57rFXRYIQ+kmiYtr+1Bx0AceypDLJJSyi9s= 15 | github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33 h1:TwqSV3qLp3tKSqirGLRHnjFk9Tc2oy57LIl+FQ4GjI4= 16 | github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33/go.mod h1:CvCKCt3v04Ufos1zZnNCelBDeCGRpPucaN8QczoUsN4= 17 | github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012 h1:Xvxck3tE5FW7F7bTS97iNM2ADMyCMJztVqn5HYKdJGo= 18 | github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012/go.mod h1:T40D0O1cPvUU/+AmiXVXy1cncYQT6wem4Z0g4SfAYvY= 19 | github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0 h1:c46K6uh5Dz00zJeU9BfjXdb8I+E4RkUdfnWJpQADXFo= 20 | github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0/go.mod h1:hcNt/kOJHcIcuMvouE7LJcYdeFUFbVpBJ6d4wmOA+tU= 21 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495 h1:jrt4qbJVEFs4H93/ITxygHc6u0TGqAkkate7TQ4wFSA= 22 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495/go.mod h1:oyaR7fLnRV0hT9z6qwE9GkaeTom/hTDwK3H2idcOJFc= 23 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5 h1:om4X9AVg3asL8gxNJDcz4e/Wp+VpQj1PY3uJXKr6EOg= 24 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5/go.mod h1:nNqgPoV/h9uYWk6kYEFdEAhNVOacpfpRW5SFmdaP4tU= 25 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5 h1:pfV3G3k7NCKqKk8THBmyuh2zA33lgYHS3GVrzRR8ry4= 26 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5/go.mod h1:GbMKRjLfk0H+PI7nLi1Sx5lHf5wCpLz9al8tQYSxpEk= 27 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1 h1:ZXZMDwE+IhUtGug4Brv6NjJWUU3rfkZBKpemf6RY8/g= 28 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1/go.mod h1:UKCLuYnJ312Mei+3cyTmGOHzn0YAnaPRECgJmHtzrqs= 29 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb h1:EXEM82lFM7JjJb6qiKZXkpIDaCcbV2obNn82ghwj9lw= 30 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb/go.mod h1:lXCF1nGG5Dr4J3BTS0ObN4xJCCICiSu/b+Xe/VqMV7g= 31 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d h1:fcYCvoXdcP1uRQYXqJHRy6Hec+uKScQdKVtMwK9JeCI= 32 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d/go.mod h1:T1nShQ4v5AJtozZ8YyAS4uzUtDAJj/iv4YfwXSbUHzg= 33 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447 h1:o9alBu1J/WjrcTKEthYtXmdkDc5OVXD+PqlvnEZ0Lzc= 34 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447/go.mod h1:1Oh95COkkTn6Ezp0vcMbvfhRP5gLeqqljR0BYnBzWvc= 35 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 36 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-typescript", 3 | "version": "0.23.2", 4 | "description": "TypeScript and TSX grammars for tree-sitter", 5 | "repository": "https://github.com/tree-sitter/tree-sitter-typescript", 6 | "license": "MIT", 7 | "author": "Max Brunsfeld ", 8 | "maintainers": [ 9 | "Amaan Qureshi " 10 | ], 11 | "main": "bindings/node", 12 | "types": "bindings/node", 13 | "keywords": [ 14 | "incremental", 15 | "parsing", 16 | "tree-sitter", 17 | "typescript", 18 | "tsx" 19 | ], 20 | "files": [ 21 | "binding.gyp", 22 | "prebuilds/**", 23 | "bindings/node/*", 24 | "queries/*", 25 | "typescript/grammar.js", 26 | "tsx/grammar.js", 27 | "tree-sitter.json", 28 | "typescript/package.json", 29 | "tsx/package.json", 30 | "typescript/src/**", 31 | "tsx/src/**", 32 | "common/**", 33 | "*.wasm" 34 | ], 35 | "dependencies": { 36 | "node-addon-api": "^8.2.2", 37 | "node-gyp-build": "^4.8.2", 38 | "tree-sitter-javascript": "^0.23.1" 39 | }, 40 | "peerDependencies": { 41 | "tree-sitter": "^0.21.0" 42 | }, 43 | "peerDependenciesMeta": { 44 | "tree-sitter": { 45 | "optional": true 46 | } 47 | }, 48 | "devDependencies": { 49 | "eslint": ">=9.14.0", 50 | "eslint-config-treesitter": "^1.0.2", 51 | "tree-sitter-cli": "^0.24.4", 52 | "prebuildify": "^6.0.1" 53 | }, 54 | "scripts": { 55 | "install": "node-gyp-build", 56 | "lint": "eslint common/define-grammar.js", 57 | "test": "node --test bindings/node/*_test.js" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-typescript" 7 | description = "TypeScript and TSX grammars for tree-sitter" 8 | version = "0.23.2" 9 | keywords = ["incremental", "parsing", "tree-sitter", "typescript", "tsx"] 10 | classifiers = [ 11 | "Intended Audience :: Developers", 12 | "License :: OSI Approved :: MIT License", 13 | "Topic :: Software Development :: Compilers", 14 | "Topic :: Text Processing :: Linguistic", 15 | "Typing :: Typed", 16 | ] 17 | authors = [ 18 | { name = "Max Brunsfeld", email = "maxbrunsfeld@gmail.com" }, 19 | { name = "Amaan Qureshi", email = "amaanq12@gmail.com" }, 20 | ] 21 | requires-python = ">=3.9" 22 | license.text = "MIT" 23 | readme = "README.md" 24 | 25 | [project.urls] 26 | Homepage = "https://github.com/tree-sitter/tree-sitter-typescript" 27 | 28 | [project.optional-dependencies] 29 | core = ["tree-sitter~=0.23"] 30 | 31 | [tool.cibuildwheel] 32 | build = "cp39-*" 33 | build-frontend = "build" 34 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | ; Types 2 | 3 | (type_identifier) @type 4 | (predefined_type) @type.builtin 5 | 6 | ((identifier) @type 7 | (#match? @type "^[A-Z]")) 8 | 9 | (type_arguments 10 | "<" @punctuation.bracket 11 | ">" @punctuation.bracket) 12 | 13 | ; Variables 14 | 15 | (required_parameter (identifier) @variable.parameter) 16 | (optional_parameter (identifier) @variable.parameter) 17 | 18 | ; Keywords 19 | 20 | [ "abstract" 21 | "declare" 22 | "enum" 23 | "export" 24 | "implements" 25 | "interface" 26 | "keyof" 27 | "namespace" 28 | "private" 29 | "protected" 30 | "public" 31 | "type" 32 | "readonly" 33 | "override" 34 | "satisfies" 35 | ] @keyword 36 | -------------------------------------------------------------------------------- /queries/locals.scm: -------------------------------------------------------------------------------- 1 | (required_parameter (identifier) @local.definition) 2 | (optional_parameter (identifier) @local.definition) 3 | -------------------------------------------------------------------------------- /queries/tags.scm: -------------------------------------------------------------------------------- 1 | (function_signature 2 | name: (identifier) @name) @definition.function 3 | 4 | (method_signature 5 | name: (property_identifier) @name) @definition.method 6 | 7 | (abstract_method_signature 8 | name: (property_identifier) @name) @definition.method 9 | 10 | (abstract_class_declaration 11 | name: (type_identifier) @name) @definition.class 12 | 13 | (module 14 | name: (identifier) @name) @definition.module 15 | 16 | (interface_declaration 17 | name: (type_identifier) @name) @definition.interface 18 | 19 | (type_annotation 20 | (type_identifier) @name) @reference.type 21 | 22 | (new_expression 23 | constructor: (identifier) @name) @reference.class 24 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from os.path import isdir, join 2 | from platform import system 3 | 4 | from setuptools import Extension, find_packages, setup 5 | from setuptools.command.build import build 6 | from wheel.bdist_wheel import bdist_wheel 7 | 8 | 9 | class Build(build): 10 | def run(self): 11 | if isdir("queries"): 12 | dest = join(self.build_lib, "tree_sitter_typescript", "queries") 13 | self.copy_tree("queries", dest) 14 | super().run() 15 | 16 | 17 | class BdistWheel(bdist_wheel): 18 | def get_tag(self): 19 | python, abi, platform = super().get_tag() 20 | if python.startswith("cp"): 21 | python, abi = "cp39", "abi3" 22 | return python, abi, platform 23 | 24 | 25 | setup( 26 | packages=find_packages("bindings/python"), 27 | package_dir={"": "bindings/python"}, 28 | package_data={ 29 | "tree_sitter_typescript": ["*.pyi", "py.typed"], 30 | "tree_sitter_typescript.queries": ["*.scm"], 31 | }, 32 | ext_package="tree_sitter_typescript", 33 | ext_modules=[ 34 | Extension( 35 | name="_binding", 36 | sources=[ 37 | "bindings/python/tree_sitter_typescript/binding.c", 38 | "typescript/src/parser.c", 39 | "typescript/src/scanner.c", 40 | "tsx/src/parser.c", 41 | "tsx/src/scanner.c", 42 | ], 43 | extra_compile_args=[ 44 | "-std=c11", 45 | "-fvisibility=hidden", 46 | ] if system() != "Windows" else [ 47 | "/std:c11", 48 | "/utf-8", 49 | ], 50 | define_macros=[ 51 | ("Py_LIMITED_API", "0x03090000"), 52 | ("PY_SSIZE_T_CLEAN", None), 53 | ("TREE_SITTER_HIDE_SYMBOLS", None), 54 | ], 55 | include_dirs=["typescript/src"], 56 | py_limited_api=True, 57 | ) 58 | ], 59 | cmdclass={ 60 | "build": Build, 61 | "bdist_wheel": BdistWheel 62 | }, 63 | zip_safe=False 64 | ) 65 | -------------------------------------------------------------------------------- /test/corpus/declarations.txt: -------------------------------------------------------------------------------- 1 | ================================== 2 | Ambient declarations 3 | ================================== 4 | 5 | declare class Error { 6 | constructor: Function 7 | } 8 | 9 | declare var foo: number; 10 | 11 | declare const bar = "baz"; 12 | 13 | declare function greet(greeting: string): void; 14 | 15 | declare namespace myLib { 16 | function makeGreeting(s: string): string; 17 | let numberOfGreetings: number; 18 | 19 | interface LogOptions { 20 | verbose?: boolean; 21 | } 22 | interface AlertOptions { 23 | modal: boolean; 24 | title?: string; 25 | color?: string; 26 | } 27 | } 28 | 29 | declare class Greeter { 30 | constructor(greeting: string); 31 | 32 | greeting: string; 33 | showGreeting(): void; 34 | } 35 | 36 | declare module Foo.Bar { export var foo; }; 37 | 38 | declare module Foo { 39 | break; 40 | continue; 41 | debugger; 42 | do { } while (true); 43 | for (x in null) { } 44 | for (;;) { } 45 | if (true) { } else { } 46 | 1; 47 | return; 48 | switch (x) { 49 | case 1: 50 | break; 51 | default: 52 | break; 53 | } 54 | throw "hello"; 55 | try { } 56 | catch (e) { } 57 | finally { } 58 | } 59 | 60 | --- 61 | 62 | (program 63 | (ambient_declaration 64 | (class_declaration 65 | name: (type_identifier) 66 | body: (class_body 67 | (public_field_definition 68 | name: (property_identifier) 69 | type: (type_annotation 70 | (type_identifier)))))) 71 | (ambient_declaration 72 | (variable_declaration 73 | (variable_declarator 74 | name: (identifier) 75 | type: (type_annotation 76 | (predefined_type))))) 77 | (ambient_declaration 78 | (lexical_declaration 79 | (variable_declarator 80 | name: (identifier) 81 | value: (string 82 | (string_fragment))))) 83 | (ambient_declaration 84 | (function_signature 85 | name: (identifier) 86 | parameters: (formal_parameters 87 | (required_parameter 88 | pattern: (identifier) 89 | type: (type_annotation 90 | (predefined_type)))) 91 | return_type: (type_annotation 92 | (predefined_type)))) 93 | (ambient_declaration 94 | (internal_module 95 | name: (identifier) 96 | body: (statement_block 97 | (function_signature 98 | name: (identifier) 99 | parameters: (formal_parameters 100 | (required_parameter 101 | pattern: (identifier) 102 | type: (type_annotation 103 | (predefined_type)))) 104 | return_type: (type_annotation 105 | (predefined_type))) 106 | (lexical_declaration 107 | (variable_declarator 108 | name: (identifier) 109 | type: (type_annotation 110 | (predefined_type)))) 111 | (interface_declaration 112 | name: (type_identifier) 113 | body: (interface_body 114 | (property_signature 115 | name: (property_identifier) 116 | type: (type_annotation 117 | (predefined_type))))) 118 | (interface_declaration 119 | name: (type_identifier) 120 | body: (interface_body 121 | (property_signature 122 | name: (property_identifier) 123 | type: (type_annotation 124 | (predefined_type))) 125 | (property_signature 126 | name: (property_identifier) 127 | type: (type_annotation 128 | (predefined_type))) 129 | (property_signature 130 | name: (property_identifier) 131 | type: (type_annotation 132 | (predefined_type)))))))) 133 | (ambient_declaration 134 | (class_declaration 135 | name: (type_identifier) 136 | body: (class_body 137 | (method_signature 138 | name: (property_identifier) 139 | parameters: (formal_parameters 140 | (required_parameter 141 | pattern: (identifier) 142 | type: (type_annotation 143 | (predefined_type))))) 144 | (public_field_definition 145 | name: (property_identifier) 146 | type: (type_annotation 147 | (predefined_type))) 148 | (method_signature 149 | name: (property_identifier) 150 | parameters: (formal_parameters) 151 | return_type: (type_annotation 152 | (predefined_type)))))) 153 | (ambient_declaration 154 | (module 155 | name: (nested_identifier 156 | object: (identifier) 157 | property: (property_identifier)) 158 | body: (statement_block 159 | (export_statement 160 | declaration: (variable_declaration 161 | (variable_declarator 162 | name: (identifier))))))) 163 | (empty_statement) 164 | (ambient_declaration 165 | (module 166 | name: (identifier) 167 | body: (statement_block 168 | (break_statement) 169 | (continue_statement) 170 | (debugger_statement) 171 | (do_statement 172 | body: (statement_block) 173 | condition: (parenthesized_expression 174 | (true))) 175 | (for_in_statement 176 | left: (identifier) 177 | right: (null) 178 | body: (statement_block)) 179 | (for_statement 180 | initializer: (empty_statement) 181 | condition: (empty_statement) 182 | body: (statement_block)) 183 | (if_statement 184 | condition: (parenthesized_expression 185 | (true)) 186 | consequence: (statement_block) 187 | alternative: (else_clause 188 | (statement_block))) 189 | (expression_statement 190 | (number)) 191 | (return_statement) 192 | (switch_statement 193 | value: (parenthesized_expression 194 | (identifier)) 195 | body: (switch_body 196 | (switch_case 197 | value: (number) 198 | body: (break_statement)) 199 | (switch_default 200 | body: (break_statement)))) 201 | (throw_statement 202 | (string 203 | (string_fragment))) 204 | (try_statement 205 | body: (statement_block) 206 | handler: (catch_clause 207 | parameter: (identifier) 208 | body: (statement_block)) 209 | finalizer: (finally_clause 210 | body: (statement_block))))))) 211 | 212 | ================================================== 213 | Exception handling 214 | ================================================== 215 | 216 | try {} 217 | catch (e: unknown) {} 218 | finally {} 219 | 220 | --- 221 | 222 | (program 223 | (try_statement 224 | body: (statement_block) 225 | handler: (catch_clause 226 | parameter: (identifier) 227 | type: (type_annotation 228 | (predefined_type)) 229 | body: (statement_block)) 230 | finalizer: (finally_clause 231 | body: (statement_block)))) 232 | 233 | ================================================== 234 | Flow-style ambient class declarations with commas 235 | ================================================== 236 | 237 | declare interface IFoo { 238 | bar(): number, 239 | baz(): IBaz, 240 | } 241 | 242 | declare class Foo { 243 | bar(): number, 244 | baz(): Baz, 245 | } 246 | 247 | --- 248 | 249 | (program 250 | (ambient_declaration 251 | (interface_declaration 252 | (type_identifier) 253 | (interface_body 254 | (method_signature 255 | (property_identifier) 256 | (formal_parameters) 257 | (type_annotation 258 | (predefined_type))) 259 | (method_signature 260 | (property_identifier) 261 | (formal_parameters) 262 | (type_annotation 263 | (type_identifier)))))) 264 | (ambient_declaration 265 | (class_declaration 266 | (type_identifier) 267 | (class_body 268 | (method_signature 269 | (property_identifier) 270 | (formal_parameters) 271 | (type_annotation 272 | (predefined_type))) 273 | (method_signature 274 | (property_identifier) 275 | (formal_parameters) 276 | (type_annotation 277 | (type_identifier))))))) 278 | 279 | ================================== 280 | Flow module.exports declarations 281 | ================================== 282 | 283 | declare module.exports: { 284 | foo: string; 285 | } 286 | 287 | --- 288 | 289 | (program 290 | (ambient_declaration 291 | (property_identifier) 292 | (object_type 293 | (property_signature 294 | (property_identifier) 295 | (type_annotation 296 | (predefined_type)))))) 297 | 298 | ================================== 299 | Ambient exports 300 | ================================== 301 | 302 | export default function point(x: number, y: number) { 303 | return { x, y }; 304 | } 305 | 306 | // a comment 307 | 308 | export default class A {} 309 | 310 | export async function readFile(filename: string): Promise 311 | 312 | --- 313 | 314 | (program 315 | (export_statement 316 | (function_declaration 317 | (identifier) 318 | (formal_parameters 319 | (required_parameter 320 | (identifier) 321 | (type_annotation 322 | (predefined_type))) 323 | (required_parameter 324 | (identifier) 325 | (type_annotation 326 | (predefined_type)))) 327 | (statement_block 328 | (return_statement 329 | (object 330 | (shorthand_property_identifier) 331 | (shorthand_property_identifier)))))) 332 | (comment) 333 | (export_statement 334 | (class_declaration 335 | (type_identifier) 336 | (class_body))) 337 | (export_statement 338 | (function_signature 339 | (identifier) 340 | (formal_parameters 341 | (required_parameter 342 | (identifier) 343 | (type_annotation 344 | (predefined_type)))) 345 | (type_annotation 346 | (generic_type 347 | (type_identifier) 348 | (type_arguments 349 | (type_identifier))))))) 350 | 351 | ================================== 352 | Typeof types 353 | ================================== 354 | 355 | declare class Linter { 356 | static findConfiguration: typeof findConfiguration; 357 | } 358 | 359 | --- 360 | 361 | (program 362 | (ambient_declaration 363 | (class_declaration 364 | (type_identifier) 365 | (class_body 366 | (public_field_definition 367 | (property_identifier) 368 | (type_annotation 369 | (type_query 370 | (identifier)))))))) 371 | 372 | ================================== 373 | Export assignments 374 | ================================== 375 | 376 | export = Linter; 377 | export = {}; 378 | 379 | --- 380 | 381 | (program 382 | (export_statement 383 | (identifier)) 384 | (export_statement 385 | (object))) 386 | 387 | ================================== 388 | Import aliases 389 | ================================== 390 | 391 | import r = X.N; 392 | 393 | --- 394 | 395 | (program 396 | (import_alias 397 | (identifier) 398 | (nested_identifier 399 | (identifier) 400 | (property_identifier)))) 401 | 402 | ================================== 403 | Import aliases in modules 404 | ================================== 405 | 406 | module C { 407 | import r = X.N; 408 | } 409 | 410 | --- 411 | 412 | (program 413 | (module 414 | (identifier) 415 | (statement_block 416 | (import_alias 417 | (identifier) 418 | (nested_identifier 419 | (identifier) 420 | (property_identifier)))))) 421 | 422 | ================================== 423 | Export import aliases 424 | ================================== 425 | 426 | module M { 427 | export module N { 428 | } 429 | export import X = N; 430 | } 431 | 432 | --- 433 | 434 | (program 435 | (module 436 | (identifier) 437 | (statement_block 438 | (export_statement 439 | (module 440 | (identifier) 441 | (statement_block))) 442 | (export_statement 443 | (import_alias 444 | (identifier) 445 | (identifier)))))) 446 | 447 | ================================== 448 | Property signatures with accessibility modifiers 449 | ================================== 450 | 451 | export interface IAppState { 452 | public readonly users: ReadonlyArray 453 | } 454 | 455 | export class CloningRepository { 456 | public readonly id = CloningRepositoryID++ 457 | } 458 | 459 | 460 | --- 461 | 462 | (program 463 | (export_statement 464 | (interface_declaration 465 | (type_identifier) 466 | (interface_body 467 | (property_signature 468 | (accessibility_modifier) 469 | (property_identifier) 470 | (type_annotation 471 | (generic_type 472 | (type_identifier) 473 | (type_arguments 474 | (type_identifier)))))))) 475 | (export_statement 476 | (class_declaration 477 | (type_identifier) 478 | (class_body 479 | (public_field_definition 480 | (accessibility_modifier) 481 | (property_identifier) 482 | (update_expression 483 | (identifier))))))) 484 | 485 | ================================== 486 | Ambient type declarations 487 | ================================== 488 | 489 | declare type IndexableType = string | number | Date | Array; 490 | 491 | --- 492 | 493 | (program 494 | (ambient_declaration 495 | (type_alias_declaration 496 | (type_identifier) 497 | (union_type 498 | (union_type 499 | (union_type 500 | (predefined_type) 501 | (predefined_type)) 502 | (type_identifier)) 503 | (generic_type 504 | (type_identifier) 505 | (type_arguments 506 | (union_type 507 | (union_type 508 | (predefined_type) 509 | (predefined_type)) 510 | (type_identifier)))))))) 511 | 512 | ================================== 513 | Ambient module declarations 514 | ================================== 515 | 516 | module Promise { 517 | var on: {} 518 | export function resolve(value?: Thenable): Promise; 519 | } 520 | 521 | declare module "example" 522 | 523 | declare module "example" { } 524 | 525 | --- 526 | 527 | (program 528 | (module 529 | (identifier) 530 | (statement_block 531 | (variable_declaration 532 | (variable_declarator 533 | (identifier) 534 | (type_annotation 535 | (object_type)))) 536 | (export_statement 537 | (function_signature 538 | (identifier) 539 | (type_parameters 540 | (type_parameter 541 | (type_identifier))) 542 | (formal_parameters 543 | (optional_parameter 544 | (identifier) 545 | (type_annotation 546 | (generic_type 547 | (type_identifier) 548 | (type_arguments 549 | (type_identifier)))))) 550 | (type_annotation 551 | (generic_type 552 | (type_identifier) 553 | (type_arguments 554 | (type_identifier)))))))) 555 | (ambient_declaration 556 | (module 557 | (string 558 | (string_fragment)))) 559 | (ambient_declaration 560 | (module 561 | (string 562 | (string_fragment)) 563 | (statement_block)))) 564 | 565 | ================================= 566 | Accessibility modifiers as pair keywords 567 | ================================= 568 | 569 | x = { name, description, private: private_ } 570 | 571 | --- 572 | 573 | (program 574 | (expression_statement 575 | (assignment_expression 576 | (identifier) 577 | (object 578 | (shorthand_property_identifier) 579 | (shorthand_property_identifier) 580 | (pair 581 | (property_identifier) 582 | (identifier)))))) 583 | 584 | ================================= 585 | Type casts 586 | ================================= 587 | 588 | foo as any as Array 589 | bar satisfies number[] 590 | "foobar" as const 591 | 592 | --- 593 | 594 | (program 595 | (expression_statement 596 | (as_expression 597 | (as_expression 598 | (identifier) 599 | (predefined_type)) 600 | (generic_type 601 | (type_identifier) 602 | (type_arguments 603 | (predefined_type))))) 604 | (expression_statement 605 | (satisfies_expression 606 | (identifier) 607 | (array_type 608 | (predefined_type)))) 609 | (expression_statement 610 | (as_expression 611 | (string 612 | (string_fragment))))) 613 | 614 | ================================= 615 | Ambient export function declarations 616 | ================================= 617 | 618 | export interface Foo { 619 | export function OrderedMap(iter: Iterable.Keyed): OrderedMap; 620 | } 621 | 622 | --- 623 | 624 | (program 625 | (export_statement 626 | (interface_declaration 627 | (type_identifier) 628 | (interface_body 629 | (export_statement 630 | (function_signature 631 | (identifier) 632 | (type_parameters 633 | (type_parameter 634 | (type_identifier)) 635 | (type_parameter 636 | (type_identifier))) 637 | (formal_parameters 638 | (required_parameter 639 | (identifier) 640 | (type_annotation 641 | (generic_type 642 | (nested_type_identifier 643 | (identifier) 644 | (type_identifier)) 645 | (type_arguments 646 | (type_identifier) 647 | (type_identifier)))))) 648 | (type_annotation 649 | (generic_type 650 | (type_identifier) 651 | (type_arguments 652 | (type_identifier) 653 | (type_identifier)))))))))) 654 | 655 | ================================= 656 | Ambient type alias declarations in namespaces 657 | ================================= 658 | 659 | declare namespace moment { 660 | type formatFunction = () => string; 661 | 662 | export var x: string; 663 | export class foo { 664 | 665 | } 666 | export function utc(): Moment; 667 | export const enum Blah { Blaz, Bloz, Bleez } 668 | } 669 | 670 | --- 671 | 672 | (program 673 | (ambient_declaration 674 | (internal_module 675 | (identifier) 676 | (statement_block 677 | (type_alias_declaration 678 | (type_identifier) 679 | (function_type 680 | (formal_parameters) 681 | (predefined_type))) 682 | (export_statement 683 | (variable_declaration 684 | (variable_declarator 685 | (identifier) 686 | (type_annotation 687 | (predefined_type))))) 688 | (export_statement 689 | (class_declaration 690 | (type_identifier) 691 | (class_body))) 692 | (export_statement 693 | (function_signature 694 | (identifier) 695 | (formal_parameters) 696 | (type_annotation 697 | (type_identifier)))) 698 | (export_statement 699 | (enum_declaration 700 | (identifier) 701 | (enum_body 702 | (property_identifier) 703 | (property_identifier) 704 | (property_identifier)))))))) 705 | 706 | ================================= 707 | Export interfaces in namespaces 708 | ================================= 709 | 710 | declare namespace Foo { 711 | export interface Bar { 712 | } 713 | } 714 | 715 | --- 716 | 717 | (program 718 | (ambient_declaration 719 | (internal_module 720 | (identifier) 721 | (statement_block 722 | (export_statement 723 | (interface_declaration 724 | (type_identifier) 725 | (interface_body))))))) 726 | 727 | ================================= 728 | Namespaces as internal modules 729 | ================================= 730 | 731 | namespace Foo { 732 | } 733 | 734 | namespace Bar { 735 | var x; 736 | } 737 | 738 | --- 739 | 740 | (program 741 | (expression_statement 742 | (internal_module 743 | (identifier) 744 | (statement_block))) 745 | (expression_statement 746 | (internal_module 747 | (identifier) 748 | (statement_block 749 | (variable_declaration 750 | (variable_declarator 751 | (identifier))))))) 752 | 753 | =========================================== 754 | Method declarations with keywords as names 755 | =========================================== 756 | 757 | class Foo { 758 | private async() {}; 759 | get(): Result {}; 760 | private set(plugin) {}; 761 | } 762 | 763 | --- 764 | 765 | (program 766 | (class_declaration 767 | (type_identifier) 768 | (class_body 769 | (method_definition 770 | (accessibility_modifier) 771 | (property_identifier) 772 | (formal_parameters) 773 | (statement_block)) 774 | (method_definition 775 | (property_identifier) 776 | (formal_parameters) 777 | (type_annotation 778 | (type_identifier)) 779 | (statement_block)) 780 | (method_definition 781 | (accessibility_modifier) 782 | (property_identifier) 783 | (formal_parameters 784 | (required_parameter 785 | (identifier))) 786 | (statement_block))))) 787 | 788 | ======================================= 789 | Classes with method signatures 790 | ======================================= 791 | 792 | class Foo { 793 | public async waitFor(func: () => T | Promise, accept?: (result: T) => boolean | Promise, timeoutMessage?: string, retryCount?: number): Promise; 794 | 795 | public readonly async bar?(); 796 | private static bar(); 797 | private static async bar(): T; 798 | } 799 | 800 | --- 801 | 802 | (program 803 | (class_declaration 804 | (type_identifier) 805 | (class_body 806 | (method_signature 807 | (accessibility_modifier) 808 | (property_identifier) 809 | (type_parameters 810 | (type_parameter 811 | (type_identifier))) 812 | (formal_parameters 813 | (required_parameter 814 | (identifier) 815 | (type_annotation 816 | (function_type 817 | (formal_parameters) 818 | (union_type 819 | (type_identifier) 820 | (generic_type 821 | (type_identifier) 822 | (type_arguments 823 | (union_type 824 | (type_identifier) 825 | (literal_type 826 | (undefined))))))))) 827 | (optional_parameter 828 | (identifier) 829 | (type_annotation 830 | (function_type 831 | (formal_parameters 832 | (required_parameter 833 | (identifier) 834 | (type_annotation 835 | (type_identifier)))) 836 | (union_type 837 | (predefined_type) 838 | (generic_type 839 | (type_identifier) 840 | (type_arguments 841 | (predefined_type))))))) 842 | (optional_parameter 843 | (identifier) 844 | (type_annotation 845 | (predefined_type))) 846 | (optional_parameter 847 | (identifier) 848 | (type_annotation 849 | (predefined_type)))) 850 | (type_annotation 851 | (generic_type 852 | (type_identifier) 853 | (type_arguments 854 | (type_identifier))))) 855 | (method_signature 856 | (accessibility_modifier) 857 | (property_identifier) 858 | (type_parameters 859 | (type_parameter 860 | (type_identifier))) 861 | (formal_parameters)) 862 | (method_signature 863 | (accessibility_modifier) 864 | (property_identifier) 865 | (formal_parameters)) 866 | (method_signature 867 | (accessibility_modifier) 868 | (property_identifier) 869 | (formal_parameters) 870 | (type_annotation 871 | (type_identifier)))))) 872 | 873 | ======================================= 874 | Classes with property names as strings or numbers 875 | ======================================= 876 | 877 | class Foo { 878 | static 2: string; 879 | public static 2: string = 'string'; 880 | public static readonly 'hello'?: int = 'string'; 881 | static readonly 'hello'?: int = 'string'; 882 | readonly 'hello'?: int = 'string'; 883 | } 884 | 885 | --- 886 | 887 | (program 888 | (class_declaration 889 | (type_identifier) 890 | (class_body 891 | (public_field_definition 892 | (number) 893 | (type_annotation 894 | (predefined_type))) 895 | (public_field_definition 896 | (accessibility_modifier) 897 | (number) 898 | (type_annotation 899 | (predefined_type)) 900 | (string 901 | (string_fragment))) 902 | (public_field_definition 903 | (accessibility_modifier) 904 | (string 905 | (string_fragment)) 906 | (type_annotation 907 | (type_identifier)) 908 | (string 909 | (string_fragment))) 910 | (public_field_definition 911 | (string 912 | (string_fragment)) 913 | (type_annotation 914 | (type_identifier)) 915 | (string 916 | (string_fragment))) 917 | (public_field_definition 918 | (string 919 | (string_fragment)) 920 | (type_annotation 921 | (type_identifier)) 922 | (string 923 | (string_fragment)))))) 924 | 925 | =========================================================== 926 | Classes with decorator calls that have type arguments 927 | =========================================================== 928 | 929 | class Foo { 930 | @bar() 931 | method() { 932 | } 933 | } 934 | 935 | --- 936 | 937 | (program 938 | (class_declaration 939 | (type_identifier) 940 | (class_body 941 | (decorator 942 | (call_expression 943 | (identifier) 944 | (type_arguments 945 | (type_identifier)) 946 | (arguments))) 947 | (method_definition 948 | (property_identifier) 949 | (formal_parameters) 950 | (statement_block))))) 951 | 952 | ======================================= 953 | Classes with decorators 954 | ======================================= 955 | 956 | @baz @bam class Foo { 957 | @foo static 2: string; 958 | @bar.buzz(grue) public static 2: string = 'string'; 959 | @readonly readonly 'hello'?: int = 'string'; 960 | @readonly fooBar(@required param: any, @optional param2?: any) { 961 | } 962 | } 963 | 964 | --- 965 | 966 | (program 967 | (class_declaration 968 | (decorator 969 | (identifier)) 970 | (decorator 971 | (identifier)) 972 | (type_identifier) 973 | (class_body 974 | (public_field_definition 975 | (decorator 976 | (identifier)) 977 | (number) 978 | (type_annotation 979 | (predefined_type))) 980 | (public_field_definition 981 | (decorator 982 | (call_expression 983 | (member_expression 984 | (identifier) 985 | (property_identifier)) 986 | (arguments 987 | (identifier)))) 988 | (accessibility_modifier) 989 | (number) 990 | (type_annotation 991 | (predefined_type)) 992 | (string 993 | (string_fragment))) 994 | (public_field_definition 995 | (decorator 996 | (identifier)) 997 | (string 998 | (string_fragment)) 999 | (type_annotation 1000 | (type_identifier)) 1001 | (string 1002 | (string_fragment))) 1003 | (decorator 1004 | (identifier)) 1005 | (method_definition 1006 | (property_identifier) 1007 | (formal_parameters 1008 | (required_parameter 1009 | (decorator 1010 | (identifier)) 1011 | (identifier) 1012 | (type_annotation 1013 | (predefined_type))) 1014 | (optional_parameter 1015 | (decorator 1016 | (identifier)) 1017 | (identifier) 1018 | (type_annotation 1019 | (predefined_type)))) 1020 | (statement_block))))) 1021 | 1022 | ======================================= 1023 | Classes with methods with and without trailing semicolons on one line 1024 | ======================================= 1025 | 1026 | class Foo extends Baz { bar = 5; static one(a) { return a; }; two(b) { return b; } three(c) { return c; } } 1027 | 1028 | --- 1029 | 1030 | (program 1031 | (class_declaration 1032 | (type_identifier) 1033 | (type_parameters 1034 | (type_parameter 1035 | (type_identifier))) 1036 | (class_heritage 1037 | (extends_clause 1038 | (identifier))) 1039 | (class_body 1040 | (public_field_definition 1041 | (property_identifier) 1042 | (number)) 1043 | (method_definition 1044 | (property_identifier) 1045 | (formal_parameters 1046 | (required_parameter 1047 | (identifier))) 1048 | (statement_block 1049 | (return_statement 1050 | (identifier)))) 1051 | (method_definition 1052 | (property_identifier) 1053 | (formal_parameters 1054 | (required_parameter 1055 | (identifier))) 1056 | (statement_block 1057 | (return_statement 1058 | (identifier)))) 1059 | (method_definition 1060 | (property_identifier) 1061 | (formal_parameters 1062 | (required_parameter 1063 | (identifier))) 1064 | (statement_block 1065 | (return_statement 1066 | (identifier))))))) 1067 | 1068 | ======================================= 1069 | Classes with static blocks 1070 | ======================================= 1071 | 1072 | class Foo { 1073 | static { 1074 | this.#bar = ''; 1075 | } 1076 | static { 1077 | this.baz(); 1078 | } 1079 | } 1080 | 1081 | --- 1082 | 1083 | (program 1084 | (class_declaration 1085 | (type_identifier) 1086 | (class_body 1087 | (class_static_block 1088 | (statement_block 1089 | (expression_statement 1090 | (assignment_expression 1091 | (member_expression 1092 | (this) 1093 | (private_property_identifier)) 1094 | (string))))) 1095 | (class_static_block 1096 | (statement_block 1097 | (expression_statement 1098 | (call_expression 1099 | (member_expression 1100 | (this) 1101 | (property_identifier)) 1102 | (arguments)))))))) 1103 | 1104 | ======================================= 1105 | Global namespace declarations 1106 | ======================================= 1107 | 1108 | declare global { 1109 | } 1110 | 1111 | --- 1112 | 1113 | (program 1114 | (ambient_declaration 1115 | (statement_block))) 1116 | 1117 | ======================================= 1118 | Abstract classes 1119 | ======================================= 1120 | 1121 | abstract class Foo { 1122 | } 1123 | 1124 | abstract class Animal { 1125 | readonly abstract prop: string; 1126 | requiredProp!: string; 1127 | abstract makeSound(): void; 1128 | abstract get readonlyProp(): string; 1129 | protected abstract readonlyProp?(): string; 1130 | move(): void { 1131 | console.log("roaming the earth..."); 1132 | } 1133 | } 1134 | 1135 | @bar 1136 | abstract class Foo { 1137 | } 1138 | 1139 | --- 1140 | 1141 | (program 1142 | (abstract_class_declaration 1143 | name: (type_identifier) 1144 | body: (class_body)) 1145 | (abstract_class_declaration 1146 | name: (type_identifier) 1147 | body: (class_body 1148 | (public_field_definition 1149 | name: (property_identifier) 1150 | type: (type_annotation 1151 | (predefined_type))) 1152 | (public_field_definition 1153 | name: (property_identifier) 1154 | type: (type_annotation 1155 | (predefined_type))) 1156 | (abstract_method_signature 1157 | name: (property_identifier) 1158 | parameters: (formal_parameters) 1159 | return_type: (type_annotation 1160 | (predefined_type))) 1161 | (abstract_method_signature 1162 | name: (property_identifier) 1163 | parameters: (formal_parameters) 1164 | return_type: (type_annotation 1165 | (predefined_type))) 1166 | (abstract_method_signature 1167 | (accessibility_modifier) 1168 | name: (property_identifier) 1169 | parameters: (formal_parameters) 1170 | return_type: (type_annotation 1171 | (predefined_type))) 1172 | (method_definition 1173 | name: (property_identifier) 1174 | parameters: (formal_parameters) 1175 | return_type: (type_annotation 1176 | (predefined_type)) 1177 | body: (statement_block 1178 | (expression_statement 1179 | (call_expression 1180 | function: (member_expression 1181 | object: (identifier) 1182 | property: (property_identifier)) 1183 | arguments: (arguments 1184 | (string 1185 | (string_fragment))))))))) 1186 | (abstract_class_declaration 1187 | decorator: (decorator 1188 | (identifier)) 1189 | name: (type_identifier) 1190 | body: (class_body))) 1191 | 1192 | ======================================= 1193 | Decorator with parenthesized expression 1194 | ======================================= 1195 | 1196 | class C { 1197 | @(super.decorate) 1198 | method2() { } 1199 | } 1200 | 1201 | --- 1202 | 1203 | (program 1204 | (class_declaration 1205 | (type_identifier) 1206 | (class_body 1207 | (decorator 1208 | (parenthesized_expression 1209 | (member_expression 1210 | (identifier) 1211 | (property_identifier)))) 1212 | (method_definition 1213 | (property_identifier) 1214 | (formal_parameters) 1215 | (statement_block))))) 1216 | 1217 | ================================== 1218 | Index type queries 1219 | ================================== 1220 | 1221 | export type Extracted = keyof Pick 1222 | 1223 | --- 1224 | 1225 | (program 1226 | (export_statement 1227 | declaration: (type_alias_declaration 1228 | name: (type_identifier) 1229 | value: (index_type_query 1230 | (generic_type 1231 | name: (type_identifier) 1232 | type_arguments: (type_arguments 1233 | (type_identifier) 1234 | (literal_type 1235 | (string 1236 | (string_fragment))))))))) 1237 | 1238 | ================================== 1239 | Definite assignment assertions 1240 | ================================== 1241 | 1242 | var a!: b; 1243 | let a!: b; 1244 | 1245 | --- 1246 | 1247 | (program 1248 | (variable_declaration 1249 | (variable_declarator 1250 | (identifier) 1251 | (type_annotation 1252 | (type_identifier)))) 1253 | (lexical_declaration 1254 | (variable_declarator 1255 | (identifier) 1256 | (type_annotation 1257 | (type_identifier))))) 1258 | 1259 | ==================================== 1260 | Top-level exports 1261 | ==================================== 1262 | 1263 | export default abstract class C { } 1264 | export default class C { } 1265 | export class C { } 1266 | export default interface I { } 1267 | export interface I { } 1268 | 1269 | --- 1270 | 1271 | (program 1272 | (export_statement 1273 | (abstract_class_declaration 1274 | (type_identifier) 1275 | (class_body))) 1276 | (export_statement 1277 | (class_declaration 1278 | (type_identifier) 1279 | (class_body))) 1280 | (export_statement 1281 | (class_declaration 1282 | (type_identifier) 1283 | (class_body))) 1284 | (export_statement 1285 | (interface_declaration 1286 | (type_identifier) 1287 | (interface_body))) 1288 | (export_statement 1289 | (interface_declaration 1290 | (type_identifier) 1291 | (interface_body)))) 1292 | 1293 | ======================================= 1294 | Classes with generic parameters 1295 | ======================================= 1296 | 1297 | class A< 1298 | B, 1299 | C, 1300 | > {} 1301 | 1302 | class D extends A< 1303 | X, 1304 | Y, 1305 | > {} 1306 | 1307 | --- 1308 | 1309 | (program 1310 | (class_declaration 1311 | (type_identifier) 1312 | (type_parameters 1313 | (type_parameter 1314 | (type_identifier)) 1315 | (type_parameter 1316 | (type_identifier))) 1317 | (class_body)) 1318 | (class_declaration 1319 | (type_identifier) 1320 | (class_heritage 1321 | (extends_clause 1322 | (identifier) 1323 | (type_arguments 1324 | (type_identifier) 1325 | (type_identifier)))) 1326 | (class_body))) 1327 | 1328 | ======================================= 1329 | Classes with extensions 1330 | ======================================= 1331 | 1332 | class A extends B(D) implements C {} 1333 | export class A extends B(D) implements C {} 1334 | 1335 | class A extends B(D) implements C {} 1336 | export class A extends B(D) implements C {} 1337 | 1338 | export class A extends B implements C {} 1339 | 1340 | --- 1341 | 1342 | (program 1343 | (class_declaration 1344 | (type_identifier) 1345 | (class_heritage 1346 | (extends_clause 1347 | (call_expression 1348 | (identifier) 1349 | (type_arguments 1350 | (type_identifier)) 1351 | (arguments 1352 | (identifier)))) 1353 | (implements_clause 1354 | (type_identifier))) 1355 | (class_body)) 1356 | (export_statement 1357 | (class_declaration 1358 | (type_identifier) 1359 | (class_heritage 1360 | (extends_clause 1361 | (call_expression 1362 | (identifier) 1363 | (type_arguments 1364 | (type_identifier)) 1365 | (arguments 1366 | (identifier)))) 1367 | (implements_clause 1368 | (type_identifier))) 1369 | (class_body))) 1370 | (class_declaration 1371 | (type_identifier) 1372 | (class_heritage 1373 | (extends_clause 1374 | (call_expression 1375 | (identifier) 1376 | (type_arguments 1377 | (type_identifier)) 1378 | (arguments 1379 | (identifier))) 1380 | (type_arguments 1381 | (type_identifier))) 1382 | (implements_clause 1383 | (type_identifier))) 1384 | (class_body)) 1385 | (export_statement 1386 | (class_declaration 1387 | (type_identifier) 1388 | (class_heritage 1389 | (extends_clause 1390 | (call_expression 1391 | (identifier) 1392 | (type_arguments 1393 | (type_identifier)) 1394 | (arguments 1395 | (identifier))) 1396 | (type_arguments 1397 | (type_identifier))) 1398 | (implements_clause 1399 | (type_identifier))) 1400 | (class_body))) 1401 | (export_statement 1402 | (class_declaration 1403 | (type_identifier) 1404 | (class_heritage 1405 | (extends_clause 1406 | (identifier) 1407 | (type_arguments 1408 | (type_identifier) 1409 | (type_identifier))) 1410 | (implements_clause 1411 | (type_identifier))) 1412 | (class_body)))) 1413 | 1414 | ========================================================================== 1415 | Semicolon is not automatically inserted for method definitions with a body 1416 | ========================================================================== 1417 | 1418 | class Foo { 1419 | public bar() 1420 | { 1421 | } 1422 | } 1423 | 1424 | --- 1425 | 1426 | (program 1427 | (class_declaration 1428 | (type_identifier) 1429 | (class_body 1430 | (method_definition 1431 | (accessibility_modifier) 1432 | (property_identifier) 1433 | (formal_parameters) 1434 | (statement_block))))) 1435 | 1436 | ===================== 1437 | Override modifier 1438 | ===================== 1439 | 1440 | abstract class Foo { 1441 | abstract baz(): void; 1442 | } 1443 | 1444 | class Bar extends Foo { 1445 | override baz() {} 1446 | } 1447 | 1448 | --- 1449 | 1450 | (program 1451 | (abstract_class_declaration 1452 | name: (type_identifier) 1453 | body: (class_body 1454 | (abstract_method_signature 1455 | name: (property_identifier) 1456 | parameters: (formal_parameters) 1457 | return_type: (type_annotation 1458 | (predefined_type))))) 1459 | (class_declaration 1460 | name: (type_identifier) 1461 | (class_heritage 1462 | (extends_clause 1463 | value: (identifier))) 1464 | body: (class_body 1465 | (method_definition 1466 | (override_modifier) 1467 | name: (property_identifier) 1468 | parameters: (formal_parameters) 1469 | body: (statement_block))))) 1470 | -------------------------------------------------------------------------------- /test/corpus/expressions.txt: -------------------------------------------------------------------------------- 1 | ================================== 2 | As expressions 3 | ================================== 4 | 5 | h as `hello` 6 | T as {} & { [t: T]: T } 7 | T as {} & { [t: T]: T } & { [g: G]: G } 8 | 9 | --- 10 | 11 | (program 12 | (expression_statement 13 | (as_expression 14 | (identifier) 15 | (template_literal_type 16 | (string_fragment)))) 17 | (expression_statement 18 | (as_expression 19 | (identifier) 20 | (intersection_type 21 | (object_type) 22 | (object_type 23 | (index_signature 24 | (identifier) 25 | (type_identifier) 26 | (type_annotation 27 | (type_identifier))))))) 28 | (expression_statement 29 | (as_expression 30 | (identifier) 31 | (intersection_type 32 | (intersection_type 33 | (object_type) 34 | (object_type 35 | (index_signature 36 | (identifier) 37 | (type_identifier) 38 | (type_annotation 39 | (type_identifier))))) 40 | (object_type 41 | (index_signature 42 | (identifier) 43 | (type_identifier) 44 | (type_annotation 45 | (type_identifier)))))))) 46 | 47 | ================================== 48 | Satisfies expressions 49 | ================================== 50 | 51 | h satisfies `hello` 52 | T satisfies {} & { [t: T]: T } 53 | T satisfies {} & { [t: T]: T } & { [g: G]: G } 54 | 55 | --- 56 | 57 | (program 58 | (expression_statement 59 | (satisfies_expression 60 | (identifier) 61 | (template_literal_type 62 | (string_fragment)))) 63 | (expression_statement 64 | (satisfies_expression 65 | (identifier) 66 | (intersection_type 67 | (object_type) 68 | (object_type 69 | (index_signature 70 | (identifier) 71 | (type_identifier) 72 | (type_annotation 73 | (type_identifier))))))) 74 | (expression_statement 75 | (satisfies_expression 76 | (identifier) 77 | (intersection_type 78 | (intersection_type 79 | (object_type) 80 | (object_type 81 | (index_signature 82 | (identifier) 83 | (type_identifier) 84 | (type_annotation 85 | (type_identifier))))) 86 | (object_type 87 | (index_signature 88 | (identifier) 89 | (type_identifier) 90 | (type_annotation 91 | (type_identifier)))))))) 92 | 93 | ================================== 94 | Typeof expressions 95 | ================================== 96 | 97 | typeof class {} === "function"; 98 | 99 | typeof module === "object" && typeof module.exports === "object" 100 | 101 | --- 102 | 103 | (program 104 | (expression_statement 105 | (binary_expression 106 | (unary_expression 107 | (class 108 | (class_body))) 109 | (string 110 | (string_fragment)))) 111 | (expression_statement 112 | (binary_expression 113 | (binary_expression 114 | (unary_expression 115 | (identifier)) 116 | (string 117 | (string_fragment))) 118 | (binary_expression 119 | (unary_expression 120 | (member_expression 121 | (identifier) 122 | (property_identifier))) 123 | (string 124 | (string_fragment)))))) 125 | 126 | ================================== 127 | Array with empty elements 128 | ================================== 129 | 130 | [, a, , b, , , , s, , , ] 131 | 132 | --- 133 | 134 | (program 135 | (expression_statement 136 | (array 137 | (identifier) 138 | (identifier) 139 | (identifier)))) 140 | 141 | ================================== 142 | Variable named 'module' 143 | ================================== 144 | 145 | var module; 146 | module; 147 | 148 | --- 149 | 150 | (program 151 | (variable_declaration 152 | (variable_declarator 153 | (identifier))) 154 | (expression_statement 155 | (identifier))) 156 | 157 | ================================== 158 | Multi-line variable declarations 159 | ================================== 160 | 161 | var a = b 162 | , c = d 163 | , e = f 164 | 165 | --- 166 | 167 | (program 168 | (variable_declaration 169 | (variable_declarator 170 | (identifier) 171 | (identifier)) 172 | (variable_declarator 173 | (identifier) 174 | (identifier)) 175 | (variable_declarator 176 | (identifier) 177 | (identifier)))) 178 | 179 | ===================================== 180 | The 'less than' operator 181 | ===================================== 182 | 183 | i < foo.length; 184 | i < type.length; 185 | i < string.length; 186 | 187 | --- 188 | 189 | (program 190 | (expression_statement 191 | (binary_expression 192 | (identifier) 193 | (member_expression 194 | (identifier) 195 | (property_identifier)))) 196 | (expression_statement 197 | (binary_expression 198 | (identifier) 199 | (member_expression 200 | (identifier) 201 | (property_identifier)))) 202 | (expression_statement 203 | (binary_expression 204 | (identifier) 205 | (member_expression 206 | (identifier) 207 | (property_identifier))))) 208 | 209 | ===================================== 210 | Subscript expressions in if statements 211 | ===================================== 212 | 213 | if ( foo ) { 214 | set[ 1 ].apply() 215 | } 216 | 217 | --- 218 | 219 | (program 220 | (if_statement 221 | (parenthesized_expression 222 | (identifier)) 223 | (statement_block 224 | (expression_statement 225 | (call_expression 226 | (member_expression 227 | (subscript_expression 228 | (identifier) 229 | (number)) 230 | (property_identifier)) 231 | (arguments)))))) 232 | 233 | ==================================== 234 | Objects with reserved words as keys 235 | ==================================== 236 | 237 | { 238 | public: true, 239 | private: true, 240 | readonly: true 241 | }; 242 | 243 | { 244 | readonly: 1, 245 | abstract: 1, 246 | static: 1 247 | }; 248 | 249 | --- 250 | 251 | (program 252 | (expression_statement 253 | (object 254 | (pair 255 | key: (property_identifier) 256 | value: (true)) 257 | (pair 258 | key: (property_identifier) 259 | value: (true)) 260 | (pair 261 | key: (property_identifier) 262 | value: (true)))) 263 | (expression_statement 264 | (object 265 | (pair 266 | key: (property_identifier) 267 | value: (number)) 268 | (pair 269 | key: (property_identifier) 270 | value: (number)) 271 | (pair 272 | key: (property_identifier) 273 | value: (number))))) 274 | 275 | ==================================== 276 | Assignment to non-null LHS 277 | ==================================== 278 | 279 | foo! = bar; 280 | foo! += bar; 281 | (foo)! = bar; 282 | (foo)! += bar; 283 | 284 | --- 285 | 286 | (program 287 | (expression_statement 288 | (assignment_expression 289 | (non_null_expression 290 | (identifier)) 291 | (identifier))) 292 | (expression_statement 293 | (augmented_assignment_expression 294 | (non_null_expression 295 | (identifier)) 296 | (identifier))) 297 | (expression_statement 298 | (assignment_expression 299 | (non_null_expression 300 | (parenthesized_expression 301 | (identifier))) 302 | (identifier))) 303 | (expression_statement 304 | (augmented_assignment_expression 305 | (non_null_expression 306 | (parenthesized_expression 307 | (identifier))) 308 | (identifier)))) 309 | 310 | ================================== 311 | Generic calls 312 | ================================== 313 | 314 | f(x) 315 | 316 | --- 317 | 318 | (program 319 | (expression_statement 320 | (call_expression 321 | (identifier) 322 | (type_arguments 323 | (type_identifier)) 324 | (arguments 325 | (identifier))))) 326 | 327 | ================================== 328 | Instantiation expressions 329 | ================================== 330 | 331 | const makeHammerBox = makeBox; 332 | const makeStringBox = makeBox; 333 | const ErrorMap = Map; 334 | 335 | --- 336 | 337 | (program 338 | (lexical_declaration 339 | (variable_declarator 340 | (identifier) 341 | (instantiation_expression 342 | (identifier) 343 | (type_arguments 344 | (type_identifier))))) 345 | (lexical_declaration 346 | (variable_declarator 347 | (identifier) 348 | (instantiation_expression 349 | (identifier) 350 | (type_arguments 351 | (predefined_type))))) 352 | (lexical_declaration 353 | (variable_declarator 354 | (identifier) 355 | (instantiation_expression 356 | (identifier) 357 | (type_arguments 358 | (predefined_type) 359 | (type_identifier)))))) 360 | 361 | ========================== 362 | Type assertions 363 | :language(typescript) 364 | ========================== 365 | 366 | b; 367 | >e.f; 368 | 369 | --- 370 | 371 | (program 372 | (expression_statement (type_assertion 373 | (type_arguments (type_identifier)) 374 | (identifier))) 375 | (expression_statement (type_assertion 376 | (type_arguments (generic_type 377 | (type_identifier) 378 | (type_arguments (type_identifier)))) 379 | (member_expression 380 | (identifier) 381 | (property_identifier))))) 382 | 383 | ========================================================== 384 | Type arguments in JSX 385 | :language(tsx) 386 | ========================================================== 387 | 388 | >hi; 389 | />; 390 | <>fragment; 391 | 392 | --- 393 | 394 | (program 395 | (expression_statement 396 | (jsx_element 397 | (jsx_opening_element (identifier) (type_arguments (type_identifier))) 398 | (jsx_text) 399 | (jsx_closing_element (identifier)))) 400 | (expression_statement 401 | (jsx_self_closing_element 402 | (identifier) (type_arguments (type_identifier)))) 403 | (expression_statement 404 | (jsx_element 405 | (jsx_opening_element) 406 | (jsx_text) 407 | (jsx_closing_element)))) 408 | 409 | ================================== 410 | Ternary expression 411 | ================================== 412 | 413 | a ? function(){ return true } : b; 414 | 415 | --- 416 | 417 | (program 418 | (expression_statement 419 | (ternary_expression 420 | (identifier) 421 | (function_expression 422 | (formal_parameters) 423 | (statement_block 424 | (return_statement 425 | (true)))) 426 | (identifier)))) 427 | -------------------------------------------------------------------------------- /test/corpus/functions.txt: -------------------------------------------------------------------------------- 1 | ================================== 2 | Functions with typed parameters 3 | ================================== 4 | 5 | function greeter(person: string) { 6 | return "Hello, " + person; 7 | } 8 | 9 | function foo(x: T): T { 10 | 11 | } 12 | 13 | function foo(a: T[], f: (x: T) => U): U[] { 14 | 15 | } 16 | 17 | function foo(this: T[]): U[] { 18 | return [] 19 | } 20 | 21 | function foo(x: T, y: U) { 22 | 23 | } 24 | 25 | --- 26 | 27 | (program 28 | (function_declaration 29 | name: (identifier) 30 | parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (predefined_type)))) 31 | body: (statement_block 32 | (return_statement (binary_expression 33 | left: (string (string_fragment)) 34 | right: (identifier))))) 35 | (function_declaration 36 | name: (identifier) 37 | type_parameters: (type_parameters (type_parameter name: (type_identifier))) 38 | parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (type_identifier)))) 39 | return_type: (type_annotation (type_identifier)) 40 | body: (statement_block)) 41 | (function_declaration 42 | name: (identifier) 43 | type_parameters: (type_parameters (type_parameter name: (type_identifier)) (type_parameter name: (type_identifier))) 44 | parameters: (formal_parameters 45 | (required_parameter 46 | pattern: (identifier) 47 | type: (type_annotation (array_type (type_identifier)))) 48 | (required_parameter 49 | pattern: (identifier) 50 | type: (type_annotation 51 | (function_type 52 | parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (type_identifier)))) 53 | return_type: (type_identifier))))) 54 | return_type: (type_annotation (array_type (type_identifier))) 55 | body: (statement_block)) 56 | (function_declaration 57 | name: (identifier) 58 | type_parameters: (type_parameters (type_parameter name: (type_identifier)) (type_parameter name: (type_identifier))) 59 | parameters: (formal_parameters 60 | (required_parameter 61 | pattern: (this) 62 | type: (type_annotation (array_type (type_identifier))))) 63 | return_type: (type_annotation (array_type (type_identifier))) 64 | body: (statement_block (return_statement (array)))) 65 | (function_declaration 66 | name: (identifier) 67 | type_parameters: (type_parameters 68 | (type_parameter name: (type_identifier)) 69 | (type_parameter name: (type_identifier) constraint: (constraint (predefined_type)))) 70 | parameters: (formal_parameters 71 | (required_parameter 72 | pattern: (identifier) 73 | type: (type_annotation (type_identifier))) 74 | (required_parameter 75 | pattern: (identifier) 76 | type: (type_annotation (type_identifier)))) 77 | body: (statement_block))) 78 | 79 | ================================== 80 | New object with type arguments 81 | ================================== 82 | 83 | const lines = new Array() 84 | 85 | --- 86 | 87 | (program 88 | (lexical_declaration 89 | (variable_declarator 90 | (identifier) 91 | (new_expression 92 | (identifier) 93 | (type_arguments (type_identifier)) 94 | (arguments))))) 95 | 96 | =================================================== 97 | Function calls with array and tuple type arguments 98 | =================================================== 99 | 100 | a.b<[C]>(); 101 | a(); 102 | 103 | --- 104 | 105 | (program 106 | (expression_statement 107 | (call_expression 108 | function: (member_expression 109 | object: (identifier) 110 | property: (property_identifier)) 111 | type_arguments: (type_arguments (tuple_type (type_identifier))) 112 | arguments: (arguments))) 113 | (expression_statement 114 | (call_expression 115 | function: (identifier) 116 | type_arguments: (type_arguments 117 | (array_type (nested_type_identifier 118 | module: (identifier) 119 | name: (type_identifier)))) 120 | arguments: (arguments)))) 121 | 122 | ========================================================= 123 | Function calls with optional chaining and type arguments 124 | ========================================================= 125 | 126 | A?.(); 127 | 128 | --- 129 | 130 | (program 131 | (expression_statement 132 | (call_expression 133 | (identifier) 134 | (type_arguments (type_identifier)) 135 | (arguments)))) 136 | 137 | ================================== 138 | Arrow functions and generators with call signatures 139 | ================================== 140 | 141 | (amount, interestRate, duration): number => 2 142 | 143 | function* foo(amount, interestRate, duration): number { 144 | yield amount * interestRate * duration / 12 145 | } 146 | 147 | (module: any): number => 2 148 | 149 | --- 150 | 151 | (program 152 | (expression_statement 153 | (arrow_function 154 | type_parameters: (type_parameters (type_parameter name: (type_identifier))) 155 | parameters: (formal_parameters 156 | (required_parameter pattern: (identifier)) 157 | (required_parameter pattern: (identifier)) 158 | (required_parameter pattern: (identifier))) 159 | return_type: (type_annotation (predefined_type)) 160 | body: (number))) 161 | (generator_function_declaration 162 | name: (identifier) 163 | type_parameters: (type_parameters (type_parameter name: (type_identifier))) 164 | parameters: (formal_parameters 165 | (required_parameter pattern: (identifier)) 166 | (required_parameter pattern: (identifier)) 167 | (required_parameter pattern: (identifier))) 168 | return_type: (type_annotation (predefined_type)) 169 | body: (statement_block 170 | (expression_statement (yield_expression (binary_expression 171 | left: (binary_expression left: (binary_expression left: (identifier) right: (identifier)) right: (identifier)) 172 | right: (number)))))) 173 | (expression_statement 174 | (arrow_function 175 | parameters: (formal_parameters (required_parameter pattern: (identifier) type: (type_annotation (predefined_type)))) 176 | return_type: (type_annotation (predefined_type)) 177 | body: (number)))) 178 | 179 | ================================== 180 | Arrow function with parameter named async 181 | ================================== 182 | 183 | const x = async => async; 184 | 185 | --- 186 | 187 | (program 188 | (lexical_declaration (variable_declarator (identifier) (arrow_function (identifier) (identifier))))) 189 | 190 | ================================== 191 | Super 192 | ================================== 193 | 194 | class A extends B { 195 | constructor(x: number, y: number) { 196 | super(x); 197 | } 198 | public toString() { 199 | return super.toString() + " y=" + this.y; 200 | } 201 | } 202 | 203 | --- 204 | 205 | (program 206 | (class_declaration 207 | name: (type_identifier) 208 | (class_heritage (extends_clause value: (identifier))) 209 | body: (class_body 210 | (method_definition 211 | name: (property_identifier) 212 | parameters: (formal_parameters 213 | (required_parameter pattern: (identifier) type: (type_annotation (predefined_type))) 214 | (required_parameter pattern: (identifier) type: (type_annotation (predefined_type)))) 215 | body: (statement_block 216 | (expression_statement (call_expression 217 | function: (super) 218 | arguments: (arguments (identifier)))))) 219 | (method_definition 220 | (accessibility_modifier) 221 | name: (property_identifier) 222 | parameters: (formal_parameters) 223 | body: (statement_block 224 | (return_statement 225 | (binary_expression 226 | left: (binary_expression 227 | left: (call_expression 228 | function: (member_expression 229 | object: (super) 230 | property: (property_identifier)) 231 | arguments: (arguments)) 232 | right: (string (string_fragment))) 233 | right: (member_expression 234 | object: (this) 235 | property: (property_identifier))))))))) 236 | 237 | 238 | ================== 239 | Function signature 240 | ================== 241 | 242 | export default function foo(): bar 243 | 244 | --- 245 | 246 | (program 247 | (export_statement 248 | (function_signature 249 | (identifier) 250 | (formal_parameters) 251 | (type_annotation (type_identifier))))) 252 | 253 | ============================================================= 254 | Ambiguity between function signature and function declaration 255 | ============================================================= 256 | 257 | function foo() 258 | {} 259 | 260 | function foo(bar) 261 | function foo(bar): baz; 262 | function foo(bar) 263 | 264 | function foo(): () => { [key: foo]: bar } 265 | function foo(): () => { [key: foo]: bar } {} 266 | 267 | --- 268 | 269 | (program 270 | (function_declaration 271 | name: (identifier) 272 | parameters: (formal_parameters) 273 | body: (statement_block)) 274 | (function_signature 275 | name: (identifier) 276 | parameters: (formal_parameters (required_parameter pattern: (identifier)))) 277 | (function_signature 278 | name: (identifier) 279 | parameters: (formal_parameters (required_parameter pattern: (identifier))) 280 | return_type: (type_annotation (type_identifier))) 281 | (function_signature 282 | name: (identifier) 283 | parameters: (formal_parameters 284 | (required_parameter pattern: (identifier)))) 285 | (function_signature 286 | name: (identifier) 287 | parameters: (formal_parameters) 288 | return_type: (type_annotation 289 | (function_type 290 | parameters: (formal_parameters) 291 | return_type: (object_type 292 | (index_signature 293 | name: (identifier) 294 | index_type: (type_identifier) 295 | type: (type_annotation (type_identifier))))))) 296 | (function_declaration 297 | name: (identifier) 298 | parameters: (formal_parameters) 299 | return_type: (type_annotation 300 | (function_type 301 | parameters: (formal_parameters) 302 | return_type: (object_type 303 | (index_signature 304 | name: (identifier) 305 | index_type: (type_identifier) 306 | type: (type_annotation (type_identifier)))))) 307 | body: (statement_block))) 308 | 309 | ==================================================================================== 310 | Ambiguity between function signature and function declaration: comments and newlines 311 | ==================================================================================== 312 | 313 | function foo() 314 | // above is a signature 315 | foo(); 316 | 317 | function bar() 318 | // above is a function declaration 319 | {} 320 | 321 | function foo() 322 | : number; 323 | 324 | --- 325 | 326 | (program 327 | (function_signature (identifier) (formal_parameters)) 328 | (comment) 329 | (expression_statement (call_expression (identifier) (arguments))) 330 | 331 | (function_declaration 332 | (identifier) 333 | (formal_parameters) 334 | (comment) 335 | (statement_block)) 336 | 337 | (function_signature 338 | (identifier) 339 | (formal_parameters) 340 | (type_annotation (predefined_type)))) 341 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "typescript", 5 | "camelcase": "TypeScript", 6 | "scope": "source.ts", 7 | "path": "typescript", 8 | "external-files": [ 9 | "common/scanner.h" 10 | ], 11 | "file-types": [ 12 | "ts" 13 | ], 14 | "highlights": [ 15 | "queries/highlights.scm", 16 | "node_modules/tree-sitter-javascript/queries/highlights.scm" 17 | ], 18 | "injections": "node_modules/tree-sitter-javascript/queries/injections.scm", 19 | "locals": [ 20 | "queries/locals.scm", 21 | "node_modules/tree-sitter-javascript/queries/locals.scm" 22 | ], 23 | "tags": [ 24 | "queries/tags.scm", 25 | "node_modules/tree-sitter-javascript/queries/tags.scm" 26 | ], 27 | "injection-regex": "^(ts|typescript)$" 28 | }, 29 | { 30 | "name": "tsx", 31 | "camelcase": "TSX", 32 | "scope": "source.tsx", 33 | "path": "tsx", 34 | "external-files": [ 35 | "common/scanner.h" 36 | ], 37 | "file-types": [ 38 | "tsx" 39 | ], 40 | "highlights": [ 41 | "queries/highlights.scm", 42 | "node_modules/tree-sitter-javascript/queries/highlights-jsx.scm", 43 | "node_modules/tree-sitter-javascript/queries/highlights.scm" 44 | ], 45 | "injections": "node_modules/tree-sitter-javascript/queries/injections.scm", 46 | "locals": "node_modules/tree-sitter-javascript/queries/locals.scm", 47 | "tags": [ 48 | "queries/tags.scm", 49 | "node_modules/tree-sitter-javascript/queries/tags.scm" 50 | ], 51 | "injection-regex": "^(ts|typescript)$" 52 | }, 53 | { 54 | "name": "flow", 55 | "camelcase": "Flow", 56 | "scope": "source.js.flow", 57 | "path": "tsx", 58 | "external-files": [ 59 | "common/scanner.h" 60 | ], 61 | "file-types": [ 62 | "js" 63 | ], 64 | "highlights": [ 65 | "queries/highlights.scm", 66 | "node_modules/tree-sitter-javascript/queries/highlights-jsx.scm", 67 | "node_modules/tree-sitter-javascript/queries/highlights.scm" 68 | ], 69 | "injections": "node_modules/tree-sitter-javascript/queries/injections.scm", 70 | "locals": "node_modules/tree-sitter-javascript/queries/locals.scm", 71 | "tags": [ 72 | "queries/tags.scm", 73 | "node_modules/tree-sitter-javascript/queries/tags.scm" 74 | ], 75 | "content-regex": "@flow" 76 | } 77 | ], 78 | "metadata": { 79 | "version": "0.23.2", 80 | "license": "MIT", 81 | "description": "TypeScript and TSX grammars for tree-sitter", 82 | "authors": [ 83 | { 84 | "name": "Max Brunsfeld", 85 | "email": "maxbrunsfeld@gmail.com" 86 | }, 87 | { 88 | "name": "Amaan Qureshi", 89 | "email": "amaanq12@gmail.com" 90 | } 91 | ], 92 | "links": { 93 | "repository": "https://github.com/tree-sitter/tree-sitter-typescript" 94 | } 95 | }, 96 | "bindings": { 97 | "c": true, 98 | "go": true, 99 | "node": true, 100 | "python": true, 101 | "rust": true, 102 | "swift": true 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /tsx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_DESCRIPTION "TSX grammar for tree-sitter") 2 | 3 | add_parser(tsx) 4 | -------------------------------------------------------------------------------- /tsx/Makefile: -------------------------------------------------------------------------------- 1 | LANGUAGE_NAME := tree-sitter-tsx 2 | DESCRIPTION := TSX grammar for tree-sitter 3 | 4 | include ../common/common.mak 5 | -------------------------------------------------------------------------------- /tsx/grammar.js: -------------------------------------------------------------------------------- 1 | const defineGrammar = require('../common/define-grammar'); 2 | 3 | module.exports = defineGrammar('tsx'); 4 | -------------------------------------------------------------------------------- /tsx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "../bindings/node/tsx", 3 | "private": true, 4 | "scripts": { 5 | "build": "tree-sitter generate", 6 | "prestart": "tree-sitter build --wasm", 7 | "start": "tree-sitter playground" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tsx/src/scanner.c: -------------------------------------------------------------------------------- 1 | #include "../../common/scanner.h" 2 | 3 | void *tree_sitter_tsx_external_scanner_create() { return NULL; } 4 | 5 | void tree_sitter_tsx_external_scanner_destroy(void *payload) {} 6 | 7 | unsigned tree_sitter_tsx_external_scanner_serialize(void *payload, char *buffer) { return 0; } 8 | 9 | void tree_sitter_tsx_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {} 10 | 11 | bool tree_sitter_tsx_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) { 12 | return external_scanner_scan(payload, lexer, valid_symbols); 13 | } 14 | -------------------------------------------------------------------------------- /tsx/src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /tsx/src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(disable : 4101) 18 | #elif defined(__GNUC__) || defined(__clang__) 19 | #pragma GCC diagnostic push 20 | #pragma GCC diagnostic ignored "-Wunused-variable" 21 | #endif 22 | 23 | #define Array(T) \ 24 | struct { \ 25 | T *contents; \ 26 | uint32_t size; \ 27 | uint32_t capacity; \ 28 | } 29 | 30 | /// Initialize an array. 31 | #define array_init(self) \ 32 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 33 | 34 | /// Create an empty array. 35 | #define array_new() \ 36 | { NULL, 0, 0 } 37 | 38 | /// Get a pointer to the element at a given `index` in the array. 39 | #define array_get(self, _index) \ 40 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 41 | 42 | /// Get a pointer to the first element in the array. 43 | #define array_front(self) array_get(self, 0) 44 | 45 | /// Get a pointer to the last element in the array. 46 | #define array_back(self) array_get(self, (self)->size - 1) 47 | 48 | /// Clear the array, setting its size to zero. Note that this does not free any 49 | /// memory allocated for the array's contents. 50 | #define array_clear(self) ((self)->size = 0) 51 | 52 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 53 | /// less than the array's current capacity, this function has no effect. 54 | #define array_reserve(self, new_capacity) \ 55 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 56 | 57 | /// Free any memory allocated for this array. Note that this does not free any 58 | /// memory allocated for the array's contents. 59 | #define array_delete(self) _array__delete((Array *)(self)) 60 | 61 | /// Push a new `element` onto the end of the array. 62 | #define array_push(self, element) \ 63 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 64 | (self)->contents[(self)->size++] = (element)) 65 | 66 | /// Increase the array's size by `count` elements. 67 | /// New elements are zero-initialized. 68 | #define array_grow_by(self, count) \ 69 | do { \ 70 | if ((count) == 0) break; \ 71 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 72 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 73 | (self)->size += (count); \ 74 | } while (0) 75 | 76 | /// Append all elements from one array to the end of another. 77 | #define array_push_all(self, other) \ 78 | array_extend((self), (other)->size, (other)->contents) 79 | 80 | /// Append `count` elements to the end of the array, reading their values from the 81 | /// `contents` pointer. 82 | #define array_extend(self, count, contents) \ 83 | _array__splice( \ 84 | (Array *)(self), array_elem_size(self), (self)->size, \ 85 | 0, count, contents \ 86 | ) 87 | 88 | /// Remove `old_count` elements from the array starting at the given `index`. At 89 | /// the same index, insert `new_count` new elements, reading their values from the 90 | /// `new_contents` pointer. 91 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 92 | _array__splice( \ 93 | (Array *)(self), array_elem_size(self), _index, \ 94 | old_count, new_count, new_contents \ 95 | ) 96 | 97 | /// Insert one `element` into the array at the given `index`. 98 | #define array_insert(self, _index, element) \ 99 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 100 | 101 | /// Remove one element from the array at the given `index`. 102 | #define array_erase(self, _index) \ 103 | _array__erase((Array *)(self), array_elem_size(self), _index) 104 | 105 | /// Pop the last element off the array, returning the element by value. 106 | #define array_pop(self) ((self)->contents[--(self)->size]) 107 | 108 | /// Assign the contents of one array to another, reallocating if necessary. 109 | #define array_assign(self, other) \ 110 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 111 | 112 | /// Swap one array with another 113 | #define array_swap(self, other) \ 114 | _array__swap((Array *)(self), (Array *)(other)) 115 | 116 | /// Get the size of the array contents 117 | #define array_elem_size(self) (sizeof *(self)->contents) 118 | 119 | /// Search a sorted array for a given `needle` value, using the given `compare` 120 | /// callback to determine the order. 121 | /// 122 | /// If an existing element is found to be equal to `needle`, then the `index` 123 | /// out-parameter is set to the existing value's index, and the `exists` 124 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 125 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 126 | /// is set to false. 127 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 128 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 129 | 130 | /// Search a sorted array for a given `needle` value, using integer comparisons 131 | /// of a given struct field (specified with a leading dot) to determine the order. 132 | /// 133 | /// See also `array_search_sorted_with`. 134 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 135 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 136 | 137 | /// Insert a given `value` into a sorted array, using the given `compare` 138 | /// callback to determine the order. 139 | #define array_insert_sorted_with(self, compare, value) \ 140 | do { \ 141 | unsigned _index, _exists; \ 142 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 143 | if (!_exists) array_insert(self, _index, value); \ 144 | } while (0) 145 | 146 | /// Insert a given `value` into a sorted array, using integer comparisons of 147 | /// a given struct field (specified with a leading dot) to determine the order. 148 | /// 149 | /// See also `array_search_sorted_by`. 150 | #define array_insert_sorted_by(self, field, value) \ 151 | do { \ 152 | unsigned _index, _exists; \ 153 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 154 | if (!_exists) array_insert(self, _index, value); \ 155 | } while (0) 156 | 157 | // Private 158 | 159 | typedef Array(void) Array; 160 | 161 | /// This is not what you're looking for, see `array_delete`. 162 | static inline void _array__delete(Array *self) { 163 | if (self->contents) { 164 | ts_free(self->contents); 165 | self->contents = NULL; 166 | self->size = 0; 167 | self->capacity = 0; 168 | } 169 | } 170 | 171 | /// This is not what you're looking for, see `array_erase`. 172 | static inline void _array__erase(Array *self, size_t element_size, 173 | uint32_t index) { 174 | assert(index < self->size); 175 | char *contents = (char *)self->contents; 176 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 177 | (self->size - index - 1) * element_size); 178 | self->size--; 179 | } 180 | 181 | /// This is not what you're looking for, see `array_reserve`. 182 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 183 | if (new_capacity > self->capacity) { 184 | if (self->contents) { 185 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 186 | } else { 187 | self->contents = ts_malloc(new_capacity * element_size); 188 | } 189 | self->capacity = new_capacity; 190 | } 191 | } 192 | 193 | /// This is not what you're looking for, see `array_assign`. 194 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 195 | _array__reserve(self, element_size, other->size); 196 | self->size = other->size; 197 | memcpy(self->contents, other->contents, self->size * element_size); 198 | } 199 | 200 | /// This is not what you're looking for, see `array_swap`. 201 | static inline void _array__swap(Array *self, Array *other) { 202 | Array swap = *other; 203 | *other = *self; 204 | *self = swap; 205 | } 206 | 207 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 208 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 209 | uint32_t new_size = self->size + count; 210 | if (new_size > self->capacity) { 211 | uint32_t new_capacity = self->capacity * 2; 212 | if (new_capacity < 8) new_capacity = 8; 213 | if (new_capacity < new_size) new_capacity = new_size; 214 | _array__reserve(self, element_size, new_capacity); 215 | } 216 | } 217 | 218 | /// This is not what you're looking for, see `array_splice`. 219 | static inline void _array__splice(Array *self, size_t element_size, 220 | uint32_t index, uint32_t old_count, 221 | uint32_t new_count, const void *elements) { 222 | uint32_t new_size = self->size + new_count - old_count; 223 | uint32_t old_end = index + old_count; 224 | uint32_t new_end = index + new_count; 225 | assert(old_end <= self->size); 226 | 227 | _array__reserve(self, element_size, new_size); 228 | 229 | char *contents = (char *)self->contents; 230 | if (self->size > old_end) { 231 | memmove( 232 | contents + new_end * element_size, 233 | contents + old_end * element_size, 234 | (self->size - old_end) * element_size 235 | ); 236 | } 237 | if (new_count > 0) { 238 | if (elements) { 239 | memcpy( 240 | (contents + index * element_size), 241 | elements, 242 | new_count * element_size 243 | ); 244 | } else { 245 | memset( 246 | (contents + index * element_size), 247 | 0, 248 | new_count * element_size 249 | ); 250 | } 251 | } 252 | self->size += new_count - old_count; 253 | } 254 | 255 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 256 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 257 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 258 | do { \ 259 | *(_index) = start; \ 260 | *(_exists) = false; \ 261 | uint32_t size = (self)->size - *(_index); \ 262 | if (size == 0) break; \ 263 | int comparison; \ 264 | while (size > 1) { \ 265 | uint32_t half_size = size / 2; \ 266 | uint32_t mid_index = *(_index) + half_size; \ 267 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 268 | if (comparison <= 0) *(_index) = mid_index; \ 269 | size -= half_size; \ 270 | } \ 271 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 272 | if (comparison == 0) *(_exists) = true; \ 273 | else if (comparison < 0) *(_index) += 1; \ 274 | } while (0) 275 | 276 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 277 | /// parameter by reference in order to work with the generic sorting function above. 278 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 279 | 280 | #ifdef _MSC_VER 281 | #pragma warning(default : 4101) 282 | #elif defined(__GNUC__) || defined(__clang__) 283 | #pragma GCC diagnostic pop 284 | #endif 285 | 286 | #ifdef __cplusplus 287 | } 288 | #endif 289 | 290 | #endif // TREE_SITTER_ARRAY_H_ 291 | -------------------------------------------------------------------------------- /tsx/src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | #endif 22 | 23 | typedef struct { 24 | TSFieldId field_id; 25 | uint8_t child_index; 26 | bool inherited; 27 | } TSFieldMapEntry; 28 | 29 | typedef struct { 30 | uint16_t index; 31 | uint16_t length; 32 | } TSFieldMapSlice; 33 | 34 | typedef struct { 35 | bool visible; 36 | bool named; 37 | bool supertype; 38 | } TSSymbolMetadata; 39 | 40 | typedef struct TSLexer TSLexer; 41 | 42 | struct TSLexer { 43 | int32_t lookahead; 44 | TSSymbol result_symbol; 45 | void (*advance)(TSLexer *, bool); 46 | void (*mark_end)(TSLexer *); 47 | uint32_t (*get_column)(TSLexer *); 48 | bool (*is_at_included_range_start)(const TSLexer *); 49 | bool (*eof)(const TSLexer *); 50 | void (*log)(const TSLexer *, const char *, ...); 51 | }; 52 | 53 | typedef enum { 54 | TSParseActionTypeShift, 55 | TSParseActionTypeReduce, 56 | TSParseActionTypeAccept, 57 | TSParseActionTypeRecover, 58 | } TSParseActionType; 59 | 60 | typedef union { 61 | struct { 62 | uint8_t type; 63 | TSStateId state; 64 | bool extra; 65 | bool repetition; 66 | } shift; 67 | struct { 68 | uint8_t type; 69 | uint8_t child_count; 70 | TSSymbol symbol; 71 | int16_t dynamic_precedence; 72 | uint16_t production_id; 73 | } reduce; 74 | uint8_t type; 75 | } TSParseAction; 76 | 77 | typedef struct { 78 | uint16_t lex_state; 79 | uint16_t external_lex_state; 80 | } TSLexMode; 81 | 82 | typedef union { 83 | TSParseAction action; 84 | struct { 85 | uint8_t count; 86 | bool reusable; 87 | } entry; 88 | } TSParseActionEntry; 89 | 90 | typedef struct { 91 | int32_t start; 92 | int32_t end; 93 | } TSCharacterRange; 94 | 95 | struct TSLanguage { 96 | uint32_t version; 97 | uint32_t symbol_count; 98 | uint32_t alias_count; 99 | uint32_t token_count; 100 | uint32_t external_token_count; 101 | uint32_t state_count; 102 | uint32_t large_state_count; 103 | uint32_t production_id_count; 104 | uint32_t field_count; 105 | uint16_t max_alias_sequence_length; 106 | const uint16_t *parse_table; 107 | const uint16_t *small_parse_table; 108 | const uint32_t *small_parse_table_map; 109 | const TSParseActionEntry *parse_actions; 110 | const char * const *symbol_names; 111 | const char * const *field_names; 112 | const TSFieldMapSlice *field_map_slices; 113 | const TSFieldMapEntry *field_map_entries; 114 | const TSSymbolMetadata *symbol_metadata; 115 | const TSSymbol *public_symbol_map; 116 | const uint16_t *alias_map; 117 | const TSSymbol *alias_sequences; 118 | const TSLexMode *lex_modes; 119 | bool (*lex_fn)(TSLexer *, TSStateId); 120 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 121 | TSSymbol keyword_capture_token; 122 | struct { 123 | const bool *states; 124 | const TSSymbol *symbol_map; 125 | void *(*create)(void); 126 | void (*destroy)(void *); 127 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 128 | unsigned (*serialize)(void *, char *); 129 | void (*deserialize)(void *, const char *, unsigned); 130 | } external_scanner; 131 | const TSStateId *primary_state_ids; 132 | }; 133 | 134 | static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 135 | uint32_t index = 0; 136 | uint32_t size = len - index; 137 | while (size > 1) { 138 | uint32_t half_size = size / 2; 139 | uint32_t mid_index = index + half_size; 140 | TSCharacterRange *range = &ranges[mid_index]; 141 | if (lookahead >= range->start && lookahead <= range->end) { 142 | return true; 143 | } else if (lookahead > range->end) { 144 | index = mid_index; 145 | } 146 | size -= half_size; 147 | } 148 | TSCharacterRange *range = &ranges[index]; 149 | return (lookahead >= range->start && lookahead <= range->end); 150 | } 151 | 152 | /* 153 | * Lexer Macros 154 | */ 155 | 156 | #ifdef _MSC_VER 157 | #define UNUSED __pragma(warning(suppress : 4101)) 158 | #else 159 | #define UNUSED __attribute__((unused)) 160 | #endif 161 | 162 | #define START_LEXER() \ 163 | bool result = false; \ 164 | bool skip = false; \ 165 | UNUSED \ 166 | bool eof = false; \ 167 | int32_t lookahead; \ 168 | goto start; \ 169 | next_state: \ 170 | lexer->advance(lexer, skip); \ 171 | start: \ 172 | skip = false; \ 173 | lookahead = lexer->lookahead; 174 | 175 | #define ADVANCE(state_value) \ 176 | { \ 177 | state = state_value; \ 178 | goto next_state; \ 179 | } 180 | 181 | #define ADVANCE_MAP(...) \ 182 | { \ 183 | static const uint16_t map[] = { __VA_ARGS__ }; \ 184 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 185 | if (map[i] == lookahead) { \ 186 | state = map[i + 1]; \ 187 | goto next_state; \ 188 | } \ 189 | } \ 190 | } 191 | 192 | #define SKIP(state_value) \ 193 | { \ 194 | skip = true; \ 195 | state = state_value; \ 196 | goto next_state; \ 197 | } 198 | 199 | #define ACCEPT_TOKEN(symbol_value) \ 200 | result = true; \ 201 | lexer->result_symbol = symbol_value; \ 202 | lexer->mark_end(lexer); 203 | 204 | #define END_STATE() return result; 205 | 206 | /* 207 | * Parse Table Macros 208 | */ 209 | 210 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 211 | 212 | #define STATE(id) id 213 | 214 | #define ACTIONS(id) id 215 | 216 | #define SHIFT(state_value) \ 217 | {{ \ 218 | .shift = { \ 219 | .type = TSParseActionTypeShift, \ 220 | .state = (state_value) \ 221 | } \ 222 | }} 223 | 224 | #define SHIFT_REPEAT(state_value) \ 225 | {{ \ 226 | .shift = { \ 227 | .type = TSParseActionTypeShift, \ 228 | .state = (state_value), \ 229 | .repetition = true \ 230 | } \ 231 | }} 232 | 233 | #define SHIFT_EXTRA() \ 234 | {{ \ 235 | .shift = { \ 236 | .type = TSParseActionTypeShift, \ 237 | .extra = true \ 238 | } \ 239 | }} 240 | 241 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 242 | {{ \ 243 | .reduce = { \ 244 | .type = TSParseActionTypeReduce, \ 245 | .symbol = symbol_name, \ 246 | .child_count = children, \ 247 | .dynamic_precedence = precedence, \ 248 | .production_id = prod_id \ 249 | }, \ 250 | }} 251 | 252 | #define RECOVER() \ 253 | {{ \ 254 | .type = TSParseActionTypeRecover \ 255 | }} 256 | 257 | #define ACCEPT_INPUT() \ 258 | {{ \ 259 | .type = TSParseActionTypeAccept \ 260 | }} 261 | 262 | #ifdef __cplusplus 263 | } 264 | #endif 265 | 266 | #endif // TREE_SITTER_PARSER_H_ 267 | -------------------------------------------------------------------------------- /typescript/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(PROJECT_DESCRIPTION "TypeScript grammar for tree-sitter") 2 | 3 | add_parser(typescript) 4 | -------------------------------------------------------------------------------- /typescript/Makefile: -------------------------------------------------------------------------------- 1 | LANGUAGE_NAME := tree-sitter-typescript 2 | DESCRIPTION := TypeScript grammar for tree-sitter 3 | 4 | include ../common/common.mak 5 | -------------------------------------------------------------------------------- /typescript/grammar.js: -------------------------------------------------------------------------------- 1 | const defineGrammar = require('../common/define-grammar'); 2 | 3 | module.exports = defineGrammar('typescript'); 4 | -------------------------------------------------------------------------------- /typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "../bindings/node/typescript", 3 | "private": true, 4 | "scripts": { 5 | "build": "tree-sitter generate", 6 | "prestart": "tree-sitter build --wasm", 7 | "start": "tree-sitter playground" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /typescript/src/scanner.c: -------------------------------------------------------------------------------- 1 | #include "../../common/scanner.h" 2 | 3 | void *tree_sitter_typescript_external_scanner_create() { return NULL; } 4 | 5 | void tree_sitter_typescript_external_scanner_destroy(void *payload) {} 6 | 7 | unsigned tree_sitter_typescript_external_scanner_serialize(void *payload, char *buffer) { return 0; } 8 | 9 | void tree_sitter_typescript_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {} 10 | 11 | bool tree_sitter_typescript_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) { 12 | return external_scanner_scan(payload, lexer, valid_symbols); 13 | } 14 | -------------------------------------------------------------------------------- /typescript/src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /typescript/src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(disable : 4101) 18 | #elif defined(__GNUC__) || defined(__clang__) 19 | #pragma GCC diagnostic push 20 | #pragma GCC diagnostic ignored "-Wunused-variable" 21 | #endif 22 | 23 | #define Array(T) \ 24 | struct { \ 25 | T *contents; \ 26 | uint32_t size; \ 27 | uint32_t capacity; \ 28 | } 29 | 30 | /// Initialize an array. 31 | #define array_init(self) \ 32 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 33 | 34 | /// Create an empty array. 35 | #define array_new() \ 36 | { NULL, 0, 0 } 37 | 38 | /// Get a pointer to the element at a given `index` in the array. 39 | #define array_get(self, _index) \ 40 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 41 | 42 | /// Get a pointer to the first element in the array. 43 | #define array_front(self) array_get(self, 0) 44 | 45 | /// Get a pointer to the last element in the array. 46 | #define array_back(self) array_get(self, (self)->size - 1) 47 | 48 | /// Clear the array, setting its size to zero. Note that this does not free any 49 | /// memory allocated for the array's contents. 50 | #define array_clear(self) ((self)->size = 0) 51 | 52 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 53 | /// less than the array's current capacity, this function has no effect. 54 | #define array_reserve(self, new_capacity) \ 55 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 56 | 57 | /// Free any memory allocated for this array. Note that this does not free any 58 | /// memory allocated for the array's contents. 59 | #define array_delete(self) _array__delete((Array *)(self)) 60 | 61 | /// Push a new `element` onto the end of the array. 62 | #define array_push(self, element) \ 63 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 64 | (self)->contents[(self)->size++] = (element)) 65 | 66 | /// Increase the array's size by `count` elements. 67 | /// New elements are zero-initialized. 68 | #define array_grow_by(self, count) \ 69 | do { \ 70 | if ((count) == 0) break; \ 71 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 72 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 73 | (self)->size += (count); \ 74 | } while (0) 75 | 76 | /// Append all elements from one array to the end of another. 77 | #define array_push_all(self, other) \ 78 | array_extend((self), (other)->size, (other)->contents) 79 | 80 | /// Append `count` elements to the end of the array, reading their values from the 81 | /// `contents` pointer. 82 | #define array_extend(self, count, contents) \ 83 | _array__splice( \ 84 | (Array *)(self), array_elem_size(self), (self)->size, \ 85 | 0, count, contents \ 86 | ) 87 | 88 | /// Remove `old_count` elements from the array starting at the given `index`. At 89 | /// the same index, insert `new_count` new elements, reading their values from the 90 | /// `new_contents` pointer. 91 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 92 | _array__splice( \ 93 | (Array *)(self), array_elem_size(self), _index, \ 94 | old_count, new_count, new_contents \ 95 | ) 96 | 97 | /// Insert one `element` into the array at the given `index`. 98 | #define array_insert(self, _index, element) \ 99 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 100 | 101 | /// Remove one element from the array at the given `index`. 102 | #define array_erase(self, _index) \ 103 | _array__erase((Array *)(self), array_elem_size(self), _index) 104 | 105 | /// Pop the last element off the array, returning the element by value. 106 | #define array_pop(self) ((self)->contents[--(self)->size]) 107 | 108 | /// Assign the contents of one array to another, reallocating if necessary. 109 | #define array_assign(self, other) \ 110 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 111 | 112 | /// Swap one array with another 113 | #define array_swap(self, other) \ 114 | _array__swap((Array *)(self), (Array *)(other)) 115 | 116 | /// Get the size of the array contents 117 | #define array_elem_size(self) (sizeof *(self)->contents) 118 | 119 | /// Search a sorted array for a given `needle` value, using the given `compare` 120 | /// callback to determine the order. 121 | /// 122 | /// If an existing element is found to be equal to `needle`, then the `index` 123 | /// out-parameter is set to the existing value's index, and the `exists` 124 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 125 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 126 | /// is set to false. 127 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 128 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 129 | 130 | /// Search a sorted array for a given `needle` value, using integer comparisons 131 | /// of a given struct field (specified with a leading dot) to determine the order. 132 | /// 133 | /// See also `array_search_sorted_with`. 134 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 135 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 136 | 137 | /// Insert a given `value` into a sorted array, using the given `compare` 138 | /// callback to determine the order. 139 | #define array_insert_sorted_with(self, compare, value) \ 140 | do { \ 141 | unsigned _index, _exists; \ 142 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 143 | if (!_exists) array_insert(self, _index, value); \ 144 | } while (0) 145 | 146 | /// Insert a given `value` into a sorted array, using integer comparisons of 147 | /// a given struct field (specified with a leading dot) to determine the order. 148 | /// 149 | /// See also `array_search_sorted_by`. 150 | #define array_insert_sorted_by(self, field, value) \ 151 | do { \ 152 | unsigned _index, _exists; \ 153 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 154 | if (!_exists) array_insert(self, _index, value); \ 155 | } while (0) 156 | 157 | // Private 158 | 159 | typedef Array(void) Array; 160 | 161 | /// This is not what you're looking for, see `array_delete`. 162 | static inline void _array__delete(Array *self) { 163 | if (self->contents) { 164 | ts_free(self->contents); 165 | self->contents = NULL; 166 | self->size = 0; 167 | self->capacity = 0; 168 | } 169 | } 170 | 171 | /// This is not what you're looking for, see `array_erase`. 172 | static inline void _array__erase(Array *self, size_t element_size, 173 | uint32_t index) { 174 | assert(index < self->size); 175 | char *contents = (char *)self->contents; 176 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 177 | (self->size - index - 1) * element_size); 178 | self->size--; 179 | } 180 | 181 | /// This is not what you're looking for, see `array_reserve`. 182 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 183 | if (new_capacity > self->capacity) { 184 | if (self->contents) { 185 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 186 | } else { 187 | self->contents = ts_malloc(new_capacity * element_size); 188 | } 189 | self->capacity = new_capacity; 190 | } 191 | } 192 | 193 | /// This is not what you're looking for, see `array_assign`. 194 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 195 | _array__reserve(self, element_size, other->size); 196 | self->size = other->size; 197 | memcpy(self->contents, other->contents, self->size * element_size); 198 | } 199 | 200 | /// This is not what you're looking for, see `array_swap`. 201 | static inline void _array__swap(Array *self, Array *other) { 202 | Array swap = *other; 203 | *other = *self; 204 | *self = swap; 205 | } 206 | 207 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 208 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 209 | uint32_t new_size = self->size + count; 210 | if (new_size > self->capacity) { 211 | uint32_t new_capacity = self->capacity * 2; 212 | if (new_capacity < 8) new_capacity = 8; 213 | if (new_capacity < new_size) new_capacity = new_size; 214 | _array__reserve(self, element_size, new_capacity); 215 | } 216 | } 217 | 218 | /// This is not what you're looking for, see `array_splice`. 219 | static inline void _array__splice(Array *self, size_t element_size, 220 | uint32_t index, uint32_t old_count, 221 | uint32_t new_count, const void *elements) { 222 | uint32_t new_size = self->size + new_count - old_count; 223 | uint32_t old_end = index + old_count; 224 | uint32_t new_end = index + new_count; 225 | assert(old_end <= self->size); 226 | 227 | _array__reserve(self, element_size, new_size); 228 | 229 | char *contents = (char *)self->contents; 230 | if (self->size > old_end) { 231 | memmove( 232 | contents + new_end * element_size, 233 | contents + old_end * element_size, 234 | (self->size - old_end) * element_size 235 | ); 236 | } 237 | if (new_count > 0) { 238 | if (elements) { 239 | memcpy( 240 | (contents + index * element_size), 241 | elements, 242 | new_count * element_size 243 | ); 244 | } else { 245 | memset( 246 | (contents + index * element_size), 247 | 0, 248 | new_count * element_size 249 | ); 250 | } 251 | } 252 | self->size += new_count - old_count; 253 | } 254 | 255 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 256 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 257 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 258 | do { \ 259 | *(_index) = start; \ 260 | *(_exists) = false; \ 261 | uint32_t size = (self)->size - *(_index); \ 262 | if (size == 0) break; \ 263 | int comparison; \ 264 | while (size > 1) { \ 265 | uint32_t half_size = size / 2; \ 266 | uint32_t mid_index = *(_index) + half_size; \ 267 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 268 | if (comparison <= 0) *(_index) = mid_index; \ 269 | size -= half_size; \ 270 | } \ 271 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 272 | if (comparison == 0) *(_exists) = true; \ 273 | else if (comparison < 0) *(_index) += 1; \ 274 | } while (0) 275 | 276 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 277 | /// parameter by reference in order to work with the generic sorting function above. 278 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 279 | 280 | #ifdef _MSC_VER 281 | #pragma warning(default : 4101) 282 | #elif defined(__GNUC__) || defined(__clang__) 283 | #pragma GCC diagnostic pop 284 | #endif 285 | 286 | #ifdef __cplusplus 287 | } 288 | #endif 289 | 290 | #endif // TREE_SITTER_ARRAY_H_ 291 | -------------------------------------------------------------------------------- /typescript/src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | #endif 22 | 23 | typedef struct { 24 | TSFieldId field_id; 25 | uint8_t child_index; 26 | bool inherited; 27 | } TSFieldMapEntry; 28 | 29 | typedef struct { 30 | uint16_t index; 31 | uint16_t length; 32 | } TSFieldMapSlice; 33 | 34 | typedef struct { 35 | bool visible; 36 | bool named; 37 | bool supertype; 38 | } TSSymbolMetadata; 39 | 40 | typedef struct TSLexer TSLexer; 41 | 42 | struct TSLexer { 43 | int32_t lookahead; 44 | TSSymbol result_symbol; 45 | void (*advance)(TSLexer *, bool); 46 | void (*mark_end)(TSLexer *); 47 | uint32_t (*get_column)(TSLexer *); 48 | bool (*is_at_included_range_start)(const TSLexer *); 49 | bool (*eof)(const TSLexer *); 50 | void (*log)(const TSLexer *, const char *, ...); 51 | }; 52 | 53 | typedef enum { 54 | TSParseActionTypeShift, 55 | TSParseActionTypeReduce, 56 | TSParseActionTypeAccept, 57 | TSParseActionTypeRecover, 58 | } TSParseActionType; 59 | 60 | typedef union { 61 | struct { 62 | uint8_t type; 63 | TSStateId state; 64 | bool extra; 65 | bool repetition; 66 | } shift; 67 | struct { 68 | uint8_t type; 69 | uint8_t child_count; 70 | TSSymbol symbol; 71 | int16_t dynamic_precedence; 72 | uint16_t production_id; 73 | } reduce; 74 | uint8_t type; 75 | } TSParseAction; 76 | 77 | typedef struct { 78 | uint16_t lex_state; 79 | uint16_t external_lex_state; 80 | } TSLexMode; 81 | 82 | typedef union { 83 | TSParseAction action; 84 | struct { 85 | uint8_t count; 86 | bool reusable; 87 | } entry; 88 | } TSParseActionEntry; 89 | 90 | typedef struct { 91 | int32_t start; 92 | int32_t end; 93 | } TSCharacterRange; 94 | 95 | struct TSLanguage { 96 | uint32_t version; 97 | uint32_t symbol_count; 98 | uint32_t alias_count; 99 | uint32_t token_count; 100 | uint32_t external_token_count; 101 | uint32_t state_count; 102 | uint32_t large_state_count; 103 | uint32_t production_id_count; 104 | uint32_t field_count; 105 | uint16_t max_alias_sequence_length; 106 | const uint16_t *parse_table; 107 | const uint16_t *small_parse_table; 108 | const uint32_t *small_parse_table_map; 109 | const TSParseActionEntry *parse_actions; 110 | const char * const *symbol_names; 111 | const char * const *field_names; 112 | const TSFieldMapSlice *field_map_slices; 113 | const TSFieldMapEntry *field_map_entries; 114 | const TSSymbolMetadata *symbol_metadata; 115 | const TSSymbol *public_symbol_map; 116 | const uint16_t *alias_map; 117 | const TSSymbol *alias_sequences; 118 | const TSLexMode *lex_modes; 119 | bool (*lex_fn)(TSLexer *, TSStateId); 120 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 121 | TSSymbol keyword_capture_token; 122 | struct { 123 | const bool *states; 124 | const TSSymbol *symbol_map; 125 | void *(*create)(void); 126 | void (*destroy)(void *); 127 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 128 | unsigned (*serialize)(void *, char *); 129 | void (*deserialize)(void *, const char *, unsigned); 130 | } external_scanner; 131 | const TSStateId *primary_state_ids; 132 | }; 133 | 134 | static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 135 | uint32_t index = 0; 136 | uint32_t size = len - index; 137 | while (size > 1) { 138 | uint32_t half_size = size / 2; 139 | uint32_t mid_index = index + half_size; 140 | TSCharacterRange *range = &ranges[mid_index]; 141 | if (lookahead >= range->start && lookahead <= range->end) { 142 | return true; 143 | } else if (lookahead > range->end) { 144 | index = mid_index; 145 | } 146 | size -= half_size; 147 | } 148 | TSCharacterRange *range = &ranges[index]; 149 | return (lookahead >= range->start && lookahead <= range->end); 150 | } 151 | 152 | /* 153 | * Lexer Macros 154 | */ 155 | 156 | #ifdef _MSC_VER 157 | #define UNUSED __pragma(warning(suppress : 4101)) 158 | #else 159 | #define UNUSED __attribute__((unused)) 160 | #endif 161 | 162 | #define START_LEXER() \ 163 | bool result = false; \ 164 | bool skip = false; \ 165 | UNUSED \ 166 | bool eof = false; \ 167 | int32_t lookahead; \ 168 | goto start; \ 169 | next_state: \ 170 | lexer->advance(lexer, skip); \ 171 | start: \ 172 | skip = false; \ 173 | lookahead = lexer->lookahead; 174 | 175 | #define ADVANCE(state_value) \ 176 | { \ 177 | state = state_value; \ 178 | goto next_state; \ 179 | } 180 | 181 | #define ADVANCE_MAP(...) \ 182 | { \ 183 | static const uint16_t map[] = { __VA_ARGS__ }; \ 184 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 185 | if (map[i] == lookahead) { \ 186 | state = map[i + 1]; \ 187 | goto next_state; \ 188 | } \ 189 | } \ 190 | } 191 | 192 | #define SKIP(state_value) \ 193 | { \ 194 | skip = true; \ 195 | state = state_value; \ 196 | goto next_state; \ 197 | } 198 | 199 | #define ACCEPT_TOKEN(symbol_value) \ 200 | result = true; \ 201 | lexer->result_symbol = symbol_value; \ 202 | lexer->mark_end(lexer); 203 | 204 | #define END_STATE() return result; 205 | 206 | /* 207 | * Parse Table Macros 208 | */ 209 | 210 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 211 | 212 | #define STATE(id) id 213 | 214 | #define ACTIONS(id) id 215 | 216 | #define SHIFT(state_value) \ 217 | {{ \ 218 | .shift = { \ 219 | .type = TSParseActionTypeShift, \ 220 | .state = (state_value) \ 221 | } \ 222 | }} 223 | 224 | #define SHIFT_REPEAT(state_value) \ 225 | {{ \ 226 | .shift = { \ 227 | .type = TSParseActionTypeShift, \ 228 | .state = (state_value), \ 229 | .repetition = true \ 230 | } \ 231 | }} 232 | 233 | #define SHIFT_EXTRA() \ 234 | {{ \ 235 | .shift = { \ 236 | .type = TSParseActionTypeShift, \ 237 | .extra = true \ 238 | } \ 239 | }} 240 | 241 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 242 | {{ \ 243 | .reduce = { \ 244 | .type = TSParseActionTypeReduce, \ 245 | .symbol = symbol_name, \ 246 | .child_count = children, \ 247 | .dynamic_precedence = precedence, \ 248 | .production_id = prod_id \ 249 | }, \ 250 | }} 251 | 252 | #define RECOVER() \ 253 | {{ \ 254 | .type = TSParseActionTypeRecover \ 255 | }} 256 | 257 | #define ACCEPT_INPUT() \ 258 | {{ \ 259 | .type = TSParseActionTypeAccept \ 260 | }} 261 | 262 | #ifdef __cplusplus 263 | } 264 | #endif 265 | 266 | #endif // TREE_SITTER_PARSER_H_ 267 | --------------------------------------------------------------------------------