@willbooster/tree-sitter-c-sharp 1.0.0 → 1.0.2

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
@@ -27,6 +27,8 @@ The grammar is based upon the Roslyn grammar with changes in order to:
27
27
  Known gaps:
28
28
 
29
29
  - `async`, `var` and `await` cannot be used as identifiers everywhere they are valid
30
+ - A pointer dereference can be assigned to only when its operand is a variable, member access, element access,
31
+ or another dereference (`*p = 1`, `*(p) = 1`, `*a.b = 1`); `*(int*)p = 1` and `*(p + 1) = 1` are not recognized
30
32
  - File-based apps preprocessor directives (`#:property`, `#:package`, `#:sdk`, `#:project`) are not yet recognized
31
33
 
32
34
  ## Usage
@@ -74,11 +76,13 @@ parser.setLanguage(await Language.load(cSharp));
74
76
 
75
77
  The package also ships the node types in `src/node-types.json`.
76
78
 
77
- In Rust, depend on the [crate](https://crates.io/crates/willbooster-tree-sitter-c-sharp):
79
+ In Rust, depend on the [crate](https://crates.io/crates/willbooster-tree-sitter-c-sharp) and the
80
+ [runtime](https://crates.io/crates/willbooster-tree-sitter), whose fixes keep incremental reparses consistent with
81
+ fresh parses:
78
82
 
79
83
  ```toml
80
84
  [dependencies]
81
- tree-sitter = "0.27"
85
+ tree-sitter = { package = "willbooster-tree-sitter", version = "1.0.3" }
82
86
  tree-sitter-c-sharp = { package = "willbooster-tree-sitter-c-sharp", version = "1" }
83
87
  ```
84
88
 
@@ -115,6 +119,9 @@ cargo test
115
119
  which needs Chromium installed once by `bunx playwright install chromium`) and in Cloudflare Workers with and without
116
120
  `nodejs_compat` (`test/unit/workers.test.ts`).
117
121
 
122
+ `cargo test` also replays edits that `tree-sitter fuzz` found to break incremental parsing, with the
123
+ willbooster-tree-sitter runtime that fixes them; `tree-sitter fuzz` itself runs the runtime built into tree-sitter-cli.
124
+
118
125
  CI also runs these tests on Linux arm64 and macOS, where the Rust binding compiles the parser natively, and fuzzes the parser with libFuzzer and sanitizers
119
126
  (`.github/workflows/robustness.yml`).
120
127
 
package/grammar.js CHANGED
@@ -1133,6 +1133,7 @@ module.exports = grammar({
1133
1133
  // Parallels `_pointer_indirection_expression` (the `*` operator),
1134
1134
  // which is similarly aliased back into `lvalue_expression`.
1135
1135
  alias($._address_of_expression, $.prefix_unary_expression),
1136
+ alias($._value_indirection_expression, $.prefix_unary_expression),
1136
1137
  $.reftype_expression,
1137
1138
  $.refvalue_expression,
1138
1139
  $.stackalloc_expression,
@@ -1230,16 +1231,31 @@ module.exports = grammar({
1230
1231
  // `&` and `*` are intentionally NOT in this choice list:
1231
1232
  // * `&` → `_address_of_expression` (operand restricted to lvalue
1232
1233
  // — see comment on that rule for the #413 rationale)
1233
- // * `*` → `_pointer_indirection_expression` (same shape,
1234
- // restricted to lvalue, surfaced in `lvalue_expression`)
1235
- // Both are aliased back to `prefix_unary_expression` so the
1234
+ // * `*` → `_pointer_indirection_expression` and
1235
+ // `_value_indirection_expression`
1236
+ // They are aliased back to `prefix_unary_expression` so the
1236
1237
  // public AST is unaffected.
1237
1238
  choice('++', '--', '+', '-', '!', '~', '^'),
1238
1239
  $.expression
1239
1240
  )
1240
1241
  ),
1241
1242
 
1242
- _pointer_indirection_expression: ($) => prec.right(PREC.UNARY, seq('*', $.lvalue_expression)),
1243
+ // Pointer indirection is split by its operand. Dereferencing an lvalue
1244
+ // (`*p`, `*(p)`, `**pp`) yields an lvalue, so it is surfaced in
1245
+ // `lvalue_expression` and can be assigned to. Dereferencing any other
1246
+ // expression (`*(long*)&v`, `*(p + 1)`) is only read: surfacing it in
1247
+ // `lvalue_expression` too would let `=` follow every expression that can
1248
+ // be its operand, which grows the parser from 8,495 to 13,339 states.
1249
+ //
1250
+ // A parenthesized expression followed by `*` is a multiplication, not a
1251
+ // cast of a dereference (C# spec §12.9.8 Cast expressions: `(a) * b` is
1252
+ // a cast only when `a` cannot be an expression), so a dereference's
1253
+ // penalty outweighs the cast's +1. `*(p) + 1` is likewise the sum of a
1254
+ // dereference of `(p)` (-2), not a dereference of a cast of `+1`
1255
+ // (-4 + 1), so dereferencing a non-lvalue carries the larger penalty.
1256
+ _pointer_indirection_expression: ($) => prec.dynamic(-2, prec.right(PREC.UNARY, seq('*', $.lvalue_expression))),
1257
+
1258
+ _value_indirection_expression: ($) => prec.dynamic(-4, prec.right(PREC.UNARY, seq('*', $.non_lvalue_expression))),
1243
1259
 
1244
1260
  // Address-of is split out from `prefix_unary_expression` so that
1245
1261
  // `&` can't act as a fallback when the lexer would otherwise
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-c-sharp",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "C# grammar for tree-sitter",
5
5
  "keywords": [
6
6
  "incremental",
Binary file
package/tree-sitter.json CHANGED
@@ -19,7 +19,7 @@
19
19
  }
20
20
  ],
21
21
  "metadata": {
22
- "version": "1.0.0",
22
+ "version": "1.0.2",
23
23
  "license": "MIT",
24
24
  "description": "C# grammar for tree-sitter",
25
25
  "authors": [