@willbooster/tree-sitter-c-sharp 1.0.8 → 1.0.9
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 +3 -2
- package/grammar.js +85 -30
- package/package.json +1 -1
- package/src/node-types.json +27 -23
- package/tree-sitter-c_sharp.wasm +0 -0
- package/tree-sitter.json +1 -1
package/README.md
CHANGED
|
@@ -27,8 +27,9 @@ 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,
|
|
31
|
-
or
|
|
30
|
+
- A pointer dereference can be assigned to only when its operand is a variable, an address, a parenthesized or
|
|
31
|
+
postfix expression, or a cast of one of these or of an invocation (`*p = 1`, `*(p + 1) = 1`, `*(int*)p = 1`,
|
|
32
|
+
`*dst++ = 1`); `*++p = 1` and `*f() = 1` are not recognized
|
|
32
33
|
- File-based apps preprocessor directives (`#:property`, `#:package`, `#:sdk`, `#:project`) are not yet recognized
|
|
33
34
|
|
|
34
35
|
## Usage
|
package/grammar.js
CHANGED
|
@@ -1007,9 +1007,10 @@ module.exports = grammar({
|
|
|
1007
1007
|
_name_invocation_pattern: ($) => seq(field('function', $._name), field('arguments', $.argument_list)),
|
|
1008
1008
|
|
|
1009
1009
|
// Invocation where function is not a simple name
|
|
1010
|
+
// One above `invocation_expression`, which reads the same tokens where both fit.
|
|
1010
1011
|
_complex_invocation_expression: ($) =>
|
|
1011
1012
|
prec(
|
|
1012
|
-
PREC.INVOCATION,
|
|
1013
|
+
PREC.INVOCATION + 1,
|
|
1013
1014
|
seq(
|
|
1014
1015
|
field(
|
|
1015
1016
|
'function',
|
|
@@ -1242,7 +1243,7 @@ module.exports = grammar({
|
|
|
1242
1243
|
)
|
|
1243
1244
|
),
|
|
1244
1245
|
|
|
1245
|
-
postfix_unary_expression: ($) => prec(PREC.POSTFIX, seq(
|
|
1246
|
+
postfix_unary_expression: ($) => prec(PREC.POSTFIX, seq(postfixOperand($), choice('++', '--', '!'))),
|
|
1246
1247
|
|
|
1247
1248
|
prefix_unary_expression: ($) =>
|
|
1248
1249
|
prec(
|
|
@@ -1260,35 +1261,69 @@ module.exports = grammar({
|
|
|
1260
1261
|
)
|
|
1261
1262
|
),
|
|
1262
1263
|
|
|
1263
|
-
// Pointer indirection is split by its operand.
|
|
1264
|
-
// (`*p`, `*(p)`, `**pp`)
|
|
1265
|
-
// `
|
|
1266
|
-
// expression (`*(
|
|
1267
|
-
// `
|
|
1268
|
-
// be
|
|
1264
|
+
// Pointer indirection is split by its operand. The assignable form, surfaced in `lvalue_expression`, takes an
|
|
1265
|
+
// lvalue (`*p`, `*(p)`, `**pp`) or an operand that ends in a closing token or an lvalue: a parenthesized
|
|
1266
|
+
// expression (`*(p + 1)`), a postfix expression (`*p++`), an address (`*&v`), or a cast of an lvalue, a
|
|
1267
|
+
// parenthesized, postfix, or invocation expression, or an address (`*(int*)p`, `*(long*)(p + 4)`, `*(T*)f()`,
|
|
1268
|
+
// `*(long*)&v`). Dereferencing any other expression (`*++p`) is only read: letting any expression be the assignable
|
|
1269
|
+
// form's operand lets `=` follow every expression that can be the operand, which grows the parser by about 4,800
|
|
1270
|
+
// states and nearly doubles the Wasm build, while these operands add about 550.
|
|
1269
1271
|
//
|
|
1270
|
-
//
|
|
1271
|
-
//
|
|
1272
|
-
//
|
|
1273
|
-
//
|
|
1274
|
-
// dereference of `
|
|
1275
|
-
// (-
|
|
1276
|
-
_pointer_indirection_expression: ($) =>
|
|
1272
|
+
// Dynamic precedences: an assignable dereference -2, a read-only one -4, a read-only cast +1, and an assignable cast
|
|
1273
|
+
// -1. C# reads a parenthesized name as a cast only when the token after `)` is `~`, `!`, `(`, an identifier, a
|
|
1274
|
+
// literal, or a keyword (C# spec §12.9.8 Cast expressions), and these values keep that reading: `(a) * b` is a
|
|
1275
|
+
// multiplication (0), not a cast of `*b` (+1 - 2); `*(p) + 1` and `*(p) & x` apply to a dereference of `(p)` (-2),
|
|
1276
|
+
// not to a dereference of a cast of `+1` or `&x` (-4 + 1 or -2 - 1); `*(b)[0]` dereferences an element access
|
|
1277
|
+
// (-2), not a cast of `[0]` (-2 - 1). Where both casts fit, they give the same tree.
|
|
1278
|
+
_pointer_indirection_expression: ($) =>
|
|
1279
|
+
prec.dynamic(
|
|
1280
|
+
-2,
|
|
1281
|
+
prec.right(
|
|
1282
|
+
PREC.UNARY,
|
|
1283
|
+
seq(
|
|
1284
|
+
'*',
|
|
1285
|
+
choice(
|
|
1286
|
+
$.lvalue_expression,
|
|
1287
|
+
$.parenthesized_expression,
|
|
1288
|
+
alias($._address_of_expression, $.prefix_unary_expression),
|
|
1289
|
+
alias($._lvalue_cast_expression, $.cast_expression),
|
|
1290
|
+
$.postfix_unary_expression
|
|
1291
|
+
)
|
|
1292
|
+
)
|
|
1293
|
+
)
|
|
1294
|
+
),
|
|
1295
|
+
|
|
1296
|
+
_lvalue_cast_expression: ($) =>
|
|
1297
|
+
prec(
|
|
1298
|
+
PREC.CAST,
|
|
1299
|
+
prec.dynamic(
|
|
1300
|
+
-1,
|
|
1301
|
+
seq(
|
|
1302
|
+
'(',
|
|
1303
|
+
field('type', $.type),
|
|
1304
|
+
')',
|
|
1305
|
+
field(
|
|
1306
|
+
'value',
|
|
1307
|
+
choice(
|
|
1308
|
+
$.lvalue_expression,
|
|
1309
|
+
$.parenthesized_expression,
|
|
1310
|
+
alias($._address_of_expression, $.prefix_unary_expression),
|
|
1311
|
+
$.postfix_unary_expression,
|
|
1312
|
+
$.invocation_expression
|
|
1313
|
+
)
|
|
1314
|
+
)
|
|
1315
|
+
)
|
|
1316
|
+
)
|
|
1317
|
+
),
|
|
1277
1318
|
|
|
1278
1319
|
_value_indirection_expression: ($) => prec.dynamic(-4, prec.right(PREC.UNARY, seq('*', $.non_lvalue_expression))),
|
|
1279
1320
|
|
|
1280
|
-
// Address-of is split out from `prefix_unary_expression`
|
|
1281
|
-
//
|
|
1282
|
-
//
|
|
1283
|
-
//
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
// a unary start and the lexer split `&&` into two `&` tokens.
|
|
1287
|
-
// With this split, `&` is only valid before an lvalue, which
|
|
1288
|
-
// `(b > 0)` is not — so the cast interpretation can no longer
|
|
1289
|
-
// consume the trailing parenthesized expression and `&&` must
|
|
1290
|
-
// be emitted as a single token for the binary path to succeed.
|
|
1291
|
-
_address_of_expression: ($) => prec.right(PREC.UNARY, seq('&', $.lvalue_expression)),
|
|
1321
|
+
// Address-of is split out from `prefix_unary_expression` and takes only a variable: an lvalue, or an invocation,
|
|
1322
|
+
// which can return a reference (`&span.GetPinnableReference()`). If a cast could take `&` before any expression,
|
|
1323
|
+
// the lexer would split `&&` into two `&` tokens and `(a) && (b > 0)` would read as a cast of `&(&(b > 0))`; as
|
|
1324
|
+
// `(b > 0)` is not a variable, that reading fails and `&&` stays one token.
|
|
1325
|
+
_address_of_expression: ($) =>
|
|
1326
|
+
prec.right(PREC.UNARY, seq('&', choice($.lvalue_expression, $.invocation_expression))),
|
|
1292
1327
|
|
|
1293
1328
|
query_expression: ($) => seq($.from_clause, $._query_body),
|
|
1294
1329
|
|
|
@@ -1370,7 +1405,7 @@ module.exports = grammar({
|
|
|
1370
1405
|
checked_expression: ($) => seq(choice('checked', 'unchecked'), '(', $.expression, ')'),
|
|
1371
1406
|
|
|
1372
1407
|
invocation_expression: ($) =>
|
|
1373
|
-
prec(PREC.INVOCATION, seq(field('function',
|
|
1408
|
+
prec(PREC.INVOCATION, seq(field('function', postfixOperand($)), field('arguments', $.argument_list))),
|
|
1374
1409
|
|
|
1375
1410
|
switch_expression: ($) => prec(PREC.SWITCH, seq($.expression, 'switch', $._switch_expression_body)),
|
|
1376
1411
|
_switch_expression_body: ($) => seq('{', commaSep($.switch_expression_arm), optional(','), '}'),
|
|
@@ -1384,7 +1419,7 @@ module.exports = grammar({
|
|
|
1384
1419
|
throw_expression: ($) => seq('throw', $.expression),
|
|
1385
1420
|
|
|
1386
1421
|
element_access_expression: ($) =>
|
|
1387
|
-
prec(PREC.POSTFIX, seq(field('expression',
|
|
1422
|
+
prec(PREC.POSTFIX, seq(field('expression', postfixOperand($)), field('subscript', $.bracketed_argument_list))),
|
|
1388
1423
|
|
|
1389
1424
|
interpolated_string_expression: ($) =>
|
|
1390
1425
|
choice(
|
|
@@ -1434,7 +1469,7 @@ module.exports = grammar({
|
|
|
1434
1469
|
prec(
|
|
1435
1470
|
PREC.DOT,
|
|
1436
1471
|
seq(
|
|
1437
|
-
field('expression', choice(
|
|
1472
|
+
field('expression', choice(postfixOperand($), $.predefined_type, $._name)),
|
|
1438
1473
|
choice('.', '->'),
|
|
1439
1474
|
field('name', $._simple_name)
|
|
1440
1475
|
)
|
|
@@ -1855,6 +1890,26 @@ function preprocIf(suffix, content, precedence = 0, rep = true) {
|
|
|
1855
1890
|
};
|
|
1856
1891
|
}
|
|
1857
1892
|
|
|
1893
|
+
/**
|
|
1894
|
+
* The operand of a postfix operator, an invocation, an element access, or a member access. Besides `expression`, it
|
|
1895
|
+
* lists the forms that are operands of `&`, of the assignable `*`, or of the assignable cast: reaching them only
|
|
1896
|
+
* through `expression` would reduce the unary operator or the cast (precedence UNARY or CAST) before `expression`
|
|
1897
|
+
* (precedence 0) lets the postfix operator apply, reading `&a[0]` as `(&a)[0]` and `*(T*)f()[0]` as `(*(T*)f())[0]`.
|
|
1898
|
+
*
|
|
1899
|
+
* @param {GrammarSymbols<string>} $
|
|
1900
|
+
*
|
|
1901
|
+
* @returns {ChoiceRule}
|
|
1902
|
+
*/
|
|
1903
|
+
function postfixOperand($) {
|
|
1904
|
+
return choice(
|
|
1905
|
+
$.expression,
|
|
1906
|
+
$.lvalue_expression,
|
|
1907
|
+
$.invocation_expression,
|
|
1908
|
+
$.postfix_unary_expression,
|
|
1909
|
+
$.parenthesized_expression
|
|
1910
|
+
);
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1858
1913
|
/**
|
|
1859
1914
|
* Creates a rule to match one or more of the rules separated by a comma
|
|
1860
1915
|
*
|
package/package.json
CHANGED
package/src/node-types.json
CHANGED
|
@@ -1511,6 +1511,14 @@
|
|
|
1511
1511
|
{
|
|
1512
1512
|
"type": "expression",
|
|
1513
1513
|
"named": true
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
"type": "invocation_expression",
|
|
1517
|
+
"named": true
|
|
1518
|
+
},
|
|
1519
|
+
{
|
|
1520
|
+
"type": "postfix_unary_expression",
|
|
1521
|
+
"named": true
|
|
1514
1522
|
}
|
|
1515
1523
|
]
|
|
1516
1524
|
}
|
|
@@ -2316,6 +2324,14 @@
|
|
|
2316
2324
|
{
|
|
2317
2325
|
"type": "expression",
|
|
2318
2326
|
"named": true
|
|
2327
|
+
},
|
|
2328
|
+
{
|
|
2329
|
+
"type": "invocation_expression",
|
|
2330
|
+
"named": true
|
|
2331
|
+
},
|
|
2332
|
+
{
|
|
2333
|
+
"type": "postfix_unary_expression",
|
|
2334
|
+
"named": true
|
|
2319
2335
|
}
|
|
2320
2336
|
]
|
|
2321
2337
|
},
|
|
@@ -3449,36 +3465,16 @@
|
|
|
3449
3465
|
"type": "cast_expression",
|
|
3450
3466
|
"named": true
|
|
3451
3467
|
},
|
|
3452
|
-
{
|
|
3453
|
-
"type": "conditional_access_expression",
|
|
3454
|
-
"named": true
|
|
3455
|
-
},
|
|
3456
|
-
{
|
|
3457
|
-
"type": "element_access_expression",
|
|
3458
|
-
"named": true
|
|
3459
|
-
},
|
|
3460
3468
|
{
|
|
3461
3469
|
"type": "expression",
|
|
3462
3470
|
"named": true
|
|
3463
3471
|
},
|
|
3464
|
-
{
|
|
3465
|
-
"type": "generic_name",
|
|
3466
|
-
"named": true
|
|
3467
|
-
},
|
|
3468
|
-
{
|
|
3469
|
-
"type": "identifier",
|
|
3470
|
-
"named": true
|
|
3471
|
-
},
|
|
3472
3472
|
{
|
|
3473
3473
|
"type": "invocation_expression",
|
|
3474
3474
|
"named": true
|
|
3475
3475
|
},
|
|
3476
3476
|
{
|
|
3477
|
-
"type": "
|
|
3478
|
-
"named": true
|
|
3479
|
-
},
|
|
3480
|
-
{
|
|
3481
|
-
"type": "parenthesized_expression",
|
|
3477
|
+
"type": "postfix_unary_expression",
|
|
3482
3478
|
"named": true
|
|
3483
3479
|
},
|
|
3484
3480
|
{
|
|
@@ -3894,11 +3890,11 @@
|
|
|
3894
3890
|
"named": true
|
|
3895
3891
|
},
|
|
3896
3892
|
{
|
|
3897
|
-
"type": "
|
|
3893
|
+
"type": "invocation_expression",
|
|
3898
3894
|
"named": true
|
|
3899
3895
|
},
|
|
3900
3896
|
{
|
|
3901
|
-
"type": "
|
|
3897
|
+
"type": "postfix_unary_expression",
|
|
3902
3898
|
"named": true
|
|
3903
3899
|
},
|
|
3904
3900
|
{
|
|
@@ -4668,6 +4664,14 @@
|
|
|
4668
4664
|
{
|
|
4669
4665
|
"type": "expression",
|
|
4670
4666
|
"named": true
|
|
4667
|
+
},
|
|
4668
|
+
{
|
|
4669
|
+
"type": "invocation_expression",
|
|
4670
|
+
"named": true
|
|
4671
|
+
},
|
|
4672
|
+
{
|
|
4673
|
+
"type": "postfix_unary_expression",
|
|
4674
|
+
"named": true
|
|
4671
4675
|
}
|
|
4672
4676
|
]
|
|
4673
4677
|
}
|
package/tree-sitter-c_sharp.wasm
CHANGED
|
Binary file
|