@willbooster/tree-sitter-c-sharp 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,14 +5,15 @@
5
5
  [![Test](https://github.com/WillBooster/tree-sitter-c-sharp/actions/workflows/test.yml/badge.svg)](https://github.com/WillBooster/tree-sitter-c-sharp/actions/workflows/test.yml)
6
6
  [![Test rust](https://github.com/WillBooster/tree-sitter-c-sharp/actions/workflows/test-rust.yml/badge.svg)](https://github.com/WillBooster/tree-sitter-c-sharp/actions/workflows/test-rust.yml)
7
7
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
8
- [![wbfy](https://img.shields.io/badge/wbfy-20.26.0-1e90ff.svg)](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
8
+ [![wbfy](https://img.shields.io/badge/wbfy-20.28.6-1e90ff.svg)](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
9
9
  [![crates.io](https://img.shields.io/crates/v/willbooster-tree-sitter-c-sharp.svg)](https://crates.io/crates/willbooster-tree-sitter-c-sharp)
10
10
 
11
11
  C# grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter), forked from
12
12
  [tree-sitter/tree-sitter-c-sharp](https://github.com/tree-sitter/tree-sitter-c-sharp). We are grateful
13
13
  to its authors and contributors. This is not an official release of that project.
14
14
 
15
- This fork fixes parsing bugs and raises conformance with the [C# language specification](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/readme).
15
+ This fork fixes parsing bugs and raises conformance with the
16
+ [C# language specification](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/readme).
16
17
 
17
18
  The grammar is based upon the Roslyn grammar with changes in order to:
18
19
 
@@ -75,7 +76,7 @@ const parser = new Parser();
75
76
  parser.setLanguage(await Language.load(cSharp));
76
77
  ```
77
78
 
78
- The package also ships the node types in `src/node-types.json`.
79
+ The package also ships the queries in `queries/` and the node types in `src/node-types.json`.
79
80
 
80
81
  In Rust, depend on the [crate](https://crates.io/crates/willbooster-tree-sitter-c-sharp) and on
81
82
  [willbooster-tree-sitter](https://crates.io/crates/willbooster-tree-sitter), the runtime this package is tested and
@@ -104,25 +105,38 @@ script/parse-examples
104
105
  cargo test
105
106
  ```
106
107
 
108
+ `script/tree-sitter` (also `bun run tree-sitter`) runs the tree-sitter CLI of WillBooster/tree-sitter at the runtime
109
+ version locked in `Cargo.lock`, so the parser is generated, built, tested, and fuzzed with the generator and the
110
+ runtime this package ships. The first run downloads that CLI from its GitHub Release into `.tmp/`, or builds it with
111
+ `cargo` (with the `cmake` that `mise.toml` pins) when the download fails or the release has no binary that runs here. The `tree-sitter-cli` package provides
112
+ only the types of the grammar DSL that `grammar.js` checks against; its `tree-sitter` binary is upstream's.
113
+
107
114
  `bun run test` runs:
108
115
 
109
116
  - the corpus in `test/corpus`, with the native build and with the Wasm build (the first run downloads the WASI SDK);
110
- - an incremental-parsing check (`test/unit/incremental.test.ts`): `tree-sitter fuzz` edits each corpus case at random,
111
- reparses it, undoes the edits, and reparses again. `TREE_SITTER_SEED`, `TREE_SITTER_ITERATIONS`, and
112
- `TREE_SITTER_EDITS` run other or more edits;
117
+ - an incremental-parsing check (`test/unit/incremental.test.ts`): `script/fuzz-corpus` runs `tree-sitter fuzz`, which
118
+ edits each corpus case at random, reparses it, undoes the edits, and reparses again. `TREE_SITTER_SEED`,
119
+ `TREE_SITTER_ITERATIONS`, and `TREE_SITTER_EDITS` run other or more edits;
113
120
  - a check that the real-world C# files cloned into `examples/` fail to parse exactly as listed in
114
121
  `script/known-failures.txt`. The first run clones them. The example repositories are pinned to commits in
115
122
  `script/parse-examples`. After a grammar change or a moved pin alters that list, `script/parse-examples` rewrites
116
123
  it; review its diff before committing;
117
- - a performance check (`test/unit/performance.test.ts`) that recovering from an error on each of 10,000 lines takes
118
- linear time, since consumers parse files while they are being edited. It loads the Wasm build through
119
- @willbooster/web-tree-sitter, which `bun run build/ci` rebuilds after regenerating the parser;
124
+ - a performance check (`test/unit/performance.test.ts`) that recovering from an error on each line takes linear time
125
+ (ten times the lines take about ten times the CPU time, under a ceiling), since consumers parse files while they are
126
+ being edited. It loads the Wasm build through @willbooster/web-tree-sitter, which `bun run build/ci` rebuilds after
127
+ regenerating the parser;
128
+ - a check that `package.json` and `Cargo.lock` test the same runtime version (`test/unit/runtimeVersion.test.ts`);
120
129
  - checks that the Wasm build parses C# with @willbooster/web-tree-sitter in Chromium (`test/unit/browser.test.ts`,
121
130
  which needs Chromium installed once by `bunx playwright install chromium`) and in Cloudflare Workers with and without
122
131
  `nodejs_compat` (`test/unit/workers.test.ts`).
123
132
 
124
- `cargo test` also replays edits that `tree-sitter fuzz` found to break incremental parsing, with the
125
- willbooster-tree-sitter runtime that fixes them; `tree-sitter fuzz` itself runs the runtime built into tree-sitter-cli.
133
+ The tests and `script/parse-examples` compile the parser into `.tmp/tree-sitter-lib` rather than the CLI's cache shared
134
+ by every checkout; `script/fuzz-corpus` builds a per-run parser in `.tmp/fuzz` and deletes it afterwards. `mise.toml`
135
+ sets `TREE_SITTER_LIBDIR` to `.tmp/tree-sitter-lib` as well, so other `tree-sitter` commands run in the checkout use
136
+ this checkout's parser too.
137
+
138
+ `cargo test` also replays edits that `tree-sitter fuzz` found to break incremental parsing on runtimes without the
139
+ fixes of willbooster-tree-sitter.
126
140
 
127
141
  CI also runs these tests on Linux arm64 and macOS, where the Rust binding compiles the parser natively, and fuzzes the
128
142
  parser with libFuzzer and sanitizers on the willbooster-tree-sitter runtime locked in `Cargo.lock`
@@ -131,6 +145,7 @@ parser with libFuzzer and sanitizers on the willbooster-tree-sitter runtime lock
131
145
  ### References
132
146
 
133
147
  - [C# language specification](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/readme)
134
- - [Official C# 8 Draft Language Spec](https://github.com/dotnet/csharpstandard/tree/draft-v8/standard) provides chapters that formally define the language grammar.
148
+ - [Official C# 8 Draft Language Spec](https://github.com/dotnet/csharpstandard/tree/draft-v8/standard) provides
149
+ chapters that formally define the language grammar.
135
150
  - [Roslyn C# language grammar export](https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4)
136
151
  - [SharpLab](https://sharplab.io) (web-based syntax tree playground based on Roslyn)
package/grammar.js CHANGED
@@ -137,6 +137,7 @@ module.exports = grammar({
137
137
  // simple-lambda parameter list (at least one element has a parameter
138
138
  // modifier) closed by ')=>'.
139
139
  $._lambda_paren_open,
140
+ $._end_of_input,
140
141
  ],
141
142
 
142
143
  extras: ($) => [
@@ -1766,9 +1767,10 @@ module.exports = grammar({
1766
1767
  );
1767
1768
  },
1768
1769
 
1769
- preproc_region: ($) => seq(preprocessor('region'), optional(field('content', $.preproc_arg)), /\n/),
1770
+ preproc_region: ($) => seq(preprocessor('region'), optional(field('content', $.preproc_arg)), directiveEnd($)),
1770
1771
 
1771
- preproc_endregion: ($) => seq(preprocessor('endregion'), optional(field('content', $.preproc_arg)), /\n/),
1772
+ preproc_endregion: ($) =>
1773
+ seq(preprocessor('endregion'), optional(field('content', $.preproc_arg)), directiveEnd($)),
1772
1774
 
1773
1775
  preproc_line: ($) =>
1774
1776
  seq(
@@ -1793,7 +1795,7 @@ module.exports = grammar({
1793
1795
  $.string_literal
1794
1796
  )
1795
1797
  ),
1796
- /\n/
1798
+ directiveEnd($)
1797
1799
  ),
1798
1800
 
1799
1801
  preproc_pragma: ($) =>
@@ -1803,24 +1805,24 @@ module.exports = grammar({
1803
1805
  seq('warning', choice('disable', 'restore'), commaSep(choice($.identifier, $.integer_literal))),
1804
1806
  seq('checksum', $.string_literal, $.string_literal, $.string_literal)
1805
1807
  ),
1806
- /\n/
1808
+ directiveEnd($)
1807
1809
  ),
1808
1810
 
1809
- preproc_nullable: () =>
1811
+ preproc_nullable: ($) =>
1810
1812
  seq(
1811
1813
  preprocessor('nullable'),
1812
1814
  choice('enable', 'disable', 'restore'),
1813
1815
  optional(choice('annotations', 'warnings')),
1814
- /\n/
1816
+ directiveEnd($)
1815
1817
  ),
1816
1818
 
1817
- preproc_error: ($) => seq(preprocessor('error'), $.preproc_arg, /\n/),
1819
+ preproc_error: ($) => seq(preprocessor('error'), $.preproc_arg, directiveEnd($)),
1818
1820
 
1819
- preproc_warning: ($) => seq(preprocessor('warning'), $.preproc_arg, /\n/),
1821
+ preproc_warning: ($) => seq(preprocessor('warning'), $.preproc_arg, directiveEnd($)),
1820
1822
 
1821
- preproc_define: ($) => seq(preprocessor('define'), $.preproc_arg, /\n/),
1823
+ preproc_define: ($) => seq(preprocessor('define'), $.preproc_arg, directiveEnd($)),
1822
1824
 
1823
- preproc_undef: ($) => seq(preprocessor('undef'), $.preproc_arg, /\n/),
1825
+ preproc_undef: ($) => seq(preprocessor('undef'), $.preproc_arg, directiveEnd($)),
1824
1826
 
1825
1827
  shebang_directive: () => token(seq('#!', /.*/)),
1826
1828
 
@@ -1828,6 +1830,18 @@ module.exports = grammar({
1828
1830
  },
1829
1831
  });
1830
1832
 
1833
+ /**
1834
+ * Ends a directive that opens no conditional section: at a line break, or at the end of the input, which a file may
1835
+ * reach without a final line break.
1836
+ *
1837
+ * @param {GrammarSymbols<string>} $
1838
+ *
1839
+ * @returns {ChoiceRule}
1840
+ */
1841
+ function directiveEnd($) {
1842
+ return choice(/\n/, $._end_of_input);
1843
+ }
1844
+
1831
1845
  /**
1832
1846
  * Creates a preprocessor regex rule
1833
1847
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-c-sharp",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "C# grammar for tree-sitter",
5
5
  "keywords": [
6
6
  "incremental",
@@ -16,13 +16,14 @@
16
16
  "author": "WillBooster Inc.",
17
17
  "files": [
18
18
  "grammar.js",
19
+ "queries/*.scm",
19
20
  "tree-sitter.json",
20
21
  "src/node-types.json",
21
22
  "*.wasm"
22
23
  ],
23
24
  "scripts": {
24
- "build-wasm": "tree-sitter build --wasm",
25
- "build/ci": "tree-sitter generate && tree-sitter build --wasm",
25
+ "build-wasm": "script/tree-sitter build --wasm",
26
+ "build/ci": "script/tree-sitter generate && script/tree-sitter build --wasm",
26
27
  "cleanup": "bun wb lint --fix --format",
27
28
  "format": "bun wb lint --format",
28
29
  "lint": "bun wb lint",
@@ -30,10 +31,11 @@
30
31
  "prepare": "(bun lefthook install || true) && (test ! -f .lefthook/normalize-bun-lockfile.sh || bash .lefthook/normalize-bun-lockfile.sh)",
31
32
  "release": "wb release",
32
33
  "prestart": "bun run build-wasm",
33
- "start": "tree-sitter playground",
34
+ "start": "script/tree-sitter playground",
34
35
  "test": "bun wb test",
35
36
  "test/ci": "bun wb test-on-ci",
36
37
  "test/ci-setup": "playwright install --with-deps chromium",
38
+ "tree-sitter": "script/tree-sitter",
37
39
  "typecheck": "bun wb typecheck",
38
40
  "verify": "bun wb verify",
39
41
  "verify-full": "bun wb verify --full"
@@ -44,13 +46,13 @@
44
46
  "@vitest/browser-playwright": "5.0.1",
45
47
  "@willbooster/oxfmt-config": "1.2.2",
46
48
  "@willbooster/oxlint-config": "1.4.8",
47
- "@willbooster/wb": "22.13.0",
48
- "@willbooster/web-tree-sitter": "1.0.7",
49
+ "@willbooster/wb": "22.13.1",
50
+ "@willbooster/web-tree-sitter": "1.0.17",
49
51
  "conventional-changelog-conventionalcommits": "10.4.0",
50
52
  "lefthook": "2.1.14",
51
53
  "oxfmt": "0.70.0",
52
54
  "oxlint": "1.85.0",
53
- "oxlint-tsgolint": "7.0.2002",
55
+ "oxlint-tsgolint": "7.0.2003",
54
56
  "playwright": "1.63.0",
55
57
  "semantic-release": "25.0.9",
56
58
  "sort-package-json": "4.0.0",
@@ -0,0 +1,214 @@
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
+ ".."
114
+ ] @operator
115
+
116
+ [
117
+ "("
118
+ ")"
119
+ "["
120
+ "]"
121
+ "{"
122
+ "}"
123
+ (interpolation_brace)
124
+ ] @punctuation.bracket
125
+
126
+ ;; Keywords
127
+
128
+ [
129
+ (modifier)
130
+ "this"
131
+ (implicit_type)
132
+ ] @keyword
133
+
134
+ [
135
+ "add"
136
+ "alias"
137
+ "as"
138
+ "base"
139
+ "break"
140
+ "case"
141
+ "catch"
142
+ "checked"
143
+ "class"
144
+ "continue"
145
+ "default"
146
+ "delegate"
147
+ "do"
148
+ "else"
149
+ "enum"
150
+ "event"
151
+ "explicit"
152
+ "extern"
153
+ "finally"
154
+ "for"
155
+ "foreach"
156
+ "global"
157
+ "goto"
158
+ "if"
159
+ "implicit"
160
+ "interface"
161
+ "is"
162
+ "lock"
163
+ "namespace"
164
+ "notnull"
165
+ "operator"
166
+ "params"
167
+ "return"
168
+ "remove"
169
+ "sizeof"
170
+ "stackalloc"
171
+ "static"
172
+ "struct"
173
+ "switch"
174
+ "throw"
175
+ "try"
176
+ "typeof"
177
+ "unchecked"
178
+ "using"
179
+ "while"
180
+ "new"
181
+ "await"
182
+ "in"
183
+ "yield"
184
+ "get"
185
+ "set"
186
+ "when"
187
+ "out"
188
+ "ref"
189
+ "from"
190
+ "where"
191
+ "select"
192
+ "record"
193
+ "init"
194
+ "with"
195
+ "let"
196
+ "unsafe"
197
+ ] @keyword
198
+
199
+ ;; Attribute
200
+
201
+ (attribute name: (identifier) @attribute)
202
+
203
+ ;; Parameters
204
+
205
+ (parameter
206
+ name: (identifier) @variable.parameter)
207
+
208
+ ;; Type constraints
209
+
210
+ (type_parameter_constraints_clause (identifier) @property.definition)
211
+
212
+ ;; Method calls
213
+
214
+ (invocation_expression (member_access_expression name: (identifier) @function))
@@ -0,0 +1,23 @@
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: (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
Binary file
package/tree-sitter.json CHANGED
@@ -19,7 +19,7 @@
19
19
  }
20
20
  ],
21
21
  "metadata": {
22
- "version": "1.0.13",
22
+ "version": "1.0.15",
23
23
  "license": "MIT",
24
24
  "description": "C# grammar for tree-sitter",
25
25
  "authors": [