@willbooster/tree-sitter-c-sharp 14.1.2 → 14.1.3

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/grammar.js CHANGED
@@ -11,7 +11,7 @@
11
11
  const { alias, choice, field, grammar, optional, prec, repeat, repeat1, seq, sym, token } =
12
12
  /** @type {typeof globalThis & import('@willbooster/web-tree-sitter/dsl').DSL} */ (globalThis);
13
13
 
14
- /** @typedef {'_preproc_expression' | '_top_level_item_no_statement' | '_namespace_body_item' | '_base_list_mixed_type' | '_base_list_mixed_suffix' | '_base_list_trivia' | '_base_list' | '_base_list_type' | '_base_list_suffix' | '_base_list_prefix' | '_base_list_separator' | '_base_list_separator_path' | '_enum_base_clause' | '_enum_base_type' | '_dangling_else_if_statement' | 'attribute_list' | 'declaration' | 'enum_member_declaration' | 'expression' | 'if_statement' | 'method_signature' | 'statement'} PreprocContentRule */
14
+ /** @typedef {'_preproc_expression' | '_top_level_item_no_statement' | '_namespace_body_item' | '_base_list_mixed_type' | '_base_list_mixed_suffix' | '_base_list_trivia' | '_base_list' | '_base_list_type' | '_base_list_suffix' | '_base_list_prefix' | '_base_list_separator' | '_base_list_separator_path' | '_enum_base_clause' | '_enum_base_type' | '_dangling_else_if_statement' | '_object_initializer_element' | '_modified_argument' | '_spread_collection_element' | '_object_member_initializers' | 'argument' | 'attribute_list' | 'collection_element' | 'declaration' | 'enum_member_declaration' | 'expression' | 'if_statement' | 'method_signature' | 'statement' | 'switch_expression_arm'} PreprocContentRule */
15
15
 
16
16
  const PREC = {
17
17
  GENERIC: 19,
@@ -143,6 +143,16 @@ module.exports = grammar({
143
143
  [$._simple_name, $._definite_cast_name],
144
144
  [$._name, $._definite_cast_name],
145
145
  [$._object_initializer_expression, $.initializer_expression],
146
+ [$._object_initializer_element, $.initializer_expression],
147
+ [$._object_initializer_element, sym('preproc_elif_in_initializer')],
148
+ [sym('preproc_elif_in_initializer'), sym('preproc_elif_in_object_initializer')],
149
+ [$._object_initializer_element, sym('preproc_else_in_initializer')],
150
+ [$._object_initializer_element, sym('preproc_if_in_initializer')],
151
+ [sym('preproc_else_in_initializer'), sym('preproc_else_in_object_initializer')],
152
+ [sym('preproc_if_in_initializer'), sym('preproc_if_in_object_initializer')],
153
+ [sym('preproc_elif_in_top_level'), sym('preproc_elif_in_initializer')],
154
+ [sym('preproc_else_in_top_level'), sym('preproc_else_in_initializer')],
155
+ [sym('preproc_if_in_top_level'), sym('preproc_if_in_initializer')],
146
156
  [
147
157
  $._pattern_primary_expression,
148
158
  $._primary_no_conditional_access_expression,
@@ -979,16 +989,20 @@ module.exports = grammar({
979
989
 
980
990
  constructor_initializer: ($) => seq(':', choice('base', 'this'), $.argument_list),
981
991
 
982
- argument_list: ($) => seq('(', commaSep($.argument), ')'),
992
+ argument_list: ($) => seq('(', conditionalList($.argument, 'preproc_if_in_argument_list', false), ')'),
983
993
 
984
994
  tuple_pattern: ($) => seq('(', commaSep1(choice(field('name', $.identifier), $.discard, $.tuple_pattern)), ')'),
985
995
 
986
- argument: ($) =>
996
+ argument: ($) => prec(1, seq(optional(seq(field('name', $.identifier), ':')), argumentValue($))),
997
+
998
+ // An argument that a directive branch cannot hold as a bare expression.
999
+ _modified_argument: ($) =>
987
1000
  prec(
988
1001
  1,
989
- seq(
990
- optional(seq(field('name', $.identifier), ':')),
991
- choice(seq(optional(choice('ref', 'out', 'in')), $.expression), seq('out', $.declaration_expression))
1002
+ choice(
1003
+ seq(field('name', $.identifier), ':', argumentValue($)),
1004
+ seq(choice('ref', 'out', 'in'), $.expression),
1005
+ seq('out', $.declaration_expression)
992
1006
  )
993
1007
  ),
994
1008
 
@@ -2323,8 +2337,7 @@ module.exports = grammar({
2323
2337
  _switch_expression_body: ($) =>
2324
2338
  seq(
2325
2339
  '{',
2326
- commaSep($.switch_expression_arm),
2327
- optional(','),
2340
+ conditionalList($.switch_expression_arm, 'preproc_if_in_switch_expression'),
2328
2341
  choice('}', alias(sym('_nonprimary_expression_end'), '}'))
2329
2342
  ),
2330
2343
 
@@ -2516,26 +2529,25 @@ module.exports = grammar({
2516
2529
 
2517
2530
  implicit_stackalloc_expression: ($) => seq('stackalloc', '[', ']', $.initializer_expression),
2518
2531
 
2519
- collection_expression: ($) => seq('[', optional(seq(commaSep1($.collection_element), optional(','))), ']'),
2532
+ collection_expression: ($) => seq('[', conditionalList($.collection_element, 'preproc_if_in_collection'), ']'),
2520
2533
 
2521
2534
  collection_element: ($) => choice($.expression_element, $.spread_element),
2522
2535
 
2536
+ _spread_collection_element: ($) => $.spread_element,
2537
+
2523
2538
  expression_element: ($) => prec(1, $.expression),
2524
2539
 
2525
2540
  spread_element: ($) => prec.dynamic(1, prec(PREC.RANGE, seq('..', $.expression))),
2526
2541
 
2527
2542
  _object_initializer_expression: ($) =>
2528
- seq(
2529
- '{',
2530
- commaSep(
2531
- choice(
2532
- alias($._object_index_initializer, $.assignment_expression),
2533
- alias($._object_member_initializer, $.assignment_expression),
2534
- $.expression
2535
- )
2536
- ),
2537
- optional(','),
2538
- '}'
2543
+ seq('{', conditionalList($._object_initializer_element, 'preproc_if_in_object_initializer'), '}'),
2544
+
2545
+ _object_initializer_element: ($) => choice($._object_member_initializers, $.expression),
2546
+
2547
+ _object_member_initializers: ($) =>
2548
+ choice(
2549
+ alias($._object_index_initializer, $.assignment_expression),
2550
+ alias($._object_member_initializer, $.assignment_expression)
2539
2551
  ),
2540
2552
 
2541
2553
  _object_initializer_value: ($) =>
@@ -2553,7 +2565,7 @@ module.exports = grammar({
2553
2565
 
2554
2566
  _object_member_initializer: ($) => assignmentExpression($, $.identifier, '=', $._object_initializer_value),
2555
2567
 
2556
- initializer_expression: ($) => seq('{', commaSep($.expression), optional(','), '}'),
2568
+ initializer_expression: ($) => seq('{', conditionalList($.expression, 'preproc_if_in_initializer'), '}'),
2557
2569
 
2558
2570
  declaration_expression: ($) => prec.dynamic(1, seq(field('type', $.type), field('name', $.identifier))),
2559
2571
 
@@ -2712,6 +2724,27 @@ module.exports = grammar({
2712
2724
  ...preprocIf('_in_if_alternative', ($) => seq(optional('else'), conditionalStatements($)), 0, false),
2713
2725
 
2714
2726
  ...preprocIf('_in_expression', ($) => $.expression, -2, false),
2727
+ ...conditionalListDirective('_in_initializer', ($) => $.expression),
2728
+ ...conditionalListDirective(
2729
+ '_in_object_initializer',
2730
+ ($) => $._object_initializer_element,
2731
+ ($) => $._object_member_initializers
2732
+ ),
2733
+ ...conditionalListDirective(
2734
+ '_in_collection',
2735
+ ($) => $.collection_element,
2736
+ ($) => alias($._spread_collection_element, $.collection_element)
2737
+ ),
2738
+ ...conditionalListDirective(
2739
+ '_in_argument_list',
2740
+ ($) => $.argument,
2741
+ ($) => alias($._modified_argument, $.argument)
2742
+ ),
2743
+ ...conditionalListDirective(
2744
+ '_in_switch_expression',
2745
+ ($) => $.switch_expression_arm,
2746
+ ($) => $.switch_expression_arm
2747
+ ),
2715
2748
  ...preprocIf('_in_enum_member_declaration', ($) => $.enum_member_declaration, 0, false),
2716
2749
  ...preprocIf('_in_attribute_list', ($) => $.attribute_list, -1, false),
2717
2750
 
@@ -3121,6 +3154,13 @@ function preprocIf(suffix, content, precedence = 0, rep = true, required = false
3121
3154
  };
3122
3155
  }
3123
3156
 
3157
+ /**
3158
+ * @param {import('@willbooster/web-tree-sitter/dsl').GrammarSymbols<'declaration_expression' | 'expression'>} $
3159
+ */
3160
+ function argumentValue($) {
3161
+ return choice(seq(optional(choice('ref', 'out', 'in')), $.expression), seq('out', $.declaration_expression));
3162
+ }
3163
+
3124
3164
  /**
3125
3165
  * Statements of a conditional branch, where the last may be an if statement whose `else` body follows the directive.
3126
3166
  *
@@ -3329,6 +3369,68 @@ function nullableQuestion() {
3329
3369
  return choice(alias(sym('_question_nullable'), '?'), alias(sym('_question_unknown'), '?'));
3330
3370
  }
3331
3371
 
3372
+ /**
3373
+ * Comma-separated elements, optionally with a trailing comma, where conditional directives may enclose whole elements
3374
+ * together with their commas.
3375
+ *
3376
+ * @param {import('@willbooster/web-tree-sitter/dsl').RuleOrLiteral} element
3377
+ * @param {string} directive
3378
+ * @param {boolean} trailingComma
3379
+ */
3380
+ function conditionalList(element, directive, trailingComma = true) {
3381
+ const items = repeat(conditionalListItem(element, directive));
3382
+ const conditional = alias(sym(directive), sym('preproc_if'));
3383
+ return trailingComma
3384
+ ? seq(items, optional(element))
3385
+ : optional(seq(items, choice(element, seq(optional(element), conditional))));
3386
+ }
3387
+
3388
+ /**
3389
+ * @param {import('@willbooster/web-tree-sitter/dsl').RuleOrLiteral} element
3390
+ * @param {string} directive
3391
+ */
3392
+ function conditionalListItem(element, directive) {
3393
+ return choice(seq(element, ','), seq(optional(element), alias(sym(directive), sym('preproc_if')), optional(',')));
3394
+ }
3395
+
3396
+ /**
3397
+ * Conditional directive rules for a comma-separated list. The `#if` branch alone decides between this rule and the
3398
+ * expression-level directive, so only `#elif` and `#else` branches may hold a single expression.
3399
+ *
3400
+ * @param {string} suffix
3401
+ * @param {import('@willbooster/web-tree-sitter/dsl').RuleBuilder<PreprocContentRule>} element
3402
+ * @param {import('@willbooster/web-tree-sitter/dsl').RuleBuilder<PreprocContentRule>} [single]
3403
+ * @returns {Record<string, import('@willbooster/web-tree-sitter/dsl').RuleBuilder<PreprocContentRule>>}
3404
+ */
3405
+ function conditionalListDirective(suffix, element, single) {
3406
+ const directive = 'preproc_if' + suffix;
3407
+ const rules = preprocIf(suffix, ($) => conditionalListContent(element($), directive, single?.($)), 0, false);
3408
+ /** @param {import('@willbooster/web-tree-sitter/dsl').GrammarSymbols<PreprocContentRule>} $ */
3409
+ const alternativeContent = ($) => choice(conditionalListContent(element($), directive), element($));
3410
+ const alternatives = Object.entries(preprocIf(suffix, alternativeContent, 0, false)).filter(
3411
+ ([name]) => !name.startsWith('preproc_if')
3412
+ );
3413
+ return { ...rules, ...Object.fromEntries(alternatives) };
3414
+ }
3415
+
3416
+ /**
3417
+ * The elements of a conditional branch, which may start with the comma after the preceding element and contain nested
3418
+ * conditional groups. A single expression without commas is left to the expression-level directive, which lets an
3419
+ * operator after the directive continue it.
3420
+ *
3421
+ * @param {import('@willbooster/web-tree-sitter/dsl').RuleOrLiteral} element
3422
+ * @param {string} directive
3423
+ * @param {import('@willbooster/web-tree-sitter/dsl').RuleOrLiteral} [single] a single element without commas that cannot be an
3424
+ * expression
3425
+ */
3426
+ function conditionalListContent(element, directive, single) {
3427
+ return choice(
3428
+ seq(',', conditionalList(element, directive)),
3429
+ seq(repeat1(conditionalListItem(element, directive)), optional(element)),
3430
+ ...(single ? [single] : [])
3431
+ );
3432
+ }
3433
+
3332
3434
  /**
3333
3435
  * @param {import('@willbooster/web-tree-sitter/dsl').Rule} rule
3334
3436
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-c-sharp",
3
- "version": "14.1.2",
3
+ "version": "14.1.3",
4
4
  "description": "C# grammar for tree-sitter",
5
5
  "keywords": [
6
6
  "incremental",
@@ -231,6 +231,13 @@
231
231
  (member_binding_expression name: (generic_name (identifier) @variable.member))
232
232
  ]
233
233
 
234
+ ;; Object initializer members inside conditional directives (alternative branches are omitted because each nested
235
+ ;; pattern through `preproc_elif` or `preproc_else` adds noticeable query compilation time)
236
+
237
+ (object_creation_expression initializer: (initializer_expression (preproc_if (assignment_expression left: (identifier) @variable.member))))
238
+ (implicit_object_creation_expression (initializer_expression (preproc_if (assignment_expression left: (identifier) @variable.member))))
239
+ (assignment_expression right: (initializer_expression (preproc_if (assignment_expression left: (identifier) @variable.member))))
240
+
234
241
  ;; Calls
235
242
 
236
243
  (invocation_expression
@@ -808,6 +808,10 @@
808
808
  {
809
809
  "type": "argument",
810
810
  "named": true
811
+ },
812
+ {
813
+ "type": "preproc_if",
814
+ "named": true
811
815
  }
812
816
  ]
813
817
  }
@@ -2089,6 +2093,10 @@
2089
2093
  {
2090
2094
  "type": "collection_element",
2091
2095
  "named": true
2096
+ },
2097
+ {
2098
+ "type": "preproc_if",
2099
+ "named": true
2092
2100
  }
2093
2101
  ]
2094
2102
  }
@@ -6304,6 +6312,10 @@
6304
6312
  "multiple": true,
6305
6313
  "required": false,
6306
6314
  "types": [
6315
+ {
6316
+ "type": "argument",
6317
+ "named": true
6318
+ },
6307
6319
  {
6308
6320
  "type": "argument_list",
6309
6321
  "named": true
@@ -6316,6 +6328,10 @@
6316
6328
  "type": "base_list",
6317
6329
  "named": true
6318
6330
  },
6331
+ {
6332
+ "type": "collection_element",
6333
+ "named": true
6334
+ },
6319
6335
  {
6320
6336
  "type": "declaration",
6321
6337
  "named": true
@@ -6348,6 +6364,10 @@
6348
6364
  "type": "statement",
6349
6365
  "named": true
6350
6366
  },
6367
+ {
6368
+ "type": "switch_expression_arm",
6369
+ "named": true
6370
+ },
6351
6371
  {
6352
6372
  "type": "type_declaration",
6353
6373
  "named": true
@@ -6384,6 +6404,10 @@
6384
6404
  "multiple": true,
6385
6405
  "required": false,
6386
6406
  "types": [
6407
+ {
6408
+ "type": "argument",
6409
+ "named": true
6410
+ },
6387
6411
  {
6388
6412
  "type": "argument_list",
6389
6413
  "named": true
@@ -6396,6 +6420,10 @@
6396
6420
  "type": "base_list",
6397
6421
  "named": true
6398
6422
  },
6423
+ {
6424
+ "type": "collection_element",
6425
+ "named": true
6426
+ },
6399
6427
  {
6400
6428
  "type": "declaration",
6401
6429
  "named": true
@@ -6428,6 +6456,10 @@
6428
6456
  "type": "statement",
6429
6457
  "named": true
6430
6458
  },
6459
+ {
6460
+ "type": "switch_expression_arm",
6461
+ "named": true
6462
+ },
6431
6463
  {
6432
6464
  "type": "type_declaration",
6433
6465
  "named": true
@@ -6545,6 +6577,10 @@
6545
6577
  "multiple": true,
6546
6578
  "required": false,
6547
6579
  "types": [
6580
+ {
6581
+ "type": "argument",
6582
+ "named": true
6583
+ },
6548
6584
  {
6549
6585
  "type": "argument_list",
6550
6586
  "named": true
@@ -6553,6 +6589,10 @@
6553
6589
  "type": "base_list",
6554
6590
  "named": true
6555
6591
  },
6592
+ {
6593
+ "type": "collection_element",
6594
+ "named": true
6595
+ },
6556
6596
  {
6557
6597
  "type": "declaration",
6558
6598
  "named": true
@@ -6585,6 +6625,10 @@
6585
6625
  "type": "statement",
6586
6626
  "named": true
6587
6627
  },
6628
+ {
6629
+ "type": "switch_expression_arm",
6630
+ "named": true
6631
+ },
6588
6632
  {
6589
6633
  "type": "type_declaration",
6590
6634
  "named": true
Binary file
package/tree-sitter.json CHANGED
@@ -31,7 +31,7 @@
31
31
  }
32
32
  ],
33
33
  "metadata": {
34
- "version": "14.1.2",
34
+ "version": "14.1.3",
35
35
  "license": "MIT",
36
36
  "description": "C# grammar for tree-sitter",
37
37
  "authors": [