@willbooster/tree-sitter-c-sharp 2.0.0 → 2.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
@@ -28,9 +28,6 @@ The grammar is based upon the Roslyn grammar with changes in order to:
28
28
  Known gaps:
29
29
 
30
30
  - `var` and `await` cannot be used as identifiers everywhere they are valid
31
- - A pointer dereference can be assigned to only when its operand is a variable, an address, a parenthesized or
32
- postfix expression, or a cast of one of these or of an invocation (`*p = 1`, `*(p + 1) = 1`, `*(int*)p = 1`,
33
- `*dst++ = 1`); `*++p = 1` and `*f() = 1` are not recognized
34
31
 
35
32
  ## Usage
36
33
 
package/grammar.js CHANGED
@@ -49,6 +49,8 @@ module.exports = grammar({
49
49
  name: 'c_sharp',
50
50
 
51
51
  conflicts: ($) => [
52
+ [$._assignment_pointer_cast, $._lvalue_cast_expression],
53
+ [$._assignment_pointer_expression, $._pointer_indirection_expression],
52
54
  [$.modifier, $._constructor_declaration_initializer, $._reserved_identifier],
53
55
  [$._simple_name, $.generic_name],
54
56
  [$._simple_name, $.type_parameter],
@@ -1209,11 +1211,67 @@ module.exports = grammar({
1209
1211
  seq(
1210
1212
  // An invocation can return a reference (`Unsafe.Add(ref x, i) = v`). It ends with `)`, so `=` after it adds few
1211
1213
  // parse states, unlike making any expression assignable.
1212
- field('left', choice($.lvalue_expression, $.invocation_expression)),
1214
+ field(
1215
+ 'left',
1216
+ choice(
1217
+ $.lvalue_expression,
1218
+ $.invocation_expression,
1219
+ alias($._assignment_pointer_expression, $.prefix_unary_expression)
1220
+ )
1221
+ ),
1213
1222
  field('operator', choice('=', '+=', '-=', '*=', '/=', '%=', '&=', '^=', '|=', '<<=', '>>=', '>>>=', '??=')),
1214
1223
  field('right', $.expression)
1215
1224
  ),
1216
1225
 
1226
+ // Keep this alternative confined to assignment targets: sharing it with ordinary dereferences changes hidden
1227
+ // expression-supertype captures in nested reads. -3 prefers the existing lvalue path (-2) when both fit.
1228
+ _assignment_pointer_expression: ($) =>
1229
+ prec.dynamic(
1230
+ -3,
1231
+ prec.right(
1232
+ PREC.UNARY,
1233
+ seq(
1234
+ '*',
1235
+ choice(
1236
+ $.lvalue_expression,
1237
+ $.parenthesized_expression,
1238
+ $.invocation_expression,
1239
+ $.postfix_unary_expression,
1240
+ alias($._assignment_pointer_expression, $.prefix_unary_expression),
1241
+ alias($._pointer_prefix_update, $.prefix_unary_expression),
1242
+ alias($._assignment_pointer_cast, $.cast_expression)
1243
+ )
1244
+ )
1245
+ )
1246
+ ),
1247
+
1248
+ _pointer_prefix_update: ($) =>
1249
+ prec(
1250
+ PREC.UNARY,
1251
+ seq(choice('++', '--'), choice($.lvalue_expression, $.invocation_expression, $.parenthesized_expression))
1252
+ ),
1253
+
1254
+ _assignment_pointer_cast: ($) =>
1255
+ prec(
1256
+ PREC.CAST,
1257
+ seq(
1258
+ '(',
1259
+ field('type', $.type),
1260
+ ')',
1261
+ field(
1262
+ 'value',
1263
+ choice(
1264
+ $.lvalue_expression,
1265
+ $.parenthesized_expression,
1266
+ $.invocation_expression,
1267
+ $.postfix_unary_expression,
1268
+ alias($._assignment_pointer_expression, $.prefix_unary_expression),
1269
+ alias($._pointer_prefix_update, $.prefix_unary_expression)
1270
+ )
1271
+ )
1272
+ )
1273
+ ),
1274
+
1217
1275
  binary_expression: ($) =>
1218
1276
  choice(
1219
1277
  ...[
@@ -1267,14 +1325,9 @@ module.exports = grammar({
1267
1325
  )
1268
1326
  ),
1269
1327
 
1270
- // Pointer indirection is split by its operand. The assignable form, surfaced in `lvalue_expression`, takes an
1271
- // lvalue (`*p`, `*(p)`, `**pp`) or an operand that ends in a closing token or an lvalue: a parenthesized
1272
- // expression (`*(p + 1)`), a postfix expression (`*p++`), an address (`*&v`), or a cast of an lvalue, a
1273
- // parenthesized, postfix, or invocation expression, or an address (`*(int*)p`, `*(long*)(p + 4)`, `*(T*)f()`,
1274
- // `*(long*)&v`). Dereferencing any other expression (`*++p`) is only read: letting any expression be the assignable
1275
- // form's operand lets `=` follow every expression that can be the operand, which grows the parser by about 4,800
1276
- // states and nearly doubles the Wasm build, while these operands add about 550.
1277
- //
1328
+ // Keep the lvalue operand set restricted: a general expression also permits assignment after every operand,
1329
+ // substantially increasing parser states. Additional call and prefix-update operands use the assignment-only
1330
+ // `_assignment_pointer_expression` path to preserve the shared read derivations and their query captures.
1278
1331
  // Dynamic precedences: an assignable dereference -2, a read-only one -4, a read-only cast +1, an assignable cast -1,
1279
1332
  // and a unary `+`, `-`, `^`, or `&` -2. C# reads a parenthesized name as a cast only when the token after `)` is
1280
1333
  // `~`, `!`, `(`, an identifier, a literal, or a keyword (C# spec §12.9.8 Cast expressions), and these values keep
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-c-sharp",
3
- "version": "2.0.0",
3
+ "version": "2.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": "2.0.0",
22
+ "version": "2.0.2",
23
23
  "license": "MIT",
24
24
  "description": "C# grammar for tree-sitter",
25
25
  "authors": [