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

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