@willbooster/tree-sitter-dart 0.0.0-stage → 1.0.1

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 ADDED
@@ -0,0 +1,2385 @@
1
+ /**
2
+ * @file Dart grammar for tree-sitter
3
+ * @author Kasper Overgård Nielsen <kasper@byolimit.com>
4
+ * @license MIT
5
+ */
6
+
7
+ /// <reference types="tree-sitter-cli/dsl" />
8
+ // @ts-check
9
+
10
+ // Operator precedence levels (from Dart spec, ascending)
11
+ const PREC = {
12
+ CASCADE: 2,
13
+ ASSIGNMENT: 3,
14
+ CONDITIONAL: 4,
15
+ IF_NULL: 5,
16
+ LOGICAL_OR: 6,
17
+ LOGICAL_AND: 7,
18
+ EQUALITY: 8,
19
+ RELATIONAL: 9,
20
+ BITWISE_OR: 10,
21
+ BITWISE_XOR: 11,
22
+ BITWISE_AND: 12,
23
+ SHIFT: 13,
24
+ ADDITIVE: 14,
25
+ MULTIPLICATIVE: 15,
26
+ UNARY_PREFIX: 16,
27
+ UNARY_POSTFIX: 17,
28
+ SELECTOR: 18,
29
+ TYPE_IDENTIFIER: 19,
30
+ };
31
+
32
+ function commaSep1(rule) {
33
+ return seq(rule, repeat(seq(",", rule)));
34
+ }
35
+
36
+ function commaSep(rule) {
37
+ return optional(commaSep1(rule));
38
+ }
39
+
40
+ function commaSep1TrailingComma(rule) {
41
+ return seq(rule, repeat(seq(",", rule)), optional(","));
42
+ }
43
+
44
+ function commaSepTrailingComma(rule) {
45
+ return optional(commaSep1TrailingComma(rule));
46
+ }
47
+
48
+ // Wraps a type expression with the optional `?` nullable marker.
49
+ function nullable(rule) {
50
+ return seq(rule, optional("?"));
51
+ }
52
+
53
+ // Produces the 5 wrapper rules shared between non-cascade and cascade postfix
54
+ // chains: member/index/null-aware-member/null-aware-index/null-assertion.
55
+ // `base` is the recursive postfix-chain rule name (the "object" position).
56
+ // `prefix` is "" for non-cascade and "cascade_" for cascade variants.
57
+ function postfixChainWrappers(base, prefix) {
58
+ return {
59
+ [`${prefix}member_expression`]: ($) =>
60
+ prec.left(PREC.UNARY_POSTFIX, seq(
61
+ field("object", $[base]), ".", field("property", $.identifier),
62
+ )),
63
+ [`${prefix}index_expression`]: ($) =>
64
+ prec.left(PREC.UNARY_POSTFIX, seq(
65
+ field("object", $[base]), "[", field("index", $._expression), "]",
66
+ )),
67
+ [`${prefix}null_aware_member_expression`]: ($) =>
68
+ prec.left(PREC.UNARY_POSTFIX, seq(
69
+ field("object", $[base]), "?.", field("property", $.identifier),
70
+ )),
71
+ [`${prefix}null_aware_index_expression`]: ($) =>
72
+ prec.left(PREC.UNARY_POSTFIX, seq(
73
+ field("object", $[base]), "?", "[", field("index", $._expression), "]",
74
+ )),
75
+ [`${prefix}null_assertion_expression`]: ($) =>
76
+ prec.left(PREC.UNARY_POSTFIX, seq(
77
+ field("value", $[base]), "!",
78
+ )),
79
+ };
80
+ }
81
+
82
+ module.exports = grammar({
83
+ name: "dart",
84
+
85
+ externals: ($) => [
86
+ $.template_chars_single,
87
+ $.template_chars_double,
88
+ $.template_chars_single_single,
89
+ $.template_chars_double_single,
90
+ $.template_chars_raw_slash,
91
+ $.block_comment,
92
+ $.documentation_block_comment,
93
+ $.annotation_open_paren,
94
+ ],
95
+
96
+ extras: ($) => [/\s/, $.comment],
97
+
98
+ word: ($) => $._name,
99
+
100
+ supertypes: ($) => [$._statement, $._literal, $._declaration, $._instantiation],
101
+
102
+ precedences: ($) => [
103
+ ["call", "instantiation"],
104
+ ],
105
+
106
+ conflicts: ($) => [
107
+ // Type vs expression ambiguity: `x<y>` could be type args or relational
108
+ // [$.type_arguments, $.relational_expression], -- unnecessary
109
+ // Identifier could be type_identifier or expression
110
+ [$._type_name, $._primary],
111
+ [$._type_name, $._primary, $._function_name],
112
+ // [$._type_name, $._primary, $.function_signature], -- covered by _function_name conflicts
113
+ [$._primary, $._simple_formal_parameter],
114
+ [$._primary, $._simple_formal_parameter, $.constant_pattern],
115
+ // Constructor signature shares prefix with function_signature
116
+ // [$.constructor_signature, $._formal_parameter_part], -- covered by _function_name conflicts
117
+ // Declaration ambiguity with external/static
118
+ [$.declaration, $._external_and_static],
119
+ // Type ambiguities
120
+ [$._type_not_function, $._type_not_void],
121
+ [$._type_not_void_not_function],
122
+ [$._type_not_void],
123
+ [$._function_type_tail],
124
+ [$._type_not_void_not_function, $._function_type_tail],
125
+ [$.type, $._type_not_function],
126
+ [$.type, $._function_type_tail, $._built_in_identifier],
127
+ [$.type, $._type_not_function, $._function_type_tail, $._built_in_identifier],
128
+ [$.type, $._function_type_tail],
129
+ [$.type, $._type_not_function, $._function_type_tail],
130
+ [$._type_not_function, $._function_type_tail, $._built_in_identifier],
131
+ [$._type_not_void, $._function_type_tail, $._built_in_identifier],
132
+ [$._type_not_function, $._type_not_void, $._function_type_tail, $._built_in_identifier],
133
+ [$._type_not_function, $._function_type_tail],
134
+ [$.type, $._type_not_function, $._type_not_void, $._function_type_tail, $._built_in_identifier],
135
+ [$._type_not_void, $._function_type_tail],
136
+ [$.function_type],
137
+ // Var or type ambiguities
138
+ [$._var_or_type],
139
+ [$._var_or_type, $.function_signature],
140
+ [$._var_or_type, $._function_formal_parameter],
141
+ [$._final_const_var_or_type],
142
+ [$._final_const_var_or_type, $.const_object_expression],
143
+ // Expression ambiguities
144
+ [$._expression],
145
+ [$._primary, $.assignable_expression],
146
+ [$._primary, $.labeled_statement],
147
+ // Assignable-vs-wrapper: same chain reduces under either name; lookahead picks
148
+ [$.assignable_expression, $.null_aware_index_expression, $._unary_expression],
149
+ // Type name ambiguities
150
+ [$._type_name],
151
+ // [$._type_name, $._simple_formal_parameter], -- subsumed
152
+ // [$._type_name, $._function_formal_parameter], -- subsumed
153
+ // [$._type_name, $.function_signature], -- covered by _function_name conflicts
154
+ // [$._type_name, $._primary, $.assignable_expression], -- subsumed
155
+ // Parameter ambiguities
156
+ [$._normal_formal_parameters],
157
+ [$._normal_formal_parameter],
158
+ [$.typed_identifier, $._var_or_type, $._function_formal_parameter],
159
+ [$.record_type_field, $._function_formal_parameter, $._var_or_type],
160
+ [$.record_type_field, $._var_or_type, $._final_var_or_type, $._function_formal_parameter],
161
+ [$._var_or_type, $._final_var_or_type],
162
+ [$._var_or_type, $._final_var_or_type, $._function_formal_parameter],
163
+ [$._final_const_var_or_type, $._final_var_or_type],
164
+ [$.record_type_field, $._final_var_or_type],
165
+ [$._final_var_or_type],
166
+ // Type parameter vs type name
167
+ [$.type_parameter, $._type_name],
168
+ // For loop parts ambiguity
169
+ [$._var_or_type, $._for_loop_parts, $.pattern_variable_declaration],
170
+ [$.pattern_variable_declaration, $._for_loop_parts, $._final_const_var_or_type],
171
+ [$.pattern_variable_declaration, $._var_or_type],
172
+ [$._final_const_var_or_type, $.pattern_variable_declaration],
173
+ // Pattern ambiguities
174
+ [$.set_or_map_literal, $.map_pattern],
175
+ [$.list_literal, $.list_pattern],
176
+ [$.static_member_shorthand, $.constant_pattern],
177
+ // [$.constant_pattern, $._type_name], -- subsumed
178
+ [$._primary, $.constant_pattern],
179
+ [$._instantiation, $.constant_pattern],
180
+ // [$._primary, $.constant_pattern, $._type_name], -- subsumed
181
+ // [$._primary, $.constant_pattern, $._simple_formal_parameter], -- subsumed
182
+ // [$._primary, $.constant_pattern, $._type_name, $._simple_formal_parameter], -- subsumed
183
+ [$._literal, $.constant_pattern],
184
+ [$.prefix_operator, $.constant_pattern],
185
+ [$._parenthesized_pattern, $._pattern_field],
186
+ [$.set_or_map_literal, $.constant_pattern],
187
+ [$.list_literal, $.constant_pattern],
188
+ [$.record_literal, $.constant_pattern],
189
+ // Constructor tearoff vs primary
190
+ [$.constructor_tearoff, $._identifier_or_new],
191
+ // [$._simple_formal_parameter, $.assignable_expression], -- unnecessary
192
+ // Declaration external
193
+ [$.declaration, $.external],
194
+ // Type arguments vs type parameters vs relational
195
+ [$.type_arguments, $.relational_operator],
196
+ // [$.relational_operator, $.type_parameters], -- unnecessary
197
+ [$.type_arguments, $.relational_operator, $.type_parameters],
198
+ // Generic call/instantiation vs comparisons (TS-style GLR fork on `<`)
199
+ [$._unary_expression, $.instantiation_expression],
200
+ // Record literal vs record field / record type
201
+ [$._record_literal_no_const, $.record_field],
202
+ [$.record_type, $._record_literal_no_const],
203
+ [$.record_type, $._record_literal_no_const, $.record_pattern],
204
+ [$._record_literal_no_const, $.record_pattern],
205
+ [$.record_type, $.record_pattern],
206
+ [$._record_literal_no_const, $.formal_parameter_list],
207
+ // Block vs set_or_map literal
208
+ [$.block, $.set_or_map_literal],
209
+ // Empty switch block vs empty switch expression
210
+ [$.switch_block, $.switch_expression],
211
+ // Primary + constructor_param
212
+ [$._primary, $.constructor_param],
213
+ // Switch statement case
214
+ [$.switch_statement_case],
215
+ // Primary + function_formal_parameter + type_name
216
+ [$._type_name, $._function_formal_parameter],
217
+ [$._type_name, $.constant_pattern],
218
+ [$._type_name, $._simple_formal_parameter],
219
+ // [$._type_name, $._function_name], -- subsumed
220
+ // [$._type_name, $._function_name, $._primary], -- subsumed
221
+ // [$._function_name, $.constructor_signature], -- subsumed
222
+ // Built-in identifier conflicts
223
+ // Top-level wrapper rules competing with `_built_in_identifier` for the
224
+ // `augment` lookahead. Each top-level form needs to keep itself alive when
225
+ // a containing rule (class/mixin/etc.) is also a candidate.
226
+ [$.function_declaration, $.getter_declaration, $.setter_declaration,
227
+ $.external_function_declaration, $.external_getter_declaration, $.external_setter_declaration,
228
+ $.top_level_variable_declaration, $._built_in_identifier],
229
+ [$.function_declaration, $.getter_declaration, $.setter_declaration,
230
+ $.external_function_declaration, $.external_getter_declaration, $.external_setter_declaration,
231
+ $.top_level_variable_declaration, $.external_variable_declaration, $._built_in_identifier],
232
+ [$.class_declaration, $.function_declaration, $.getter_declaration, $.setter_declaration,
233
+ $.external_function_declaration, $.external_getter_declaration, $.external_setter_declaration,
234
+ $.top_level_variable_declaration, $._built_in_identifier],
235
+ [$.class_declaration, $.mixin_declaration, $.function_declaration, $.getter_declaration, $.setter_declaration,
236
+ $.external_function_declaration, $.external_getter_declaration, $.external_setter_declaration,
237
+ $.top_level_variable_declaration, $._built_in_identifier],
238
+ [$.top_level_variable_declaration, $._built_in_identifier],
239
+ [$.class_member, $.method_declaration, $._built_in_identifier],
240
+ [$.type_alias, $._built_in_identifier],
241
+ [$.function_signature, $.getter_signature, $._var_or_type],
242
+ [$.function_signature, $.setter_signature, $._var_or_type],
243
+ [$._final_const_var_or_type, $._built_in_identifier],
244
+ [$._declared_identifier, $._built_in_identifier],
245
+ [$.external, $._built_in_identifier],
246
+ [$.declaration, $._built_in_identifier],
247
+ [$.method_signature, $.declaration, $._built_in_identifier],
248
+ [$.operator_signature, $._built_in_identifier],
249
+ [$.function_signature, $._var_or_type, $.operator_signature],
250
+ [$._function_formal_parameter, $._declared_identifier, $._built_in_identifier],
251
+ [$.try_statement],
252
+ [$._default_named_parameter, $._built_in_identifier],
253
+ [$.library_name, $._built_in_identifier],
254
+ [$.getter_signature, $._built_in_identifier],
255
+ [$.setter_signature, $._built_in_identifier],
256
+ [$._class_modifiers, $._mixin_class_modifiers, $._built_in_identifier],
257
+ [$._class_modifiers, $._built_in_identifier],
258
+ [$._mixin_class_modifiers, $._built_in_identifier],
259
+ [$._mixin_class_modifiers, $.mixin_declaration, $._built_in_identifier],
260
+ [$.mixin_declaration, $._built_in_identifier],
261
+ [$._type_name, $._function_name],
262
+ [$.extension_declaration, $._built_in_identifier],
263
+ [$.extension_type_declaration, $._built_in_identifier],
264
+ [$._function_formal_parameter, $._simple_formal_parameter, $._declared_identifier, $._built_in_identifier],
265
+ [$._named_parameter_type, $._built_in_identifier],
266
+ [$.declaration, $.external, $._built_in_identifier],
267
+ [$.declaration, $._external_and_static, $._built_in_identifier],
268
+ [$.factory_constructor_signature, $.redirecting_factory_constructor_signature, $._built_in_identifier],
269
+ [$.redirecting_factory_constructor_signature, $._built_in_identifier],
270
+ [$._function_name, $.constructor_signature],
271
+ [$._type_name, $._primary, $.constant_pattern],
272
+ [$._type_name, $._primary, $._function_formal_parameter],
273
+ [$._type_name, $._primary, $._simple_formal_parameter, $.constant_pattern],
274
+ [$._type_name, $.assignable_expression, $._primary],
275
+ [$._type_not_void_not_function, $._function_type_tail, $._built_in_identifier],
276
+ [$._function_type_tail, $._built_in_identifier],
277
+ [$.factory_constructor_signature, $._built_in_identifier],
278
+ [$.assignable_expression, $._simple_formal_parameter],
279
+ [$._primary, $.super_formal_parameter],
280
+ // this.identifier in initializer_list_entry vs redirection
281
+ [$.initializer_list_entry, $._identifier_or_new],
282
+ ],
283
+
284
+ rules: {
285
+ // ========================================================================
286
+ // Top-level structure
287
+ // ========================================================================
288
+
289
+ source_file: ($) =>
290
+ seq(
291
+ optional($.script_tag),
292
+ optional($.library_name),
293
+ repeat($.import_or_export),
294
+ repeat($.part_directive),
295
+ repeat($.part_of_directive),
296
+ repeat($._top_level_definition),
297
+ ),
298
+
299
+ _top_level_definition: ($) =>
300
+ choice(
301
+ $._declaration,
302
+ $.function_declaration,
303
+ $.getter_declaration,
304
+ $.setter_declaration,
305
+ $.external_function_declaration,
306
+ $.external_getter_declaration,
307
+ $.external_setter_declaration,
308
+ $.top_level_variable_declaration,
309
+ $.external_variable_declaration,
310
+ ),
311
+
312
+ // ========================================================================
313
+ // Library structure (Phase 9)
314
+ // ========================================================================
315
+
316
+ script_tag: (_) => seq("#!", /[^\n]*/, "\n"),
317
+
318
+ library_name: ($) =>
319
+ choice(
320
+ seq(
321
+ optional($._metadata),
322
+ "library",
323
+ optional($.dotted_identifier_list),
324
+ ";",
325
+ ),
326
+ seq(
327
+ optional($._metadata),
328
+ "library",
329
+ "augment",
330
+ field("uri", $.uri),
331
+ ";",
332
+ ),
333
+ ),
334
+
335
+ import_or_export: ($) =>
336
+ prec(PREC.TYPE_IDENTIFIER, choice($.library_import, $.library_export)),
337
+
338
+ library_import: ($) => seq(optional($._metadata), $.import_specification),
339
+
340
+ import_specification: ($) =>
341
+ choice(
342
+ seq(
343
+ "import",
344
+ field("uri", $.configurable_uri),
345
+ optional(seq(optional("deferred"), "as", field("alias", $.identifier))),
346
+ repeat($.combinator),
347
+ ";",
348
+ ),
349
+ prec(1, seq(
350
+ "import",
351
+ field("uri", $.uri),
352
+ "deferred",
353
+ "as",
354
+ field("alias", $.identifier),
355
+ repeat($.combinator),
356
+ ";",
357
+ )),
358
+ ),
359
+
360
+ library_export: ($) =>
361
+ seq(
362
+ optional($._metadata),
363
+ "export",
364
+ field("uri", $.configurable_uri),
365
+ repeat($.combinator),
366
+ ";",
367
+ ),
368
+
369
+ part_directive: ($) =>
370
+ seq(optional($._metadata), "part", field("uri", $.uri), ";"),
371
+
372
+ part_of_directive: ($) =>
373
+ seq(
374
+ optional($._metadata),
375
+ "part",
376
+ "of",
377
+ choice($.dotted_identifier_list, $.uri),
378
+ ";",
379
+ ),
380
+
381
+ uri: ($) => $.string_literal,
382
+
383
+ configurable_uri: ($) => seq($.uri, repeat($.configuration_uri)),
384
+
385
+ configuration_uri: ($) =>
386
+ seq("if", "(", $.uri_test, ")", $.uri),
387
+
388
+ uri_test: ($) =>
389
+ seq($.dotted_identifier_list, optional(seq("==", $.string_literal))),
390
+
391
+ combinator: ($) =>
392
+ choice(
393
+ seq("show", commaSep1($.identifier)),
394
+ seq("hide", commaSep1($.identifier)),
395
+ ),
396
+
397
+ dotted_identifier_list: ($) => seq($.identifier, repeat(seq(".", $.identifier))),
398
+
399
+ // ========================================================================
400
+ // Metadata / Annotations (Phase 9)
401
+ // ========================================================================
402
+
403
+ _metadata: ($) => repeat1($._annotation),
404
+
405
+ _annotation: ($) =>
406
+ choice(
407
+ alias($._annotation_with_args, $.annotation),
408
+ alias($._annotation_no_args, $.annotation),
409
+ ),
410
+
411
+ _annotation_with_args: ($) =>
412
+ seq(
413
+ "@",
414
+ field("name", choice($.identifier, $.qualified)),
415
+ optional(seq($.type_arguments, optional(seq(".", $._identifier_or_new)))),
416
+ $.annotation_arguments,
417
+ ),
418
+
419
+ annotation_arguments: ($) =>
420
+ seq($.annotation_open_paren, optional($._argument_list), ")"),
421
+
422
+ _annotation_no_args: ($) =>
423
+ seq("@", field("name", choice($.identifier, $.qualified))),
424
+
425
+ qualified: ($) =>
426
+ choice(
427
+ seq($._type_name, ".", $._identifier_or_new),
428
+ seq($._type_name, ".", $._type_name, ".", $._identifier_or_new),
429
+ ),
430
+
431
+ // ========================================================================
432
+ // Types (Phase 2)
433
+ // ========================================================================
434
+
435
+ // Public wrapper: every type-labeled position emits exactly one `type`
436
+ // child. The scope-restricted variants below alias to `type` so consumers
437
+ // see a uniform `(type ...)` regardless of which slot matched.
438
+ type: ($) =>
439
+ choice(
440
+ nullable($.function_type),
441
+ nullable($.record_type),
442
+ $.void_type,
443
+ nullable(seq($._type_name, optional($.type_arguments))),
444
+ nullable("Function"),
445
+ ),
446
+
447
+ _type_not_function: ($) =>
448
+ alias(
449
+ choice(
450
+ nullable(seq($._type_name, optional($.type_arguments))),
451
+ nullable("Function"),
452
+ nullable($.record_type),
453
+ $.void_type,
454
+ ),
455
+ $.type,
456
+ ),
457
+
458
+ _type_not_void: ($) =>
459
+ alias(
460
+ choice(
461
+ nullable($.function_type),
462
+ nullable($.record_type),
463
+ nullable(seq($._type_name, optional($.type_arguments))),
464
+ nullable("Function"),
465
+ ),
466
+ $.type,
467
+ ),
468
+
469
+ _type_not_void_not_function: ($) =>
470
+ alias(
471
+ choice(
472
+ nullable(seq($._type_name, optional($.type_arguments))),
473
+ nullable("Function"),
474
+ ),
475
+ $.type,
476
+ ),
477
+
478
+ _type_name: ($) =>
479
+ seq(
480
+ alias($.identifier, $.type_identifier),
481
+ optional(
482
+ prec.right(PREC.TYPE_IDENTIFIER, seq(".", alias($.identifier, $.type_identifier))),
483
+ ),
484
+ ),
485
+
486
+ void_type: (_) => "void",
487
+
488
+ function_type: ($) =>
489
+ choice(
490
+ $._function_type_tails,
491
+ seq($._type_not_function, $._function_type_tails),
492
+ ),
493
+
494
+ _function_type_tails: ($) => repeat1($._function_type_tail),
495
+
496
+ _function_type_tail: ($) =>
497
+ seq(
498
+ "Function",
499
+ optional($.type_parameters),
500
+ optional($.parameter_type_list),
501
+ optional("?"),
502
+ ),
503
+
504
+ parameter_type_list: ($) =>
505
+ seq(
506
+ "(",
507
+ optional(
508
+ choice(
509
+ commaSep1TrailingComma($.normal_parameter_type),
510
+ seq(
511
+ commaSep1($.normal_parameter_type),
512
+ ",",
513
+ $.optional_parameter_types,
514
+ ),
515
+ $.optional_parameter_types,
516
+ ),
517
+ ),
518
+ ")",
519
+ ),
520
+
521
+ normal_parameter_type: ($) =>
522
+ seq(optional($._metadata), choice($.typed_identifier, $.type)),
523
+
524
+ optional_parameter_types: ($) =>
525
+ choice(
526
+ $.optional_positional_parameter_types,
527
+ $.named_parameter_types,
528
+ ),
529
+
530
+ optional_positional_parameter_types: ($) =>
531
+ seq("[", commaSep1TrailingComma($.normal_parameter_type), "]"),
532
+
533
+ named_parameter_types: ($) =>
534
+ seq("{", commaSep1TrailingComma($._named_parameter_type), "}"),
535
+
536
+ _named_parameter_type: ($) =>
537
+ seq(optional($._metadata), optional("required"), $.typed_identifier),
538
+
539
+ typed_identifier: ($) => seq(field("type", $.type), field("name", $.identifier)),
540
+
541
+ type_arguments: ($) =>
542
+ seq("<", commaSep1($.type), ">"),
543
+
544
+ type_parameters: ($) =>
545
+ seq("<", commaSep1($.type_parameter), ">"),
546
+
547
+ type_parameter: ($) =>
548
+ seq(
549
+ optional($._metadata),
550
+ optional(field("variance", $.variance_modifier)),
551
+ field("name", alias($.identifier, $.type_identifier)),
552
+ optional(seq("extends", field("bound", $._type_not_void))),
553
+ ),
554
+
555
+ variance_modifier: (_) => choice("in", "out", "inout"),
556
+
557
+ record_type: ($) =>
558
+ choice(
559
+ seq("(", ")"),
560
+ seq(
561
+ "(",
562
+ commaSep1($.record_type_field),
563
+ ",",
564
+ "{",
565
+ commaSep1TrailingComma($.record_type_named_field),
566
+ "}",
567
+ ")",
568
+ ),
569
+ seq("(", commaSep1TrailingComma($.record_type_field), ")"),
570
+ seq(
571
+ "(",
572
+ "{",
573
+ commaSep1TrailingComma($.record_type_named_field),
574
+ "}",
575
+ ")",
576
+ ),
577
+ ),
578
+
579
+ record_type_field: ($) =>
580
+ seq(optional($._metadata), field("type", $.type), optional(field("name", $.identifier))),
581
+
582
+ record_type_named_field: ($) =>
583
+ seq(optional($._metadata), $.typed_identifier),
584
+
585
+ // ========================================================================
586
+ // Literals (Phase 3)
587
+ // ========================================================================
588
+
589
+ _literal: ($) =>
590
+ choice(
591
+ $.null_literal,
592
+ $.true,
593
+ $.false,
594
+ $.decimal_integer_literal,
595
+ $.hex_integer_literal,
596
+ $.decimal_floating_point_literal,
597
+ $.string_literal,
598
+ $.symbol_literal,
599
+ $.list_literal,
600
+ $.set_or_map_literal,
601
+ $.record_literal,
602
+ ),
603
+
604
+ null_literal: (_) => "null",
605
+
606
+ true: (_) => "true",
607
+ false: (_) => "false",
608
+
609
+ // Numeric literals (with digit separator support for Dart 3.6)
610
+ decimal_integer_literal: (_) =>
611
+ token(sep1(/[0-9]+/, /_+/)),
612
+
613
+ hex_integer_literal: (_) =>
614
+ token(seq(choice("0x", "0X"), sep1(/[A-Fa-f0-9]+/, /_+/))),
615
+
616
+ decimal_floating_point_literal: (_) =>
617
+ token(
618
+ choice(
619
+ seq(
620
+ sep1(/[0-9]+/, /_+/),
621
+ ".",
622
+ sep1(/[0-9]+/, /_+/),
623
+ optional(seq(/[eE]/, optional(choice("-", "+")), sep1(/[0-9]+/, /_+/))),
624
+ ),
625
+ seq(
626
+ ".",
627
+ sep1(/[0-9]+/, /_+/),
628
+ optional(seq(/[eE]/, optional(choice("-", "+")), sep1(/[0-9]+/, /_+/))),
629
+ ),
630
+ seq(sep1(/[0-9]+/, /_+/), /[eE]/, optional(choice("-", "+")), sep1(/[0-9]+/, /_+/)),
631
+ ),
632
+ ),
633
+
634
+ // --- Strings ---
635
+
636
+ string_literal: ($) =>
637
+ repeat1(
638
+ choice(
639
+ $.string_literal_double_quotes,
640
+ $.string_literal_single_quotes,
641
+ $.string_literal_double_quotes_multiple,
642
+ $.string_literal_single_quotes_multiple,
643
+ $.raw_string_literal_double_quotes,
644
+ $.raw_string_literal_single_quotes,
645
+ $.raw_string_literal_double_quotes_multiple,
646
+ $.raw_string_literal_single_quotes_multiple,
647
+ ),
648
+ ),
649
+
650
+ string_literal_double_quotes: ($) =>
651
+ seq(
652
+ '"',
653
+ repeat(
654
+ choice(
655
+ $.template_chars_double_single,
656
+ "'",
657
+ $.escape_sequence,
658
+ $._sub_string_test,
659
+ $.template_substitution,
660
+ ),
661
+ ),
662
+ '"',
663
+ ),
664
+
665
+ string_literal_single_quotes: ($) =>
666
+ seq(
667
+ "'",
668
+ repeat(
669
+ choice(
670
+ $.template_chars_single_single,
671
+ '"',
672
+ $.escape_sequence,
673
+ $._sub_string_test,
674
+ $.template_substitution,
675
+ ),
676
+ ),
677
+ "'",
678
+ ),
679
+
680
+ string_literal_double_quotes_multiple: ($) =>
681
+ prec.left(
682
+ seq(
683
+ '"""',
684
+ repeat(
685
+ choice(
686
+ $.template_chars_double,
687
+ "'",
688
+ '"',
689
+ $.escape_sequence,
690
+ $._sub_string_test,
691
+ $.template_substitution,
692
+ ),
693
+ ),
694
+ '"""',
695
+ ),
696
+ ),
697
+
698
+ string_literal_single_quotes_multiple: ($) =>
699
+ prec.left(
700
+ seq(
701
+ "'''",
702
+ repeat(
703
+ choice(
704
+ $.template_chars_single,
705
+ '"',
706
+ "'",
707
+ $.escape_sequence,
708
+ $._sub_string_test,
709
+ $.template_substitution,
710
+ ),
711
+ ),
712
+ "'''",
713
+ ),
714
+ ),
715
+
716
+ raw_string_literal_double_quotes: ($) =>
717
+ seq(
718
+ 'r"',
719
+ repeat(
720
+ choice(
721
+ $.template_chars_double_single,
722
+ "'",
723
+ $.template_chars_raw_slash,
724
+ $._unused_escape_sequence,
725
+ $._sub_string_test,
726
+ "$",
727
+ ),
728
+ ),
729
+ '"',
730
+ ),
731
+
732
+ raw_string_literal_single_quotes: ($) =>
733
+ seq(
734
+ "r'",
735
+ repeat(
736
+ choice(
737
+ $.template_chars_single_single,
738
+ '"',
739
+ $.template_chars_raw_slash,
740
+ $._unused_escape_sequence,
741
+ $._sub_string_test,
742
+ "$",
743
+ ),
744
+ ),
745
+ "'",
746
+ ),
747
+
748
+ raw_string_literal_double_quotes_multiple: ($) =>
749
+ prec.left(
750
+ seq(
751
+ 'r"""',
752
+ repeat(
753
+ choice(
754
+ $.template_chars_double,
755
+ "'",
756
+ $.template_chars_raw_slash,
757
+ '"',
758
+ $._unused_escape_sequence,
759
+ $._sub_string_test,
760
+ "$",
761
+ ),
762
+ ),
763
+ '"""',
764
+ ),
765
+ ),
766
+
767
+ raw_string_literal_single_quotes_multiple: ($) =>
768
+ prec.left(
769
+ seq(
770
+ "r'''",
771
+ repeat(
772
+ choice(
773
+ $.template_chars_single,
774
+ '"',
775
+ "'",
776
+ $.template_chars_raw_slash,
777
+ $._unused_escape_sequence,
778
+ $._sub_string_test,
779
+ "$",
780
+ ),
781
+ ),
782
+ "'''",
783
+ ),
784
+ ),
785
+
786
+ template_substitution: ($) =>
787
+ seq(
788
+ "$",
789
+ choice(
790
+ seq("{", $._expression, "}"),
791
+ $.identifier_dollar_escaped,
792
+ ),
793
+ ),
794
+
795
+ _sub_string_test: (_) => seq("$", /[^a-zA-Z_{]/),
796
+
797
+ identifier_dollar_escaped: (_) => /([a-zA-Z_]|(\\\$))([\w]|(\\\$))*/,
798
+
799
+ _unused_escape_sequence: (_) =>
800
+ token.immediate(
801
+ seq(
802
+ "\\",
803
+ choice(
804
+ /[^xu0-7]/,
805
+ /[0-7]{1,3}/,
806
+ /x[0-9a-fA-F]{2}/,
807
+ /u[0-9a-fA-F]{4}/,
808
+ /u\{[0-9a-fA-F]+\}/,
809
+ ),
810
+ ),
811
+ ),
812
+
813
+ escape_sequence: ($) => $._unused_escape_sequence,
814
+
815
+ // --- Symbol literals ---
816
+
817
+ symbol_literal: ($) =>
818
+ prec.right(
819
+ seq(
820
+ "#",
821
+ choice(
822
+ seq($.identifier, repeat(seq(".", $.identifier))),
823
+ "~",
824
+ $.binary_operator,
825
+ "[]",
826
+ "[]=",
827
+ ),
828
+ ),
829
+ ),
830
+
831
+ // --- Collection literals ---
832
+
833
+ list_literal: ($) =>
834
+ seq(
835
+ optional("const"),
836
+ optional($.type_arguments),
837
+ "[",
838
+ commaSepTrailingComma($._element),
839
+ "]",
840
+ ),
841
+
842
+ set_or_map_literal: ($) =>
843
+ seq(
844
+ optional("const"),
845
+ optional($.type_arguments),
846
+ "{",
847
+ commaSepTrailingComma($._element),
848
+ "}",
849
+ ),
850
+
851
+ _element: ($) =>
852
+ choice(
853
+ $._expression,
854
+ $.pair,
855
+ $.spread_element,
856
+ $.null_aware_element,
857
+ $.null_aware_pair,
858
+ $.if_element,
859
+ $.for_element,
860
+ ),
861
+
862
+ null_aware_element: ($) => seq("?", $._expression),
863
+
864
+ null_aware_pair: ($) =>
865
+ seq("?", field("key", $._expression), ":", field("value", choice($._expression, $.null_aware_element))),
866
+
867
+ pair: ($) =>
868
+ seq(
869
+ field("key", $._expression),
870
+ ":",
871
+ field("value", choice($._expression, $.null_aware_element)),
872
+ ),
873
+
874
+ spread_element: ($) => seq(choice("...", "...?"), field("value", $._expression)),
875
+
876
+ if_element: ($) =>
877
+ prec.right(
878
+ seq(
879
+ "if",
880
+ "(",
881
+ field("condition", $._expression),
882
+ optional(seq("case", $._guarded_pattern)),
883
+ ")",
884
+ field("consequence", $._element),
885
+ optional(seq("else", field("alternative", $._element))),
886
+ ),
887
+ ),
888
+
889
+ for_element: ($) =>
890
+ seq(
891
+ optional("await"),
892
+ "for",
893
+ "(", $._for_loop_parts, ")",
894
+ field("body", $._element),
895
+ ),
896
+
897
+ // --- Record literals ---
898
+
899
+ record_literal: ($) =>
900
+ seq(optional("const"), $._record_literal_no_const),
901
+
902
+ _record_literal_no_const: ($) =>
903
+ choice(
904
+ seq("(", ")"),
905
+ seq(
906
+ "(",
907
+ choice(
908
+ seq($.label, $._expression, optional(",")),
909
+ seq($._expression, ","),
910
+ seq($.record_field, repeat1(seq(",", $.record_field)), optional(",")),
911
+ ),
912
+ ")",
913
+ ),
914
+ ),
915
+
916
+ record_field: ($) => seq(optional($.label), $._expression),
917
+
918
+ // ========================================================================
919
+ // Expressions (Phase 4)
920
+ // ========================================================================
921
+
922
+ _expression: ($) =>
923
+ choice(
924
+ $.pattern_assignment,
925
+ $.assignment_expression,
926
+ $.throw_expression,
927
+ seq($._real_expression, repeat($.cascade_section)),
928
+ ),
929
+
930
+ _expression_without_cascade: ($) =>
931
+ choice(
932
+ $.assignment_expression,
933
+ $._real_expression,
934
+ $.throw_expression,
935
+ ),
936
+
937
+ _real_expression: ($) =>
938
+ choice(
939
+ $.conditional_expression,
940
+ $.logical_or_expression,
941
+ $.if_null_expression,
942
+ $.logical_and_expression,
943
+ $.equality_expression,
944
+ $.relational_expression,
945
+ $.bitwise_or_expression,
946
+ $.bitwise_xor_expression,
947
+ $.bitwise_and_expression,
948
+ $.shift_expression,
949
+ $.additive_expression,
950
+ $.multiplicative_expression,
951
+ $.type_cast_expression,
952
+ $.type_test_expression,
953
+ $._unary_expression,
954
+ ),
955
+
956
+ // --- Throw ---
957
+
958
+ throw_expression: ($) => seq("throw", field("value", $._expression)),
959
+
960
+ // --- Assignment ---
961
+
962
+ assignment_expression: ($) =>
963
+ prec.right(
964
+ PREC.ASSIGNMENT,
965
+ seq(
966
+ field("left", $.assignable_expression),
967
+ field("operator", $._assignment_operator),
968
+ field("right", $._expression),
969
+ ),
970
+ ),
971
+
972
+ _assignment_operator: (_) =>
973
+ choice(
974
+ "=", "+=", "-=", "*=", "/=", "%=", "~/=",
975
+ "<<=", ">>=", ">>>=", "&=", "^=", "|=", "??=",
976
+ ),
977
+
978
+ assignable_expression: ($) =>
979
+ choice(
980
+ $.identifier,
981
+ seq(
982
+ field("object", $._postfix_expression),
983
+ ".",
984
+ field("property", $.identifier),
985
+ ),
986
+ seq(
987
+ field("object", $._postfix_expression),
988
+ "[",
989
+ field("index", $._expression),
990
+ "]",
991
+ ),
992
+ seq(
993
+ field("object", $._postfix_expression),
994
+ "?.",
995
+ field("property", $.identifier),
996
+ ),
997
+ seq(
998
+ field("object", $._postfix_expression),
999
+ "?",
1000
+ "[",
1001
+ field("index", $._expression),
1002
+ "]",
1003
+ ),
1004
+ ),
1005
+
1006
+ // --- Conditional ---
1007
+
1008
+ conditional_expression: ($) =>
1009
+ prec.left(
1010
+ PREC.CONDITIONAL,
1011
+ seq(
1012
+ $._real_expression,
1013
+ "?",
1014
+ field("consequence", $._expression_without_cascade),
1015
+ ":",
1016
+ field("alternative", $._expression_without_cascade),
1017
+ ),
1018
+ ),
1019
+
1020
+ // --- If-null ---
1021
+
1022
+ if_null_expression: ($) =>
1023
+ prec.left(
1024
+ PREC.IF_NULL,
1025
+ seq($._real_expression, repeat1(seq("??", $._real_expression))),
1026
+ ),
1027
+
1028
+ // --- Logical ---
1029
+
1030
+ logical_or_expression: ($) =>
1031
+ prec.left(PREC.LOGICAL_OR, seq($._real_expression, "||", $._real_expression)),
1032
+
1033
+ logical_and_expression: ($) =>
1034
+ prec.left(PREC.LOGICAL_AND, seq($._real_expression, "&&", $._real_expression)),
1035
+
1036
+ // --- Equality ---
1037
+
1038
+ equality_expression: ($) =>
1039
+ prec.left(
1040
+ PREC.EQUALITY,
1041
+ choice(
1042
+ seq($._real_expression, choice("==", "!="), $._real_expression),
1043
+ seq("super", choice("==", "!="), $._real_expression),
1044
+ ),
1045
+ ),
1046
+
1047
+ // --- Relational ---
1048
+
1049
+ relational_expression: ($) =>
1050
+ prec.left(
1051
+ PREC.RELATIONAL,
1052
+ choice(
1053
+ seq($._real_expression, $.relational_operator, $._real_expression),
1054
+ seq("super", $.relational_operator, $._real_expression),
1055
+ ),
1056
+ ),
1057
+
1058
+ relational_operator: (_) => choice("<", ">", "<=", ">="),
1059
+
1060
+ // --- Type test/cast ---
1061
+
1062
+ type_test_expression: ($) =>
1063
+ prec(PREC.RELATIONAL, seq($._real_expression, $.type_test)),
1064
+
1065
+ type_test: ($) => seq($.is_operator, $._type_not_void),
1066
+
1067
+ is_operator: (_) => seq("is", optional("!")),
1068
+
1069
+ type_cast_expression: ($) =>
1070
+ prec.left(PREC.RELATIONAL, seq($._real_expression, $.type_cast)),
1071
+
1072
+ type_cast: ($) => seq("as", $._type_not_void),
1073
+
1074
+ // --- Bitwise ---
1075
+
1076
+ bitwise_or_expression: ($) =>
1077
+ prec.left(
1078
+ PREC.BITWISE_OR,
1079
+ choice(
1080
+ seq($._real_expression, "|", $._real_expression),
1081
+ seq("super", repeat1(seq("|", $._real_expression))),
1082
+ ),
1083
+ ),
1084
+
1085
+ bitwise_xor_expression: ($) =>
1086
+ prec.left(
1087
+ PREC.BITWISE_XOR,
1088
+ choice(
1089
+ seq($._real_expression, "^", $._real_expression),
1090
+ seq("super", repeat1(seq("^", $._real_expression))),
1091
+ ),
1092
+ ),
1093
+
1094
+ bitwise_and_expression: ($) =>
1095
+ prec.left(
1096
+ PREC.BITWISE_AND,
1097
+ choice(
1098
+ seq($._real_expression, "&", $._real_expression),
1099
+ seq("super", repeat1(seq("&", $._real_expression))),
1100
+ ),
1101
+ ),
1102
+
1103
+ // --- Shift ---
1104
+
1105
+ shift_expression: ($) =>
1106
+ prec.left(
1107
+ PREC.SHIFT,
1108
+ choice(
1109
+ seq($._real_expression, $._shift_operator, $._real_expression),
1110
+ seq("super", repeat1(seq($._shift_operator, $._real_expression))),
1111
+ ),
1112
+ ),
1113
+
1114
+ _shift_operator: (_) => choice("<<", ">>>", ">>"),
1115
+
1116
+ // --- Additive ---
1117
+
1118
+ additive_expression: ($) =>
1119
+ prec.left(
1120
+ PREC.ADDITIVE,
1121
+ choice(
1122
+ seq($._real_expression, $._additive_operator, $._real_expression),
1123
+ seq("super", repeat1(seq($._additive_operator, $._real_expression))),
1124
+ ),
1125
+ ),
1126
+
1127
+ _additive_operator: (_) => choice("+", "-"),
1128
+
1129
+ // --- Multiplicative ---
1130
+
1131
+ multiplicative_expression: ($) =>
1132
+ prec.left(
1133
+ PREC.MULTIPLICATIVE,
1134
+ choice(
1135
+ seq(
1136
+ $._unary_expression,
1137
+ repeat1(seq(choice("*", "/", "%", "~/"), $._unary_expression)),
1138
+ ),
1139
+ seq("super", repeat1(seq(choice("*", "/", "%", "~/"), $._unary_expression))),
1140
+ ),
1141
+ ),
1142
+
1143
+ // --- Unary ---
1144
+
1145
+ _unary_expression: ($) =>
1146
+ prec(
1147
+ PREC.UNARY_PREFIX,
1148
+ choice($._postfix_expression, $.unary_expression, $.function_expression),
1149
+ ),
1150
+
1151
+ unary_expression: ($) =>
1152
+ prec(
1153
+ PREC.UNARY_PREFIX,
1154
+ choice(
1155
+ seq($.prefix_operator, $._unary_expression),
1156
+ seq($.negate_operator, $._unary_expression),
1157
+ $.await_expression,
1158
+ seq(choice("-", "~"), "super"),
1159
+ seq(choice("++", "--"), $.assignable_expression),
1160
+ ),
1161
+ ),
1162
+
1163
+ prefix_operator: (_) => choice("-", "~"),
1164
+
1165
+ negate_operator: (_) => "!",
1166
+
1167
+ await_expression: ($) => seq("await", $._unary_expression),
1168
+
1169
+ // --- Postfix ---
1170
+
1171
+ _postfix_expression: ($) =>
1172
+ choice(
1173
+ $._primary,
1174
+ $.call_expression,
1175
+ $.member_expression,
1176
+ $.index_expression,
1177
+ $.null_aware_member_expression,
1178
+ $.null_aware_index_expression,
1179
+ $.null_assertion_expression,
1180
+ $.instantiation_expression,
1181
+ $.postfix_expression,
1182
+ ),
1183
+
1184
+ postfix_expression: ($) =>
1185
+ prec.right(
1186
+ seq(field("argument", $.assignable_expression), choice("++", "--")),
1187
+ ),
1188
+
1189
+ call_expression: ($) =>
1190
+ prec.dynamic(1, prec("call",
1191
+ seq(
1192
+ field("function", $._postfix_expression),
1193
+ field("arguments", $.arguments),
1194
+ ),
1195
+ )),
1196
+
1197
+ // Named prec required so the `<` ambiguity (call/instantiation/relational)
1198
+ // falls through to GLR conflict declarations rather than being auto-resolved.
1199
+ instantiation_expression: ($) =>
1200
+ prec("instantiation",
1201
+ seq(
1202
+ field("function", $._postfix_expression),
1203
+ field("type_arguments", $.type_arguments),
1204
+ ),
1205
+ ),
1206
+
1207
+ ...postfixChainWrappers("_postfix_expression", ""),
1208
+
1209
+ // --- Cascade ---
1210
+
1211
+ cascade_section: ($) =>
1212
+ prec.left(
1213
+ PREC.CASCADE,
1214
+ seq(
1215
+ choice("..", "?.."),
1216
+ $._cascade_postfix_expression,
1217
+ optional(seq($._assignment_operator, $._expression_without_cascade)),
1218
+ ),
1219
+ ),
1220
+
1221
+ _cascade_postfix_expression: ($) =>
1222
+ choice(
1223
+ $.cascade_selector,
1224
+ $.cascade_call_expression,
1225
+ $.cascade_member_expression,
1226
+ $.cascade_index_expression,
1227
+ $.cascade_null_aware_member_expression,
1228
+ $.cascade_null_aware_index_expression,
1229
+ $.cascade_null_assertion_expression,
1230
+ ),
1231
+
1232
+ cascade_selector: ($) =>
1233
+ choice(
1234
+ seq(optional("?"), "[", $._expression, "]"),
1235
+ $.identifier,
1236
+ ),
1237
+
1238
+ // cascade_call_expression keeps `optional(type_arguments)` inline because
1239
+ // there's no `cascade_instantiation_expression` - bare `..foo<int>` (cascade
1240
+ // tearoff) isn't valid Dart, so the `<` fork that forced the call/instantiation
1241
+ // split on the non-cascade side doesn't apply here.
1242
+ //
1243
+ // The simple `..foo()` / `..foo<T>()` form exposes the method name as
1244
+ // `property:` directly (mirroring `member_expression` and
1245
+ // `cascade_member_expression`), so consumers don't need an extra hop
1246
+ // through `cascade_selector`. Chained forms (e.g. `..foo().bar()`) keep
1247
+ // the `function:` field for the more complex tail.
1248
+ cascade_call_expression: ($) =>
1249
+ prec.left(
1250
+ PREC.UNARY_POSTFIX,
1251
+ choice(
1252
+ prec.dynamic(1, seq(
1253
+ field("property", $.identifier),
1254
+ optional(field("type_arguments", $.type_arguments)),
1255
+ field("arguments", $.arguments),
1256
+ )),
1257
+ seq(
1258
+ field("function", $._cascade_postfix_expression),
1259
+ optional(field("type_arguments", $.type_arguments)),
1260
+ field("arguments", $.arguments),
1261
+ ),
1262
+ ),
1263
+ ),
1264
+
1265
+ ...postfixChainWrappers("_cascade_postfix_expression", "cascade_"),
1266
+
1267
+ // --- Primary expressions ---
1268
+
1269
+ _primary: ($) =>
1270
+ choice(
1271
+ $._literal,
1272
+ $.identifier,
1273
+ alias($._function_primary, $.function_expression),
1274
+ $._instantiation,
1275
+ $.parenthesized_expression,
1276
+ "this",
1277
+ "super",
1278
+ $.constructor_tearoff,
1279
+ $.switch_expression,
1280
+ $.static_member_shorthand,
1281
+ ),
1282
+
1283
+ parenthesized_expression: ($) => seq("(", $._expression, ")"),
1284
+
1285
+ function_expression: ($) =>
1286
+ seq(
1287
+ field("parameters", $._formal_parameter_part),
1288
+ field("body", $.function_expression_body),
1289
+ ),
1290
+
1291
+ function_expression_body: ($) =>
1292
+ seq(optional("async"), "=>", $._expression),
1293
+
1294
+ _function_primary: ($) =>
1295
+ seq(
1296
+ field("parameters", $._formal_parameter_part),
1297
+ field("body", alias($._function_primary_body, $.function_expression_body)),
1298
+ ),
1299
+
1300
+ _function_primary_body: ($) =>
1301
+ seq(optional(choice("async", "async*", "sync*")), $.block),
1302
+
1303
+ // Hidden supertype: any expression that constructs an instance. Lets
1304
+ // queries address the three forms (new/const/implicit) uniformly via
1305
+ // (_instantiation) without alternation. Does not add an AST layer.
1306
+ _instantiation: ($) =>
1307
+ choice($.new_expression, $.const_object_expression, $.constructor_invocation),
1308
+
1309
+ new_expression: ($) =>
1310
+ seq("new", field("type", $._type_not_void), optional(seq(".", field("constructor", $.identifier))), field("arguments", $.arguments)),
1311
+
1312
+ const_object_expression: ($) =>
1313
+ seq("const", field("type", $._type_not_void), optional(seq(".", field("constructor", $.identifier))), field("arguments", $.arguments)),
1314
+
1315
+ constructor_invocation: ($) =>
1316
+ prec.right(
1317
+ choice(
1318
+ seq(field("type", $._type_name), $.type_arguments, ".", field("constructor", $.identifier), field("arguments", $.arguments)),
1319
+ seq(field("type", $._type_name), ".", "new", field("arguments", $.arguments)),
1320
+ ),
1321
+ ),
1322
+
1323
+ constructor_tearoff: ($) =>
1324
+ prec.right(
1325
+ seq($._type_name, optional($.type_arguments), ".", "new"),
1326
+ ),
1327
+
1328
+ // Dot shorthand syntax (Dart 3.10+)
1329
+ static_member_shorthand: ($) =>
1330
+ prec.dynamic(-1,
1331
+ choice(
1332
+ seq(".", $.identifier),
1333
+ seq(".", "new"),
1334
+ seq("const", ".", choice($.identifier, "new"), $.arguments),
1335
+ ),
1336
+ ),
1337
+
1338
+ // --- Arguments ---
1339
+
1340
+ arguments: ($) => seq("(", optional($._argument_list), ")"),
1341
+
1342
+ _argument_list: ($) =>
1343
+ prec.right(commaSep1TrailingComma(choice($.named_argument, $._expression))),
1344
+
1345
+ named_argument: ($) => seq($.label, $._expression),
1346
+
1347
+ // ========================================================================
1348
+ // Formal Parameters (Phase 5)
1349
+ // ========================================================================
1350
+
1351
+ _formal_parameter_part: ($) =>
1352
+ seq(optional($.type_parameters), $.formal_parameter_list),
1353
+
1354
+ formal_parameter_list: ($) =>
1355
+ choice(
1356
+ seq("(", ")"),
1357
+ seq("(", $._normal_formal_parameters, optional(","), ")"),
1358
+ seq(
1359
+ "(",
1360
+ $._normal_formal_parameters,
1361
+ ",",
1362
+ $.optional_formal_parameters,
1363
+ ")",
1364
+ ),
1365
+ seq("(", $.optional_formal_parameters, ")"),
1366
+ ),
1367
+
1368
+ _normal_formal_parameters: ($) => commaSep1($.formal_parameter),
1369
+
1370
+ formal_parameter: ($) => $._normal_formal_parameter,
1371
+
1372
+ optional_formal_parameters: ($) =>
1373
+ choice(
1374
+ seq("[", commaSep1TrailingComma($._default_formal_parameter), "]"),
1375
+ seq("{", commaSep1TrailingComma($._default_named_parameter), "}"),
1376
+ ),
1377
+
1378
+ _default_formal_parameter: ($) =>
1379
+ seq($.formal_parameter, optional(seq("=", $._expression))),
1380
+
1381
+ _default_named_parameter: ($) =>
1382
+ seq(
1383
+ optional($._metadata),
1384
+ optional("required"),
1385
+ $.formal_parameter,
1386
+ optional(seq(choice("=", ":"), $._expression)),
1387
+ ),
1388
+
1389
+ _normal_formal_parameter: ($) =>
1390
+ seq(
1391
+ optional($._metadata),
1392
+ choice(
1393
+ $._function_formal_parameter,
1394
+ $._simple_formal_parameter,
1395
+ $.constructor_param,
1396
+ $.super_formal_parameter,
1397
+ ),
1398
+ ),
1399
+
1400
+ _function_formal_parameter: ($) =>
1401
+ seq(
1402
+ optional("covariant"),
1403
+ optional($.type),
1404
+ $.identifier,
1405
+ $._formal_parameter_part,
1406
+ optional("?"),
1407
+ ),
1408
+
1409
+ _simple_formal_parameter: ($) =>
1410
+ choice(
1411
+ $._declared_identifier,
1412
+ seq(optional("covariant"), $.identifier),
1413
+ ),
1414
+
1415
+ _declared_identifier: ($) =>
1416
+ seq(
1417
+ optional("covariant"),
1418
+ $._final_const_var_or_type,
1419
+ field("name", $.identifier),
1420
+ ),
1421
+
1422
+ constructor_param: ($) =>
1423
+ seq(
1424
+ optional($._final_const_var_or_type),
1425
+ "this",
1426
+ ".",
1427
+ $.identifier,
1428
+ optional(seq($._formal_parameter_part, optional("?"))),
1429
+ ),
1430
+
1431
+ super_formal_parameter: ($) =>
1432
+ seq(
1433
+ optional($._final_const_var_or_type),
1434
+ "super",
1435
+ ".",
1436
+ $.identifier,
1437
+ optional(seq($._formal_parameter_part, optional("?"))),
1438
+ ),
1439
+
1440
+ // ========================================================================
1441
+ // Statements (Phase 6)
1442
+ // ========================================================================
1443
+
1444
+ _statement: ($) =>
1445
+ choice(
1446
+ $.block,
1447
+ prec.dynamic(1, $.local_function_declaration),
1448
+ prec.dynamic(2, $.local_variable_declaration),
1449
+ $.for_statement,
1450
+ $.while_statement,
1451
+ $.do_statement,
1452
+ $.switch_statement,
1453
+ $.if_statement,
1454
+ $.try_statement,
1455
+ $.break_statement,
1456
+ $.continue_statement,
1457
+ $.rethrow_statement,
1458
+ $.return_statement,
1459
+ $.yield_statement,
1460
+ $.yield_each_statement,
1461
+ $.expression_statement,
1462
+ $.assert_statement,
1463
+ $.labeled_statement,
1464
+ $.empty_statement,
1465
+ ),
1466
+
1467
+ empty_statement: (_) => ";",
1468
+
1469
+ block: ($) => seq("{", repeat($._statement), "}"),
1470
+
1471
+ expression_statement: ($) => seq($._expression, ";"),
1472
+
1473
+ local_variable_declaration: ($) =>
1474
+ choice(
1475
+ seq(
1476
+ optional($._metadata),
1477
+ $.initialized_variable_definition,
1478
+ ";",
1479
+ ),
1480
+ seq(
1481
+ optional($._metadata),
1482
+ $.pattern_variable_declaration,
1483
+ ";",
1484
+ ),
1485
+ ),
1486
+
1487
+ initialized_variable_definition: ($) =>
1488
+ seq(
1489
+ $._declared_identifier,
1490
+ optional(seq("=", field("value", $._expression))),
1491
+ repeat(seq(",", $.initialized_identifier)),
1492
+ ),
1493
+
1494
+ local_function_declaration: ($) =>
1495
+ seq(
1496
+ optional($._metadata),
1497
+ $.function_signature,
1498
+ $.function_body,
1499
+ ),
1500
+
1501
+ labeled_statement: ($) => seq($.identifier, ":", $._statement),
1502
+
1503
+ // --- Control flow ---
1504
+
1505
+ if_statement: ($) =>
1506
+ prec.right(
1507
+ seq(
1508
+ "if",
1509
+ "(",
1510
+ $._expression,
1511
+ optional(seq("case", $._guarded_pattern)),
1512
+ ")",
1513
+ field("consequence", $._statement),
1514
+ optional(seq("else", field("alternative", $._statement))),
1515
+ ),
1516
+ ),
1517
+
1518
+ for_statement: ($) =>
1519
+ seq(
1520
+ optional("await"),
1521
+ "for",
1522
+ "(", $._for_loop_parts, ")",
1523
+ field("body", $._statement),
1524
+ ),
1525
+
1526
+ _for_loop_parts: ($) =>
1527
+ choice(
1528
+ // for-in loop
1529
+ seq(
1530
+ optional($._metadata),
1531
+ choice($._declared_identifier, $.identifier),
1532
+ "in",
1533
+ field("value", $._expression),
1534
+ ),
1535
+ // C-style for loop
1536
+ seq(
1537
+ optional(
1538
+ choice(
1539
+ field("init", $.local_variable_declaration),
1540
+ seq(commaSep(field("init", $._expression)), ";"),
1541
+ ),
1542
+ ),
1543
+ field("condition", optional($._expression)),
1544
+ ";",
1545
+ commaSep(field("update", $._expression)),
1546
+ ),
1547
+ // Pattern for-in loop (Dart 3.0)
1548
+ seq(
1549
+ optional($._metadata),
1550
+ choice("final", "var"),
1551
+ $._outer_pattern,
1552
+ "in",
1553
+ field("value", $._expression),
1554
+ ),
1555
+ ),
1556
+
1557
+ while_statement: ($) =>
1558
+ seq(
1559
+ "while",
1560
+ field("condition", $.parenthesized_expression),
1561
+ field("body", $._statement),
1562
+ ),
1563
+
1564
+ do_statement: ($) =>
1565
+ seq(
1566
+ "do",
1567
+ field("body", $._statement),
1568
+ "while",
1569
+ field("condition", $.parenthesized_expression),
1570
+ ";",
1571
+ ),
1572
+
1573
+ // --- Switch ---
1574
+
1575
+ switch_statement: ($) =>
1576
+ seq(
1577
+ "switch",
1578
+ field("condition", $.parenthesized_expression),
1579
+ field("body", $.switch_block),
1580
+ ),
1581
+
1582
+ switch_block: ($) =>
1583
+ seq(
1584
+ "{",
1585
+ repeat($.switch_statement_case),
1586
+ optional($.switch_statement_default),
1587
+ "}",
1588
+ ),
1589
+
1590
+ switch_statement_case: ($) =>
1591
+ seq(
1592
+ repeat($.label),
1593
+ "case",
1594
+ $._guarded_pattern,
1595
+ ":",
1596
+ repeat($._statement),
1597
+ ),
1598
+
1599
+ switch_statement_default: ($) =>
1600
+ seq(repeat($.label), "default", ":", repeat($._statement)),
1601
+
1602
+ switch_expression: ($) =>
1603
+ seq(
1604
+ "switch",
1605
+ field("condition", $.parenthesized_expression),
1606
+ field("body", seq("{", commaSepTrailingComma($.switch_expression_case), "}")),
1607
+ ),
1608
+
1609
+ switch_expression_case: ($) =>
1610
+ seq($._guarded_pattern, "=>", $._expression),
1611
+
1612
+ // --- Exception handling ---
1613
+
1614
+ try_statement: ($) =>
1615
+ seq(
1616
+ "try",
1617
+ field("body", $.block),
1618
+ optional(
1619
+ choice(
1620
+ $.finally_clause,
1621
+ seq(repeat1($._on_part), optional($.finally_clause)),
1622
+ ),
1623
+ ),
1624
+ ),
1625
+
1626
+ _on_part: ($) =>
1627
+ choice(
1628
+ seq($.catch_clause, $.block),
1629
+ seq("on", $._type_not_void, optional($.catch_clause), $.block),
1630
+ ),
1631
+
1632
+ catch_clause: ($) =>
1633
+ seq("catch", "(", field("exception", $.identifier), optional(seq(",", field("stack_trace", $.identifier))), ")"),
1634
+
1635
+ finally_clause: ($) => seq("finally", $.block),
1636
+
1637
+ // --- Jump statements ---
1638
+
1639
+ break_statement: ($) => seq("break", optional($.identifier), ";"),
1640
+
1641
+ continue_statement: ($) => seq("continue", optional($.identifier), ";"),
1642
+
1643
+ rethrow_statement: (_) => seq("rethrow", ";"),
1644
+
1645
+ return_statement: ($) => seq("return", optional($._expression), ";"),
1646
+
1647
+ yield_statement: ($) => seq("yield", $._expression, ";"),
1648
+
1649
+ yield_each_statement: ($) => seq("yield", "*", $._expression, ";"),
1650
+
1651
+ // --- Assert ---
1652
+
1653
+ assert_statement: ($) => seq($.assertion, ";"),
1654
+
1655
+ assertion: ($) =>
1656
+ seq("assert", "(", $._expression, optional(seq(",", $._expression)), optional(","), ")"),
1657
+
1658
+ // ========================================================================
1659
+ // Function signatures and bodies (Phase 7)
1660
+ // ========================================================================
1661
+
1662
+ function_signature: ($) =>
1663
+ seq(
1664
+ optional(field("return_type", $.type)),
1665
+ field("name", $._function_name),
1666
+ field("parameters", $._formal_parameter_part),
1667
+ ),
1668
+
1669
+ // All built-in identifiers can be used as function/method names
1670
+ _function_name: ($) => $.identifier,
1671
+
1672
+ getter_signature: ($) =>
1673
+ seq(optional(field("return_type", $.type)), "get", field("name", $.identifier)),
1674
+
1675
+ setter_signature: ($) =>
1676
+ seq(optional(field("return_type", $.type)), "set", field("name", $.identifier), field("parameters", $._formal_parameter_part)),
1677
+
1678
+ function_body: ($) =>
1679
+ choice(
1680
+ seq(optional("async"), "=>", $._expression, ";"),
1681
+ seq(optional(choice("async", "async*", "sync*")), $.block),
1682
+ $.native,
1683
+ ),
1684
+
1685
+ native: ($) => seq("native", optional($.string_literal), ";"),
1686
+
1687
+ // ========================================================================
1688
+ // Declarations and class members (Phase 7)
1689
+ // ========================================================================
1690
+
1691
+ _declaration: ($) =>
1692
+ prec(
1693
+ 1,
1694
+ choice(
1695
+ $.class_declaration,
1696
+ $.mixin_declaration,
1697
+ $.extension_declaration,
1698
+ $.extension_type_declaration,
1699
+ $.enum_declaration,
1700
+ $.type_alias,
1701
+ ),
1702
+ ),
1703
+
1704
+ // --- Type helpers ---
1705
+
1706
+ _final_const_var_or_type: ($) =>
1707
+ choice(
1708
+ seq(optional("late"), "final", optional($.type)),
1709
+ seq("const", optional($.type)),
1710
+ seq(optional("late"), $._var_or_type),
1711
+ ),
1712
+
1713
+ _var_or_type: ($) =>
1714
+ choice($.type, seq("var", optional($.type))),
1715
+
1716
+ _final_var_or_type: ($) =>
1717
+ choice(
1718
+ "var",
1719
+ "final",
1720
+ seq(optional("final"), $.type),
1721
+ ),
1722
+
1723
+ // --- Class members ---
1724
+
1725
+ method_signature: ($) =>
1726
+ choice(
1727
+ seq($.constructor_signature, optional($.initializers)),
1728
+ $.factory_constructor_signature,
1729
+ seq(optional("static"), choice($.function_signature, $.getter_signature, $.setter_signature)),
1730
+ $.operator_signature,
1731
+ ),
1732
+
1733
+ declaration: ($) =>
1734
+ choice(
1735
+ seq(
1736
+ $.constant_constructor_signature,
1737
+ optional(choice($.redirection, $.initializers)),
1738
+ ),
1739
+ seq(
1740
+ $.constructor_signature,
1741
+ optional(choice($.redirection, $.initializers)),
1742
+ ),
1743
+ seq($.external, optional("const"), $.factory_constructor_signature),
1744
+ seq("external", $.constant_constructor_signature),
1745
+ $.redirecting_factory_constructor_signature,
1746
+ seq("external", $.constructor_signature),
1747
+ seq(optional($._external_and_static), $.getter_signature),
1748
+ seq(optional($._external_and_static), $.setter_signature),
1749
+ seq(optional($.external), $.operator_signature),
1750
+ seq(optional($._external_and_static), $.function_signature),
1751
+ seq("static", $.function_signature),
1752
+ // Static field declarations
1753
+ seq(
1754
+ "static",
1755
+ choice(
1756
+ seq(
1757
+ choice("final", "const"),
1758
+ optional($.type),
1759
+ $.static_final_declaration_list,
1760
+ ),
1761
+ seq(
1762
+ "late",
1763
+ choice(
1764
+ seq("final", optional($.type), $.initialized_identifier_list),
1765
+ seq($._var_or_type, $.initialized_identifier_list),
1766
+ ),
1767
+ ),
1768
+ seq($._var_or_type, $.initialized_identifier_list),
1769
+ ),
1770
+ ),
1771
+ // Covariant field declarations
1772
+ seq(
1773
+ "covariant",
1774
+ choice(
1775
+ seq(
1776
+ "late",
1777
+ choice(
1778
+ seq("final", optional($.type), $.identifier_list),
1779
+ seq($._var_or_type, $.initialized_identifier_list),
1780
+ ),
1781
+ ),
1782
+ seq($._var_or_type, $.initialized_identifier_list),
1783
+ ),
1784
+ ),
1785
+ // Instance field declarations
1786
+ seq(optional("late"), "final", optional($.type), $.initialized_identifier_list),
1787
+ seq(optional("late"), $._var_or_type, $.initialized_identifier_list),
1788
+ seq("const", optional($.type), $.static_final_declaration_list),
1789
+ // Abstract field declarations
1790
+ seq("abstract", "final", optional($.type), $.identifier_list),
1791
+ seq("abstract", optional($.type), $.identifier_list),
1792
+ seq("abstract", "covariant", "final", optional($.type), $.identifier_list),
1793
+ seq("abstract", "covariant", optional($.type), $.identifier_list),
1794
+ // External field declarations
1795
+ seq($.external, optional("static"), optional("covariant"), optional(choice("final", "var")), optional($.type), $.identifier_list),
1796
+ ),
1797
+
1798
+ external: (_) => "external",
1799
+
1800
+ _external_and_static: ($) => seq($.external, optional("static")),
1801
+
1802
+ // --- Constructors ---
1803
+
1804
+ constructor_signature: ($) =>
1805
+ seq(
1806
+ field("name", seq($.identifier, optional(seq(".", $._identifier_or_new)))),
1807
+ field("parameters", $.formal_parameter_list),
1808
+ ),
1809
+
1810
+ constant_constructor_signature: ($) =>
1811
+ seq(
1812
+ "const",
1813
+ field("name", seq($.identifier, optional(seq(".", $._identifier_or_new)))),
1814
+ field("parameters", $.formal_parameter_list),
1815
+ ),
1816
+
1817
+ factory_constructor_signature: ($) =>
1818
+ seq(
1819
+ "factory",
1820
+ field("name", seq($.identifier, optional(seq(".", $._identifier_or_new)))),
1821
+ field("parameters", $.formal_parameter_list),
1822
+ ),
1823
+
1824
+ redirecting_factory_constructor_signature: ($) =>
1825
+ seq(
1826
+ optional("const"),
1827
+ "factory",
1828
+ field("name", seq($.identifier, optional(seq(".", $._identifier_or_new)))),
1829
+ field("parameters", $.formal_parameter_list),
1830
+ "=",
1831
+ field("target", $._type_not_void),
1832
+ optional(seq(".", field("target_constructor", $.identifier))),
1833
+ ),
1834
+
1835
+ redirection: ($) =>
1836
+ seq(":", "this", optional(seq(".", $._identifier_or_new)), $.arguments),
1837
+
1838
+ initializers: ($) => seq(":", commaSep1($.initializer_list_entry)),
1839
+
1840
+ initializer_list_entry: ($) =>
1841
+ choice(
1842
+ seq("super", $.arguments),
1843
+ seq("super", ".", choice($.identifier, "new"), $.arguments),
1844
+ seq("this", ".", choice($.identifier, "new"), $.arguments),
1845
+ $.field_initializer,
1846
+ $.assertion,
1847
+ ),
1848
+
1849
+ field_initializer: ($) =>
1850
+ seq(
1851
+ optional(seq("this", ".")),
1852
+ field("name", $.identifier),
1853
+ "=",
1854
+ field("value", $._expression),
1855
+ ),
1856
+
1857
+ // --- Operators ---
1858
+
1859
+ operator_signature: ($) =>
1860
+ seq(
1861
+ optional(field("return_type", $.type)),
1862
+ "operator",
1863
+ field("operator", choice("~", $.binary_operator, "[]", "[]=")),
1864
+ field("parameters", $.formal_parameter_list),
1865
+ ),
1866
+
1867
+ binary_operator: ($) =>
1868
+ choice(
1869
+ choice("*", "/", "%", "~/"),
1870
+ $._additive_operator,
1871
+ $._shift_operator,
1872
+ $.relational_operator,
1873
+ "==",
1874
+ "|",
1875
+ "^",
1876
+ "&",
1877
+ ),
1878
+
1879
+ // --- Field helpers ---
1880
+
1881
+ static_final_declaration_list: ($) =>
1882
+ commaSep1($.static_final_declaration),
1883
+
1884
+ static_final_declaration: ($) =>
1885
+ seq(field("name", $.identifier), optional(seq("=", field("value", $._expression)))),
1886
+
1887
+ initialized_identifier_list: ($) =>
1888
+ commaSep1($.initialized_identifier),
1889
+
1890
+ initialized_identifier: ($) =>
1891
+ seq(field("name", $.identifier), optional(seq("=", field("value", $._expression)))),
1892
+
1893
+ identifier_list: ($) => commaSep1($.identifier),
1894
+
1895
+ // ========================================================================
1896
+ // Top-level declarations (Phase 8)
1897
+ // ========================================================================
1898
+
1899
+ // --- Classes ---
1900
+
1901
+ class_declaration: ($) =>
1902
+ choice(
1903
+ seq(
1904
+ optional($._metadata),
1905
+ optional("augment"),
1906
+ choice($._class_modifiers, $._mixin_class_modifiers),
1907
+ field("name", $.identifier),
1908
+ optional(field("type_parameters", $.type_parameters)),
1909
+ optional(field("superclass", $.superclass)),
1910
+ optional(field("interfaces", $.interfaces)),
1911
+ field("body", $.class_body),
1912
+ ),
1913
+ seq(
1914
+ optional($._metadata),
1915
+ choice($._class_modifiers, $._mixin_class_modifiers),
1916
+ $.mixin_application_class,
1917
+ ),
1918
+ ),
1919
+
1920
+ _class_modifiers: ($) =>
1921
+ seq(
1922
+ choice(
1923
+ "sealed",
1924
+ seq(
1925
+ optional("abstract"),
1926
+ optional(choice("base", "interface", "final", "inline")),
1927
+ ),
1928
+ ),
1929
+ "class",
1930
+ ),
1931
+
1932
+ _mixin_class_modifiers: ($) =>
1933
+ seq(optional("abstract"), optional("base"), "mixin", "class"),
1934
+
1935
+ class_body: ($) =>
1936
+ seq(
1937
+ "{",
1938
+ repeat($.class_member),
1939
+ "}",
1940
+ ),
1941
+
1942
+ class_member: ($) =>
1943
+ choice(
1944
+ seq(optional($._metadata), optional("augment"), $.declaration, ";"),
1945
+ $.method_declaration,
1946
+ ),
1947
+
1948
+ method_declaration: ($) =>
1949
+ seq(
1950
+ optional($._metadata),
1951
+ optional("augment"),
1952
+ field("signature", $.method_signature),
1953
+ field("body", $.function_body),
1954
+ ),
1955
+
1956
+ superclass: ($) =>
1957
+ choice(
1958
+ seq("extends", field("type", $._type_not_void), optional($.mixins)),
1959
+ $.mixins,
1960
+ ),
1961
+
1962
+ mixins: ($) => seq("with", commaSep1($._type_not_void)),
1963
+
1964
+ interfaces: ($) => seq("implements", commaSep1($._type_not_void)),
1965
+
1966
+ mixin_application_class: ($) =>
1967
+ seq(
1968
+ $.identifier,
1969
+ optional($.type_parameters),
1970
+ "=",
1971
+ $.mixin_application,
1972
+ ";",
1973
+ ),
1974
+
1975
+ mixin_application: ($) =>
1976
+ seq($._type_not_void, $.mixins, optional($.interfaces)),
1977
+
1978
+ // --- Mixins ---
1979
+
1980
+ mixin_declaration: ($) =>
1981
+ seq(
1982
+ optional($._metadata),
1983
+ optional("augment"),
1984
+ optional("base"),
1985
+ "mixin",
1986
+ field("name", $.identifier),
1987
+ optional(field("type_parameters", $.type_parameters)),
1988
+ optional(seq("on", commaSep1($._type_not_void))),
1989
+ optional(field("interfaces", $.interfaces)),
1990
+ field("body", $.class_body),
1991
+ ),
1992
+
1993
+ // --- Extensions ---
1994
+
1995
+ extension_declaration: ($) =>
1996
+ choice(
1997
+ seq(
1998
+ optional($._metadata),
1999
+ "extension",
2000
+ optional(field("name", $.identifier)),
2001
+ optional(field("type_parameters", $.type_parameters)),
2002
+ "on",
2003
+ field("class", $.type),
2004
+ field("body", $.extension_body),
2005
+ ),
2006
+ seq(
2007
+ optional($._metadata),
2008
+ "augment",
2009
+ "extension",
2010
+ field("name", $.identifier),
2011
+ optional(field("type_parameters", $.type_parameters)),
2012
+ field("body", $.extension_body),
2013
+ ),
2014
+ ),
2015
+
2016
+ extension_body: ($) =>
2017
+ seq(
2018
+ "{",
2019
+ repeat($.class_member),
2020
+ "}",
2021
+ ),
2022
+
2023
+ // --- Extension types (Dart 3.3) ---
2024
+
2025
+ extension_type_declaration: ($) =>
2026
+ choice(
2027
+ seq(
2028
+ optional($._metadata),
2029
+ "extension",
2030
+ "type",
2031
+ optional("const"),
2032
+ field("name", $.extension_type_name),
2033
+ field("representation", $.extension_type_representation),
2034
+ optional(seq("implements", commaSep1($.type))),
2035
+ field("body", $.class_body),
2036
+ ),
2037
+ seq(
2038
+ optional($._metadata),
2039
+ "augment",
2040
+ "extension",
2041
+ "type",
2042
+ field("name", $.identifier),
2043
+ optional(field("type_parameters", $.type_parameters)),
2044
+ optional(field("interfaces", $.interfaces)),
2045
+ field("body", $.class_body),
2046
+ ),
2047
+ ),
2048
+
2049
+ extension_type_name: ($) =>
2050
+ seq(
2051
+ $.identifier,
2052
+ optional($.type_parameters),
2053
+ optional(seq(".", $.identifier)),
2054
+ ),
2055
+
2056
+ extension_type_representation: ($) =>
2057
+ seq("(", optional($._metadata), field("type", $.type), field("name", $.identifier), ")"),
2058
+
2059
+ // --- Enums (enhanced, Dart 2.17) ---
2060
+
2061
+ enum_declaration: ($) =>
2062
+ seq(
2063
+ optional($._metadata),
2064
+ optional("augment"),
2065
+ "enum",
2066
+ field("name", $.identifier),
2067
+ optional($.type_parameters),
2068
+ optional($.mixins),
2069
+ optional($.interfaces),
2070
+ field("body", $.enum_body),
2071
+ ),
2072
+
2073
+ enum_body: ($) =>
2074
+ seq(
2075
+ "{",
2076
+ commaSep1TrailingComma($.enum_constant),
2077
+ optional(
2078
+ seq(
2079
+ ";",
2080
+ repeat($.class_member),
2081
+ ),
2082
+ ),
2083
+ "}",
2084
+ ),
2085
+
2086
+ enum_constant: ($) =>
2087
+ choice(
2088
+ seq(
2089
+ optional($._metadata),
2090
+ field("name", $.identifier),
2091
+ optional(seq(optional($.type_arguments), $.arguments)),
2092
+ ),
2093
+ seq(
2094
+ optional($._metadata),
2095
+ field("name", $.identifier),
2096
+ optional($.type_arguments),
2097
+ ".",
2098
+ choice($.identifier, "new"),
2099
+ $.arguments,
2100
+ ),
2101
+ ),
2102
+
2103
+ // --- Typedefs ---
2104
+
2105
+ type_alias: ($) =>
2106
+ choice(
2107
+ seq(
2108
+ optional($._metadata),
2109
+ "typedef",
2110
+ optional($.type),
2111
+ $._type_name,
2112
+ $._formal_parameter_part,
2113
+ ";",
2114
+ ),
2115
+ seq(
2116
+ optional($._metadata),
2117
+ "typedef",
2118
+ $._type_name,
2119
+ optional($.type_parameters),
2120
+ "=",
2121
+ $.type,
2122
+ ";",
2123
+ ),
2124
+ ),
2125
+
2126
+ function_declaration: ($) =>
2127
+ seq(
2128
+ optional($._metadata),
2129
+ optional("augment"),
2130
+ field("signature", $.function_signature),
2131
+ field("body", $.function_body),
2132
+ ),
2133
+
2134
+ getter_declaration: ($) =>
2135
+ seq(
2136
+ optional($._metadata),
2137
+ optional("augment"),
2138
+ field("signature", $.getter_signature),
2139
+ field("body", $.function_body),
2140
+ ),
2141
+
2142
+ setter_declaration: ($) =>
2143
+ seq(
2144
+ optional($._metadata),
2145
+ optional("augment"),
2146
+ field("signature", $.setter_signature),
2147
+ field("body", $.function_body),
2148
+ ),
2149
+
2150
+ // `external` is optional to accept the (technically-invalid-at-top-level)
2151
+ // bodyless `void f();` form the previous grammar permitted; in practice
2152
+ // top-level bodyless functions are external.
2153
+ external_function_declaration: ($) =>
2154
+ seq(
2155
+ optional($._metadata),
2156
+ optional("augment"),
2157
+ optional(field("modifier", $.external)),
2158
+ field("signature", $.function_signature),
2159
+ ";",
2160
+ ),
2161
+
2162
+ external_getter_declaration: ($) =>
2163
+ seq(
2164
+ optional($._metadata),
2165
+ optional("augment"),
2166
+ optional(field("modifier", $.external)),
2167
+ field("signature", $.getter_signature),
2168
+ ";",
2169
+ ),
2170
+
2171
+ external_setter_declaration: ($) =>
2172
+ seq(
2173
+ optional($._metadata),
2174
+ optional("augment"),
2175
+ optional(field("modifier", $.external)),
2176
+ field("signature", $.setter_signature),
2177
+ ";",
2178
+ ),
2179
+
2180
+ external_variable_declaration: ($) =>
2181
+ seq(
2182
+ optional($._metadata),
2183
+ optional("augment"),
2184
+ field("modifier", $.external),
2185
+ optional("final"),
2186
+ optional(field("type", $.type)),
2187
+ $.identifier_list,
2188
+ ";",
2189
+ ),
2190
+
2191
+ top_level_variable_declaration: ($) =>
2192
+ seq(
2193
+ optional($._metadata),
2194
+ optional("augment"),
2195
+ choice(
2196
+ seq(
2197
+ field("modifier", choice("final", "const")),
2198
+ optional(field("type", $.type)),
2199
+ $.static_final_declaration_list,
2200
+ ),
2201
+ seq(
2202
+ field("modifier", "late"),
2203
+ "final",
2204
+ optional(field("type", $.type)),
2205
+ $.initialized_identifier_list,
2206
+ ),
2207
+ seq(
2208
+ optional(field("modifier", "late")),
2209
+ $._var_or_type,
2210
+ $.initialized_identifier_list,
2211
+ ),
2212
+ ),
2213
+ ";",
2214
+ ),
2215
+
2216
+ // ========================================================================
2217
+ // Patterns (Phase 10 - Dart 3.0)
2218
+ // ========================================================================
2219
+
2220
+ _guarded_pattern: ($) =>
2221
+ seq($._pattern, optional(seq("when", $._expression))),
2222
+
2223
+ _pattern: ($) => $._logical_or_pattern,
2224
+
2225
+ _logical_or_pattern: ($) =>
2226
+ seq($._logical_and_pattern, repeat(seq("||", $._logical_and_pattern))),
2227
+
2228
+ _logical_and_pattern: ($) =>
2229
+ seq($._relational_pattern, repeat(seq("&&", $._relational_pattern))),
2230
+
2231
+ _relational_pattern: ($) =>
2232
+ prec(
2233
+ PREC.RELATIONAL,
2234
+ choice(
2235
+ seq(choice($.relational_operator, choice("==", "!=")), $._real_expression),
2236
+ $._unary_pattern,
2237
+ ),
2238
+ ),
2239
+
2240
+ _unary_pattern: ($) =>
2241
+ choice(
2242
+ $.cast_pattern,
2243
+ $.null_check_pattern,
2244
+ $.null_assert_pattern,
2245
+ $._primary_pattern,
2246
+ ),
2247
+
2248
+ _primary_pattern: ($) =>
2249
+ choice(
2250
+ $.constant_pattern,
2251
+ $.variable_pattern,
2252
+ $._parenthesized_pattern,
2253
+ $.list_pattern,
2254
+ $.map_pattern,
2255
+ $.record_pattern,
2256
+ $.object_pattern,
2257
+ ),
2258
+
2259
+ cast_pattern: ($) => seq($._primary_pattern, "as", field("type", $.type)),
2260
+
2261
+ null_check_pattern: ($) => seq($._primary_pattern, "?"),
2262
+
2263
+ null_assert_pattern: ($) => seq($._primary_pattern, "!"),
2264
+
2265
+ constant_pattern: ($) =>
2266
+ choice(
2267
+ $.true,
2268
+ $.false,
2269
+ $.null_literal,
2270
+ seq(optional("-"), choice($.decimal_integer_literal, $.hex_integer_literal, $.decimal_floating_point_literal)),
2271
+ seq($.string_literal, optional(seq(".", $.identifier))),
2272
+ $.symbol_literal,
2273
+ seq($.identifier, optional(seq(".", $.identifier))),
2274
+ $.qualified,
2275
+ $.const_object_expression,
2276
+ seq("const", optional($.type_arguments), "[", commaSep1TrailingComma($._element), "]"),
2277
+ seq("const", optional($.type_arguments), "{", commaSep1TrailingComma($._element), "}"),
2278
+ seq("const", "(", $._expression, ")"),
2279
+ seq("const", $._record_literal_no_const),
2280
+ // Dot shorthand (Dart 3.6+): .enumValue in patterns
2281
+ seq(".", $.identifier),
2282
+ ),
2283
+
2284
+ variable_pattern: ($) => seq($._final_var_or_type, field("name", $.identifier)),
2285
+
2286
+ _parenthesized_pattern: ($) => seq("(", $._pattern, ")"),
2287
+
2288
+ list_pattern: ($) =>
2289
+ seq(
2290
+ optional($.type_arguments),
2291
+ "[",
2292
+ commaSepTrailingComma(choice($._pattern, $.rest_pattern)),
2293
+ "]",
2294
+ ),
2295
+
2296
+ rest_pattern: ($) => seq("...", optional($._pattern)),
2297
+
2298
+ map_pattern: ($) =>
2299
+ seq(
2300
+ optional($.type_arguments),
2301
+ "{",
2302
+ commaSepTrailingComma(choice(seq($._expression, ":", $._pattern), $.rest_pattern)),
2303
+ "}",
2304
+ ),
2305
+
2306
+ record_pattern: ($) =>
2307
+ seq("(", commaSepTrailingComma($._pattern_field), ")"),
2308
+
2309
+ _pattern_field: ($) =>
2310
+ seq(optional(choice($.label, ":")), $._pattern),
2311
+
2312
+ object_pattern: ($) =>
2313
+ seq(
2314
+ $._type_name,
2315
+ optional($.type_arguments),
2316
+ "(",
2317
+ commaSepTrailingComma($._pattern_field),
2318
+ ")",
2319
+ ),
2320
+
2321
+ pattern_variable_declaration: ($) =>
2322
+ seq(
2323
+ choice("final", "var"),
2324
+ $._outer_pattern,
2325
+ "=",
2326
+ $._expression,
2327
+ ),
2328
+
2329
+ _outer_pattern: ($) =>
2330
+ choice(
2331
+ $._parenthesized_pattern,
2332
+ $.list_pattern,
2333
+ $.map_pattern,
2334
+ $.record_pattern,
2335
+ $.object_pattern,
2336
+ ),
2337
+
2338
+ pattern_assignment: ($) => seq($._outer_pattern, "=", $._expression),
2339
+
2340
+ // ========================================================================
2341
+ // Identifiers and helpers
2342
+ // ========================================================================
2343
+
2344
+ _identifier_or_new: ($) => choice($.identifier, "new"),
2345
+
2346
+ label: ($) => seq($.identifier, ":"),
2347
+
2348
+ // The raw regex for word-like tokens - used as the `word` rule
2349
+ _name: (_) => /[a-zA-Z_$][\w$]*/,
2350
+
2351
+ // Dart built-in identifiers (category 2) and context keywords (category 3)
2352
+ _built_in_identifier: (_) =>
2353
+ choice(
2354
+ // Category 2: built-in identifiers
2355
+ "abstract", "as", "covariant", "deferred",
2356
+ "dynamic", "export", "external", "factory", "Function", "get", "implements",
2357
+ "import", "interface", "late", "library", "mixin",
2358
+ "operator", "part", "required", "set", "show",
2359
+ "static", "typedef",
2360
+ // Category 3: context keywords
2361
+ "hide", "native", "on", "sealed", "when", "base", "inline", "type", "augment",
2362
+ ),
2363
+
2364
+ // The "super-identifier" - accepts both regular names and contextual keywords
2365
+ identifier: ($) => choice($._name, $._built_in_identifier),
2366
+
2367
+ // ========================================================================
2368
+ // Comments
2369
+ // ========================================================================
2370
+
2371
+ comment: ($) =>
2372
+ choice(
2373
+ // Block comments (via external scanner)
2374
+ $.block_comment,
2375
+ $.documentation_block_comment,
2376
+ // Single-line comments
2377
+ seq("//", /([^/\n].*)?/),
2378
+ seq("///", /.*/),
2379
+ ),
2380
+ },
2381
+ });
2382
+
2383
+ function sep1(rule, separator) {
2384
+ return seq(rule, repeat(seq(separator, rule)));
2385
+ }