├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ ├── fuzz.yml │ ├── lint.yml │ └── publish.yml ├── .gitignore ├── CMakeLists.txt ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.swift ├── README.md ├── binding.gyp ├── bindings ├── c │ ├── tree-sitter-c-sharp.h │ └── tree-sitter-c-sharp.pc.in ├── go │ ├── binding.go │ └── binding_test.go ├── node │ ├── binding.cc │ ├── binding_test.js │ ├── index.d.ts │ └── index.js ├── python │ ├── tests │ │ └── test_binding.py │ └── tree_sitter_c_sharp │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed ├── rust │ ├── build.rs │ └── lib.rs └── swift │ ├── TreeSitterCSharp │ └── c-sharp.h │ └── TreeSitterCSharpTests │ └── TreeSitterCSharpTests.swift ├── eslint.config.mjs ├── go.mod ├── go.sum ├── grammar.js ├── package-lock.json ├── package.json ├── pyproject.toml ├── queries ├── highlights.scm └── tags.scm ├── setup.py ├── src ├── grammar.json ├── node-types.json ├── parser.c ├── scanner.c └── tree_sitter │ ├── alloc.h │ ├── array.h │ └── parser.h ├── test ├── corpus │ ├── attributes.txt │ ├── classes.txt │ ├── contextual-keywords.txt │ ├── enums.txt │ ├── expressions.txt │ ├── identifiers.txt │ ├── interfaces.txt │ ├── literals.txt │ ├── preprocessor.txt │ ├── query-syntax.txt │ ├── records.txt │ ├── source-file-structure.txt │ ├── statements.txt │ ├── structs.txt │ ├── type-events.txt │ ├── type-fields.txt │ ├── type-methods.txt │ ├── type-operators.txt │ └── type-properties.txt ├── highlight │ ├── baseline.cs │ ├── operators.cs │ ├── types.cs │ ├── var.cs │ └── variableDeclarations.cs └── queries │ └── identifiers.cs ├── tools └── highlight-test-generator │ ├── .gitignore │ ├── .vscode │ ├── launch.json │ └── tasks.json │ ├── Generator.cs │ ├── Generator.csproj │ └── run-generator └── tree-sitter.json /.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 | src/*.json linguist-generated 5 | src/parser.c linguist-generated 6 | src/tree_sitter/* linguist-generated 7 | 8 | # C bindings 9 | bindings/c/* linguist-generated 10 | CMakeLists.txt linguist-generated 11 | Makefile linguist-generated 12 | 13 | # Rust bindings 14 | bindings/rust/* linguist-generated 15 | Cargo.toml linguist-generated 16 | Cargo.lock linguist-generated 17 | 18 | # Node.js bindings 19 | bindings/node/* linguist-generated 20 | binding.gyp linguist-generated 21 | package.json linguist-generated 22 | package-lock.json linguist-generated 23 | 24 | # Python bindings 25 | bindings/python/** linguist-generated 26 | setup.py linguist-generated 27 | pyproject.toml linguist-generated 28 | 29 | # Go bindings 30 | bindings/go/* linguist-generated 31 | go.mod linguist-generated 32 | go.sum linguist-generated 33 | 34 | # Swift bindings 35 | bindings/swift/** linguist-generated 36 | Package.swift linguist-generated 37 | Package.resolved linguist-generated 38 | -------------------------------------------------------------------------------- /.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/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - grammar.js 8 | - src/** 9 | - test/** 10 | - bindings/** 11 | - binding.gyp 12 | pull_request: 13 | paths: 14 | - grammar.js 15 | - src/** 16 | - test/** 17 | - bindings/** 18 | - binding.gyp 19 | 20 | concurrency: 21 | group: ${{github.workflow}}-${{github.ref}} 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | test: 26 | name: Test parser 27 | runs-on: ${{matrix.os}} 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | os: [ubuntu-latest, windows-latest, macos-14] 32 | steps: 33 | - name: Checkout repository 34 | uses: actions/checkout@v4 35 | - name: Set up tree-sitter 36 | uses: tree-sitter/setup-action/cli@v1 37 | - name: Set up examples 38 | run: |- 39 | git clone https://github.com/JamesNK/Newtonsoft.Json examples/Newtonsoft.Json --single-branch --depth=1 --filter=blob:none 40 | git clone https://github.com/nunit/nunit examples/nunit --single-branch --depth=1 --filter=blob:none 41 | git clone https://github.com/OrchardCMS/orchard examples/orchard --single-branch --depth=1 --filter=blob:none 42 | git clone https://github.com/microsoft/PowerToys examples/PowerToys --single-branch --depth=1 --filter=blob:none 43 | - name: Run tests 44 | uses: tree-sitter/parser-test-action@v2 45 | with: 46 | test-rust: true 47 | test-node: true 48 | test-python: true 49 | test-go: true 50 | test-swift: true 51 | - name: Parse examples 52 | uses: tree-sitter/parse-action@v4 53 | id: test 54 | with: 55 | files: | 56 | examples/**/*.cs 57 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ExceptionHandlingAsyncTests.cs 58 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ExceptionHandlingTests.cs 59 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/FloatAsyncTests.cs 60 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/FloatTests.cs 61 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/MiscAsyncTests.cs 62 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/MiscTests.cs 63 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseAsyncTests.cs 64 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseTests.cs 65 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadAsyncTests.cs 66 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadTests.cs 67 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs 68 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs 69 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Linq/JsonPath/JPathExecuteTests.cs 70 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaSpecTests.cs 71 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs 72 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs 73 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs 74 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs 75 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs 76 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs 77 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/TestObjects/Organization/Person.cs 78 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/TestObjects/Pair.cs 79 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Utilities/DateTimeUtilsTests.cs 80 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json.Tests/Utilities/EnumUtilsTests.cs 81 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs 82 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs 83 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs 84 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs 85 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/UnixDateTimeConverter.cs 86 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs 87 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs 88 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonException.cs 89 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.Async.cs 90 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs 91 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs 92 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs 93 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.Async.cs 94 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs 95 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs 96 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs 97 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.Async.cs 98 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs 99 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs 100 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs 101 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs 102 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs 103 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs 104 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs 105 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs 106 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JsonPath/FieldMultipleFilter.cs 107 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JsonPath/QueryExpression.cs 108 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs 109 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs 110 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs 111 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs 112 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs 113 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs 114 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs 115 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs 116 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs 117 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs 118 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs 119 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs 120 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/TraceJsonWriter.cs 121 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs 122 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs 123 | !examples/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs 124 | !examples/PowerToys/src/modules/MouseWithoutBorders/App/Class/InputHook.cs 125 | !examples/PowerToys/src/settings-ui/Settings.UI.Library/Attributes/CmdConfigureIgnoreAttribute.cs 126 | !examples/PowerToys/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs 127 | !examples/nunit/src/NUnitFramework/benchmarks/nunit.framework.benchmarks/ParamAttributeTypeConversionsBenchmark.cs 128 | !examples/nunit/src/NUnitFramework/framework/Attributes/TimeoutAttribute.cs 129 | !examples/nunit/src/NUnitFramework/framework/Compatibility/LongLivedMarshalByRefObject.cs 130 | !examples/nunit/src/NUnitFramework/framework/Constraints/MsgUtils.cs 131 | !examples/nunit/src/NUnitFramework/framework/Internal/DisposeHelper.cs 132 | !examples/nunit/src/NUnitFramework/framework/Internal/OSPlatform.cs 133 | !examples/nunit/src/NUnitFramework/framework/Internal/Reflect.cs 134 | !examples/nunit/src/NUnitFramework/framework/Internal/Results/TestResult.cs 135 | !examples/nunit/src/NUnitFramework/framework/Internal/TestExecutionContext.cs 136 | !examples/nunit/src/NUnitFramework/framework/Internal/TypeHelper.cs 137 | !examples/nunit/src/NUnitFramework/nunitlite/Options.cs 138 | !examples/nunit/src/NUnitFramework/testdata/TestCaseAttributeFixture.cs 139 | !examples/nunit/src/NUnitFramework/tests/Assertions/WarningTests.cs 140 | !examples/nunit/src/NUnitFramework/tests/Attributes/ApartmentAttributeTests.cs 141 | !examples/nunit/src/NUnitFramework/tests/Attributes/DerivedPropertyAttributeTests.cs 142 | !examples/nunit/src/NUnitFramework/tests/Attributes/RequiresThreadAttributeTests.cs 143 | !examples/nunit/src/NUnitFramework/tests/Attributes/SingleThreadedFixtureTests.cs 144 | !examples/nunit/src/NUnitFramework/tests/Attributes/TimeoutTests.cs 145 | !examples/nunit/src/NUnitFramework/tests/Internal/EventQueueTests.cs 146 | !examples/nunit/src/NUnitFramework/tests/SynchronizationContextTests.cs 147 | !examples/nunit/src/NUnitFramework/tests/Syntax/PathConstraintTests.cs 148 | !examples/nunit/src/NUnitFramework/windows-tests/SynchronizationContextTests.cs 149 | -------------------------------------------------------------------------------- /.github/workflows/fuzz.yml: -------------------------------------------------------------------------------- 1 | name: Fuzz Parser 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - src/scanner.c 8 | pull_request: 9 | paths: 10 | - src/scanner.c 11 | 12 | jobs: 13 | fuzz: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | - name: Run fuzzer 19 | uses: tree-sitter/fuzz-action@v4 20 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - grammar.js 8 | pull_request: 9 | paths: 10 | - 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 | 42 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | project(tree-sitter-c-sharp 4 | VERSION "0.23.1" 5 | DESCRIPTION "C# grammar for tree-sitter" 6 | HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-c-sharp" 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 | add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" 21 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" 22 | COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json 23 | --abi=${TREE_SITTER_ABI_VERSION} 24 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 25 | COMMENT "Generating parser.c") 26 | 27 | add_library(tree-sitter-c-sharp src/parser.c) 28 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) 29 | target_sources(tree-sitter-c-sharp PRIVATE src/scanner.c) 30 | endif() 31 | target_include_directories(tree-sitter-c-sharp PRIVATE src) 32 | 33 | target_compile_definitions(tree-sitter-c-sharp PRIVATE 34 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 35 | $<$:TREE_SITTER_DEBUG>) 36 | 37 | set_target_properties(tree-sitter-c-sharp 38 | PROPERTIES 39 | C_STANDARD 11 40 | POSITION_INDEPENDENT_CODE ON 41 | SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}" 42 | DEFINE_SYMBOL "") 43 | 44 | configure_file(bindings/c/tree-sitter-c-sharp.pc.in 45 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-c-sharp.pc" @ONLY) 46 | 47 | include(GNUInstallDirs) 48 | 49 | install(FILES bindings/c/tree-sitter-c-sharp.h 50 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tree_sitter") 51 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-c-sharp.pc" 52 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") 53 | install(TARGETS tree-sitter-c-sharp 54 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 55 | 56 | add_custom_target(ts-test "${TREE_SITTER_CLI}" test 57 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 58 | COMMENT "tree-sitter test") 59 | -------------------------------------------------------------------------------- /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-c-sharp" 85 | version = "0.23.1" 86 | dependencies = [ 87 | "cc", 88 | "tree-sitter", 89 | "tree-sitter-language", 90 | ] 91 | 92 | [[package]] 93 | name = "tree-sitter-language" 94 | version = "0.1.2" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "e8ddffe35a0e5eeeadf13ff7350af564c6e73993a24db62caee1822b185c2600" 97 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-c-sharp" 3 | description = "C# grammar for tree-sitter" 4 | version = "0.23.1" 5 | authors = [ 6 | "Max Brunsfeld ", 7 | "Amaan Qureshi ", 8 | ] 9 | license = "MIT" 10 | readme = "README.md" 11 | keywords = ["incremental", "parsing", "tree-sitter", "c-sharp"] 12 | categories = ["parsing", "text-editors"] 13 | repository = "https://github.com/tree-sitter/tree-sitter-c-sharp" 14 | edition = "2021" 15 | autoexamples = false 16 | 17 | build = "bindings/rust/build.rs" 18 | include = ["LICENSE", "bindings/rust/*", "grammar.js", "queries/*", "src/*", "tree-sitter.json"] 19 | 20 | [lib] 21 | path = "bindings/rust/lib.rs" 22 | 23 | [dependencies] 24 | tree-sitter-language = "0.1" 25 | 26 | [build-dependencies] 27 | cc = "1.1" 28 | 29 | [dev-dependencies] 30 | tree-sitter = "0.24" 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2023 Max Brunsfeld, Damien Guard, Amaan Qureshi, and contributors. 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 | ifeq ($(OS),Windows_NT) 2 | $(error Windows is not supported) 3 | endif 4 | 5 | LANGUAGE_NAME := tree-sitter-c-sharp 6 | HOMEPAGE_URL := https://github.com/tree-sitter/tree-sitter-c-sharp 7 | VERSION := 0.23.1 8 | 9 | # repository 10 | SRC_DIR := src 11 | 12 | TS ?= tree-sitter 13 | 14 | # install directory layout 15 | PREFIX ?= /usr/local 16 | INCLUDEDIR ?= $(PREFIX)/include 17 | LIBDIR ?= $(PREFIX)/lib 18 | PCLIBDIR ?= $(LIBDIR)/pkgconfig 19 | 20 | # source/object files 21 | PARSER := $(SRC_DIR)/parser.c 22 | EXTRAS := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c)) 23 | OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS)) 24 | 25 | # flags 26 | ARFLAGS ?= rcs 27 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC 28 | 29 | # ABI versioning 30 | SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER)) 31 | SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION))) 32 | 33 | # OS-specific bits 34 | ifeq ($(shell uname),Darwin) 35 | SOEXT = dylib 36 | SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT) 37 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT) 38 | LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks 39 | else 40 | SOEXT = so 41 | SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR) 42 | SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR) 43 | LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER) 44 | endif 45 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 46 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 47 | endif 48 | 49 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 50 | 51 | lib$(LANGUAGE_NAME).a: $(OBJS) 52 | $(AR) $(ARFLAGS) $@ $^ 53 | 54 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 55 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 56 | ifneq ($(STRIP),) 57 | $(STRIP) $@ 58 | endif 59 | 60 | $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in 61 | sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \ 62 | -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \ 63 | -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \ 64 | -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \ 65 | -e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \ 66 | -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ 67 | 68 | $(PARSER): $(SRC_DIR)/grammar.json 69 | $(TS) generate $^ 70 | 71 | install: all 72 | install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' 73 | install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 74 | install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 75 | install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 76 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 77 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 78 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 79 | 80 | uninstall: 81 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 82 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 83 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 84 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 85 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 86 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 87 | 88 | clean: 89 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 90 | 91 | test: 92 | $(TS) test 93 | 94 | .PHONY: all install uninstall clean test 95 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "TreeSitterCSharp", 6 | products: [ 7 | .library(name: "TreeSitterCSharp", targets: ["TreeSitterCSharp"]), 8 | ], 9 | dependencies: [ 10 | .package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"), 11 | ], 12 | targets: [ 13 | .target( 14 | name: "TreeSitterCSharp", 15 | dependencies: [], 16 | path: ".", 17 | sources: [ 18 | "src/parser.c", 19 | "src/scanner.c", 20 | ], 21 | resources: [ 22 | .copy("queries") 23 | ], 24 | publicHeadersPath: "bindings/swift", 25 | cSettings: [.headerSearchPath("src")] 26 | ), 27 | .testTarget( 28 | name: "TreeSitterCSharpTests", 29 | dependencies: [ 30 | "SwiftTreeSitter", 31 | "TreeSitterCSharp", 32 | ], 33 | path: "bindings/swift/TreeSitterCSharpTests" 34 | ) 35 | ], 36 | cLanguageStandard: .c11 37 | ) 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-c-sharp 2 | 3 | [![CI][ci]](https://github.com/tree-sitter/tree-sitter-c-sharp/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-c-sharp) 7 | [![npm][npm]](https://www.npmjs.com/package/tree-sitter-c-sharp) 8 | [![pypi][pypi]](https://pypi.org/project/tree-sitter-c-sharp) 9 | 10 | C# grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter) based upon the Roslyn grammar with changes in order to: 11 | 12 | - Deal with differences between the parsing technologies 13 | - Work around some bugs in that grammar 14 | - Handle `#if`, `#else`, `#elif`, `#endif` blocks 15 | - Support syntax highlighting/parsing of fragments 16 | - Simplify the output tree 17 | - Reduce parser state count and complexity 18 | - Be in-line with tree-sitter's convention where applicable 19 | 20 | ### Status 21 | 22 | Comprehensive supports C# 1 through 13.0 with the following exception: 23 | 24 | - [ ] `async`, `var` and `await` cannot be used as identifiers everywhere they are valid 25 | 26 | ### References 27 | 28 | - [Official C# 8 Draft Language Spec](https://github.com/dotnet/csharpstandard/tree/draft-v8/standard) provides chapters that formally define the language grammar. 29 | - [Roslyn C# language grammar export](https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4) 30 | - [SharpLab](https://sharplab.io) (web-based syntax tree playground based on Roslyn) 31 | 32 | [ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-c-sharp/ci.yml?logo=github&label=CI 33 | [discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord 34 | [matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix 35 | [npm]: https://img.shields.io/npm/v/tree-sitter-c-sharp?logo=npm 36 | [crates]: https://img.shields.io/crates/v/tree-sitter-c-sharp?logo=rust 37 | [pypi]: https://img.shields.io/pypi/v/tree-sitter-c-sharp?logo=pypi&logoColor=ffd242 38 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_c_sharp_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_c_sharp(); 6 | 7 | // "tree-sitter", "language" hashed with BLAKE2 8 | const napi_type_tag LANGUAGE_TYPE_TAG = { 9 | 0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16 10 | }; 11 | 12 | Napi::Object Init(Napi::Env env, Napi::Object exports) { 13 | exports["name"] = Napi::String::New(env, "c-sharp"); 14 | auto language = Napi::External::New(env, tree_sitter_c_sharp()); 15 | language.TypeTag(&LANGUAGE_TYPE_TAG); 16 | exports["language"] = language; 17 | return exports; 18 | } 19 | 20 | NODE_API_MODULE(tree_sitter_c_sharp_binding, Init) 21 | -------------------------------------------------------------------------------- /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 grammar", () => { 7 | const parser = new Parser(); 8 | assert.doesNotThrow(() => parser.setLanguage(require("."))); 9 | }); 10 | -------------------------------------------------------------------------------- /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 language: Language; 28 | export = language; 29 | -------------------------------------------------------------------------------- /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-c-sharp.node`) 7 | : require("node-gyp-build")(root); 8 | 9 | try { 10 | module.exports.nodeTypeInfo = require("../../src/node-types.json"); 11 | } catch (_) {} 12 | -------------------------------------------------------------------------------- /bindings/python/tests/test_binding.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import tree_sitter, tree_sitter_c_sharp 4 | 5 | 6 | class TestLanguage(TestCase): 7 | def test_can_load_grammar(self): 8 | try: 9 | tree_sitter.Language(tree_sitter_c_sharp.language()) 10 | except Exception: 11 | self.fail("Error loading C# grammar") 12 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_c_sharp/__init__.py: -------------------------------------------------------------------------------- 1 | """C# grammar for tree-sitter""" 2 | 3 | from importlib.resources import files as _files 4 | 5 | from ._binding import language 6 | 7 | 8 | def _get_query(name, file): 9 | query = _files(f"{__package__}.queries") / file 10 | globals()[name] = query.read_text() 11 | return globals()[name] 12 | 13 | 14 | def __getattr__(name): 15 | # NOTE: uncomment these to include any queries that this grammar contains: 16 | 17 | # if name == "HIGHLIGHTS_QUERY": 18 | # return _get_query("HIGHLIGHTS_QUERY", "highlights.scm") 19 | # if name == "INJECTIONS_QUERY": 20 | # return _get_query("INJECTIONS_QUERY", "injections.scm") 21 | # if name == "LOCALS_QUERY": 22 | # return _get_query("LOCALS_QUERY", "locals.scm") 23 | # if name == "TAGS_QUERY": 24 | # return _get_query("TAGS_QUERY", "tags.scm") 25 | 26 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 27 | 28 | 29 | __all__ = [ 30 | "language", 31 | # "HIGHLIGHTS_QUERY", 32 | # "INJECTIONS_QUERY", 33 | # "LOCALS_QUERY", 34 | # "TAGS_QUERY", 35 | ] 36 | 37 | 38 | def __dir__(): 39 | return sorted(__all__ + [ 40 | "__all__", "__builtins__", "__cached__", "__doc__", "__file__", 41 | "__loader__", "__name__", "__package__", "__path__", "__spec__", 42 | ]) 43 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_c_sharp/__init__.pyi: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | # NOTE: uncomment these to include any queries that this grammar contains: 4 | 5 | # HIGHLIGHTS_QUERY: Final[str] 6 | # INJECTIONS_QUERY: Final[str] 7 | # LOCALS_QUERY: Final[str] 8 | # TAGS_QUERY: Final[str] 9 | 10 | def language() -> object: ... 11 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_c_sharp/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_c_sharp(void); 6 | 7 | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 8 | return PyCapsule_New(tree_sitter_c_sharp(), "tree_sitter.Language", NULL); 9 | } 10 | 11 | static PyMethodDef methods[] = { 12 | {"language", _binding_language, METH_NOARGS, 13 | "Get the tree-sitter language for this grammar."}, 14 | {NULL, NULL, 0, NULL} 15 | }; 16 | 17 | static struct PyModuleDef module = { 18 | .m_base = PyModuleDef_HEAD_INIT, 19 | .m_name = "_binding", 20 | .m_doc = NULL, 21 | .m_size = -1, 22 | .m_methods = methods 23 | }; 24 | 25 | PyMODINIT_FUNC PyInit__binding(void) { 26 | return PyModule_Create(&module); 27 | } 28 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_c_sharp/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tree-sitter/tree-sitter-c-sharp/b5eb5742f6a7e9438bee22ce8026d6b927be2cd7/bindings/python/tree_sitter_c_sharp/py.typed -------------------------------------------------------------------------------- /bindings/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let src_dir = std::path::Path::new("src"); 3 | 4 | let mut c_config = cc::Build::new(); 5 | c_config 6 | .std("c11") 7 | .include(src_dir) 8 | .flag_if_supported("-Wno-unused-value"); 9 | 10 | #[cfg(target_env = "msvc")] 11 | c_config.flag("-utf-8"); 12 | 13 | let parser_path = src_dir.join("parser.c"); 14 | c_config.file(&parser_path); 15 | println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); 16 | 17 | let scanner_path = src_dir.join("scanner.c"); 18 | c_config.file(&scanner_path); 19 | println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); 20 | 21 | c_config.compile("tree-sitter-c-sharp"); 22 | } 23 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides CSharp language support for the [tree-sitter][] parsing library. 2 | //! 3 | //! Typically, you will use the [LANGUAGE][] constant to add this language to a 4 | //! tree-sitter [Parser][], and then use the parser to parse some code: 5 | //! 6 | //! ``` 7 | //! let code = r#" 8 | //! "#; 9 | //! let mut parser = tree_sitter::Parser::new(); 10 | //! let language = tree_sitter_c_sharp::LANGUAGE; 11 | //! parser 12 | //! .set_language(&language.into()) 13 | //! .expect("Error loading C# parser"); 14 | //! let tree = parser.parse(code, None).unwrap(); 15 | //! assert!(!tree.root_node().has_error()); 16 | //! ``` 17 | //! 18 | //! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html 19 | //! [tree-sitter]: https://tree-sitter.github.io/ 20 | 21 | use tree_sitter_language::LanguageFn; 22 | 23 | extern "C" { 24 | fn tree_sitter_c_sharp() -> *const (); 25 | } 26 | 27 | /// The tree-sitter [`LanguageFn`][LanguageFn] for this grammar. 28 | /// 29 | /// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html 30 | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_c_sharp) }; 31 | 32 | /// The content of the [`node-types.json`][] file for this grammar. 33 | /// 34 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types 35 | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); 36 | 37 | // NOTE: uncomment these to include any queries that this grammar contains: 38 | 39 | pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); 40 | // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); 41 | // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); 42 | // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); 43 | 44 | #[cfg(test)] 45 | mod tests { 46 | #[test] 47 | fn test_can_load_grammar() { 48 | let mut parser = tree_sitter::Parser::new(); 49 | parser 50 | .set_language(&super::LANGUAGE.into()) 51 | .expect("Error loading C# parser"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterCSharp/c-sharp.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_C_SHARP_H_ 2 | #define TREE_SITTER_C_SHARP_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_c_sharp(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_C_SHARP_H_ 17 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterCSharpTests/TreeSitterCSharpTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterCSharp 4 | 5 | final class TreeSitterCSharpTests: XCTestCase { 6 | func testCanLoadGrammar() throws { 7 | let parser = Parser() 8 | let language = Language(language: tree_sitter_c_sharp()) 9 | XCTAssertNoThrow(try parser.setLanguage(language), 10 | "Error loading C# grammar") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /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-c-sharp 2 | 3 | go 1.22 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-c-sharp", 3 | "version": "0.23.1", 4 | "description": "C# grammar for tree-sitter", 5 | "repository": "https://github.com/tree-sitter/tree-sitter-c-sharp", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Max Brunsfeld", 9 | "email": "maxbrunsfeld@gmail.com" 10 | }, 11 | "maintainers": [ 12 | { 13 | "name": "Amaan Qureshi", 14 | "email": "amaanq12@gmail.com" 15 | }, 16 | { 17 | "name": "Damien Guard", 18 | "email": "damieng@gmail.com" 19 | } 20 | ], 21 | "main": "bindings/node", 22 | "types": "bindings/node", 23 | "keywords": [ 24 | "incremental", 25 | "parsing", 26 | "tree-sitter", 27 | "c-sharp" 28 | ], 29 | "files": [ 30 | "grammar.js", 31 | "tree-sitter.json", 32 | "binding.gyp", 33 | "prebuilds/**", 34 | "bindings/node/*", 35 | "queries/*", 36 | "src/**", 37 | "*.wasm" 38 | ], 39 | "dependencies": { 40 | "node-addon-api": "^8.2.2", 41 | "node-gyp-build": "^4.8.2" 42 | }, 43 | "devDependencies": { 44 | "eslint": "^9.14.0", 45 | "eslint-config-treesitter": "^1.0.2", 46 | "tree-sitter-cli": "^0.24.4" 47 | }, 48 | "peerDependencies": { 49 | "tree-sitter": "^0.21.1" 50 | }, 51 | "peerDependenciesMeta": { 52 | "tree-sitter": { 53 | "optional": true 54 | } 55 | }, 56 | "scripts": { 57 | "install": "node-gyp-build", 58 | "lint": "eslint grammar.js", 59 | "prestart": "tree-sitter build --wasm", 60 | "start": "tree-sitter playground", 61 | "test": "node --test bindings/node/*_test.js" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-c-sharp" 7 | description = "C# grammar for tree-sitter" 8 | version = "0.23.1" 9 | keywords = ["incremental", "parsing", "tree-sitter", "c-sharp"] 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-c-sharp" 27 | 28 | [project.optional-dependencies] 29 | core = ["tree-sitter~=0.22"] 30 | 31 | [tool.cibuildwheel] 32 | build = "cp39-*" 33 | build-frontend = "build" 34 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | (identifier) @variable 2 | 3 | ;; Methods 4 | 5 | (method_declaration name: (identifier) @function) 6 | (local_function_statement name: (identifier) @function) 7 | 8 | ;; Types 9 | 10 | (interface_declaration name: (identifier) @type) 11 | (class_declaration name: (identifier) @type) 12 | (enum_declaration name: (identifier) @type) 13 | (struct_declaration (identifier) @type) 14 | (record_declaration (identifier) @type) 15 | (namespace_declaration name: (identifier) @module) 16 | 17 | (generic_name (identifier) @type) 18 | (type_parameter (identifier) @property.definition) 19 | (parameter type: (identifier) @type) 20 | (type_argument_list (identifier) @type) 21 | (as_expression right: (identifier) @type) 22 | (is_expression right: (identifier) @type) 23 | 24 | (constructor_declaration name: (identifier) @constructor) 25 | (destructor_declaration name: (identifier) @constructor) 26 | 27 | (_ type: (identifier) @type) 28 | 29 | (base_list (identifier) @type) 30 | 31 | (predefined_type) @type.builtin 32 | 33 | ;; Enum 34 | (enum_member_declaration (identifier) @property.definition) 35 | 36 | ;; Literals 37 | 38 | [ 39 | (real_literal) 40 | (integer_literal) 41 | ] @number 42 | 43 | [ 44 | (character_literal) 45 | (string_literal) 46 | (raw_string_literal) 47 | (verbatim_string_literal) 48 | (interpolated_string_expression) 49 | (interpolation_start) 50 | (interpolation_quote) 51 | ] @string 52 | 53 | (escape_sequence) @string.escape 54 | 55 | [ 56 | (boolean_literal) 57 | (null_literal) 58 | ] @constant.builtin 59 | 60 | ;; Comments 61 | 62 | (comment) @comment 63 | 64 | ;; Tokens 65 | 66 | [ 67 | ";" 68 | "." 69 | "," 70 | ] @punctuation.delimiter 71 | 72 | [ 73 | "--" 74 | "-" 75 | "-=" 76 | "&" 77 | "&=" 78 | "&&" 79 | "+" 80 | "++" 81 | "+=" 82 | "<" 83 | "<=" 84 | "<<" 85 | "<<=" 86 | "=" 87 | "==" 88 | "!" 89 | "!=" 90 | "=>" 91 | ">" 92 | ">=" 93 | ">>" 94 | ">>=" 95 | ">>>" 96 | ">>>=" 97 | "|" 98 | "|=" 99 | "||" 100 | "?" 101 | "??" 102 | "??=" 103 | "^" 104 | "^=" 105 | "~" 106 | "*" 107 | "*=" 108 | "/" 109 | "/=" 110 | "%" 111 | "%=" 112 | ":" 113 | ] @operator 114 | 115 | [ 116 | "(" 117 | ")" 118 | "[" 119 | "]" 120 | "{" 121 | "}" 122 | (interpolation_brace) 123 | ] @punctuation.bracket 124 | 125 | ;; Keywords 126 | 127 | [ 128 | (modifier) 129 | "this" 130 | (implicit_type) 131 | ] @keyword 132 | 133 | [ 134 | "add" 135 | "alias" 136 | "as" 137 | "base" 138 | "break" 139 | "case" 140 | "catch" 141 | "checked" 142 | "class" 143 | "continue" 144 | "default" 145 | "delegate" 146 | "do" 147 | "else" 148 | "enum" 149 | "event" 150 | "explicit" 151 | "extern" 152 | "finally" 153 | "for" 154 | "foreach" 155 | "global" 156 | "goto" 157 | "if" 158 | "implicit" 159 | "interface" 160 | "is" 161 | "lock" 162 | "namespace" 163 | "notnull" 164 | "operator" 165 | "params" 166 | "return" 167 | "remove" 168 | "sizeof" 169 | "stackalloc" 170 | "static" 171 | "struct" 172 | "switch" 173 | "throw" 174 | "try" 175 | "typeof" 176 | "unchecked" 177 | "using" 178 | "while" 179 | "new" 180 | "await" 181 | "in" 182 | "yield" 183 | "get" 184 | "set" 185 | "when" 186 | "out" 187 | "ref" 188 | "from" 189 | "where" 190 | "select" 191 | "record" 192 | "init" 193 | "with" 194 | "let" 195 | ] @keyword 196 | 197 | ;; Attribute 198 | 199 | (attribute name: (identifier) @attribute) 200 | 201 | ;; Parameters 202 | 203 | (parameter 204 | name: (identifier) @variable.parameter) 205 | 206 | ;; Type constraints 207 | 208 | (type_parameter_constraints_clause (identifier) @property.definition) 209 | 210 | ;; Method calls 211 | 212 | (invocation_expression (member_access_expression name: (identifier) @function)) 213 | -------------------------------------------------------------------------------- /queries/tags.scm: -------------------------------------------------------------------------------- 1 | (class_declaration name: (identifier) @name) @definition.class 2 | 3 | (class_declaration (base_list (_) @name)) @reference.class 4 | 5 | (interface_declaration name: (identifier) @name) @definition.interface 6 | 7 | (interface_declaration (base_list (_) @name)) @reference.interface 8 | 9 | (method_declaration name: (identifier) @name) @definition.method 10 | 11 | (object_creation_expression type: (identifier) @name) @reference.class 12 | 13 | (type_parameter_constraints_clause (identifier) @name) @reference.class 14 | 15 | (type_parameter_constraint (type type: (identifier) @name)) @reference.class 16 | 17 | (variable_declaration type: (identifier) @name) @reference.class 18 | 19 | (invocation_expression function: (member_access_expression name: (identifier) @name)) @reference.send 20 | 21 | (namespace_declaration name: (identifier) @name) @definition.module 22 | 23 | (namespace_declaration name: (identifier) @name) @module 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_c-sharp", "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_c_sharp": ["*.pyi", "py.typed"], 30 | "tree_sitter_c_sharp.queries": ["*.scm"], 31 | }, 32 | ext_package="tree_sitter_c_sharp", 33 | ext_modules=[ 34 | Extension( 35 | name="_binding", 36 | sources=[ 37 | "bindings/python/tree_sitter_c_sharp/binding.c", 38 | "src/parser.c", 39 | "src/scanner.c", 40 | ], 41 | extra_compile_args=[ 42 | "-std=c11", 43 | "-fvisibility=hidden", 44 | ] if system() != "Windows" else [ 45 | "/std:c11", 46 | "/utf-8", 47 | ], 48 | define_macros=[ 49 | ("Py_LIMITED_API", "0x03090000"), 50 | ("PY_SSIZE_T_CLEAN", None), 51 | ("TREE_SITTER_HIDE_SYMBOLS", None), 52 | ], 53 | include_dirs=["src"], 54 | py_limited_api=True, 55 | ) 56 | ], 57 | cmdclass={ 58 | "build": Build, 59 | "bdist_wheel": BdistWheel 60 | }, 61 | zip_safe=False 62 | ) 63 | -------------------------------------------------------------------------------- /src/scanner.c: -------------------------------------------------------------------------------- 1 | #include "tree_sitter/alloc.h" 2 | #include "tree_sitter/array.h" 3 | #include "tree_sitter/parser.h" 4 | 5 | #include 6 | 7 | enum TokenType { 8 | OPT_SEMI, 9 | INTERPOLATION_REGULAR_START, 10 | INTERPOLATION_VERBATIM_START, 11 | INTERPOLATION_RAW_START, 12 | INTERPOLATION_START_QUOTE, 13 | INTERPOLATION_END_QUOTE, 14 | INTERPOLATION_OPEN_BRACE, 15 | INTERPOLATION_CLOSE_BRACE, 16 | INTERPOLATION_STRING_CONTENT, 17 | RAW_STRING_START, 18 | RAW_STRING_END, 19 | RAW_STRING_CONTENT, 20 | }; 21 | 22 | typedef enum { 23 | REGULAR = 1 << 0, 24 | VERBATIM = 1 << 1, 25 | RAW = 1 << 2, 26 | } StringType; 27 | 28 | typedef struct { 29 | uint8_t dollar_count; 30 | uint8_t open_brace_count; 31 | uint8_t quote_count; 32 | StringType string_type; 33 | } Interpolation; 34 | 35 | static inline bool is_regular(Interpolation *interpolation) { return interpolation->string_type & REGULAR; } 36 | 37 | static inline bool is_verbatim(Interpolation *interpolation) { return interpolation->string_type & VERBATIM; } 38 | 39 | static inline bool is_raw(Interpolation *interpolation) { return interpolation->string_type & RAW; } 40 | 41 | typedef struct { 42 | uint8_t quote_count; 43 | Array(Interpolation) interpolation_stack; 44 | } Scanner; 45 | 46 | static inline void advance(TSLexer *lexer) { lexer->advance(lexer, false); } 47 | 48 | static inline void skip(TSLexer *lexer) { lexer->advance(lexer, true); } 49 | 50 | void *tree_sitter_c_sharp_external_scanner_create() { 51 | Scanner *scanner = ts_calloc(1, sizeof(Scanner)); 52 | array_init(&scanner->interpolation_stack); 53 | return scanner; 54 | } 55 | 56 | void tree_sitter_c_sharp_external_scanner_destroy(void *payload) { 57 | Scanner *scanner = (Scanner *)payload; 58 | array_delete(&scanner->interpolation_stack); 59 | ts_free(scanner); 60 | } 61 | 62 | unsigned tree_sitter_c_sharp_external_scanner_serialize(void *payload, char *buffer) { 63 | Scanner *scanner = (Scanner *)payload; 64 | 65 | if (scanner->interpolation_stack.size * 4 + 2 > TREE_SITTER_SERIALIZATION_BUFFER_SIZE) { 66 | return 0; 67 | } 68 | 69 | unsigned size = 0; 70 | 71 | buffer[size++] = (char)scanner->quote_count; 72 | buffer[size++] = (char)scanner->interpolation_stack.size; 73 | 74 | for (unsigned i = 0; i < scanner->interpolation_stack.size; i++) { 75 | Interpolation interpolation = scanner->interpolation_stack.contents[i]; 76 | buffer[size++] = (char)interpolation.dollar_count; 77 | buffer[size++] = (char)interpolation.open_brace_count; 78 | buffer[size++] = (char)interpolation.quote_count; 79 | buffer[size++] = (char)interpolation.string_type; 80 | } 81 | 82 | return size; 83 | } 84 | 85 | void tree_sitter_c_sharp_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) { 86 | Scanner *scanner = (Scanner *)payload; 87 | 88 | scanner->quote_count = 0; 89 | array_clear(&scanner->interpolation_stack); 90 | unsigned size = 0; 91 | 92 | if (length > 0) { 93 | scanner->quote_count = (unsigned char)buffer[size++]; 94 | scanner->interpolation_stack.size = (unsigned char)buffer[size++]; 95 | array_reserve(&scanner->interpolation_stack, scanner->interpolation_stack.size); 96 | 97 | for (unsigned i = 0; i < scanner->interpolation_stack.size; i++) { 98 | Interpolation interpolation = {0}; 99 | interpolation.dollar_count = buffer[size++]; 100 | interpolation.open_brace_count = buffer[size++]; 101 | interpolation.quote_count = buffer[size++]; 102 | interpolation.string_type = (unsigned char)buffer[size++]; 103 | scanner->interpolation_stack.contents[i] = interpolation; 104 | } 105 | } 106 | 107 | assert(size == length); 108 | } 109 | 110 | bool tree_sitter_c_sharp_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) { 111 | Scanner *scanner = (Scanner *)payload; 112 | 113 | uint8_t brace_advanced = 0; 114 | uint8_t quote_count = 0; 115 | bool did_advance = false; 116 | 117 | // error recovery, gives better trees this way 118 | if (valid_symbols[OPT_SEMI] && valid_symbols[INTERPOLATION_REGULAR_START]) { 119 | return false; 120 | } 121 | 122 | if (valid_symbols[OPT_SEMI]) { 123 | lexer->result_symbol = OPT_SEMI; 124 | if (lexer->lookahead == ';') { 125 | advance(lexer); 126 | } 127 | return true; 128 | } 129 | 130 | if (valid_symbols[RAW_STRING_START]) { 131 | while (iswspace(lexer->lookahead)) { 132 | skip(lexer); 133 | } 134 | 135 | if (lexer->lookahead == '"') { 136 | while (lexer->lookahead == '"') { 137 | advance(lexer); 138 | quote_count++; 139 | } 140 | 141 | if (quote_count >= 3) { 142 | lexer->result_symbol = RAW_STRING_START; 143 | scanner->quote_count = quote_count; 144 | return true; 145 | } 146 | } 147 | } 148 | 149 | if (valid_symbols[RAW_STRING_END] && lexer->lookahead == '"') { 150 | while (lexer->lookahead == '"') { 151 | advance(lexer); 152 | quote_count++; 153 | } 154 | 155 | if (quote_count == scanner->quote_count) { 156 | lexer->result_symbol = RAW_STRING_END; 157 | scanner->quote_count = 0; 158 | return true; 159 | } 160 | 161 | did_advance = quote_count > 0; 162 | } 163 | 164 | if (valid_symbols[RAW_STRING_CONTENT]) { 165 | while (lexer->lookahead) { 166 | if (lexer->lookahead == '"') { 167 | lexer->mark_end(lexer); 168 | quote_count = 0; 169 | 170 | while (lexer->lookahead == '"') { 171 | advance(lexer); 172 | quote_count++; 173 | } 174 | 175 | if (quote_count == scanner->quote_count) { 176 | lexer->result_symbol = RAW_STRING_CONTENT; 177 | return true; 178 | } 179 | } 180 | advance(lexer); 181 | did_advance = true; 182 | } 183 | lexer->mark_end(lexer); 184 | lexer->result_symbol = RAW_STRING_CONTENT; 185 | return true; 186 | } 187 | 188 | if (valid_symbols[INTERPOLATION_REGULAR_START] || valid_symbols[INTERPOLATION_VERBATIM_START] || 189 | valid_symbols[INTERPOLATION_RAW_START]) { 190 | while (iswspace(lexer->lookahead)) { 191 | skip(lexer); 192 | } 193 | 194 | uint8_t dollar_advanced = 0; 195 | 196 | bool is_verbatim = false; 197 | 198 | if (lexer->lookahead == '@') { 199 | is_verbatim = true; 200 | advance(lexer); 201 | } 202 | 203 | while (lexer->lookahead == '$' && quote_count == 0) { 204 | advance(lexer); 205 | dollar_advanced++; 206 | } 207 | 208 | if (dollar_advanced > 0 && (lexer->lookahead == '"' || lexer->lookahead == '@')) { 209 | lexer->result_symbol = INTERPOLATION_REGULAR_START; 210 | Interpolation interpolation = { 211 | .dollar_count = dollar_advanced, 212 | .open_brace_count = 0, 213 | .quote_count = 0, 214 | .string_type = 0, 215 | }; 216 | 217 | if (is_verbatim || lexer->lookahead == '@') { 218 | if (lexer->lookahead == '@') { 219 | advance(lexer); 220 | is_verbatim = true; 221 | } 222 | lexer->result_symbol = INTERPOLATION_VERBATIM_START; 223 | interpolation.string_type = VERBATIM; 224 | } 225 | 226 | lexer->mark_end(lexer); 227 | advance(lexer); 228 | 229 | if (lexer->lookahead == '"' && !is_verbatim) { 230 | advance(lexer); 231 | if (lexer->lookahead == '"') { 232 | lexer->result_symbol = INTERPOLATION_RAW_START; 233 | interpolation.string_type |= RAW; 234 | array_push(&scanner->interpolation_stack, interpolation); 235 | } 236 | // If we find 1 or 3 quotes, we push an interpolation. 237 | // If there's only two quotes, that's just an empty string 238 | } else { 239 | interpolation.string_type |= REGULAR; 240 | array_push(&scanner->interpolation_stack, interpolation); 241 | } 242 | 243 | return true; 244 | } 245 | } 246 | 247 | if (valid_symbols[INTERPOLATION_START_QUOTE] && scanner->interpolation_stack.size > 0) { 248 | Interpolation *current_interpolation = array_back(&scanner->interpolation_stack); 249 | 250 | if (is_verbatim(current_interpolation) || is_regular(current_interpolation)) { 251 | if (lexer->lookahead == '"') { 252 | advance(lexer); 253 | current_interpolation->quote_count++; 254 | } 255 | } else { 256 | while (lexer->lookahead == '"') { 257 | advance(lexer); 258 | current_interpolation->quote_count++; 259 | } 260 | } 261 | 262 | lexer->result_symbol = INTERPOLATION_START_QUOTE; 263 | return current_interpolation->quote_count > 0; 264 | } 265 | 266 | if (valid_symbols[INTERPOLATION_END_QUOTE] && scanner->interpolation_stack.size > 0) { 267 | Interpolation *current_interpolation = array_back(&scanner->interpolation_stack); 268 | 269 | while (lexer->lookahead == '"') { 270 | advance(lexer); 271 | quote_count++; 272 | } 273 | 274 | if (quote_count == current_interpolation->quote_count) { 275 | lexer->result_symbol = INTERPOLATION_END_QUOTE; 276 | array_pop(&scanner->interpolation_stack); 277 | return true; 278 | } 279 | 280 | did_advance = quote_count > 0; 281 | } 282 | 283 | if (valid_symbols[INTERPOLATION_OPEN_BRACE] && scanner->interpolation_stack.size > 0) { 284 | Interpolation *current_interpolation = array_back(&scanner->interpolation_stack); 285 | 286 | while (lexer->lookahead == '{' && brace_advanced < current_interpolation->dollar_count) { 287 | advance(lexer); 288 | brace_advanced++; 289 | } 290 | 291 | if (brace_advanced > 0 && brace_advanced == current_interpolation->dollar_count && 292 | (brace_advanced == 0 || lexer->lookahead != '{')) { 293 | current_interpolation->open_brace_count = brace_advanced; 294 | lexer->result_symbol = INTERPOLATION_OPEN_BRACE; 295 | return true; 296 | } 297 | } 298 | 299 | if (valid_symbols[INTERPOLATION_CLOSE_BRACE] && scanner->interpolation_stack.size > 0) { 300 | uint8_t brace_advanced = 0; 301 | Interpolation *current_interpolation = array_back(&scanner->interpolation_stack); 302 | 303 | while (iswspace(lexer->lookahead)) { 304 | advance(lexer); 305 | } 306 | 307 | while (lexer->lookahead == '}') { 308 | advance(lexer); 309 | brace_advanced++; 310 | 311 | if (brace_advanced == current_interpolation->open_brace_count) { 312 | current_interpolation->open_brace_count = 0; 313 | lexer->result_symbol = INTERPOLATION_CLOSE_BRACE; 314 | return true; 315 | } 316 | } 317 | 318 | return false; 319 | } 320 | 321 | if (valid_symbols[INTERPOLATION_STRING_CONTENT] && scanner->interpolation_stack.size > 0) { 322 | lexer->result_symbol = INTERPOLATION_STRING_CONTENT; 323 | Interpolation *current_interpolation = array_back(&scanner->interpolation_stack); 324 | 325 | while (lexer->lookahead) { 326 | // top-down approach, first see if it's raw 327 | if (is_raw(current_interpolation)) { 328 | if (lexer->lookahead == '"') { 329 | lexer->mark_end(lexer); 330 | advance(lexer); 331 | if (lexer->lookahead == '"') { 332 | advance(lexer); 333 | uint8_t quote_advanced = 2; 334 | while (lexer->lookahead == '"') { 335 | quote_advanced++; 336 | advance(lexer); 337 | } 338 | if (quote_advanced == current_interpolation->quote_count) { 339 | return did_advance; 340 | } 341 | } 342 | } 343 | 344 | if (lexer->lookahead == '{') { 345 | lexer->mark_end(lexer); 346 | 347 | while (lexer->lookahead == '{' && brace_advanced < current_interpolation->open_brace_count) { 348 | advance(lexer); 349 | brace_advanced++; 350 | } 351 | 352 | if (brace_advanced == current_interpolation->open_brace_count && 353 | (brace_advanced == 0 || lexer->lookahead != '{')) { 354 | return did_advance; 355 | } 356 | } 357 | } 358 | 359 | // then verbatim, since it could be verbatim + raw, but run the raw branch first 360 | else if (is_verbatim(current_interpolation)) { 361 | if (lexer->lookahead == '"') { 362 | lexer->mark_end(lexer); 363 | advance(lexer); 364 | if (lexer->lookahead == '"') { 365 | advance(lexer); 366 | continue; 367 | } 368 | return did_advance; 369 | } 370 | 371 | if (lexer->lookahead == '{') { 372 | lexer->mark_end(lexer); 373 | 374 | while (lexer->lookahead == '{' && brace_advanced < current_interpolation->open_brace_count) { 375 | advance(lexer); 376 | brace_advanced++; 377 | } 378 | 379 | if (brace_advanced == current_interpolation->open_brace_count && 380 | (brace_advanced == 0 || lexer->lookahead != '{')) { 381 | return did_advance; 382 | } 383 | } 384 | } 385 | 386 | // finally regular 387 | else if (is_regular(current_interpolation)) { 388 | if (lexer->lookahead == '\\' || lexer->lookahead == '\n' || lexer->lookahead == '"') { 389 | lexer->mark_end(lexer); 390 | return did_advance; 391 | } 392 | 393 | if (lexer->lookahead == '{') { 394 | lexer->mark_end(lexer); 395 | 396 | while (lexer->lookahead == '{' && brace_advanced < current_interpolation->open_brace_count) { 397 | advance(lexer); 398 | brace_advanced++; 399 | } 400 | 401 | if (brace_advanced == current_interpolation->open_brace_count && 402 | (brace_advanced == 0 || lexer->lookahead != '{')) { // if we're in a brace we're not allowed to 403 | // collect more than the open_brace_count 404 | return did_advance; 405 | } 406 | } 407 | } 408 | 409 | if (lexer->lookahead != '{') { 410 | brace_advanced = 0; 411 | } 412 | advance(lexer); 413 | did_advance = true; 414 | } 415 | 416 | lexer->mark_end(lexer); 417 | return did_advance; 418 | } 419 | 420 | return false; 421 | } 422 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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(push) 18 | #pragma warning(disable : 4101) 19 | #elif defined(__GNUC__) || defined(__clang__) 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic ignored "-Wunused-variable" 22 | #endif 23 | 24 | #define Array(T) \ 25 | struct { \ 26 | T *contents; \ 27 | uint32_t size; \ 28 | uint32_t capacity; \ 29 | } 30 | 31 | /// Initialize an array. 32 | #define array_init(self) \ 33 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 34 | 35 | /// Create an empty array. 36 | #define array_new() \ 37 | { NULL, 0, 0 } 38 | 39 | /// Get a pointer to the element at a given `index` in the array. 40 | #define array_get(self, _index) \ 41 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 42 | 43 | /// Get a pointer to the first element in the array. 44 | #define array_front(self) array_get(self, 0) 45 | 46 | /// Get a pointer to the last element in the array. 47 | #define array_back(self) array_get(self, (self)->size - 1) 48 | 49 | /// Clear the array, setting its size to zero. Note that this does not free any 50 | /// memory allocated for the array's contents. 51 | #define array_clear(self) ((self)->size = 0) 52 | 53 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 54 | /// less than the array's current capacity, this function has no effect. 55 | #define array_reserve(self, new_capacity) \ 56 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 57 | 58 | /// Free any memory allocated for this array. Note that this does not free any 59 | /// memory allocated for the array's contents. 60 | #define array_delete(self) _array__delete((Array *)(self)) 61 | 62 | /// Push a new `element` onto the end of the array. 63 | #define array_push(self, element) \ 64 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 65 | (self)->contents[(self)->size++] = (element)) 66 | 67 | /// Increase the array's size by `count` elements. 68 | /// New elements are zero-initialized. 69 | #define array_grow_by(self, count) \ 70 | do { \ 71 | if ((count) == 0) break; \ 72 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 73 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 74 | (self)->size += (count); \ 75 | } while (0) 76 | 77 | /// Append all elements from one array to the end of another. 78 | #define array_push_all(self, other) \ 79 | array_extend((self), (other)->size, (other)->contents) 80 | 81 | /// Append `count` elements to the end of the array, reading their values from the 82 | /// `contents` pointer. 83 | #define array_extend(self, count, contents) \ 84 | _array__splice( \ 85 | (Array *)(self), array_elem_size(self), (self)->size, \ 86 | 0, count, contents \ 87 | ) 88 | 89 | /// Remove `old_count` elements from the array starting at the given `index`. At 90 | /// the same index, insert `new_count` new elements, reading their values from the 91 | /// `new_contents` pointer. 92 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 93 | _array__splice( \ 94 | (Array *)(self), array_elem_size(self), _index, \ 95 | old_count, new_count, new_contents \ 96 | ) 97 | 98 | /// Insert one `element` into the array at the given `index`. 99 | #define array_insert(self, _index, element) \ 100 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 101 | 102 | /// Remove one element from the array at the given `index`. 103 | #define array_erase(self, _index) \ 104 | _array__erase((Array *)(self), array_elem_size(self), _index) 105 | 106 | /// Pop the last element off the array, returning the element by value. 107 | #define array_pop(self) ((self)->contents[--(self)->size]) 108 | 109 | /// Assign the contents of one array to another, reallocating if necessary. 110 | #define array_assign(self, other) \ 111 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 112 | 113 | /// Swap one array with another 114 | #define array_swap(self, other) \ 115 | _array__swap((Array *)(self), (Array *)(other)) 116 | 117 | /// Get the size of the array contents 118 | #define array_elem_size(self) (sizeof *(self)->contents) 119 | 120 | /// Search a sorted array for a given `needle` value, using the given `compare` 121 | /// callback to determine the order. 122 | /// 123 | /// If an existing element is found to be equal to `needle`, then the `index` 124 | /// out-parameter is set to the existing value's index, and the `exists` 125 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 126 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 127 | /// is set to false. 128 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 129 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 130 | 131 | /// Search a sorted array for a given `needle` value, using integer comparisons 132 | /// of a given struct field (specified with a leading dot) to determine the order. 133 | /// 134 | /// See also `array_search_sorted_with`. 135 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 136 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 137 | 138 | /// Insert a given `value` into a sorted array, using the given `compare` 139 | /// callback to determine the order. 140 | #define array_insert_sorted_with(self, compare, value) \ 141 | do { \ 142 | unsigned _index, _exists; \ 143 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 144 | if (!_exists) array_insert(self, _index, value); \ 145 | } while (0) 146 | 147 | /// Insert a given `value` into a sorted array, using integer comparisons of 148 | /// a given struct field (specified with a leading dot) to determine the order. 149 | /// 150 | /// See also `array_search_sorted_by`. 151 | #define array_insert_sorted_by(self, field, value) \ 152 | do { \ 153 | unsigned _index, _exists; \ 154 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 155 | if (!_exists) array_insert(self, _index, value); \ 156 | } while (0) 157 | 158 | // Private 159 | 160 | typedef Array(void) Array; 161 | 162 | /// This is not what you're looking for, see `array_delete`. 163 | static inline void _array__delete(Array *self) { 164 | if (self->contents) { 165 | ts_free(self->contents); 166 | self->contents = NULL; 167 | self->size = 0; 168 | self->capacity = 0; 169 | } 170 | } 171 | 172 | /// This is not what you're looking for, see `array_erase`. 173 | static inline void _array__erase(Array *self, size_t element_size, 174 | uint32_t index) { 175 | assert(index < self->size); 176 | char *contents = (char *)self->contents; 177 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 178 | (self->size - index - 1) * element_size); 179 | self->size--; 180 | } 181 | 182 | /// This is not what you're looking for, see `array_reserve`. 183 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 184 | if (new_capacity > self->capacity) { 185 | if (self->contents) { 186 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 187 | } else { 188 | self->contents = ts_malloc(new_capacity * element_size); 189 | } 190 | self->capacity = new_capacity; 191 | } 192 | } 193 | 194 | /// This is not what you're looking for, see `array_assign`. 195 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 196 | _array__reserve(self, element_size, other->size); 197 | self->size = other->size; 198 | memcpy(self->contents, other->contents, self->size * element_size); 199 | } 200 | 201 | /// This is not what you're looking for, see `array_swap`. 202 | static inline void _array__swap(Array *self, Array *other) { 203 | Array swap = *other; 204 | *other = *self; 205 | *self = swap; 206 | } 207 | 208 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 209 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 210 | uint32_t new_size = self->size + count; 211 | if (new_size > self->capacity) { 212 | uint32_t new_capacity = self->capacity * 2; 213 | if (new_capacity < 8) new_capacity = 8; 214 | if (new_capacity < new_size) new_capacity = new_size; 215 | _array__reserve(self, element_size, new_capacity); 216 | } 217 | } 218 | 219 | /// This is not what you're looking for, see `array_splice`. 220 | static inline void _array__splice(Array *self, size_t element_size, 221 | uint32_t index, uint32_t old_count, 222 | uint32_t new_count, const void *elements) { 223 | uint32_t new_size = self->size + new_count - old_count; 224 | uint32_t old_end = index + old_count; 225 | uint32_t new_end = index + new_count; 226 | assert(old_end <= self->size); 227 | 228 | _array__reserve(self, element_size, new_size); 229 | 230 | char *contents = (char *)self->contents; 231 | if (self->size > old_end) { 232 | memmove( 233 | contents + new_end * element_size, 234 | contents + old_end * element_size, 235 | (self->size - old_end) * element_size 236 | ); 237 | } 238 | if (new_count > 0) { 239 | if (elements) { 240 | memcpy( 241 | (contents + index * element_size), 242 | elements, 243 | new_count * element_size 244 | ); 245 | } else { 246 | memset( 247 | (contents + index * element_size), 248 | 0, 249 | new_count * element_size 250 | ); 251 | } 252 | } 253 | self->size += new_count - old_count; 254 | } 255 | 256 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 257 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 258 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 259 | do { \ 260 | *(_index) = start; \ 261 | *(_exists) = false; \ 262 | uint32_t size = (self)->size - *(_index); \ 263 | if (size == 0) break; \ 264 | int comparison; \ 265 | while (size > 1) { \ 266 | uint32_t half_size = size / 2; \ 267 | uint32_t mid_index = *(_index) + half_size; \ 268 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 269 | if (comparison <= 0) *(_index) = mid_index; \ 270 | size -= half_size; \ 271 | } \ 272 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 273 | if (comparison == 0) *(_exists) = true; \ 274 | else if (comparison < 0) *(_index) += 1; \ 275 | } while (0) 276 | 277 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 278 | /// parameter by reference in order to work with the generic sorting function above. 279 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 280 | 281 | #ifdef _MSC_VER 282 | #pragma warning(pop) 283 | #elif defined(__GNUC__) || defined(__clang__) 284 | #pragma GCC diagnostic pop 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif // TREE_SITTER_ARRAY_H_ 292 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/corpus/attributes.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Attribute targets 3 | ================================================================================ 4 | 5 | [assembly: Single] 6 | [module: A, C()] 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | (compilation_unit 11 | (global_attribute 12 | (attribute 13 | name: (identifier))) 14 | (global_attribute 15 | (attribute 16 | name: (identifier)) 17 | (attribute 18 | name: (identifier) 19 | (attribute_argument_list)))) 20 | 21 | 22 | ================================================================================ 23 | Attributes 24 | ================================================================================ 25 | 26 | [A(B.C)] 27 | class D {} 28 | 29 | [NS.A(B.C)] 30 | class D {} 31 | 32 | [One][Two] 33 | [Three] 34 | class A { } 35 | 36 | [A,B()][C] 37 | struct A { } 38 | 39 | class Zzz { 40 | [A,B()][C] 41 | public int Z; 42 | } 43 | 44 | class Methods { 45 | [ValidatedContract] 46 | int Method1() { return 0; } 47 | 48 | [method: ValidatedContract] 49 | int Method2() { return 0; } 50 | 51 | [return: ValidatedContract] 52 | int Method3() { return 0; } 53 | } 54 | 55 | [Single] 56 | enum A { B, C } 57 | 58 | class Zzz { 59 | [A,B()][C] 60 | public event EventHandler SomeEvent { add { } remove { } } 61 | } 62 | 63 | class Class<[A, B][C()]T1> { 64 | void Method<[E] [F, G(1)] T2>() { 65 | } 66 | } 67 | 68 | class Zzz { 69 | public event EventHandler SomeEvent { 70 | [A,B()][C] add { } 71 | [A,B()][C] remove { } 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- 76 | 77 | (compilation_unit 78 | (class_declaration 79 | (attribute_list 80 | (attribute 81 | name: (identifier) 82 | (attribute_argument_list 83 | (attribute_argument 84 | (member_access_expression 85 | expression: (identifier) 86 | name: (identifier)))))) 87 | name: (identifier) 88 | body: (declaration_list)) 89 | (class_declaration 90 | (attribute_list 91 | (attribute 92 | name: (qualified_name 93 | qualifier: (identifier) 94 | name: (identifier)) 95 | (attribute_argument_list 96 | (attribute_argument 97 | (member_access_expression 98 | expression: (identifier) 99 | name: (identifier)))))) 100 | name: (identifier) 101 | body: (declaration_list)) 102 | (class_declaration 103 | (attribute_list 104 | (attribute 105 | name: (identifier))) 106 | (attribute_list 107 | (attribute 108 | name: (identifier))) 109 | (attribute_list 110 | (attribute 111 | name: (identifier))) 112 | name: (identifier) 113 | body: (declaration_list)) 114 | (struct_declaration 115 | (attribute_list 116 | (attribute 117 | name: (identifier)) 118 | (attribute 119 | name: (identifier) 120 | (attribute_argument_list))) 121 | (attribute_list 122 | (attribute 123 | name: (identifier))) 124 | name: (identifier) 125 | body: (declaration_list)) 126 | (class_declaration 127 | name: (identifier) 128 | body: (declaration_list 129 | (field_declaration 130 | (attribute_list 131 | (attribute 132 | name: (identifier)) 133 | (attribute 134 | name: (identifier) 135 | (attribute_argument_list))) 136 | (attribute_list 137 | (attribute 138 | name: (identifier))) 139 | (modifier) 140 | (variable_declaration 141 | type: (predefined_type) 142 | (variable_declarator 143 | name: (identifier)))))) 144 | (class_declaration 145 | name: (identifier) 146 | body: (declaration_list 147 | (method_declaration 148 | (attribute_list 149 | (attribute 150 | name: (identifier))) 151 | returns: (predefined_type) 152 | name: (identifier) 153 | parameters: (parameter_list) 154 | body: (block 155 | (return_statement 156 | (integer_literal)))) 157 | (method_declaration 158 | (attribute_list 159 | (attribute_target_specifier) 160 | (attribute 161 | name: (identifier))) 162 | returns: (predefined_type) 163 | name: (identifier) 164 | parameters: (parameter_list) 165 | body: (block 166 | (return_statement 167 | (integer_literal)))) 168 | (method_declaration 169 | (attribute_list 170 | (attribute_target_specifier) 171 | (attribute 172 | name: (identifier))) 173 | returns: (predefined_type) 174 | name: (identifier) 175 | parameters: (parameter_list) 176 | body: (block 177 | (return_statement 178 | (integer_literal)))))) 179 | (enum_declaration 180 | (attribute_list 181 | (attribute 182 | name: (identifier))) 183 | name: (identifier) 184 | body: (enum_member_declaration_list 185 | (enum_member_declaration 186 | name: (identifier)) 187 | (enum_member_declaration 188 | name: (identifier)))) 189 | (class_declaration 190 | name: (identifier) 191 | body: (declaration_list 192 | (event_declaration 193 | (attribute_list 194 | (attribute 195 | name: (identifier)) 196 | (attribute 197 | name: (identifier) 198 | (attribute_argument_list))) 199 | (attribute_list 200 | (attribute 201 | name: (identifier))) 202 | (modifier) 203 | type: (identifier) 204 | name: (identifier) 205 | accessors: (accessor_list 206 | (accessor_declaration 207 | body: (block)) 208 | (accessor_declaration 209 | body: (block)))))) 210 | (class_declaration 211 | name: (identifier) 212 | (type_parameter_list 213 | (type_parameter 214 | (attribute_list 215 | (attribute 216 | name: (identifier)) 217 | (attribute 218 | name: (identifier))) 219 | (attribute_list 220 | (attribute 221 | name: (identifier) 222 | (attribute_argument_list))) 223 | name: (identifier))) 224 | body: (declaration_list 225 | (method_declaration 226 | returns: (predefined_type) 227 | name: (identifier) 228 | type_parameters: (type_parameter_list 229 | (type_parameter 230 | (attribute_list 231 | (attribute 232 | name: (identifier))) 233 | (attribute_list 234 | (attribute 235 | name: (identifier)) 236 | (attribute 237 | name: (identifier) 238 | (attribute_argument_list 239 | (attribute_argument 240 | (integer_literal))))) 241 | name: (identifier))) 242 | parameters: (parameter_list) 243 | body: (block)))) 244 | (class_declaration 245 | name: (identifier) 246 | body: (declaration_list 247 | (event_declaration 248 | (modifier) 249 | type: (identifier) 250 | name: (identifier) 251 | accessors: (accessor_list 252 | (accessor_declaration 253 | (attribute_list 254 | (attribute 255 | name: (identifier)) 256 | (attribute 257 | name: (identifier) 258 | (attribute_argument_list))) 259 | (attribute_list 260 | (attribute 261 | name: (identifier))) 262 | body: (block)) 263 | (accessor_declaration 264 | (attribute_list 265 | (attribute 266 | name: (identifier)) 267 | (attribute 268 | name: (identifier) 269 | (attribute_argument_list))) 270 | (attribute_list 271 | (attribute 272 | name: (identifier))) 273 | body: (block))))))) 274 | 275 | ================================================================================ 276 | Attribute targets (non-global) 277 | ================================================================================ 278 | 279 | [type: Obsolete] 280 | class A<[typevar: B] TC> 281 | { 282 | [field:JsonIgnore] 283 | [property: JsonIgnore] 284 | public int D { get; set; } 285 | 286 | [method: Obsolete] 287 | [return: MaybeNull] 288 | public void E([param: AllowNull] int f) { } 289 | 290 | [event: Obsolete] 291 | public event EventHandler OnG; 292 | } 293 | 294 | --- 295 | 296 | (compilation_unit 297 | (class_declaration 298 | (attribute_list 299 | (attribute_target_specifier) 300 | (attribute 301 | (identifier))) 302 | (identifier) 303 | (type_parameter_list 304 | (type_parameter 305 | (attribute_list 306 | (attribute_target_specifier) 307 | (attribute 308 | (identifier))) 309 | (identifier))) 310 | (declaration_list 311 | (property_declaration 312 | (attribute_list 313 | (attribute_target_specifier) 314 | (attribute 315 | (identifier))) 316 | (attribute_list 317 | (attribute_target_specifier) 318 | (attribute 319 | (identifier))) 320 | (modifier) 321 | (predefined_type) 322 | (identifier) 323 | (accessor_list 324 | (accessor_declaration) 325 | (accessor_declaration))) 326 | (method_declaration 327 | (attribute_list 328 | (attribute_target_specifier) 329 | (attribute 330 | (identifier))) 331 | (attribute_list 332 | (attribute_target_specifier) 333 | (attribute 334 | (identifier))) 335 | (modifier) 336 | (predefined_type) 337 | (identifier) 338 | (parameter_list 339 | (parameter 340 | (attribute_list 341 | (attribute_target_specifier) 342 | (attribute 343 | (identifier))) 344 | (predefined_type) 345 | (identifier))) 346 | (block)) 347 | (event_field_declaration 348 | (attribute_list 349 | (attribute_target_specifier) 350 | (attribute 351 | (identifier))) 352 | (modifier) 353 | (variable_declaration 354 | (identifier) 355 | (variable_declarator 356 | (identifier))))))) 357 | 358 | 359 | ================================================================================ 360 | Attribute quirks 361 | ================================================================================ 362 | 363 | [Theory,] 364 | void A() { } 365 | 366 | [Theory] 367 | void A() { } 368 | 369 | -------------------------------------------------------------------------------- 370 | 371 | (compilation_unit 372 | (global_statement 373 | (local_function_statement 374 | (attribute_list 375 | (attribute 376 | name: (identifier))) 377 | type: (predefined_type) 378 | name: (identifier) 379 | parameters: (parameter_list) 380 | body: (block))) 381 | (global_statement 382 | (local_function_statement 383 | (attribute_list 384 | (attribute 385 | name: (generic_name 386 | (identifier) 387 | (type_argument_list 388 | (identifier) 389 | (identifier))))) 390 | type: (predefined_type) 391 | name: (identifier) 392 | parameters: (parameter_list) 393 | body: (block)))) 394 | 395 | ================================================================================ 396 | Lambda with attribute 397 | ================================================================================ 398 | 399 | var greeting = [Hello] () => Console.WriteLine("hello"); 400 | 401 | -------------------------------------------------------------------------------- 402 | 403 | (compilation_unit 404 | (global_statement 405 | (local_declaration_statement 406 | (variable_declaration 407 | type: (implicit_type) 408 | (variable_declarator 409 | name: (identifier) 410 | (lambda_expression 411 | (attribute_list 412 | (attribute 413 | name: (identifier))) 414 | parameters: (parameter_list) 415 | body: (invocation_expression 416 | function: (member_access_expression 417 | expression: (identifier) 418 | name: (identifier)) 419 | arguments: (argument_list 420 | (argument 421 | (string_literal 422 | (string_literal_content))))))))))) 423 | -------------------------------------------------------------------------------- /test/corpus/classes.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Class Definitions 3 | ================================================================================ 4 | 5 | public class F {} 6 | 7 | public class F : object, IAlpha, IOmega { } 8 | 9 | public partial class F {} 10 | 11 | internal class F {} 12 | 13 | public class F where T:struct {} 14 | 15 | public class F where T:unmanaged {} 16 | 17 | public class F where T:class?, notnull, Mine? {} 18 | 19 | public class F where T: new() {} 20 | 21 | public class F where T: I, new() {} 22 | 23 | private class F where T1 : I1, I2, new() where T2 : I2 { } 24 | 25 | class Foo { 26 | public Foo() {} 27 | 28 | // expression bodied constructor 29 | public Foo(string name) => Name = name; 30 | 31 | // static constructor 32 | static Foo() {} 33 | static extern Foo() {} 34 | extern static Foo() {} 35 | 36 | // extern destructor 37 | extern ~Foo() {} 38 | 39 | // expression bodied destructor 40 | ~Foo() => DoSomething(); 41 | 42 | // constants 43 | private const int a = 1; 44 | const string b = $"hello"; 45 | 46 | // indexer 47 | public bool this[int index] { 48 | get { return a; } 49 | set { a = value; } 50 | } 51 | 52 | // expression bodied indexer 53 | public bool this[int index] => a[index]; 54 | 55 | public string this[int index] 56 | { 57 | get => a[index]; 58 | set => a[index] = value; 59 | } 60 | 61 | public int this[params string[] arguments] { 62 | get { return 1; } 63 | } 64 | 65 | B.C d() { 66 | return null; 67 | } 68 | } 69 | 70 | class Bar(int a, int b) { 71 | int add() { 72 | return a + b; 73 | } 74 | } 75 | 76 | // unicode class name 77 | class Ωµ { 78 | B.C d() { 79 | return null; 80 | } 81 | } 82 | 83 | // file scoped class 84 | file class A {} 85 | 86 | class Baz(int a, int b) : Bar(a, b) { } 87 | 88 | public class NoBody; 89 | 90 | private class NoBodyPrimary(int a, int b); 91 | 92 | -------------------------------------------------------------------------------- 93 | 94 | (compilation_unit 95 | (class_declaration 96 | (modifier) 97 | name: (identifier) 98 | body: (declaration_list)) 99 | (class_declaration 100 | (modifier) 101 | name: (identifier) 102 | (base_list 103 | (predefined_type) 104 | (identifier) 105 | (identifier)) 106 | body: (declaration_list)) 107 | (class_declaration 108 | (modifier) 109 | (modifier) 110 | name: (identifier) 111 | (type_parameter_list 112 | (type_parameter 113 | name: (identifier))) 114 | body: (declaration_list)) 115 | (class_declaration 116 | (modifier) 117 | name: (identifier) 118 | (type_parameter_list 119 | (type_parameter 120 | name: (identifier)) 121 | (type_parameter 122 | name: (identifier))) 123 | body: (declaration_list)) 124 | (class_declaration 125 | (modifier) 126 | name: (identifier) 127 | (type_parameter_list 128 | (type_parameter 129 | name: (identifier))) 130 | (type_parameter_constraints_clause 131 | (identifier) 132 | (type_parameter_constraint)) 133 | body: (declaration_list)) 134 | (class_declaration 135 | (modifier) 136 | name: (identifier) 137 | (type_parameter_list 138 | (type_parameter 139 | name: (identifier))) 140 | (type_parameter_constraints_clause 141 | (identifier) 142 | (type_parameter_constraint)) 143 | body: (declaration_list)) 144 | (class_declaration 145 | (modifier) 146 | name: (identifier) 147 | (type_parameter_list 148 | (type_parameter 149 | name: (identifier))) 150 | (type_parameter_constraints_clause 151 | (identifier) 152 | (type_parameter_constraint) 153 | (type_parameter_constraint) 154 | (type_parameter_constraint 155 | type: (nullable_type 156 | type: (identifier)))) 157 | body: (declaration_list)) 158 | (class_declaration 159 | (modifier) 160 | name: (identifier) 161 | (type_parameter_list 162 | (type_parameter 163 | name: (identifier))) 164 | (type_parameter_constraints_clause 165 | (identifier) 166 | (type_parameter_constraint 167 | (constructor_constraint))) 168 | body: (declaration_list)) 169 | (class_declaration 170 | (modifier) 171 | name: (identifier) 172 | (type_parameter_list 173 | (type_parameter 174 | name: (identifier))) 175 | (type_parameter_constraints_clause 176 | (identifier) 177 | (type_parameter_constraint 178 | type: (identifier)) 179 | (type_parameter_constraint 180 | (constructor_constraint))) 181 | body: (declaration_list)) 182 | (class_declaration 183 | (modifier) 184 | name: (identifier) 185 | (type_parameter_list 186 | (type_parameter 187 | name: (identifier)) 188 | (type_parameter 189 | name: (identifier))) 190 | (type_parameter_constraints_clause 191 | (identifier) 192 | (type_parameter_constraint 193 | type: (identifier)) 194 | (type_parameter_constraint 195 | type: (identifier)) 196 | (type_parameter_constraint 197 | (constructor_constraint))) 198 | (type_parameter_constraints_clause 199 | (identifier) 200 | (type_parameter_constraint 201 | type: (identifier))) 202 | body: (declaration_list)) 203 | (class_declaration 204 | name: (identifier) 205 | body: (declaration_list 206 | (constructor_declaration 207 | (modifier) 208 | name: (identifier) 209 | parameters: (parameter_list) 210 | body: (block)) 211 | (comment) 212 | (constructor_declaration 213 | (modifier) 214 | name: (identifier) 215 | parameters: (parameter_list 216 | (parameter 217 | type: (predefined_type) 218 | name: (identifier))) 219 | body: (arrow_expression_clause 220 | (assignment_expression 221 | left: (identifier) 222 | right: (identifier)))) 223 | (comment) 224 | (constructor_declaration 225 | (modifier) 226 | name: (identifier) 227 | parameters: (parameter_list) 228 | body: (block)) 229 | (constructor_declaration 230 | (modifier) 231 | (modifier) 232 | name: (identifier) 233 | parameters: (parameter_list) 234 | body: (block)) 235 | (constructor_declaration 236 | (modifier) 237 | (modifier) 238 | name: (identifier) 239 | parameters: (parameter_list) 240 | body: (block)) 241 | (comment) 242 | (destructor_declaration 243 | name: (identifier) 244 | parameters: (parameter_list) 245 | body: (block)) 246 | (comment) 247 | (destructor_declaration 248 | name: (identifier) 249 | parameters: (parameter_list) 250 | body: (arrow_expression_clause 251 | (invocation_expression 252 | function: (identifier) 253 | arguments: (argument_list)))) 254 | (comment) 255 | (field_declaration 256 | (modifier) 257 | (modifier) 258 | (variable_declaration 259 | type: (predefined_type) 260 | (variable_declarator 261 | name: (identifier) 262 | (integer_literal)))) 263 | (field_declaration 264 | (modifier) 265 | (variable_declaration 266 | type: (predefined_type) 267 | (variable_declarator 268 | name: (identifier) 269 | (interpolated_string_expression 270 | (interpolation_start) 271 | (string_content))))) 272 | (comment) 273 | (indexer_declaration 274 | (modifier) 275 | type: (predefined_type) 276 | parameters: (bracketed_parameter_list 277 | (parameter 278 | type: (predefined_type) 279 | name: (identifier))) 280 | accessors: (accessor_list 281 | (accessor_declaration 282 | body: (block 283 | (return_statement 284 | (identifier)))) 285 | (accessor_declaration 286 | body: (block 287 | (expression_statement 288 | (assignment_expression 289 | left: (identifier) 290 | right: (identifier))))))) 291 | (comment) 292 | (indexer_declaration 293 | (modifier) 294 | type: (predefined_type) 295 | parameters: (bracketed_parameter_list 296 | (parameter 297 | type: (predefined_type) 298 | name: (identifier))) 299 | value: (arrow_expression_clause 300 | (element_access_expression 301 | expression: (identifier) 302 | subscript: (bracketed_argument_list 303 | (argument 304 | (identifier)))))) 305 | (indexer_declaration 306 | (modifier) 307 | type: (predefined_type) 308 | parameters: (bracketed_parameter_list 309 | (parameter 310 | type: (predefined_type) 311 | name: (identifier))) 312 | accessors: (accessor_list 313 | (accessor_declaration 314 | body: (arrow_expression_clause 315 | (element_access_expression 316 | expression: (identifier) 317 | subscript: (bracketed_argument_list 318 | (argument 319 | (identifier)))))) 320 | (accessor_declaration 321 | body: (arrow_expression_clause 322 | (assignment_expression 323 | left: (element_access_expression 324 | expression: (identifier) 325 | subscript: (bracketed_argument_list 326 | (argument 327 | (identifier)))) 328 | right: (identifier)))))) 329 | (indexer_declaration 330 | (modifier) 331 | type: (predefined_type) 332 | parameters: (bracketed_parameter_list 333 | type: (array_type 334 | type: (predefined_type) 335 | rank: (array_rank_specifier)) 336 | name: (identifier)) 337 | accessors: (accessor_list 338 | (accessor_declaration 339 | body: (block 340 | (return_statement 341 | (integer_literal)))))) 342 | (method_declaration 343 | returns: (qualified_name 344 | qualifier: (identifier) 345 | name: (identifier)) 346 | name: (identifier) 347 | parameters: (parameter_list) 348 | body: (block 349 | (return_statement 350 | (null_literal)))))) 351 | (class_declaration 352 | name: (identifier) 353 | (parameter_list 354 | (parameter 355 | type: (predefined_type) 356 | name: (identifier)) 357 | (parameter 358 | type: (predefined_type) 359 | name: (identifier))) 360 | body: (declaration_list 361 | (method_declaration 362 | returns: (predefined_type) 363 | name: (identifier) 364 | parameters: (parameter_list) 365 | body: (block 366 | (return_statement 367 | (binary_expression 368 | left: (identifier) 369 | right: (identifier))))))) 370 | (comment) 371 | (class_declaration 372 | name: (identifier) 373 | body: (declaration_list 374 | (method_declaration 375 | returns: (qualified_name 376 | qualifier: (identifier) 377 | name: (identifier)) 378 | name: (identifier) 379 | parameters: (parameter_list) 380 | body: (block 381 | (return_statement 382 | (null_literal)))))) 383 | (comment) 384 | (class_declaration 385 | (modifier) 386 | name: (identifier) 387 | body: (declaration_list)) 388 | (class_declaration 389 | name: (identifier) 390 | (parameter_list 391 | (parameter 392 | type: (predefined_type) 393 | name: (identifier)) 394 | (parameter 395 | type: (predefined_type) 396 | name: (identifier))) 397 | (base_list 398 | (identifier) 399 | (argument_list 400 | (argument 401 | (identifier)) 402 | (argument 403 | (identifier)))) 404 | body: (declaration_list)) 405 | (class_declaration 406 | (modifier) 407 | name: (identifier) 408 | ) 409 | (class_declaration 410 | (modifier) 411 | name: (identifier) 412 | (parameter_list 413 | (parameter 414 | type: (predefined_type) 415 | name: (identifier)) 416 | (parameter 417 | type: (predefined_type) 418 | name: (identifier))) 419 | )) 420 | 421 | -------------------------------------------------------------------------------- /test/corpus/contextual-keywords.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | From keyword can be a variable 3 | ================================================================================ 4 | 5 | var a = Assert.Range(from, to); 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (compilation_unit 10 | (global_statement 11 | (local_declaration_statement 12 | (variable_declaration 13 | type: (implicit_type) 14 | (variable_declarator 15 | name: (identifier) 16 | (invocation_expression 17 | function: (member_access_expression 18 | expression: (identifier) 19 | name: (identifier)) 20 | arguments: (argument_list 21 | (argument 22 | (identifier)) 23 | (argument 24 | (identifier))))))))) 25 | 26 | ================================================================================ 27 | File keyword in invocation 28 | ================================================================================ 29 | 30 | file.Method(1, 2); 31 | 32 | -------------------------------------------------------------------------------- 33 | 34 | (compilation_unit 35 | (global_statement 36 | (expression_statement 37 | (invocation_expression 38 | function: (member_access_expression 39 | expression: (identifier) 40 | name: (identifier)) 41 | arguments: (argument_list 42 | (argument 43 | (integer_literal)) 44 | (argument 45 | (integer_literal))))))) 46 | 47 | ================================================================================ 48 | File contextual keyword 49 | ================================================================================ 50 | 51 | void file() { } 52 | void m(file p) { } 53 | void m(int file) { } 54 | void m() 55 | { 56 | file v = null; 57 | int file = file; 58 | 59 | file(); 60 | m(file); 61 | 62 | var x = file + 1; 63 | } 64 | 65 | file class file { } 66 | 67 | -------------------------------------------------------------------------------- 68 | 69 | (compilation_unit 70 | (global_statement 71 | (local_function_statement 72 | type: (predefined_type) 73 | name: (identifier) 74 | parameters: (parameter_list) 75 | body: (block))) 76 | (global_statement 77 | (local_function_statement 78 | type: (predefined_type) 79 | name: (identifier) 80 | parameters: (parameter_list 81 | (parameter 82 | type: (identifier) 83 | name: (identifier))) 84 | body: (block))) 85 | (global_statement 86 | (local_function_statement 87 | type: (predefined_type) 88 | name: (identifier) 89 | parameters: (parameter_list 90 | (parameter 91 | type: (predefined_type) 92 | name: (identifier))) 93 | body: (block))) 94 | (global_statement 95 | (local_function_statement 96 | type: (predefined_type) 97 | name: (identifier) 98 | parameters: (parameter_list) 99 | body: (block 100 | (local_declaration_statement 101 | (variable_declaration 102 | type: (identifier) 103 | (variable_declarator 104 | name: (identifier) 105 | (null_literal)))) 106 | (local_declaration_statement 107 | (variable_declaration 108 | type: (predefined_type) 109 | (variable_declarator 110 | name: (identifier) 111 | (identifier)))) 112 | (expression_statement 113 | (invocation_expression 114 | function: (identifier) 115 | arguments: (argument_list))) 116 | (expression_statement 117 | (invocation_expression 118 | function: (identifier) 119 | arguments: (argument_list 120 | (argument 121 | (identifier))))) 122 | (local_declaration_statement 123 | (variable_declaration 124 | type: (implicit_type) 125 | (variable_declarator 126 | name: (identifier) 127 | (binary_expression 128 | left: (identifier) 129 | right: (integer_literal)))))))) 130 | (class_declaration 131 | (modifier) 132 | name: (identifier) 133 | body: (declaration_list))) 134 | 135 | ================================================================================ 136 | Scoped contextual keyword 137 | ================================================================================ 138 | 139 | void scoped() { } 140 | void m(scoped p) { } 141 | void m(scoped ref int p) { } 142 | void m(scoped ref scoped p) { } 143 | void m(int scoped) { } 144 | void m() 145 | { 146 | scoped v = null; 147 | scoped ref int v = null; 148 | scoped ref scoped v = null; 149 | int scoped = null; 150 | 151 | scoped(); 152 | m(scoped); 153 | 154 | var x = scoped + 1; 155 | var l = scoped => null; 156 | var l = (scoped i) => null; 157 | var l = (scoped, i) => null; 158 | var l = scoped (int i, int j) => null; 159 | } 160 | 161 | class scoped { } 162 | 163 | -------------------------------------------------------------------------------- 164 | 165 | (compilation_unit 166 | (global_statement 167 | (local_function_statement 168 | type: (predefined_type) 169 | name: (identifier) 170 | parameters: (parameter_list) 171 | body: (block))) 172 | (global_statement 173 | (local_function_statement 174 | type: (predefined_type) 175 | name: (identifier) 176 | parameters: (parameter_list 177 | (parameter 178 | type: (identifier) 179 | name: (identifier))) 180 | body: (block))) 181 | (global_statement 182 | (local_function_statement 183 | type: (predefined_type) 184 | name: (identifier) 185 | parameters: (parameter_list 186 | (parameter 187 | (modifier) 188 | (modifier) 189 | type: (predefined_type) 190 | name: (identifier))) 191 | body: (block))) 192 | (global_statement 193 | (local_function_statement 194 | type: (predefined_type) 195 | name: (identifier) 196 | parameters: (parameter_list 197 | (parameter 198 | (modifier) 199 | (modifier) 200 | type: (identifier) 201 | name: (identifier))) 202 | body: (block))) 203 | (global_statement 204 | (local_function_statement 205 | type: (predefined_type) 206 | name: (identifier) 207 | parameters: (parameter_list 208 | (parameter 209 | type: (predefined_type) 210 | name: (identifier))) 211 | body: (block))) 212 | (global_statement 213 | (local_function_statement 214 | type: (predefined_type) 215 | name: (identifier) 216 | parameters: (parameter_list) 217 | body: (block 218 | (local_declaration_statement 219 | (variable_declaration 220 | type: (identifier) 221 | (variable_declarator 222 | name: (identifier) 223 | (null_literal)))) 224 | (local_declaration_statement 225 | (variable_declaration 226 | type: (scoped_type 227 | type: (ref_type 228 | type: (predefined_type))) 229 | (variable_declarator 230 | name: (identifier) 231 | (null_literal)))) 232 | (local_declaration_statement 233 | (variable_declaration 234 | type: (scoped_type 235 | type: (ref_type 236 | type: (identifier))) 237 | (variable_declarator 238 | name: (identifier) 239 | (null_literal)))) 240 | (local_declaration_statement 241 | (variable_declaration 242 | type: (predefined_type) 243 | (variable_declarator 244 | name: (identifier) 245 | (null_literal)))) 246 | (expression_statement 247 | (invocation_expression 248 | function: (identifier) 249 | arguments: (argument_list))) 250 | (expression_statement 251 | (invocation_expression 252 | function: (identifier) 253 | arguments: (argument_list 254 | (argument 255 | (identifier))))) 256 | (local_declaration_statement 257 | (variable_declaration 258 | type: (implicit_type) 259 | (variable_declarator 260 | name: (identifier) 261 | (binary_expression 262 | left: (identifier) 263 | right: (integer_literal))))) 264 | (local_declaration_statement 265 | (variable_declaration 266 | type: (implicit_type) 267 | (variable_declarator 268 | name: (identifier) 269 | (lambda_expression 270 | parameters: (implicit_parameter) 271 | body: (null_literal))))) 272 | (local_declaration_statement 273 | (variable_declaration 274 | type: (implicit_type) 275 | (variable_declarator 276 | name: (identifier) 277 | (lambda_expression 278 | parameters: (parameter_list 279 | (parameter 280 | type: (identifier) 281 | name: (identifier))) 282 | body: (null_literal))))) 283 | (local_declaration_statement 284 | (variable_declaration 285 | type: (implicit_type) 286 | (variable_declarator 287 | name: (identifier) 288 | (lambda_expression 289 | parameters: (parameter_list 290 | (parameter 291 | name: (identifier)) 292 | (parameter 293 | name: (identifier))) 294 | body: (null_literal))))) 295 | (local_declaration_statement 296 | (variable_declaration 297 | type: (implicit_type) 298 | (variable_declarator 299 | name: (identifier) 300 | (lambda_expression 301 | type: (identifier) 302 | parameters: (parameter_list 303 | (parameter 304 | type: (predefined_type) 305 | name: (identifier)) 306 | (parameter 307 | type: (predefined_type) 308 | name: (identifier))) 309 | body: (null_literal)))))))) 310 | (class_declaration 311 | name: (identifier) 312 | body: (declaration_list))) 313 | 314 | ================================================================================ 315 | Set contextual keyword 316 | ================================================================================ 317 | 318 | void set() { } 319 | void m(set p) { } 320 | void m(int set) { } 321 | void m() 322 | { 323 | set v = null; 324 | int set = set; 325 | 326 | set(); 327 | m(set); 328 | 329 | var x = set + 1; 330 | } 331 | 332 | class set { } 333 | 334 | -------------------------------------------------------------------------------- 335 | 336 | (compilation_unit 337 | (global_statement 338 | (local_function_statement 339 | type: (predefined_type) 340 | name: (identifier) 341 | parameters: (parameter_list) 342 | body: (block))) 343 | (global_statement 344 | (local_function_statement 345 | type: (predefined_type) 346 | name: (identifier) 347 | parameters: (parameter_list 348 | (parameter 349 | type: (identifier) 350 | name: (identifier))) 351 | body: (block))) 352 | (global_statement 353 | (local_function_statement 354 | type: (predefined_type) 355 | name: (identifier) 356 | parameters: (parameter_list 357 | (parameter 358 | type: (predefined_type) 359 | name: (identifier))) 360 | body: (block))) 361 | (global_statement 362 | (local_function_statement 363 | type: (predefined_type) 364 | name: (identifier) 365 | parameters: (parameter_list) 366 | body: (block 367 | (local_declaration_statement 368 | (variable_declaration 369 | type: (identifier) 370 | (variable_declarator 371 | name: (identifier) 372 | (null_literal)))) 373 | (local_declaration_statement 374 | (variable_declaration 375 | type: (predefined_type) 376 | (variable_declarator 377 | name: (identifier) 378 | (identifier)))) 379 | (expression_statement 380 | (invocation_expression 381 | function: (identifier) 382 | arguments: (argument_list))) 383 | (expression_statement 384 | (invocation_expression 385 | function: (identifier) 386 | arguments: (argument_list 387 | (argument 388 | (identifier))))) 389 | (local_declaration_statement 390 | (variable_declaration 391 | type: (implicit_type) 392 | (variable_declarator 393 | name: (identifier) 394 | (binary_expression 395 | left: (identifier) 396 | right: (integer_literal)))))))) 397 | (class_declaration 398 | name: (identifier) 399 | body: (declaration_list))) 400 | 401 | ================================================================================ 402 | Var contextual keyword 403 | ================================================================================ 404 | 405 | void var() { } 406 | void m(var p) { } 407 | void m(int var) { } 408 | void m() 409 | { 410 | var v = null; 411 | int var = var; 412 | var var = 1; 413 | 414 | var(); 415 | m(var); 416 | 417 | var x = var + 1; 418 | } 419 | 420 | class var { } 421 | 422 | -------------------------------------------------------------------------------- 423 | 424 | (compilation_unit 425 | (global_statement 426 | (local_function_statement 427 | type: (predefined_type) 428 | name: (identifier) 429 | parameters: (parameter_list) 430 | body: (block))) 431 | (global_statement 432 | (local_function_statement 433 | type: (predefined_type) 434 | name: (identifier) 435 | parameters: (parameter_list 436 | (parameter 437 | type: (implicit_type) 438 | name: (identifier))) 439 | body: (block))) 440 | (global_statement 441 | (local_function_statement 442 | type: (predefined_type) 443 | name: (identifier) 444 | parameters: (parameter_list 445 | (parameter 446 | type: (predefined_type) 447 | name: (identifier))) 448 | body: (block))) 449 | (global_statement 450 | (local_function_statement 451 | type: (predefined_type) 452 | name: (identifier) 453 | parameters: (parameter_list) 454 | body: (block 455 | (local_declaration_statement 456 | (variable_declaration 457 | type: (implicit_type) 458 | (variable_declarator 459 | name: (identifier) 460 | (null_literal)))) 461 | (local_declaration_statement 462 | (variable_declaration 463 | type: (predefined_type) 464 | (variable_declarator 465 | name: (identifier) 466 | (identifier)))) 467 | (local_declaration_statement 468 | (variable_declaration 469 | type: (implicit_type) 470 | (variable_declarator 471 | name: (identifier) 472 | (integer_literal)))) 473 | (expression_statement 474 | (invocation_expression 475 | function: (identifier) 476 | arguments: (argument_list))) 477 | (expression_statement 478 | (invocation_expression 479 | function: (identifier) 480 | arguments: (argument_list 481 | (argument 482 | (identifier))))) 483 | (local_declaration_statement 484 | (variable_declaration 485 | type: (implicit_type) 486 | (variable_declarator 487 | name: (identifier) 488 | (binary_expression 489 | left: (identifier) 490 | right: (integer_literal)))))))) 491 | (class_declaration 492 | name: (identifier) 493 | body: (declaration_list))) 494 | 495 | ================================================================================ 496 | Nameof contextual keyword 497 | ================================================================================ 498 | 499 | void nameof() { } 500 | void m(nameof p) { } 501 | void m(int nameof) { } 502 | void m() 503 | { 504 | nameof v = null; 505 | int nameof = nameof; 506 | 507 | nameof(); 508 | nameof(a, b); 509 | m(nameof); 510 | 511 | var x = nameof + 1; 512 | } 513 | 514 | class nameof { } 515 | 516 | -------------------------------------------------------------------------------- 517 | 518 | (compilation_unit 519 | (global_statement 520 | (local_function_statement 521 | type: (predefined_type) 522 | name: (identifier) 523 | parameters: (parameter_list) 524 | body: (block))) 525 | (global_statement 526 | (local_function_statement 527 | type: (predefined_type) 528 | name: (identifier) 529 | parameters: (parameter_list 530 | (parameter 531 | type: (identifier) 532 | name: (identifier))) 533 | body: (block))) 534 | (global_statement 535 | (local_function_statement 536 | type: (predefined_type) 537 | name: (identifier) 538 | parameters: (parameter_list 539 | (parameter 540 | type: (predefined_type) 541 | name: (identifier))) 542 | body: (block))) 543 | (global_statement 544 | (local_function_statement 545 | type: (predefined_type) 546 | name: (identifier) 547 | parameters: (parameter_list) 548 | body: (block 549 | (local_declaration_statement 550 | (variable_declaration 551 | type: (identifier) 552 | (variable_declarator 553 | name: (identifier) 554 | (null_literal)))) 555 | (local_declaration_statement 556 | (variable_declaration 557 | type: (predefined_type) 558 | (variable_declarator 559 | name: (identifier) 560 | (identifier)))) 561 | (expression_statement 562 | (invocation_expression 563 | function: (identifier) 564 | arguments: (argument_list))) 565 | (expression_statement 566 | (invocation_expression 567 | function: (identifier) 568 | arguments: (argument_list 569 | (argument 570 | (identifier)) 571 | (argument 572 | (identifier))))) 573 | (expression_statement 574 | (invocation_expression 575 | function: (identifier) 576 | arguments: (argument_list 577 | (argument 578 | (identifier))))) 579 | (local_declaration_statement 580 | (variable_declaration 581 | type: (implicit_type) 582 | (variable_declarator 583 | name: (identifier) 584 | (binary_expression 585 | left: (identifier) 586 | right: (integer_literal)))))))) 587 | (class_declaration 588 | name: (identifier) 589 | body: (declaration_list))) 590 | -------------------------------------------------------------------------------- /test/corpus/enums.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | global enum with one option 3 | ================================================================================ 4 | 5 | enum A: byte { One, Two = 2, Three = 0x03 } 6 | 7 | enum NoBody; 8 | 9 | -------------------------------------------------------------------------------- 10 | 11 | (compilation_unit 12 | (enum_declaration 13 | name: (identifier) 14 | (base_list 15 | (predefined_type)) 16 | body: (enum_member_declaration_list 17 | (enum_member_declaration 18 | name: (identifier)) 19 | (enum_member_declaration 20 | name: (identifier) 21 | value: (integer_literal)) 22 | (enum_member_declaration 23 | name: (identifier) 24 | value: (integer_literal)))) 25 | (enum_declaration 26 | name: (identifier))) 27 | -------------------------------------------------------------------------------- /test/corpus/identifiers.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Identifiers 3 | ================================================================================ 4 | 5 | int x = y; 6 | 7 | // keyword names 8 | int @var = @const; 9 | 10 | // contextual keyword names 11 | int nint = 0; 12 | int nuint = 0; 13 | 14 | // unicode identifiers 15 | int under_score = 0; 16 | int with1number = 0; 17 | int varæble = 0; 18 | int Переменная = 0; 19 | int first‿letter = 0; 20 | int ග්‍රහලෝකය = 0; 21 | int _كوكبxxx = 0; 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | (compilation_unit 26 | (global_statement 27 | (local_declaration_statement 28 | (variable_declaration 29 | type: (predefined_type) 30 | (variable_declarator 31 | name: (identifier) 32 | (identifier))))) 33 | (comment) 34 | (global_statement 35 | (local_declaration_statement 36 | (variable_declaration 37 | type: (predefined_type) 38 | (variable_declarator 39 | name: (identifier) 40 | (identifier))))) 41 | (comment) 42 | (global_statement 43 | (local_declaration_statement 44 | (variable_declaration 45 | type: (predefined_type) 46 | (variable_declarator 47 | name: (identifier) 48 | (integer_literal))))) 49 | (global_statement 50 | (local_declaration_statement 51 | (variable_declaration 52 | type: (predefined_type) 53 | (variable_declarator 54 | name: (identifier) 55 | (integer_literal))))) 56 | (comment) 57 | (global_statement 58 | (local_declaration_statement 59 | (variable_declaration 60 | type: (predefined_type) 61 | (variable_declarator 62 | name: (identifier) 63 | (integer_literal))))) 64 | (global_statement 65 | (local_declaration_statement 66 | (variable_declaration 67 | type: (predefined_type) 68 | (variable_declarator 69 | name: (identifier) 70 | (integer_literal))))) 71 | (global_statement 72 | (local_declaration_statement 73 | (variable_declaration 74 | type: (predefined_type) 75 | (variable_declarator 76 | name: (identifier) 77 | (integer_literal))))) 78 | (global_statement 79 | (local_declaration_statement 80 | (variable_declaration 81 | type: (predefined_type) 82 | (variable_declarator 83 | name: (identifier) 84 | (integer_literal))))) 85 | (global_statement 86 | (local_declaration_statement 87 | (variable_declaration 88 | type: (predefined_type) 89 | (variable_declarator 90 | name: (identifier) 91 | (integer_literal))))) 92 | (global_statement 93 | (local_declaration_statement 94 | (variable_declaration 95 | type: (predefined_type) 96 | (variable_declarator 97 | name: (identifier) 98 | (integer_literal))))) 99 | (global_statement 100 | (local_declaration_statement 101 | (variable_declaration 102 | type: (predefined_type) 103 | (variable_declarator 104 | name: (identifier) 105 | (integer_literal)))))) 106 | -------------------------------------------------------------------------------- /test/corpus/interfaces.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Interfaces 3 | ================================================================================ 4 | 5 | public interface IOne: ITwo, IThree { 6 | byte Get { get; } 7 | char Set { set; } 8 | uint GetSet { get; set; } 9 | long SetGet { set; get; } 10 | 11 | void Nothing(); 12 | int Output(); 13 | void Input(string a); 14 | int InputOutput(string a); 15 | }; 16 | 17 | // generic 18 | private interface IOne : ITwo { } 19 | 20 | // constraint 21 | private interface IOne : ITwo where T1:T2 { } 22 | 23 | private interface IOne : ITwo where T1:T2 where T3:new() { } 24 | 25 | namespace A { 26 | interface IOne : ITwo { 27 | event EventHandler SomeEvent; 28 | 29 | bool this[int index] { get; set; } 30 | } 31 | } 32 | 33 | 34 | interface MyDefault { 35 | void Log(string message) { 36 | Console.WriteLine(message); 37 | } 38 | } 39 | 40 | public interface IGetNext where T : IGetNext 41 | { 42 | static abstract T operator ++(T other); 43 | } 44 | 45 | private interface NoBody; 46 | 47 | -------------------------------------------------------------------------------- 48 | 49 | (compilation_unit 50 | (interface_declaration 51 | (modifier) 52 | name: (identifier) 53 | (base_list 54 | (identifier) 55 | (identifier)) 56 | body: (declaration_list 57 | (property_declaration 58 | type: (predefined_type) 59 | name: (identifier) 60 | accessors: (accessor_list 61 | (accessor_declaration))) 62 | (property_declaration 63 | type: (predefined_type) 64 | name: (identifier) 65 | accessors: (accessor_list 66 | (accessor_declaration))) 67 | (property_declaration 68 | type: (predefined_type) 69 | name: (identifier) 70 | accessors: (accessor_list 71 | (accessor_declaration) 72 | (accessor_declaration))) 73 | (property_declaration 74 | type: (predefined_type) 75 | name: (identifier) 76 | accessors: (accessor_list 77 | (accessor_declaration) 78 | (accessor_declaration))) 79 | (method_declaration 80 | returns: (predefined_type) 81 | name: (identifier) 82 | parameters: (parameter_list)) 83 | (method_declaration 84 | returns: (predefined_type) 85 | name: (identifier) 86 | parameters: (parameter_list)) 87 | (method_declaration 88 | returns: (predefined_type) 89 | name: (identifier) 90 | parameters: (parameter_list 91 | (parameter 92 | type: (predefined_type) 93 | name: (identifier)))) 94 | (method_declaration 95 | returns: (predefined_type) 96 | name: (identifier) 97 | parameters: (parameter_list 98 | (parameter 99 | type: (predefined_type) 100 | name: (identifier)))))) 101 | (comment) 102 | (interface_declaration 103 | (modifier) 104 | name: (identifier) 105 | type_parameters: (type_parameter_list 106 | (type_parameter 107 | name: (identifier))) 108 | (base_list 109 | (identifier)) 110 | body: (declaration_list)) 111 | (comment) 112 | (interface_declaration 113 | (modifier) 114 | name: (identifier) 115 | type_parameters: (type_parameter_list 116 | (type_parameter 117 | name: (identifier))) 118 | (base_list 119 | (identifier)) 120 | (type_parameter_constraints_clause 121 | (identifier) 122 | (type_parameter_constraint 123 | type: (identifier))) 124 | body: (declaration_list)) 125 | (interface_declaration 126 | (modifier) 127 | name: (identifier) 128 | type_parameters: (type_parameter_list 129 | (type_parameter 130 | name: (identifier)) 131 | (type_parameter 132 | name: (identifier))) 133 | (base_list 134 | (identifier)) 135 | (type_parameter_constraints_clause 136 | (identifier) 137 | (type_parameter_constraint 138 | type: (identifier))) 139 | (type_parameter_constraints_clause 140 | (identifier) 141 | (type_parameter_constraint 142 | (constructor_constraint))) 143 | body: (declaration_list)) 144 | (namespace_declaration 145 | name: (identifier) 146 | body: (declaration_list 147 | (interface_declaration 148 | name: (identifier) 149 | (base_list 150 | (identifier)) 151 | body: (declaration_list 152 | (event_field_declaration 153 | (variable_declaration 154 | type: (generic_name 155 | (identifier) 156 | (type_argument_list 157 | (identifier))) 158 | (variable_declarator 159 | name: (identifier)))) 160 | (indexer_declaration 161 | type: (predefined_type) 162 | parameters: (bracketed_parameter_list 163 | (parameter 164 | type: (predefined_type) 165 | name: (identifier))) 166 | accessors: (accessor_list 167 | (accessor_declaration) 168 | (accessor_declaration))))))) 169 | (interface_declaration 170 | name: (identifier) 171 | body: (declaration_list 172 | (method_declaration 173 | returns: (predefined_type) 174 | name: (identifier) 175 | parameters: (parameter_list 176 | (parameter 177 | type: (predefined_type) 178 | name: (identifier))) 179 | body: (block 180 | (expression_statement 181 | (invocation_expression 182 | function: (member_access_expression 183 | expression: (identifier) 184 | name: (identifier)) 185 | arguments: (argument_list 186 | (argument 187 | (identifier))))))))) 188 | (interface_declaration 189 | (modifier) 190 | name: (identifier) 191 | type_parameters: (type_parameter_list 192 | (type_parameter 193 | name: (identifier))) 194 | (type_parameter_constraints_clause 195 | (identifier) 196 | (type_parameter_constraint 197 | type: (generic_name 198 | (identifier) 199 | (type_argument_list 200 | (identifier))))) 201 | body: (declaration_list 202 | (operator_declaration 203 | (modifier) 204 | (modifier) 205 | type: (identifier) 206 | parameters: (parameter_list 207 | (parameter 208 | type: (identifier) 209 | name: (identifier)))))) 210 | (interface_declaration 211 | (modifier) 212 | name: (identifier))) 213 | 214 | -------------------------------------------------------------------------------- /test/corpus/preprocessor.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | If, elif and else directives 3 | ================================================================================ 4 | 5 | #if WIN32 6 | string os = "Win32"; 7 | #elif MACOS 8 | string os = "MacOS"; 9 | #else 10 | string os = "Unknown"; 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- 14 | 15 | (compilation_unit 16 | (preproc_if 17 | condition: (identifier) 18 | (local_declaration_statement 19 | (variable_declaration 20 | type: (predefined_type) 21 | (variable_declarator 22 | name: (identifier) 23 | (string_literal 24 | (string_literal_content))))) 25 | alternative: (preproc_elif 26 | condition: (identifier) 27 | (local_declaration_statement 28 | (variable_declaration 29 | type: (predefined_type) 30 | (variable_declarator 31 | name: (identifier) 32 | (string_literal 33 | (string_literal_content))))) 34 | alternative: (preproc_else 35 | (local_declaration_statement 36 | (variable_declaration 37 | type: (predefined_type) 38 | (variable_declarator 39 | name: (identifier) 40 | (string_literal 41 | (string_literal_content))))))))) 42 | 43 | ================================================================================ 44 | If conditions 45 | ================================================================================ 46 | 47 | #if !MACOS 48 | #endif 49 | 50 | #if WIN32==true 51 | #endif 52 | 53 | #if !MACOS!=false 54 | #endif 55 | 56 | #if A && B || C 57 | #endif 58 | 59 | #if (A) 60 | #endif 61 | 62 | #if (A || B) 63 | #endif 64 | 65 | #if (A && B) || C 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- 69 | 70 | (compilation_unit 71 | (preproc_if 72 | condition: (unary_expression 73 | argument: (identifier))) 74 | (preproc_if 75 | condition: (binary_expression 76 | left: (identifier) 77 | right: (boolean_literal))) 78 | (preproc_if 79 | condition: (binary_expression 80 | left: (unary_expression 81 | argument: (identifier)) 82 | right: (boolean_literal))) 83 | (preproc_if 84 | condition: (binary_expression 85 | left: (binary_expression 86 | left: (identifier) 87 | right: (identifier)) 88 | right: (identifier))) 89 | (preproc_if 90 | condition: (parenthesized_expression 91 | (identifier))) 92 | (preproc_if 93 | condition: (parenthesized_expression 94 | (binary_expression 95 | left: (identifier) 96 | right: (identifier)))) 97 | (preproc_if 98 | condition: (binary_expression 99 | left: (parenthesized_expression 100 | (binary_expression 101 | left: (identifier) 102 | right: (identifier))) 103 | right: (identifier)))) 104 | 105 | ================================================================================ 106 | Define and undefine directives 107 | ================================================================================ 108 | 109 | #define SOMETHING 110 | #undef BAD 111 | 112 | -------------------------------------------------------------------------------- 113 | 114 | (compilation_unit 115 | (preproc_define 116 | (preproc_arg)) 117 | (preproc_undef 118 | (preproc_arg))) 119 | 120 | ================================================================================ 121 | Line directives 122 | ================================================================================ 123 | 124 | class Of1879 { 125 | void AMethod() { 126 | #line 2001 "A Space" // Comment 127 | #line hidden 128 | #line default 129 | #line (1, 1) - (1, 3) 1 "a.cs" 130 | #line (2, 1) - (2, 3) "a.cs" 131 | # line 2001 "A Space" 132 | # line hidden 133 | # line default 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- 138 | 139 | (compilation_unit 140 | (class_declaration 141 | name: (identifier) 142 | body: (declaration_list 143 | (method_declaration 144 | returns: (predefined_type) 145 | name: (identifier) 146 | parameters: (parameter_list) 147 | body: (block 148 | (preproc_line 149 | (integer_literal) 150 | (string_literal 151 | (string_literal_content)) 152 | (comment)) 153 | (preproc_line) 154 | (preproc_line) 155 | (preproc_line 156 | (integer_literal) 157 | (integer_literal) 158 | (integer_literal) 159 | (integer_literal) 160 | (integer_literal) 161 | (string_literal 162 | (string_literal_content))) 163 | (preproc_line 164 | (integer_literal) 165 | (integer_literal) 166 | (integer_literal) 167 | (integer_literal) 168 | (string_literal 169 | (string_literal_content))) 170 | (preproc_line 171 | (integer_literal) 172 | (string_literal 173 | (string_literal_content))) 174 | (preproc_line) 175 | (preproc_line)))))) 176 | 177 | ================================================================================ 178 | Directives not in strings or comments 179 | ================================================================================ 180 | 181 | class Of1879 { 182 | void AMethod() { 183 | var s = @"Only a string 184 | #if NOPE 185 | "; 186 | /* Only a comment 187 | #if NOPE 188 | */ 189 | } 190 | } 191 | 192 | -------------------------------------------------------------------------------- 193 | 194 | (compilation_unit 195 | (class_declaration 196 | name: (identifier) 197 | body: (declaration_list 198 | (method_declaration 199 | returns: (predefined_type) 200 | name: (identifier) 201 | parameters: (parameter_list) 202 | body: (block 203 | (local_declaration_statement 204 | (variable_declaration 205 | type: (implicit_type) 206 | (variable_declarator 207 | name: (identifier) 208 | (verbatim_string_literal)))) 209 | (comment)))))) 210 | 211 | ================================================================================ 212 | Shebang directive 213 | ================================================================================ 214 | 215 | #!/usr/bin/env scriptcs 216 | 217 | -------------------------------------------------------------------------------- 218 | 219 | (compilation_unit 220 | (shebang_directive)) 221 | -------------------------------------------------------------------------------- /test/corpus/query-syntax.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Query from select 3 | ================================================================================ 4 | 5 | var x = from a in source select a.B() ? c : c * 2; 6 | 7 | var x = from a in source select somevar = a; 8 | 9 | var x = from a in source select new { Name = a.B }; 10 | 11 | var x = from a in source 12 | where a.B == "A" 13 | select new { Name = a.B }; 14 | 15 | var x = from a in source 16 | orderby a.A descending 17 | orderby a.C ascending 18 | orderby 1 19 | select a; 20 | 21 | var x = from a in source 22 | let z = new { a.A, a.B } 23 | select z; 24 | 25 | var x = from a in sourceA 26 | join b in sourceB on a.FK equals b.PK 27 | select new { A.A, B.B }; 28 | 29 | var x = from a in sourceA 30 | from b in sourceB 31 | where a.FK == b.FK 32 | select new { A.A, B.B }; 33 | 34 | var x = from a in sourceA 35 | group a by a.Country into g 36 | select new { Country = g.Key, Population = g.Sum(p => p.Population) }; 37 | 38 | 39 | -------------------------------------------------------------------------------- 40 | 41 | (compilation_unit 42 | (global_statement 43 | (local_declaration_statement 44 | (variable_declaration 45 | type: (implicit_type) 46 | (variable_declarator 47 | name: (identifier) 48 | (query_expression 49 | (from_clause 50 | name: (identifier) 51 | (identifier)) 52 | (select_clause 53 | (conditional_expression 54 | condition: (invocation_expression 55 | function: (member_access_expression 56 | expression: (identifier) 57 | name: (identifier)) 58 | arguments: (argument_list)) 59 | consequence: (identifier) 60 | alternative: (binary_expression 61 | left: (identifier) 62 | right: (integer_literal))))))))) 63 | (global_statement 64 | (local_declaration_statement 65 | (variable_declaration 66 | type: (implicit_type) 67 | (variable_declarator 68 | name: (identifier) 69 | (query_expression 70 | (from_clause 71 | name: (identifier) 72 | (identifier)) 73 | (select_clause 74 | (assignment_expression 75 | left: (identifier) 76 | right: (identifier)))))))) 77 | (global_statement 78 | (local_declaration_statement 79 | (variable_declaration 80 | type: (implicit_type) 81 | (variable_declarator 82 | name: (identifier) 83 | (query_expression 84 | (from_clause 85 | name: (identifier) 86 | (identifier)) 87 | (select_clause 88 | (anonymous_object_creation_expression 89 | (identifier) 90 | (member_access_expression 91 | expression: (identifier) 92 | name: (identifier))))))))) 93 | (global_statement 94 | (local_declaration_statement 95 | (variable_declaration 96 | type: (implicit_type) 97 | (variable_declarator 98 | name: (identifier) 99 | (query_expression 100 | (from_clause 101 | name: (identifier) 102 | (identifier)) 103 | (where_clause 104 | (binary_expression 105 | left: (member_access_expression 106 | expression: (identifier) 107 | name: (identifier)) 108 | right: (string_literal 109 | (string_literal_content)))) 110 | (select_clause 111 | (anonymous_object_creation_expression 112 | (identifier) 113 | (member_access_expression 114 | expression: (identifier) 115 | name: (identifier))))))))) 116 | (global_statement 117 | (local_declaration_statement 118 | (variable_declaration 119 | type: (implicit_type) 120 | (variable_declarator 121 | name: (identifier) 122 | (query_expression 123 | (from_clause 124 | name: (identifier) 125 | (identifier)) 126 | (order_by_clause 127 | (member_access_expression 128 | expression: (identifier) 129 | name: (identifier))) 130 | (order_by_clause 131 | (member_access_expression 132 | expression: (identifier) 133 | name: (identifier))) 134 | (order_by_clause 135 | (integer_literal)) 136 | (select_clause 137 | (identifier))))))) 138 | (global_statement 139 | (local_declaration_statement 140 | (variable_declaration 141 | type: (implicit_type) 142 | (variable_declarator 143 | name: (identifier) 144 | (query_expression 145 | (from_clause 146 | name: (identifier) 147 | (identifier)) 148 | (let_clause 149 | (identifier) 150 | (anonymous_object_creation_expression 151 | (member_access_expression 152 | expression: (identifier) 153 | name: (identifier)) 154 | (member_access_expression 155 | expression: (identifier) 156 | name: (identifier)))) 157 | (select_clause 158 | (identifier))))))) 159 | (global_statement 160 | (local_declaration_statement 161 | (variable_declaration 162 | type: (implicit_type) 163 | (variable_declarator 164 | name: (identifier) 165 | (query_expression 166 | (from_clause 167 | name: (identifier) 168 | (identifier)) 169 | (join_clause 170 | (identifier) 171 | (identifier) 172 | (member_access_expression 173 | expression: (identifier) 174 | name: (identifier)) 175 | (member_access_expression 176 | expression: (identifier) 177 | name: (identifier))) 178 | (select_clause 179 | (anonymous_object_creation_expression 180 | (member_access_expression 181 | expression: (identifier) 182 | name: (identifier)) 183 | (member_access_expression 184 | expression: (identifier) 185 | name: (identifier))))))))) 186 | (global_statement 187 | (local_declaration_statement 188 | (variable_declaration 189 | type: (implicit_type) 190 | (variable_declarator 191 | name: (identifier) 192 | (query_expression 193 | (from_clause 194 | name: (identifier) 195 | (identifier)) 196 | (from_clause 197 | name: (identifier) 198 | (identifier)) 199 | (where_clause 200 | (binary_expression 201 | left: (member_access_expression 202 | expression: (identifier) 203 | name: (identifier)) 204 | right: (member_access_expression 205 | expression: (identifier) 206 | name: (identifier)))) 207 | (select_clause 208 | (anonymous_object_creation_expression 209 | (member_access_expression 210 | expression: (identifier) 211 | name: (identifier)) 212 | (member_access_expression 213 | expression: (identifier) 214 | name: (identifier))))))))) 215 | (global_statement 216 | (local_declaration_statement 217 | (variable_declaration 218 | type: (implicit_type) 219 | (variable_declarator 220 | name: (identifier) 221 | (query_expression 222 | (from_clause 223 | name: (identifier) 224 | (identifier)) 225 | (group_clause 226 | (identifier) 227 | (member_access_expression 228 | expression: (identifier) 229 | name: (identifier))) 230 | (identifier) 231 | (select_clause 232 | (anonymous_object_creation_expression 233 | (identifier) 234 | (member_access_expression 235 | expression: (identifier) 236 | name: (identifier)) 237 | (identifier) 238 | (invocation_expression 239 | function: (member_access_expression 240 | expression: (identifier) 241 | name: (identifier)) 242 | arguments: (argument_list 243 | (argument 244 | (lambda_expression 245 | parameters: (implicit_parameter) 246 | body: (member_access_expression 247 | expression: (identifier) 248 | name: (identifier)))))))))))))) 249 | -------------------------------------------------------------------------------- /test/corpus/records.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Basic record declaration 3 | ================================================================================ 4 | 5 | record F { 6 | int Age { get; init; } 7 | } 8 | 9 | record struct F { 10 | int Age { get; init; } 11 | } 12 | 13 | record class F { 14 | int Age { get; init; } 15 | } 16 | 17 | public record F where T:struct {} 18 | 19 | public record F where T: new() {} 20 | 21 | public record A : ISomething { } 22 | 23 | [Test] 24 | private record F where T1 : I1, I2, new() where T2 : I2 { } 25 | 26 | record Person(string FirstName, string LastName); 27 | 28 | record Teacher(string FirstName, string LastName, string Subject) : Person(FirstName, LastName); 29 | 30 | record Teacher(string FirstName, string LastName, string Subject) : Person(FirstName, LastName), Ns.I1, I2; 31 | 32 | record Teacher() : Entity(), I1; 33 | 34 | public record Person { }; 35 | 36 | public record struct Person2 { }; 37 | 38 | record NoBody; 39 | 40 | -------------------------------------------------------------------------------- 41 | 42 | (compilation_unit 43 | (record_declaration 44 | name: (identifier) 45 | body: (declaration_list 46 | (property_declaration 47 | type: (predefined_type) 48 | name: (identifier) 49 | accessors: (accessor_list 50 | (accessor_declaration) 51 | (accessor_declaration))))) 52 | (record_declaration 53 | name: (identifier) 54 | body: (declaration_list 55 | (property_declaration 56 | type: (predefined_type) 57 | name: (identifier) 58 | accessors: (accessor_list 59 | (accessor_declaration) 60 | (accessor_declaration))))) 61 | (record_declaration 62 | name: (identifier) 63 | body: (declaration_list 64 | (property_declaration 65 | type: (predefined_type) 66 | name: (identifier) 67 | accessors: (accessor_list 68 | (accessor_declaration) 69 | (accessor_declaration))))) 70 | (record_declaration 71 | (modifier) 72 | name: (identifier) 73 | (type_parameter_list 74 | (type_parameter 75 | name: (identifier))) 76 | (type_parameter_constraints_clause 77 | (identifier) 78 | (type_parameter_constraint)) 79 | body: (declaration_list)) 80 | (record_declaration 81 | (modifier) 82 | name: (identifier) 83 | (type_parameter_list 84 | (type_parameter 85 | name: (identifier))) 86 | (type_parameter_constraints_clause 87 | (identifier) 88 | (type_parameter_constraint 89 | (constructor_constraint))) 90 | body: (declaration_list)) 91 | (record_declaration 92 | (modifier) 93 | name: (identifier) 94 | (base_list 95 | (identifier)) 96 | body: (declaration_list)) 97 | (record_declaration 98 | (attribute_list 99 | (attribute 100 | name: (identifier))) 101 | (modifier) 102 | name: (identifier) 103 | (type_parameter_list 104 | (type_parameter 105 | name: (identifier)) 106 | (type_parameter 107 | name: (identifier))) 108 | (type_parameter_constraints_clause 109 | (identifier) 110 | (type_parameter_constraint 111 | type: (identifier)) 112 | (type_parameter_constraint 113 | type: (identifier)) 114 | (type_parameter_constraint 115 | (constructor_constraint))) 116 | (type_parameter_constraints_clause 117 | (identifier) 118 | (type_parameter_constraint 119 | type: (identifier))) 120 | body: (declaration_list)) 121 | (record_declaration 122 | name: (identifier) 123 | (parameter_list 124 | (parameter 125 | type: (predefined_type) 126 | name: (identifier)) 127 | (parameter 128 | type: (predefined_type) 129 | name: (identifier)))) 130 | (record_declaration 131 | name: (identifier) 132 | (parameter_list 133 | (parameter 134 | type: (predefined_type) 135 | name: (identifier)) 136 | (parameter 137 | type: (predefined_type) 138 | name: (identifier)) 139 | (parameter 140 | type: (predefined_type) 141 | name: (identifier))) 142 | (base_list 143 | (primary_constructor_base_type 144 | type: (identifier) 145 | (argument_list 146 | (argument 147 | (identifier)) 148 | (argument 149 | (identifier)))))) 150 | (record_declaration 151 | name: (identifier) 152 | (parameter_list 153 | (parameter 154 | type: (predefined_type) 155 | name: (identifier)) 156 | (parameter 157 | type: (predefined_type) 158 | name: (identifier)) 159 | (parameter 160 | type: (predefined_type) 161 | name: (identifier))) 162 | (base_list 163 | (primary_constructor_base_type 164 | type: (identifier) 165 | (argument_list 166 | (argument 167 | (identifier)) 168 | (argument 169 | (identifier)))) 170 | (qualified_name 171 | qualifier: (identifier) 172 | name: (identifier)) 173 | (identifier))) 174 | (record_declaration 175 | name: (identifier) 176 | (parameter_list) 177 | (base_list 178 | (primary_constructor_base_type 179 | type: (generic_name 180 | (identifier) 181 | (type_argument_list 182 | (identifier))) 183 | (argument_list)) 184 | (identifier))) 185 | (record_declaration 186 | (modifier) 187 | name: (identifier) 188 | body: (declaration_list)) 189 | (record_declaration 190 | (modifier) 191 | name: (identifier) 192 | body: (declaration_list)) 193 | (record_declaration 194 | name: (identifier))) -------------------------------------------------------------------------------- /test/corpus/source-file-structure.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Using directives, extern alias, and namespace declarations 3 | ================================================================================ 4 | 5 | global using A; 6 | global using static A.B; 7 | 8 | using A; 9 | using B.C; 10 | using global::E.F; 11 | using G = H.I; 12 | using static J.K; 13 | 14 | using Point = (int x, int y); 15 | 16 | extern alias A; 17 | 18 | namespace Foo { 19 | using A; 20 | } 21 | 22 | namespace A { 23 | namespace B.C.D { 24 | } 25 | 26 | namespace E.F { 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- 31 | 32 | (compilation_unit 33 | (using_directive 34 | (identifier)) 35 | (using_directive 36 | (qualified_name 37 | (identifier) 38 | (identifier))) 39 | (using_directive 40 | (identifier)) 41 | (using_directive 42 | (qualified_name 43 | (identifier) 44 | (identifier))) 45 | (using_directive 46 | (qualified_name 47 | (alias_qualified_name 48 | (identifier) 49 | (identifier)) 50 | (identifier))) 51 | (using_directive 52 | (identifier) 53 | (qualified_name 54 | (identifier) 55 | (identifier))) 56 | (using_directive 57 | (qualified_name 58 | (identifier) 59 | (identifier))) 60 | (using_directive 61 | (identifier) 62 | (tuple_type 63 | (tuple_element 64 | (predefined_type) 65 | (identifier)) 66 | (tuple_element 67 | (predefined_type) 68 | (identifier)))) 69 | (extern_alias_directive 70 | (identifier)) 71 | (namespace_declaration 72 | (identifier) 73 | (declaration_list 74 | (using_directive 75 | (identifier)))) 76 | (namespace_declaration 77 | (identifier) 78 | (declaration_list 79 | (namespace_declaration 80 | (qualified_name 81 | (qualified_name 82 | (identifier) 83 | (identifier)) 84 | (identifier)) 85 | (declaration_list)) 86 | (namespace_declaration 87 | (qualified_name 88 | (identifier) 89 | (identifier)) 90 | (declaration_list))))) 91 | 92 | ================================================================================ 93 | File scoped namespaces 94 | ================================================================================ 95 | 96 | namespace A; 97 | 98 | class B { 99 | } 100 | 101 | -------------------------------------------------------------------------------- 102 | 103 | (compilation_unit 104 | (file_scoped_namespace_declaration 105 | name: (identifier)) 106 | (class_declaration 107 | name: (identifier) 108 | body: (declaration_list))) 109 | 110 | ================================================================================ 111 | Delegates 112 | ================================================================================ 113 | 114 | public delegate int Global(ref char a = '\n'); 115 | public delegate ref int Global(ref char a = '\n'); 116 | public delegate ref readonly int Global(ref char a = '\n'); 117 | 118 | delegate void A() where T:class; 119 | 120 | delegate void A(params int [] test); 121 | 122 | class Z { 123 | delegate void Zed(); 124 | } 125 | 126 | -------------------------------------------------------------------------------- 127 | 128 | (compilation_unit 129 | (delegate_declaration 130 | (modifier) 131 | type: (predefined_type) 132 | name: (identifier) 133 | parameters: (parameter_list 134 | (parameter 135 | (modifier) 136 | type: (predefined_type) 137 | name: (identifier) 138 | (character_literal 139 | (escape_sequence))))) 140 | (delegate_declaration 141 | (modifier) 142 | type: (ref_type 143 | type: (predefined_type)) 144 | name: (identifier) 145 | parameters: (parameter_list 146 | (parameter 147 | (modifier) 148 | type: (predefined_type) 149 | name: (identifier) 150 | (character_literal 151 | (escape_sequence))))) 152 | (delegate_declaration 153 | (modifier) 154 | type: (ref_type 155 | type: (predefined_type)) 156 | name: (identifier) 157 | parameters: (parameter_list 158 | (parameter 159 | (modifier) 160 | type: (predefined_type) 161 | name: (identifier) 162 | (character_literal 163 | (escape_sequence))))) 164 | (delegate_declaration 165 | type: (predefined_type) 166 | name: (identifier) 167 | type_parameters: (type_parameter_list 168 | (type_parameter 169 | name: (identifier))) 170 | parameters: (parameter_list) 171 | (type_parameter_constraints_clause 172 | (identifier) 173 | (type_parameter_constraint))) 174 | (delegate_declaration 175 | type: (predefined_type) 176 | name: (identifier) 177 | parameters: (parameter_list 178 | type: (array_type 179 | type: (predefined_type) 180 | rank: (array_rank_specifier)) 181 | name: (identifier))) 182 | (class_declaration 183 | name: (identifier) 184 | body: (declaration_list 185 | (delegate_declaration 186 | type: (predefined_type) 187 | name: (identifier) 188 | parameters: (parameter_list))))) 189 | -------------------------------------------------------------------------------- /test/corpus/structs.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Struct with a type parameter struct constraint 3 | ================================================================================ 4 | 5 | public struct F where T:struct {} 6 | 7 | public struct F where T: new() {} 8 | 9 | readonly public struct A : ISomething { } 10 | 11 | private struct F where T1 : I1, I2, new() where T2 : I2 { } 12 | 13 | ref struct Test { } 14 | 15 | struct NoBody; 16 | 17 | private struct NoBodyWithPrimary(int g); 18 | -------------------------------------------------------------------------------- 19 | 20 | (compilation_unit 21 | (struct_declaration 22 | (modifier) 23 | name: (identifier) 24 | (type_parameter_list 25 | (type_parameter 26 | name: (identifier))) 27 | (type_parameter_constraints_clause 28 | (identifier) 29 | (type_parameter_constraint)) 30 | body: (declaration_list)) 31 | (struct_declaration 32 | (modifier) 33 | name: (identifier) 34 | (type_parameter_list 35 | (type_parameter 36 | name: (identifier))) 37 | (type_parameter_constraints_clause 38 | (identifier) 39 | (type_parameter_constraint 40 | (constructor_constraint))) 41 | body: (declaration_list)) 42 | (struct_declaration 43 | (modifier) 44 | (modifier) 45 | name: (identifier) 46 | (base_list 47 | (identifier)) 48 | body: (declaration_list)) 49 | (struct_declaration 50 | (modifier) 51 | name: (identifier) 52 | (type_parameter_list 53 | (type_parameter 54 | name: (identifier)) 55 | (type_parameter 56 | name: (identifier))) 57 | (type_parameter_constraints_clause 58 | (identifier) 59 | (type_parameter_constraint 60 | type: (identifier)) 61 | (type_parameter_constraint 62 | type: (identifier)) 63 | (type_parameter_constraint 64 | (constructor_constraint))) 65 | (type_parameter_constraints_clause 66 | (identifier) 67 | (type_parameter_constraint 68 | type: (identifier))) 69 | body: (declaration_list)) 70 | (struct_declaration 71 | name: (identifier) 72 | body: (declaration_list)) 73 | (struct_declaration 74 | name: (identifier)) 75 | (struct_declaration 76 | (modifier) 77 | name: (identifier) 78 | (parameter_list 79 | (parameter 80 | type: (predefined_type) 81 | name: (identifier))))) 82 | -------------------------------------------------------------------------------- /test/corpus/type-events.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Class event declarations 3 | ================================================================================ 4 | 5 | class A { 6 | public event EventHandler SomeEvent { add { } remove { } } 7 | } 8 | 9 | struct A { 10 | public event EventHandler SomeEvent { add { } remove { } } 11 | } 12 | 13 | class A { 14 | public event EventHandler SomeEvent { add => addSomething(); remove => removeSomething(); } 15 | } 16 | 17 | -------------------------------------------------------------------------------- 18 | 19 | (compilation_unit 20 | (class_declaration 21 | name: (identifier) 22 | body: (declaration_list 23 | (event_declaration 24 | (modifier) 25 | type: (generic_name 26 | (identifier) 27 | (type_argument_list 28 | (identifier))) 29 | name: (identifier) 30 | accessors: (accessor_list 31 | (accessor_declaration 32 | body: (block)) 33 | (accessor_declaration 34 | body: (block)))))) 35 | (struct_declaration 36 | name: (identifier) 37 | body: (declaration_list 38 | (event_declaration 39 | (modifier) 40 | type: (generic_name 41 | (identifier) 42 | (type_argument_list 43 | (identifier))) 44 | name: (identifier) 45 | accessors: (accessor_list 46 | (accessor_declaration 47 | body: (block)) 48 | (accessor_declaration 49 | body: (block)))))) 50 | (class_declaration 51 | name: (identifier) 52 | body: (declaration_list 53 | (event_declaration 54 | (modifier) 55 | type: (identifier) 56 | name: (identifier) 57 | accessors: (accessor_list 58 | (accessor_declaration 59 | body: (arrow_expression_clause 60 | (invocation_expression 61 | function: (identifier) 62 | arguments: (argument_list)))) 63 | (accessor_declaration 64 | body: (arrow_expression_clause 65 | (invocation_expression 66 | function: (identifier) 67 | arguments: (argument_list))))))))) 68 | -------------------------------------------------------------------------------- /test/corpus/type-fields.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Class field declarations 3 | ================================================================================ 4 | 5 | class A { 6 | public readonly int _B; 7 | Int64 D_e_f, g; 8 | Tuple> z; 9 | 10 | public readonly int? i; 11 | private Byte? b; 12 | 13 | public readonly int* i; 14 | private Byte* b; 15 | private void* c; 16 | 17 | // Function pointer equivalent without calling convention 18 | delegate* a; 19 | delegate*, delegate*> b; 20 | 21 | // Function pointer equivalent with calling convention 22 | delegate* managed c; 23 | delegate*, delegate*> d; 24 | 25 | ref readonly Point Origin => ref origin; 26 | ref readonly Point* Origin; 27 | ref readonly Point[] Origin; 28 | ref readonly Point? Origin; 29 | 30 | (int, string str) a; 31 | (B b, C c, D d) a; 32 | 33 | nint a; 34 | nuint b; 35 | 36 | public required int B; 37 | } 38 | 39 | struct A { 40 | private readonly int c_; 41 | } 42 | 43 | -------------------------------------------------------------------------------- 44 | 45 | (compilation_unit 46 | (class_declaration 47 | name: (identifier) 48 | body: (declaration_list 49 | (field_declaration 50 | (modifier) 51 | (modifier) 52 | (variable_declaration 53 | type: (predefined_type) 54 | (variable_declarator 55 | name: (identifier)))) 56 | (field_declaration 57 | (variable_declaration 58 | type: (identifier) 59 | (variable_declarator 60 | name: (identifier)) 61 | (variable_declarator 62 | name: (identifier)))) 63 | (field_declaration 64 | (variable_declaration 65 | type: (generic_name 66 | (identifier) 67 | (type_argument_list 68 | (predefined_type) 69 | (generic_name 70 | (identifier) 71 | (type_argument_list 72 | (predefined_type))))) 73 | (variable_declarator 74 | name: (identifier)))) 75 | (field_declaration 76 | (modifier) 77 | (modifier) 78 | (variable_declaration 79 | type: (nullable_type 80 | type: (predefined_type)) 81 | (variable_declarator 82 | name: (identifier)))) 83 | (field_declaration 84 | (modifier) 85 | (variable_declaration 86 | type: (nullable_type 87 | type: (identifier)) 88 | (variable_declarator 89 | name: (identifier)))) 90 | (field_declaration 91 | (modifier) 92 | (modifier) 93 | (variable_declaration 94 | type: (pointer_type 95 | type: (predefined_type)) 96 | (variable_declarator 97 | name: (identifier)))) 98 | (field_declaration 99 | (modifier) 100 | (variable_declaration 101 | type: (pointer_type 102 | type: (identifier)) 103 | (variable_declarator 104 | name: (identifier)))) 105 | (field_declaration 106 | (modifier) 107 | (variable_declaration 108 | type: (pointer_type 109 | type: (predefined_type)) 110 | (variable_declarator 111 | name: (identifier)))) 112 | (comment) 113 | (field_declaration 114 | (variable_declaration 115 | type: (function_pointer_type 116 | (function_pointer_parameter 117 | type: (predefined_type)) 118 | returns: (predefined_type)) 119 | (variable_declarator 120 | name: (identifier)))) 121 | (field_declaration 122 | (variable_declaration 123 | type: (function_pointer_type 124 | (function_pointer_parameter 125 | type: (function_pointer_type 126 | (function_pointer_parameter 127 | type: (predefined_type)) 128 | returns: (predefined_type))) 129 | returns: (function_pointer_type 130 | (function_pointer_parameter 131 | type: (predefined_type)) 132 | returns: (ref_type 133 | type: (predefined_type)))) 134 | (variable_declarator 135 | name: (identifier)))) 136 | (comment) 137 | (field_declaration 138 | (variable_declaration 139 | type: (function_pointer_type 140 | (calling_convention) 141 | (function_pointer_parameter 142 | type: (predefined_type)) 143 | returns: (predefined_type)) 144 | (variable_declarator 145 | name: (identifier)))) 146 | (field_declaration 147 | (variable_declaration 148 | type: (function_pointer_type 149 | (function_pointer_parameter 150 | type: (function_pointer_type 151 | (calling_convention 152 | (identifier) 153 | (identifier)) 154 | (function_pointer_parameter 155 | type: (predefined_type)) 156 | returns: (predefined_type))) 157 | returns: (function_pointer_type 158 | (function_pointer_parameter 159 | type: (predefined_type)) 160 | returns: (predefined_type))) 161 | (variable_declarator 162 | name: (identifier)))) 163 | (property_declaration 164 | type: (ref_type 165 | type: (identifier)) 166 | name: (identifier) 167 | value: (arrow_expression_clause 168 | (ref_expression 169 | (identifier)))) 170 | (field_declaration 171 | (variable_declaration 172 | type: (ref_type 173 | type: (pointer_type 174 | type: (identifier))) 175 | (variable_declarator 176 | name: (identifier)))) 177 | (field_declaration 178 | (variable_declaration 179 | type: (ref_type 180 | type: (array_type 181 | type: (identifier) 182 | rank: (array_rank_specifier))) 183 | (variable_declarator 184 | name: (identifier)))) 185 | (field_declaration 186 | (variable_declaration 187 | type: (ref_type 188 | type: (nullable_type 189 | type: (identifier))) 190 | (variable_declarator 191 | name: (identifier)))) 192 | (field_declaration 193 | (variable_declaration 194 | type: (tuple_type 195 | (tuple_element 196 | type: (predefined_type)) 197 | (tuple_element 198 | type: (predefined_type) 199 | name: (identifier))) 200 | (variable_declarator 201 | name: (identifier)))) 202 | (field_declaration 203 | (variable_declaration 204 | type: (tuple_type 205 | (tuple_element 206 | type: (identifier) 207 | name: (identifier)) 208 | (tuple_element 209 | type: (identifier) 210 | name: (identifier)) 211 | (tuple_element 212 | type: (identifier) 213 | name: (identifier))) 214 | (variable_declarator 215 | name: (identifier)))) 216 | (field_declaration 217 | (variable_declaration 218 | type: (predefined_type) 219 | (variable_declarator 220 | name: (identifier)))) 221 | (field_declaration 222 | (variable_declaration 223 | type: (predefined_type) 224 | (variable_declarator 225 | name: (identifier)))) 226 | (field_declaration 227 | (modifier) 228 | (modifier) 229 | (variable_declaration 230 | type: (predefined_type) 231 | (variable_declarator 232 | name: (identifier)))))) 233 | (struct_declaration 234 | name: (identifier) 235 | body: (declaration_list 236 | (field_declaration 237 | (modifier) 238 | (modifier) 239 | (variable_declaration 240 | type: (predefined_type) 241 | (variable_declarator 242 | name: (identifier))))))) 243 | -------------------------------------------------------------------------------- /test/corpus/type-methods.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Class method with single parameter 3 | ================================================================================ 4 | 5 | class A { 6 | private int GetBack(int b) { 7 | return b; 8 | } 9 | 10 | void Accept(T accept) { 11 | } 12 | 13 | void Accept(T accept) where T: new() { 14 | } 15 | 16 | void Accept(T1 accept, T2 from) 17 | where T1: new() 18 | where T2: T1, new() { 19 | } 20 | 21 | void HasAnOut(out int a) { 22 | } 23 | 24 | void HasAnIn(in int a) { 25 | } 26 | 27 | void HasARef(ref int a) { 28 | } 29 | 30 | void M(this ref int a) { } 31 | void M(this scoped ref int a) { } 32 | 33 | void Keywords(int from, string partial) { 34 | } 35 | 36 | void Default(int a = 5) { 37 | } 38 | 39 | static int Static(int b) { 40 | return b; 41 | } 42 | 43 | public readonly double Add => x + y; 44 | 45 | DIn dIn = (ref readonly int p) => { }; 46 | 47 | public int Zero(params int[]? ints) => 0; 48 | } 49 | 50 | class A : ISomething { 51 | int ISomething.GetBack(int b) { 52 | return b; 53 | } 54 | } 55 | 56 | ref struct S { 57 | void M(scoped ref System.Span p) { 58 | scoped ref System.Span i = ref p; 59 | scoped System.Span j = p; 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- 64 | 65 | (compilation_unit 66 | (class_declaration 67 | name: (identifier) 68 | body: (declaration_list 69 | (method_declaration 70 | (modifier) 71 | returns: (predefined_type) 72 | name: (identifier) 73 | parameters: (parameter_list 74 | (parameter 75 | type: (predefined_type) 76 | name: (identifier))) 77 | body: (block 78 | (return_statement 79 | (identifier)))) 80 | (method_declaration 81 | returns: (predefined_type) 82 | name: (identifier) 83 | type_parameters: (type_parameter_list 84 | (type_parameter 85 | name: (identifier))) 86 | parameters: (parameter_list 87 | (parameter 88 | type: (identifier) 89 | name: (identifier))) 90 | body: (block)) 91 | (method_declaration 92 | returns: (predefined_type) 93 | name: (identifier) 94 | type_parameters: (type_parameter_list 95 | (type_parameter 96 | name: (identifier))) 97 | parameters: (parameter_list 98 | (parameter 99 | type: (identifier) 100 | name: (identifier))) 101 | (type_parameter_constraints_clause 102 | (identifier) 103 | (type_parameter_constraint 104 | (constructor_constraint))) 105 | body: (block)) 106 | (method_declaration 107 | returns: (predefined_type) 108 | name: (identifier) 109 | type_parameters: (type_parameter_list 110 | (type_parameter 111 | name: (identifier)) 112 | (type_parameter 113 | name: (identifier))) 114 | parameters: (parameter_list 115 | (parameter 116 | type: (identifier) 117 | name: (identifier)) 118 | (parameter 119 | type: (identifier) 120 | name: (identifier))) 121 | (type_parameter_constraints_clause 122 | (identifier) 123 | (type_parameter_constraint 124 | (constructor_constraint))) 125 | (type_parameter_constraints_clause 126 | (identifier) 127 | (type_parameter_constraint 128 | type: (identifier)) 129 | (type_parameter_constraint 130 | (constructor_constraint))) 131 | body: (block)) 132 | (method_declaration 133 | returns: (predefined_type) 134 | name: (identifier) 135 | parameters: (parameter_list 136 | (parameter 137 | (modifier) 138 | type: (predefined_type) 139 | name: (identifier))) 140 | body: (block)) 141 | (method_declaration 142 | returns: (predefined_type) 143 | name: (identifier) 144 | parameters: (parameter_list 145 | (parameter 146 | (modifier) 147 | type: (predefined_type) 148 | name: (identifier))) 149 | body: (block)) 150 | (method_declaration 151 | returns: (predefined_type) 152 | name: (identifier) 153 | parameters: (parameter_list 154 | (parameter 155 | (modifier) 156 | type: (predefined_type) 157 | name: (identifier))) 158 | body: (block)) 159 | (method_declaration 160 | returns: (predefined_type) 161 | name: (identifier) 162 | parameters: (parameter_list 163 | (parameter 164 | (modifier) 165 | (modifier) 166 | type: (predefined_type) 167 | name: (identifier))) 168 | body: (block)) 169 | (method_declaration 170 | returns: (predefined_type) 171 | name: (identifier) 172 | parameters: (parameter_list 173 | (parameter 174 | (modifier) 175 | (modifier) 176 | (modifier) 177 | type: (predefined_type) 178 | name: (identifier))) 179 | body: (block)) 180 | (method_declaration 181 | returns: (predefined_type) 182 | name: (identifier) 183 | parameters: (parameter_list 184 | (parameter 185 | type: (predefined_type) 186 | name: (identifier)) 187 | (parameter 188 | type: (predefined_type) 189 | name: (identifier))) 190 | body: (block)) 191 | (method_declaration 192 | returns: (predefined_type) 193 | name: (identifier) 194 | parameters: (parameter_list 195 | (parameter 196 | type: (predefined_type) 197 | name: (identifier) 198 | (integer_literal))) 199 | body: (block)) 200 | (method_declaration 201 | (modifier) 202 | returns: (predefined_type) 203 | name: (identifier) 204 | parameters: (parameter_list 205 | (parameter 206 | type: (predefined_type) 207 | name: (identifier))) 208 | body: (block 209 | (return_statement 210 | (identifier)))) 211 | (property_declaration 212 | (modifier) 213 | (modifier) 214 | type: (predefined_type) 215 | name: (identifier) 216 | value: (arrow_expression_clause 217 | (binary_expression 218 | left: (identifier) 219 | right: (identifier)))) 220 | (field_declaration 221 | (variable_declaration 222 | type: (identifier) 223 | (variable_declarator 224 | name: (identifier) 225 | (lambda_expression 226 | parameters: (parameter_list 227 | (parameter 228 | (modifier) 229 | (modifier) 230 | type: (predefined_type) 231 | name: (identifier))) 232 | body: (block))))) 233 | (method_declaration 234 | (modifier) 235 | returns: (predefined_type) 236 | name: (identifier) 237 | parameters: (parameter_list 238 | type: (nullable_type 239 | type: (array_type 240 | type: (predefined_type) 241 | rank: (array_rank_specifier))) 242 | name: (identifier)) 243 | body: (arrow_expression_clause 244 | (integer_literal))))) 245 | (class_declaration 246 | name: (identifier) 247 | (base_list 248 | (identifier)) 249 | body: (declaration_list 250 | (method_declaration 251 | returns: (predefined_type) 252 | (explicit_interface_specifier 253 | (identifier)) 254 | name: (identifier) 255 | parameters: (parameter_list 256 | (parameter 257 | type: (predefined_type) 258 | name: (identifier))) 259 | body: (block 260 | (return_statement 261 | (identifier)))))) 262 | (struct_declaration 263 | name: (identifier) 264 | body: (declaration_list 265 | (method_declaration 266 | returns: (predefined_type) 267 | name: (identifier) 268 | parameters: (parameter_list 269 | (parameter 270 | (modifier) 271 | (modifier) 272 | type: (qualified_name 273 | qualifier: (identifier) 274 | name: (generic_name 275 | (identifier) 276 | (type_argument_list 277 | (predefined_type)))) 278 | name: (identifier))) 279 | body: (block 280 | (local_declaration_statement 281 | (variable_declaration 282 | type: (scoped_type 283 | type: (ref_type 284 | type: (qualified_name 285 | qualifier: (identifier) 286 | name: (generic_name 287 | (identifier) 288 | (type_argument_list 289 | (predefined_type)))))) 290 | (variable_declarator 291 | name: (identifier) 292 | (ref_expression 293 | (identifier))))) 294 | (local_declaration_statement 295 | (variable_declaration 296 | type: (scoped_type 297 | type: (qualified_name 298 | qualifier: (identifier) 299 | name: (generic_name 300 | (identifier) 301 | (type_argument_list 302 | (predefined_type))))) 303 | (variable_declarator 304 | name: (identifier) 305 | (identifier))))))))) 306 | -------------------------------------------------------------------------------- /test/corpus/type-properties.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Class with bodyless properties 3 | ================================================================================ 4 | 5 | class Foo { 6 | byte Get { get; } 7 | char Set { set; } 8 | uint GetSet { get; set; } 9 | long SetGet { set; get; } 10 | 11 | public string FirstName { get; init; } 12 | 13 | byte Get { get { return 0xFF; } } 14 | char Set { set { x = value; } } 15 | } 16 | 17 | class Foo { 18 | uint GetSet { 19 | get { return x; } 20 | set { x = value; } 21 | } 22 | long SetGet { 23 | set { x = value; } 24 | get { return x; } 25 | } 26 | 27 | byte Get { get; } = 0x00; 28 | uint GetSet { get; set; } = 1; 29 | long SetGet { set; get; } = 2; 30 | } 31 | 32 | class Foo: IFoo { 33 | byte IFoo.Get { get; } 34 | public required int B { get; set; } 35 | } 36 | 37 | -------------------------------------------------------------------------------- 38 | 39 | (compilation_unit 40 | (class_declaration 41 | name: (identifier) 42 | body: (declaration_list 43 | (property_declaration 44 | type: (predefined_type) 45 | name: (identifier) 46 | accessors: (accessor_list 47 | (accessor_declaration))) 48 | (property_declaration 49 | type: (predefined_type) 50 | name: (identifier) 51 | accessors: (accessor_list 52 | (accessor_declaration))) 53 | (property_declaration 54 | type: (predefined_type) 55 | name: (identifier) 56 | accessors: (accessor_list 57 | (accessor_declaration) 58 | (accessor_declaration))) 59 | (property_declaration 60 | type: (predefined_type) 61 | name: (identifier) 62 | accessors: (accessor_list 63 | (accessor_declaration) 64 | (accessor_declaration))) 65 | (property_declaration 66 | (modifier) 67 | type: (predefined_type) 68 | name: (identifier) 69 | accessors: (accessor_list 70 | (accessor_declaration) 71 | (accessor_declaration))) 72 | (property_declaration 73 | type: (predefined_type) 74 | name: (identifier) 75 | accessors: (accessor_list 76 | (accessor_declaration 77 | body: (block 78 | (return_statement 79 | (integer_literal)))))) 80 | (property_declaration 81 | type: (predefined_type) 82 | name: (identifier) 83 | accessors: (accessor_list 84 | (accessor_declaration 85 | body: (block 86 | (expression_statement 87 | (assignment_expression 88 | left: (identifier) 89 | right: (identifier))))))))) 90 | (class_declaration 91 | name: (identifier) 92 | body: (declaration_list 93 | (property_declaration 94 | type: (predefined_type) 95 | name: (identifier) 96 | accessors: (accessor_list 97 | (accessor_declaration 98 | body: (block 99 | (return_statement 100 | (identifier)))) 101 | (accessor_declaration 102 | body: (block 103 | (expression_statement 104 | (assignment_expression 105 | left: (identifier) 106 | right: (identifier))))))) 107 | (property_declaration 108 | type: (predefined_type) 109 | name: (identifier) 110 | accessors: (accessor_list 111 | (accessor_declaration 112 | body: (block 113 | (expression_statement 114 | (assignment_expression 115 | left: (identifier) 116 | right: (identifier))))) 117 | (accessor_declaration 118 | body: (block 119 | (return_statement 120 | (identifier)))))) 121 | (property_declaration 122 | type: (predefined_type) 123 | name: (identifier) 124 | accessors: (accessor_list 125 | (accessor_declaration)) 126 | value: (integer_literal)) 127 | (property_declaration 128 | type: (predefined_type) 129 | name: (identifier) 130 | accessors: (accessor_list 131 | (accessor_declaration) 132 | (accessor_declaration)) 133 | value: (integer_literal)) 134 | (property_declaration 135 | type: (predefined_type) 136 | name: (identifier) 137 | accessors: (accessor_list 138 | (accessor_declaration) 139 | (accessor_declaration)) 140 | value: (integer_literal)))) 141 | (class_declaration 142 | name: (identifier) 143 | (base_list 144 | (identifier)) 145 | body: (declaration_list 146 | (property_declaration 147 | type: (predefined_type) 148 | (explicit_interface_specifier 149 | (identifier)) 150 | name: (identifier) 151 | accessors: (accessor_list 152 | (accessor_declaration))) 153 | (property_declaration 154 | (modifier) 155 | (modifier) 156 | type: (predefined_type) 157 | name: (identifier) 158 | accessors: (accessor_list 159 | (accessor_declaration) 160 | (accessor_declaration)))))) 161 | -------------------------------------------------------------------------------- /test/highlight/operators.cs: -------------------------------------------------------------------------------- 1 | using Namespace; 2 | 3 | class C 4 | { 5 | void M() 6 | { 7 | // unary 8 | a = +a; 9 | // ^ operator 10 | a = -a; 11 | // ^ operator 12 | a = !a; 13 | // ^ operator 14 | a = ~a; 15 | // ^ operator 16 | a = ++a; 17 | // ^ operator 18 | a = --a; 19 | // ^ operator 20 | a = a++; 21 | // ^ operator 22 | a = a--; 23 | // ^ operator 24 | a = a!; 25 | // ^ operator 26 | a = a++; 27 | // ^ operator 28 | a = a--; 29 | // ^ operator 30 | 31 | // binary 32 | a = a + a; 33 | // ^ operator 34 | a = a - a; 35 | // ^ operator 36 | a = a * a; 37 | // ^ operator 38 | a = a / a; 39 | // ^ operator 40 | a = a % a; 41 | // ^ operator 42 | a = a & a; 43 | // ^ operator 44 | a = a | a; 45 | // ^ operator 46 | a = a ^ a; 47 | // ^ operator 48 | a = a >> a; 49 | // ^ operator 50 | a = a << a; 51 | // ^ operator 52 | a = a >>> a; 53 | // ^ operator 54 | 55 | a = a == b; 56 | // ^ operator 57 | a = a != b; 58 | // ^ operator 59 | a = a < b; 60 | // ^ operator 61 | a = a <= b; 62 | // ^ operator 63 | a = a > b; 64 | // ^ operator 65 | a = a >= b; 66 | // ^ operator 67 | 68 | // assignment binary 69 | a += a; 70 | //^ operator 71 | a -= a; 72 | //^ operator 73 | a *= a; 74 | //^ operator 75 | a /= a; 76 | //^ operator 77 | a %= a; 78 | //^ operator 79 | a <<= a; 80 | //^ operator 81 | a >>= a; 82 | //^ operator 83 | a >>>= a; 84 | //^ operator 85 | 86 | // ternary 87 | string y = x ? "foo" : "bar"; 88 | // ^ operator 89 | // ^ operator 90 | 91 | // misc 92 | var l = (int i) => i; 93 | // ^ operator 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /test/highlight/types.cs: -------------------------------------------------------------------------------- 1 | class A : B, C 2 | // ^ type 3 | // ^ type 4 | // ^ type 5 | { 6 | public void M() 7 | { 8 | int a; 9 | // <- type.builtin 10 | var a; 11 | // <- keyword 12 | 13 | int? a; 14 | // <- type.builtin 15 | // ^ operator 16 | A? a; 17 | // <- type 18 | // <- operator 19 | 20 | int* a; 21 | // <- type.builtin 22 | // ^ operator 23 | A* a; 24 | // <- type 25 | // <- operator 26 | 27 | ref A* a; 28 | // <- keyword 29 | // ^ type 30 | // ^ operator 31 | 32 | var a = x is int; 33 | // ^ type.builtin 34 | var a = x is A; 35 | // ^ 36 | 37 | var a = x as int; 38 | // ^ type.builtin 39 | var a = x as A; 40 | // ^ type 41 | 42 | var a = (int)x; 43 | // ^ type.builtin 44 | var a = (A)x; 45 | // ^ type 46 | 47 | A a = new A(); 48 | // <- type 49 | //^ type.builtin 50 | // ^ type 51 | // ^ type 52 | // ^ type.builtin 53 | // ^ type 54 | } 55 | } 56 | 57 | record A(int a, B b) : B(), I; 58 | // ^ type 59 | // ^ type.builtin 60 | // ^ type 61 | // ^ type 62 | // ^ type 63 | 64 | record A : B, I; 65 | // ^ type 66 | // ^ type 67 | // ^ type 68 | -------------------------------------------------------------------------------- /test/highlight/var.cs: -------------------------------------------------------------------------------- 1 | class var 2 | // ^ type 3 | { 4 | void M() 5 | { 6 | var var = new var(); 7 | // <- keyword 8 | // ^ variable 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/highlight/variableDeclarations.cs: -------------------------------------------------------------------------------- 1 | class A 2 | { 3 | public void M() 4 | { 5 | foreach (int i in new[] { 1 }) 6 | // ^ variable 7 | { 8 | int j = i; 9 | // ^ variable 10 | } 11 | 12 | var x = from a in sourceA 13 | // ^ variable 14 | // ^ variable 15 | join b in sourceB on a.FK equals b.PK 16 | // ^ variable 17 | // ^ variable 18 | group a by a.X into g 19 | // ^ variable 20 | // ^ variable 21 | orderby g ascending 22 | // ^ variable 23 | select new { A.A, B.B }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/queries/identifiers.cs: -------------------------------------------------------------------------------- 1 | namespace World 2 | { 3 | class Hello { 4 | static void Main(string []args) 5 | { 6 | Hello x = new Hello(); 7 | System.Console.WriteLine("Hello, world."); 8 | } 9 | } 10 | 11 | interface Blah { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tools/highlight-test-generator/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ -------------------------------------------------------------------------------- /tools/highlight-test-generator/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | // Use IntelliSense to find out which attributes exist for C# debugging 6 | // Use hover for the description of the existing attributes 7 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 8 | "name": ".NET Core Launch (console)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/bin/Debug/net6.0/Generator.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}", 16 | // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console 17 | "console": "internalConsole", 18 | "stopAtEntry": false 19 | }, 20 | { 21 | "name": ".NET Core Attach", 22 | "type": "coreclr", 23 | "request": "attach" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /tools/highlight-test-generator/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/Generator.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/Generator.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "--project", 36 | "${workspaceFolder}/Generator.csproj" 37 | ], 38 | "problemMatcher": "$msCompile" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /tools/highlight-test-generator/Generator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text.RegularExpressions; 7 | 8 | if (args.Length != 1) 9 | { 10 | Console.WriteLine("Add the path to the file as an argument. The path needs to be fully qualified and point to an existing file in [REPO ROOT]/test/highlight."); 11 | return; 12 | } 13 | 14 | var filePath = args[0]; 15 | 16 | // Some basic tests on the path, so that we have a chance: 17 | if (!filePath.Contains("/test/highlight/") || 18 | !filePath.EndsWith(".cs") || 19 | !File.Exists(filePath) || 20 | !Path.IsPathFullyQualified(filePath)) 21 | { 22 | Console.WriteLine("The file needs to exist in [REPO ROOT]/test/highlight, and the path needs to be fully qualified."); 23 | return; 24 | } 25 | 26 | // Random variable name prefix, so that we don't accidentally replace something in the file: 27 | var idPrefix = "a" + new Random(filePath.GetHashCode()).NextInt64(10000000) + "_"; 28 | 29 | var originalLines = File.ReadAllLines(filePath); 30 | 31 | 32 | /// 33 | /// Adds tree-sitter highlighting comments to the input file. 34 | /// Comments start with either `// <-` or `// ^`, depending on the position of the hiughlighted token. 35 | /// For highlight category, a unique random identifier is used. 36 | /// 37 | void AddCommentsToFile() 38 | { 39 | var newLines = new List(); 40 | var index = 0; 41 | 42 | foreach (var line in originalLines) 43 | { 44 | newLines.Add(line); 45 | 46 | var leadingWhitespaces = line[..^line.TrimStart().Length]; 47 | var first = true; 48 | 49 | var position = leadingWhitespaces.Length; 50 | while (position < line.Length) 51 | { 52 | var ch = line[position]; 53 | 54 | bool HandleToken(Func isOfType) 55 | { 56 | if (!isOfType(ch)) 57 | { 58 | return false; 59 | } 60 | 61 | var variable = $"{idPrefix}{index++}"; 62 | if (first) 63 | { 64 | newLines.Add($"{leadingWhitespaces}// <- {variable}"); 65 | first = false; 66 | } 67 | else 68 | { 69 | var spacesLength = position - leadingWhitespaces.Length - 2; 70 | if (spacesLength < 0) 71 | { 72 | // Handle case when the first two characters need different highlight categories: 73 | // Shift // by one space to the right. 74 | newLines.Add($"{leadingWhitespaces} // <- {variable}"); 75 | } 76 | else 77 | { 78 | var spaces = new string(' ', position - leadingWhitespaces.Length - 2); 79 | newLines.Add($"{leadingWhitespaces}//{spaces}^ {variable}"); 80 | } 81 | } 82 | 83 | while (position < line.Length && isOfType(line[position])) 84 | { 85 | position++; 86 | } 87 | 88 | return true; 89 | } 90 | 91 | // The below char methods are not exactly what we need for token parsing, but good enough. 92 | // For example 93 | // - `_abc` is an identifier, but has both letter and punctuation characters. 94 | // - string literals are parsed pretty badly, considering they can have all sorts of characters, even spaces, on which we split. 95 | if (!HandleToken(char.IsLetterOrDigit) && 96 | !HandleToken(c => char.IsPunctuation(c) || char.IsSymbol(c))) 97 | { 98 | position++; 99 | } 100 | } 101 | } 102 | 103 | File.WriteAllLines(filePath, newLines.ToArray()); 104 | } 105 | 106 | string GetHighlighterOutput() 107 | { 108 | var process = new Process 109 | { 110 | StartInfo = new ProcessStartInfo 111 | { 112 | FileName = "tree-sitter", 113 | Arguments = $"test --filter skip-all-corpus-tests", 114 | UseShellExecute = false, 115 | RedirectStandardOutput = true, 116 | WorkingDirectory = Path.GetFullPath(Path.Combine(filePath, "..", "..", "..")), 117 | 118 | } 119 | }; 120 | process.Start(); 121 | var output = process.StandardOutput.ReadToEnd(); 122 | process.WaitForExit(); 123 | 124 | return output; 125 | } 126 | 127 | var regexWithHighlight = new Regex($@"Failure - row: \d+, column: \d+, expected highlight '{idPrefix}(\d+)', actual highlights: '(.*)'", RegexOptions.Compiled); 128 | var regexWithNone = new Regex($@"Failure - row: \d+, column: \d+, expected highlight '{idPrefix}(\d+)', actual highlights: none.", RegexOptions.Compiled); 129 | 130 | /// 131 | /// Runs the tree-sitter test command, and tries to find a single highlighting failure. 132 | /// If a failure is found, the category is extracted from the output, and the corresponding variable is replaced with the category. 133 | /// 134 | bool FindAndFixHighlightFailure() 135 | { 136 | Console.Write("."); 137 | var output = GetHighlighterOutput(); 138 | 139 | if (output.IndexOf("✗") != output.LastIndexOf("✗")) 140 | { 141 | Console.WriteLine("\nThe tree-sitter test execution identified multiple files with failed highlighting. Aborting."); 142 | File.WriteAllLines(filePath, originalLines); 143 | Environment.Exit(1); 144 | } 145 | 146 | var match = regexWithHighlight.Match(output); 147 | if (match.Success && match.Groups.Count == 3) 148 | { 149 | // Highlight found for position, so replace with expected category. 150 | var variableCat = $"{idPrefix}{match.Groups[1].Captures[0].Value}"; 151 | var category = match.Groups[2].Captures[0].Value; 152 | File.WriteAllText(filePath, File.ReadAllText(filePath).Replace(variableCat + "\n", category + "\n")); 153 | return true; 154 | } 155 | 156 | match = regexWithNone.Match(output); 157 | if (!match.Success || match.Groups.Count != 2) 158 | { 159 | // Couldn't match any of the expected patterns. 160 | return false; 161 | } 162 | 163 | // No highlight found for position, so remove entire line. 164 | var variableNone = $"{idPrefix}{match.Groups[1].Captures[0].Value}"; 165 | var lines = File.ReadAllLines(filePath).Where(line => !line.EndsWith(variableNone)).ToArray(); 166 | File.WriteAllLines(filePath, lines); 167 | return true; 168 | } 169 | 170 | AddCommentsToFile(); 171 | 172 | Console.WriteLine("Calling tree-sitter highlighter several times. This might take a while."); 173 | while (FindAndFixHighlightFailure()) 174 | { } 175 | Console.WriteLine(""); 176 | Console.WriteLine("Done modifying the input file. It may require some manual cleanup."); 177 | 178 | -------------------------------------------------------------------------------- /tools/highlight-test-generator/Generator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | net6.0 5 | 6 | -------------------------------------------------------------------------------- /tools/highlight-test-generator/run-generator: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ROOT="$(git rev-parse --show-toplevel)" 4 | echo $ROOT/tools/highlight-test-generator/Generator.csproj 5 | dotnet run --project $ROOT/tools/highlight-test-generator/Generator.csproj $1 -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "c-sharp", 5 | "camelcase": "CSharp", 6 | "scope": "source.cs", 7 | "path": ".", 8 | "file-types": [ 9 | "cs" 10 | ], 11 | "highlights": [ 12 | "queries/highlights.scm" 13 | ], 14 | "tags": [ 15 | "queries/tags.scm" 16 | ], 17 | "injection-regex": "cs" 18 | } 19 | ], 20 | "metadata": { 21 | "version": "0.23.1", 22 | "license": "MIT", 23 | "description": "C# grammar for tree-sitter", 24 | "authors": [ 25 | { 26 | "name": "Max Brunsfeld", 27 | "email": "maxbrunsfeld@gmail.com" 28 | }, 29 | { 30 | "name": "Amaan Qureshi", 31 | "email": "amaanq12@gmail.com" 32 | }, 33 | { 34 | "name": "Damien Guard", 35 | "email": "damieng@gmail.com" 36 | } 37 | ], 38 | "links": { 39 | "repository": "https://github.com/tree-sitter/tree-sitter-c-sharp" 40 | } 41 | }, 42 | "bindings": { 43 | "c": true, 44 | "go": true, 45 | "node": true, 46 | "python": true, 47 | "rust": true, 48 | "swift": true 49 | } 50 | } 51 | --------------------------------------------------------------------------------