@willbooster/tree-sitter-typescript 0.0.0-placeholder.0 → 1.1.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.
@@ -0,0 +1,1022 @@
1
+ // oxlint-disable unicorn/prefer-module -- This package is CommonJS, so tree-sitter loads the grammar as CommonJS.
2
+ const JavaScript = require('tree-sitter-javascript/grammar');
3
+
4
+ module.exports = function defineGrammar(dialect) {
5
+ return grammar(JavaScript, {
6
+ name: dialect,
7
+
8
+ externals: ($, previous) => [...previous, $._function_signature_automatic_semicolon, $.__error_recovery],
9
+
10
+ supertypes: ($, previous) => [...previous, $.type, $.primary_type],
11
+
12
+ precedences: ($, previous) => [
13
+ ...previous,
14
+ ['call', 'instantiation', 'unary', 'binary', $.await_expression, $.arrow_function],
15
+ ['extends', 'instantiation'],
16
+ [
17
+ $.intersection_type,
18
+ $.union_type,
19
+ $.conditional_type,
20
+ $.function_type,
21
+ 'binary',
22
+ $.type_predicate,
23
+ $.readonly_type,
24
+ ],
25
+ [$.mapped_type_clause, $.primary_expression],
26
+ [$.accessibility_modifier, $.primary_expression],
27
+ ['unary_void', $.expression],
28
+ [$.extends_clause, $.primary_expression],
29
+ ['unary', 'assign'],
30
+ ['declaration', $.expression],
31
+ [$.predefined_type, $.unary_expression],
32
+ [$.type, $.flow_maybe_type],
33
+ [$.tuple_type, $.array_type, $.pattern, $.type],
34
+ [$.readonly_type, $.pattern],
35
+ [$.readonly_type, $.primary_expression],
36
+ [$.type_query, $.subscript_expression, $.expression],
37
+ [$.type_query, $._type_query_subscript_expression],
38
+ [$.nested_type_identifier, $.generic_type, $.primary_type, $.lookup_type, $.index_type_query, $.type],
39
+ [$.as_expression, $.satisfies_expression, $.primary_type],
40
+ [$._type_query_member_expression, $.member_expression],
41
+ [$.member_expression, $._type_query_member_expression_in_type_annotation],
42
+ [$._type_query_member_expression, $.primary_expression],
43
+ [$._type_query_subscript_expression, $.subscript_expression],
44
+ [$._type_query_subscript_expression, $.primary_expression],
45
+ [$._type_query_call_expression, $.primary_expression],
46
+ [$._type_query_instantiation_expression, $.primary_expression],
47
+ [$.type_query, $.primary_expression],
48
+ [$.override_modifier, $.primary_expression],
49
+ [$.decorator_call_expression, $.decorator],
50
+ [$.literal_type, $.pattern],
51
+ [$.predefined_type, $.pattern],
52
+ [$.call_expression, $._type_query_call_expression],
53
+ [$.call_expression, $._type_query_call_expression_in_type_annotation],
54
+ [$.new_expression, $.primary_expression],
55
+ [$.meta_property, $.primary_expression],
56
+ [$.construct_signature, $._property_name],
57
+ ],
58
+
59
+ conflicts: ($, previous) => [
60
+ ...previous,
61
+ [$.call_expression, $.instantiation_expression, $.binary_expression],
62
+ [$.call_expression, $.instantiation_expression, $.binary_expression, $.unary_expression],
63
+ [$.call_expression, $.instantiation_expression, $.binary_expression, $.update_expression],
64
+ [$.call_expression, $.instantiation_expression, $.binary_expression, $.await_expression],
65
+
66
+ // This appears to be necessary to parse a parenthesized class expression
67
+ [$.class],
68
+
69
+ [$.nested_identifier, $.nested_type_identifier, $.primary_expression],
70
+ [$.nested_identifier, $.nested_type_identifier],
71
+
72
+ [$._call_signature, $.function_type],
73
+ [$._call_signature, $.constructor_type],
74
+
75
+ [$.primary_expression, $._parameter_name],
76
+ [$.primary_expression, $._parameter_name, $.primary_type],
77
+ [$.primary_expression, $.literal_type],
78
+ [$.primary_expression, $.literal_type, $.rest_pattern],
79
+ [$.primary_expression, $.predefined_type, $.rest_pattern],
80
+ [$.primary_expression, $.primary_type],
81
+ [$.primary_expression, $.generic_type],
82
+ [$.primary_expression, $.predefined_type],
83
+ [$.primary_expression, $.pattern, $.primary_type],
84
+ [$._parameter_name, $.primary_type],
85
+ [$.pattern, $.primary_type],
86
+
87
+ [$.optional_tuple_parameter, $.primary_type],
88
+ [$.rest_pattern, $.primary_type, $.primary_expression],
89
+
90
+ [$.object, $.object_type],
91
+ [$.object, $.object_pattern, $.object_type],
92
+ [$.object, $.object_pattern, $._property_name],
93
+ [$.object_pattern, $.object_type],
94
+ [$.object_pattern, $.object_type],
95
+
96
+ [$.array, $.tuple_type],
97
+ [$.array, $.array_pattern, $.tuple_type],
98
+ [$.array_pattern, $.tuple_type],
99
+
100
+ [$.template_literal_type, $.template_string],
101
+ ...(dialect === 'typescript'
102
+ ? [[$.primary_type, $.type_parameter]]
103
+ : [
104
+ [$.jsx_opening_element, $.type_parameter],
105
+ [$.jsx_namespace_name, $.primary_type],
106
+ ]),
107
+ ],
108
+
109
+ inline: ($, previous) => [
110
+ ...previous.filter((rule) => !['_formal_parameter', '_call_signature'].includes(rule.name)),
111
+ $._type_identifier,
112
+ $._jsx_start_opening_element,
113
+ ],
114
+
115
+ rules: {
116
+ public_field_definition: ($) =>
117
+ seq(
118
+ repeat(field('decorator', $.decorator)),
119
+ optional(
120
+ choice(
121
+ seq('declare', optional($.accessibility_modifier)),
122
+ seq($.accessibility_modifier, optional('declare'))
123
+ )
124
+ ),
125
+ choice(
126
+ seq(optional('static'), optional($.override_modifier), optional('readonly')),
127
+ seq(optional('abstract'), optional('readonly')),
128
+ seq(optional('readonly'), optional('abstract')),
129
+ optional('accessor')
130
+ ),
131
+ field('name', $._property_name),
132
+ optional(choice('?', '!')),
133
+ field('type', optional($.type_annotation)),
134
+ optional($._initializer)
135
+ ),
136
+
137
+ // override original catch_clause, add optional type annotation
138
+ catch_clause: ($) =>
139
+ seq(
140
+ 'catch',
141
+ optional(
142
+ seq(
143
+ '(',
144
+ field('parameter', choice($.identifier, $._destructuring_pattern)),
145
+ optional(
146
+ // only types that resolve to 'any' or 'unknown' are supported
147
+ // by the language but it's simpler to accept any type here.
148
+ field('type', $.type_annotation)
149
+ ),
150
+ ')'
151
+ )
152
+ ),
153
+ field('body', $.statement_block)
154
+ ),
155
+
156
+ call_expression: ($) =>
157
+ choice(
158
+ prec(
159
+ 'call',
160
+ seq(
161
+ field('function', choice($.expression, $.import)),
162
+ field('type_arguments', optional($.type_arguments)),
163
+ field('arguments', $.arguments)
164
+ )
165
+ ),
166
+ prec(
167
+ 'template_call',
168
+ seq(
169
+ field('function', choice($.primary_expression, $.new_expression)),
170
+ field('arguments', $.template_string)
171
+ )
172
+ ),
173
+ prec(
174
+ 'member',
175
+ seq(
176
+ field('function', $.primary_expression),
177
+ '?.',
178
+ field('type_arguments', optional($.type_arguments)),
179
+ field('arguments', $.arguments)
180
+ )
181
+ )
182
+ ),
183
+
184
+ new_expression: ($) =>
185
+ prec.right(
186
+ 'new',
187
+ seq(
188
+ 'new',
189
+ field('constructor', $.primary_expression),
190
+ field('type_arguments', optional($.type_arguments)),
191
+ field('arguments', optional($.arguments))
192
+ )
193
+ ),
194
+
195
+ assignment_expression: ($) =>
196
+ prec.right(
197
+ 'assign',
198
+ seq(
199
+ optional('using'),
200
+ field('left', choice($.parenthesized_expression, $._lhs_expression)),
201
+ '=',
202
+ field('right', $.expression)
203
+ )
204
+ ),
205
+
206
+ _augmented_assignment_lhs: ($, previous) => choice(previous, $.non_null_expression),
207
+
208
+ _lhs_expression: ($, previous) => choice(previous, $.non_null_expression),
209
+
210
+ primary_expression: ($, previous) => choice(previous, $.non_null_expression),
211
+
212
+ // If the dialect is regular typescript, we exclude JSX expressions and
213
+ // include type assertions. If the dialect is TSX, we do the opposite.
214
+ expression: ($, previous) => {
215
+ const choices = [$.as_expression, $.satisfies_expression, $.instantiation_expression, $.internal_module];
216
+
217
+ if (dialect === 'typescript') {
218
+ choices.push($.type_assertion);
219
+ choices.push(...previous.members.filter((member) => member.name !== '_jsx_element'));
220
+ } else if (dialect === 'tsx') {
221
+ choices.push(...previous.members);
222
+ } else {
223
+ throw new Error(`Unknown dialect ${dialect}`);
224
+ }
225
+
226
+ return choice(...choices);
227
+ },
228
+
229
+ _jsx_start_opening_element: ($) =>
230
+ seq(
231
+ '<',
232
+ optional(
233
+ seq(
234
+ choice(
235
+ field('name', choice($._jsx_identifier, $.jsx_namespace_name)),
236
+ seq(
237
+ field('name', choice($.identifier, alias($.nested_identifier, $.member_expression))),
238
+ field('type_arguments', optional($.type_arguments))
239
+ )
240
+ ),
241
+ repeat(field('attribute', $._jsx_attribute))
242
+ )
243
+ )
244
+ ),
245
+
246
+ // This rule is only referenced by expression when the dialect is 'tsx'
247
+ jsx_opening_element: ($) => prec.dynamic(-1, seq($._jsx_start_opening_element, '>')),
248
+
249
+ // tsx only. See jsx_opening_element.
250
+ jsx_self_closing_element: ($) => prec.dynamic(-1, seq($._jsx_start_opening_element, '/>')),
251
+
252
+ export_specifier: (_, previous) => seq(optional(choice('type', 'typeof')), previous),
253
+
254
+ _import_identifier: ($) => choice($.identifier, alias('type', $.identifier)),
255
+
256
+ import_specifier: ($) =>
257
+ seq(
258
+ optional(choice('type', 'typeof')),
259
+ choice(
260
+ field('name', $._import_identifier),
261
+ seq(
262
+ field('name', choice($._module_export_name, alias('type', $.identifier))),
263
+ 'as',
264
+ field('alias', $._import_identifier)
265
+ )
266
+ )
267
+ ),
268
+
269
+ import_attribute: ($) => seq(choice('with', 'assert'), $.object),
270
+
271
+ import_clause: ($) =>
272
+ choice(
273
+ $.namespace_import,
274
+ $.named_imports,
275
+ seq($._import_identifier, optional(seq(',', choice($.namespace_import, $.named_imports))))
276
+ ),
277
+
278
+ import_statement: ($) =>
279
+ seq(
280
+ 'import',
281
+ optional(choice('type', 'typeof')),
282
+ choice(seq($.import_clause, $._from_clause), $.import_require_clause, field('source', $.string)),
283
+ optional($.import_attribute),
284
+ $._semicolon
285
+ ),
286
+
287
+ export_statement: ($, previous) =>
288
+ choice(
289
+ previous,
290
+ seq('export', 'type', $.export_clause, optional($._from_clause), $._semicolon),
291
+ seq('export', 'type', choice('*', $.namespace_export), $._from_clause, $._semicolon),
292
+ seq('export', '=', $.expression, $._semicolon),
293
+ seq('export', 'as', 'namespace', $.identifier, $._semicolon)
294
+ ),
295
+
296
+ non_null_expression: ($) => prec.left('unary', seq($.expression, '!')),
297
+
298
+ variable_declarator: ($) =>
299
+ choice(
300
+ seq(
301
+ field('name', choice($.identifier, $._destructuring_pattern)),
302
+ field('type', optional($.type_annotation)),
303
+ optional($._initializer)
304
+ ),
305
+ prec('declaration', seq(field('name', $.identifier), '!', field('type', $.type_annotation)))
306
+ ),
307
+
308
+ method_signature: ($) =>
309
+ seq(
310
+ optional($.accessibility_modifier),
311
+ optional('static'),
312
+ optional($.override_modifier),
313
+ optional('readonly'),
314
+ optional('async'),
315
+ optional(choice('get', 'set', '*')),
316
+ field('name', $._property_name),
317
+ optional('?'),
318
+ $._call_signature
319
+ ),
320
+
321
+ abstract_method_signature: ($) =>
322
+ seq(
323
+ optional($.accessibility_modifier),
324
+ 'abstract',
325
+ optional($.override_modifier),
326
+ optional(choice('get', 'set', '*')),
327
+ field('name', $._property_name),
328
+ optional('?'),
329
+ $._call_signature
330
+ ),
331
+
332
+ parenthesized_expression: ($) =>
333
+ seq('(', choice(seq($.expression, field('type', optional($.type_annotation))), $.sequence_expression), ')'),
334
+
335
+ _formal_parameter: ($) => choice($.required_parameter, $.optional_parameter),
336
+
337
+ function_signature: ($) =>
338
+ seq(
339
+ optional('async'),
340
+ 'function',
341
+ field('name', $.identifier),
342
+ $._call_signature,
343
+ choice($._semicolon, $._function_signature_automatic_semicolon)
344
+ ),
345
+
346
+ decorator: ($) =>
347
+ seq(
348
+ '@',
349
+ choice(
350
+ $.identifier,
351
+ alias($.decorator_member_expression, $.member_expression),
352
+ alias($.decorator_call_expression, $.call_expression),
353
+ alias($.decorator_parenthesized_expression, $.parenthesized_expression)
354
+ )
355
+ ),
356
+
357
+ decorator_call_expression: ($) =>
358
+ prec(
359
+ 'call',
360
+ seq(
361
+ field('function', choice($.identifier, alias($.decorator_member_expression, $.member_expression))),
362
+ optional(field('type_arguments', $.type_arguments)),
363
+ field('arguments', $.arguments)
364
+ )
365
+ ),
366
+
367
+ decorator_parenthesized_expression: ($) =>
368
+ seq(
369
+ '(',
370
+ choice(
371
+ $.identifier,
372
+ alias($.decorator_member_expression, $.member_expression),
373
+ alias($.decorator_call_expression, $.call_expression)
374
+ ),
375
+ ')'
376
+ ),
377
+
378
+ class_body: ($) =>
379
+ seq(
380
+ '{',
381
+ repeat(
382
+ choice(
383
+ seq(repeat(field('decorator', $.decorator)), $.method_definition, optional($._semicolon)),
384
+ // As it happens for functions, the semicolon insertion should not
385
+ // happen if a block follows the closing paren, because then it's a
386
+ // *definition*, not a declaration. Example:
387
+ // public foo()
388
+ // { <--- this brace made the method signature become a definition
389
+ // }
390
+ // The same rule applies for functions and that's why we use
391
+ // "_function_signature_automatic_semicolon".
392
+ seq($.method_signature, choice($._function_signature_automatic_semicolon, ',')),
393
+ $.class_static_block,
394
+ seq(
395
+ choice($.abstract_method_signature, $.index_signature, $.method_signature, $.public_field_definition),
396
+ choice($._semicolon, ',')
397
+ ),
398
+ ';'
399
+ )
400
+ ),
401
+ '}'
402
+ ),
403
+
404
+ method_definition: ($) =>
405
+ prec.left(
406
+ seq(
407
+ optional($.accessibility_modifier),
408
+ optional('static'),
409
+ optional($.override_modifier),
410
+ optional('readonly'),
411
+ optional('async'),
412
+ optional(choice('get', 'set', '*')),
413
+ field('name', $._property_name),
414
+ optional('?'),
415
+ $._call_signature,
416
+ field('body', $.statement_block)
417
+ )
418
+ ),
419
+
420
+ declaration: ($, previous) =>
421
+ choice(
422
+ previous,
423
+ $.function_signature,
424
+ $.abstract_class_declaration,
425
+ $.module,
426
+ prec('declaration', $.internal_module),
427
+ $.type_alias_declaration,
428
+ $.enum_declaration,
429
+ $.interface_declaration,
430
+ $.import_alias,
431
+ $.ambient_declaration
432
+ ),
433
+
434
+ type_assertion: ($) => prec.left('unary', seq($.type_arguments, $.expression)),
435
+
436
+ as_expression: ($) => prec.left('binary', seq($.expression, 'as', choice('const', $.type))),
437
+
438
+ satisfies_expression: ($) => prec.left('binary', seq($.expression, 'satisfies', $.type)),
439
+
440
+ instantiation_expression: ($) =>
441
+ prec('instantiation', seq($.expression, field('type_arguments', $.type_arguments))),
442
+
443
+ class_heritage: ($) => choice(seq($.extends_clause, optional($.implements_clause)), $.implements_clause),
444
+
445
+ import_require_clause: ($) => seq($.identifier, '=', 'require', '(', field('source', $.string), ')'),
446
+
447
+ extends_clause: ($) => seq('extends', commaSep1($._extends_clause_single)),
448
+
449
+ _extends_clause_single: ($) =>
450
+ prec('extends', seq(field('value', $.expression), field('type_arguments', optional($.type_arguments)))),
451
+
452
+ implements_clause: ($) => seq('implements', commaSep1($.type)),
453
+
454
+ ambient_declaration: ($) =>
455
+ seq(
456
+ 'declare',
457
+ choice(
458
+ $.declaration,
459
+ seq('global', $.statement_block),
460
+ seq('module', '.', alias($.identifier, $.property_identifier), ':', $.type, $._semicolon)
461
+ )
462
+ ),
463
+
464
+ class: ($) =>
465
+ prec(
466
+ 'literal',
467
+ seq(
468
+ repeat(field('decorator', $.decorator)),
469
+ 'class',
470
+ field('name', optional($._type_identifier)),
471
+ field('type_parameters', optional($.type_parameters)),
472
+ optional($.class_heritage),
473
+ field('body', $.class_body)
474
+ )
475
+ ),
476
+
477
+ abstract_class_declaration: ($) =>
478
+ prec(
479
+ 'declaration',
480
+ seq(
481
+ repeat(field('decorator', $.decorator)),
482
+ 'abstract',
483
+ 'class',
484
+ field('name', $._type_identifier),
485
+ field('type_parameters', optional($.type_parameters)),
486
+ optional($.class_heritage),
487
+ field('body', $.class_body)
488
+ )
489
+ ),
490
+
491
+ class_declaration: ($) =>
492
+ prec.left(
493
+ 'declaration',
494
+ seq(
495
+ repeat(field('decorator', $.decorator)),
496
+ 'class',
497
+ field('name', $._type_identifier),
498
+ field('type_parameters', optional($.type_parameters)),
499
+ optional($.class_heritage),
500
+ field('body', $.class_body),
501
+ optional($._automatic_semicolon)
502
+ )
503
+ ),
504
+
505
+ module: ($) => seq('module', $._module),
506
+
507
+ internal_module: ($) => seq('namespace', $._module),
508
+
509
+ _module: ($) =>
510
+ prec.right(
511
+ seq(
512
+ field('name', choice($.string, $.identifier, $.nested_identifier)),
513
+ // On .d.ts files "declare module foo" desugars to "declare module foo {}",
514
+ // hence why it is optional here
515
+ field('body', optional($.statement_block))
516
+ )
517
+ ),
518
+
519
+ import_alias: ($) => seq('import', $.identifier, '=', choice($.identifier, $.nested_identifier), $._semicolon),
520
+
521
+ nested_type_identifier: ($) =>
522
+ prec(
523
+ 'member',
524
+ seq(field('module', choice($.identifier, $.nested_identifier)), '.', field('name', $._type_identifier))
525
+ ),
526
+
527
+ interface_declaration: ($) =>
528
+ seq(
529
+ 'interface',
530
+ field('name', $._type_identifier),
531
+ field('type_parameters', optional($.type_parameters)),
532
+ optional($.extends_type_clause),
533
+ field('body', alias($.object_type, $.interface_body))
534
+ ),
535
+
536
+ extends_type_clause: ($) =>
537
+ seq('extends', commaSep1(field('type', choice($._type_identifier, $.nested_type_identifier, $.generic_type)))),
538
+
539
+ enum_declaration: ($) => seq(optional('const'), 'enum', field('name', $.identifier), field('body', $.enum_body)),
540
+
541
+ enum_body: ($) =>
542
+ seq(
543
+ '{',
544
+ optional(seq(sepBy1(',', choice(field('name', $._property_name), $.enum_assignment)), optional(','))),
545
+ '}'
546
+ ),
547
+
548
+ enum_assignment: ($) => seq(field('name', $._property_name), $._initializer),
549
+
550
+ type_alias_declaration: ($) =>
551
+ seq(
552
+ 'type',
553
+ field('name', $._type_identifier),
554
+ field('type_parameters', optional($.type_parameters)),
555
+ '=',
556
+ field('value', $.type),
557
+ $._semicolon
558
+ ),
559
+
560
+ accessibility_modifier: () => choice('public', 'private', 'protected'),
561
+
562
+ override_modifier: () => 'override',
563
+
564
+ required_parameter: ($) =>
565
+ seq($._parameter_name, field('type', optional($.type_annotation)), optional($._initializer)),
566
+
567
+ optional_parameter: ($) =>
568
+ seq($._parameter_name, '?', field('type', optional($.type_annotation)), optional($._initializer)),
569
+
570
+ _parameter_name: ($) =>
571
+ seq(
572
+ repeat(field('decorator', $.decorator)),
573
+ optional($.accessibility_modifier),
574
+ optional($.override_modifier),
575
+ optional('readonly'),
576
+ field('pattern', choice($.pattern, $.this))
577
+ ),
578
+
579
+ omitting_type_annotation: ($) => seq('-?:', $.type),
580
+ adding_type_annotation: ($) => seq('+?:', $.type),
581
+ opting_type_annotation: ($) => seq('?:', $.type),
582
+ type_annotation: ($) => seq(':', $.type),
583
+
584
+ // Oh boy
585
+ // The issue is these special type queries need a lower relative precedence than the normal ones,
586
+ // since these are used in type annotations whereas the other ones are used where `typeof` is
587
+ // required beforehand. This allows for parsing of annotations such as
588
+ // foo: import('x').y.z;
589
+ // but was a nightmare to get working.
590
+ _type_query_member_expression_in_type_annotation: ($) =>
591
+ seq(
592
+ field(
593
+ 'object',
594
+ choice(
595
+ $.import,
596
+ alias($._type_query_member_expression_in_type_annotation, $.member_expression),
597
+ alias($._type_query_call_expression_in_type_annotation, $.call_expression)
598
+ )
599
+ ),
600
+ '.',
601
+ field('property', choice($.private_property_identifier, alias($.identifier, $.property_identifier)))
602
+ ),
603
+ _type_query_call_expression_in_type_annotation: ($) =>
604
+ seq(
605
+ field(
606
+ 'function',
607
+ choice($.import, alias($._type_query_member_expression_in_type_annotation, $.member_expression))
608
+ ),
609
+ field('arguments', $.arguments)
610
+ ),
611
+
612
+ asserts: ($) => seq('asserts', choice($.type_predicate, $.identifier, $.this)),
613
+
614
+ asserts_annotation: ($) => seq(seq(':', $.asserts)),
615
+
616
+ type: ($) =>
617
+ choice(
618
+ $.primary_type,
619
+ $.function_type,
620
+ $.readonly_type,
621
+ $.constructor_type,
622
+ $.infer_type,
623
+ prec(-1, alias($._type_query_member_expression_in_type_annotation, $.member_expression)),
624
+ prec(-1, alias($._type_query_call_expression_in_type_annotation, $.call_expression))
625
+ ),
626
+
627
+ tuple_parameter: ($) =>
628
+ seq(field('name', choice($.identifier, $.rest_pattern)), field('type', $.type_annotation)),
629
+
630
+ optional_tuple_parameter: ($) => seq(field('name', $.identifier), '?', field('type', $.type_annotation)),
631
+
632
+ optional_type: ($) => seq($.type, '?'),
633
+ rest_type: ($) => seq('...', $.type),
634
+
635
+ _tuple_type_member: ($) =>
636
+ choice(
637
+ alias($.tuple_parameter, $.required_parameter),
638
+ alias($.optional_tuple_parameter, $.optional_parameter),
639
+ $.optional_type,
640
+ $.rest_type,
641
+ $.type
642
+ ),
643
+
644
+ constructor_type: ($) =>
645
+ prec.left(
646
+ seq(
647
+ optional('abstract'),
648
+ 'new',
649
+ field('type_parameters', optional($.type_parameters)),
650
+ field('parameters', $.formal_parameters),
651
+ '=>',
652
+ field('type', $.type)
653
+ )
654
+ ),
655
+
656
+ primary_type: ($) =>
657
+ choice(
658
+ $.parenthesized_type,
659
+ $.predefined_type,
660
+ $._type_identifier,
661
+ $.nested_type_identifier,
662
+ $.generic_type,
663
+ $.object_type,
664
+ $.array_type,
665
+ $.tuple_type,
666
+ $.flow_maybe_type,
667
+ $.type_query,
668
+ $.index_type_query,
669
+ alias($.this, $.this_type),
670
+ $.existential_type,
671
+ $.literal_type,
672
+ $.lookup_type,
673
+ $.conditional_type,
674
+ $.template_literal_type,
675
+ $.intersection_type,
676
+ $.union_type,
677
+ 'const'
678
+ ),
679
+
680
+ template_type: ($) => seq('${', choice($.primary_type, $.infer_type), '}'),
681
+
682
+ template_literal_type: ($) =>
683
+ seq('`', repeat(choice(alias($._template_chars, $.string_fragment), $.template_type)), '`'),
684
+
685
+ infer_type: ($) => prec.right(seq('infer', $._type_identifier, optional(seq('extends', $.type)))),
686
+
687
+ conditional_type: ($) =>
688
+ prec.right(
689
+ seq(
690
+ field('left', $.type),
691
+ 'extends',
692
+ field('right', $.type),
693
+ '?',
694
+ field('consequence', $.type),
695
+ ':',
696
+ field('alternative', $.type)
697
+ )
698
+ ),
699
+
700
+ generic_type: ($) =>
701
+ prec(
702
+ 'call',
703
+ seq(
704
+ field('name', choice($._type_identifier, $.nested_type_identifier)),
705
+ field('type_arguments', $.type_arguments)
706
+ )
707
+ ),
708
+
709
+ type_predicate: ($) =>
710
+ seq(
711
+ field(
712
+ 'name',
713
+ choice(
714
+ $.identifier,
715
+ $.this,
716
+ // Sometimes tree-sitter contextual lexing is not good enough to know
717
+ // that 'object' in ':object is foo' is really an identifier and not
718
+ // a predefined_type, so we must explicitely list all possibilities.
719
+ // TODO: should we use '_reserved_identifier'? Should all the element in
720
+ // 'predefined_type' be added to '_reserved_identifier'?
721
+ alias($.predefined_type, $.identifier)
722
+ )
723
+ ),
724
+ 'is',
725
+ field('type', $.type)
726
+ ),
727
+
728
+ type_predicate_annotation: ($) => seq(seq(':', $.type_predicate)),
729
+
730
+ // Type query expressions are more restrictive than regular expressions
731
+ _type_query_member_expression: ($) =>
732
+ seq(
733
+ field(
734
+ 'object',
735
+ choice(
736
+ $.identifier,
737
+ $.this,
738
+ alias($._type_query_subscript_expression, $.subscript_expression),
739
+ alias($._type_query_member_expression, $.member_expression),
740
+ alias($._type_query_call_expression, $.call_expression)
741
+ )
742
+ ),
743
+ choice('.', '?.'),
744
+ field('property', choice($.private_property_identifier, alias($.identifier, $.property_identifier)))
745
+ ),
746
+ _type_query_subscript_expression: ($) =>
747
+ seq(
748
+ field(
749
+ 'object',
750
+ choice(
751
+ $.identifier,
752
+ $.this,
753
+ alias($._type_query_subscript_expression, $.subscript_expression),
754
+ alias($._type_query_member_expression, $.member_expression),
755
+ alias($._type_query_call_expression, $.call_expression)
756
+ )
757
+ ),
758
+ optional('?.'),
759
+ '[',
760
+ field('index', choice($.predefined_type, $.string, $.number)),
761
+ ']'
762
+ ),
763
+ _type_query_call_expression: ($) =>
764
+ seq(
765
+ field(
766
+ 'function',
767
+ choice(
768
+ $.import,
769
+ $.identifier,
770
+ alias($._type_query_member_expression, $.member_expression),
771
+ alias($._type_query_subscript_expression, $.subscript_expression)
772
+ )
773
+ ),
774
+ field('arguments', $.arguments)
775
+ ),
776
+ _type_query_instantiation_expression: ($) =>
777
+ seq(
778
+ field(
779
+ 'function',
780
+ choice(
781
+ $.import,
782
+ $.identifier,
783
+ alias($._type_query_member_expression, $.member_expression),
784
+ alias($._type_query_subscript_expression, $.subscript_expression)
785
+ )
786
+ ),
787
+ field('type_arguments', $.type_arguments)
788
+ ),
789
+ type_query: ($) =>
790
+ prec.right(
791
+ seq(
792
+ 'typeof',
793
+ choice(
794
+ alias($._type_query_subscript_expression, $.subscript_expression),
795
+ alias($._type_query_member_expression, $.member_expression),
796
+ alias($._type_query_call_expression, $.call_expression),
797
+ alias($._type_query_instantiation_expression, $.instantiation_expression),
798
+ $.identifier,
799
+ $.this
800
+ )
801
+ )
802
+ ),
803
+
804
+ index_type_query: ($) => seq('keyof', $.primary_type),
805
+
806
+ lookup_type: ($) => seq($.primary_type, '[', $.type, ']'),
807
+
808
+ mapped_type_clause: ($) =>
809
+ seq(
810
+ field('name', $._type_identifier),
811
+ 'in',
812
+ field('type', $.type),
813
+ optional(seq('as', field('alias', $.type)))
814
+ ),
815
+
816
+ literal_type: ($) =>
817
+ choice(alias($._number, $.unary_expression), $.number, $.string, $.true, $.false, $.null, $.undefined),
818
+
819
+ _number: ($) => prec.left(1, seq(field('operator', choice('-', '+')), field('argument', $.number))),
820
+
821
+ existential_type: () => '*',
822
+
823
+ flow_maybe_type: ($) => prec.right(seq('?', $.primary_type)),
824
+
825
+ parenthesized_type: ($) => seq('(', $.type, ')'),
826
+
827
+ predefined_type: () =>
828
+ choice(
829
+ 'any',
830
+ 'number',
831
+ 'boolean',
832
+ 'string',
833
+ 'symbol',
834
+ alias(seq('unique', 'symbol'), 'unique symbol'),
835
+ 'void',
836
+ 'unknown',
837
+ 'string',
838
+ 'never',
839
+ 'object'
840
+ ),
841
+
842
+ type_arguments: ($) => seq('<', commaSep1($.type), optional(','), '>'),
843
+
844
+ object_type: ($) =>
845
+ seq(
846
+ choice('{', '{|'),
847
+ optional(
848
+ seq(
849
+ optional(choice(',', ';')),
850
+ sepBy1(
851
+ choice(',', $._semicolon),
852
+ choice(
853
+ $.export_statement,
854
+ $.property_signature,
855
+ $.call_signature,
856
+ $.construct_signature,
857
+ $.index_signature,
858
+ $.method_signature
859
+ )
860
+ ),
861
+ optional(choice(',', $._semicolon))
862
+ )
863
+ ),
864
+ choice('}', '|}')
865
+ ),
866
+
867
+ call_signature: ($) => $._call_signature,
868
+
869
+ property_signature: ($) =>
870
+ seq(
871
+ optional($.accessibility_modifier),
872
+ optional('static'),
873
+ optional($.override_modifier),
874
+ optional('readonly'),
875
+ field('name', $._property_name),
876
+ optional('?'),
877
+ field('type', optional($.type_annotation))
878
+ ),
879
+
880
+ _call_signature: ($) =>
881
+ seq(
882
+ field('type_parameters', optional($.type_parameters)),
883
+ field('parameters', $.formal_parameters),
884
+ field('return_type', optional(choice($.type_annotation, $.asserts_annotation, $.type_predicate_annotation)))
885
+ ),
886
+
887
+ type_parameters: ($) => seq('<', commaSep1($.type_parameter), optional(','), '>'),
888
+
889
+ type_parameter: ($) =>
890
+ seq(
891
+ optional('const'),
892
+ field('name', $._type_identifier),
893
+ field('constraint', optional($.constraint)),
894
+ field('value', optional($.default_type))
895
+ ),
896
+
897
+ default_type: ($) => seq('=', $.type),
898
+
899
+ constraint: ($) => seq(choice('extends', ':'), $.type),
900
+
901
+ construct_signature: ($) =>
902
+ seq(
903
+ optional('abstract'),
904
+ 'new',
905
+ field('type_parameters', optional($.type_parameters)),
906
+ field('parameters', $.formal_parameters),
907
+ field('type', optional($.type_annotation))
908
+ ),
909
+
910
+ index_signature: ($) =>
911
+ seq(
912
+ optional(seq(field('sign', optional(choice('-', '+'))), 'readonly')),
913
+ '[',
914
+ choice(
915
+ seq(
916
+ field('name', choice($.identifier, alias($._reserved_identifier, $.identifier))),
917
+ ':',
918
+ field('index_type', $.type)
919
+ ),
920
+ $.mapped_type_clause
921
+ ),
922
+ ']',
923
+ field(
924
+ 'type',
925
+ choice($.type_annotation, $.omitting_type_annotation, $.adding_type_annotation, $.opting_type_annotation)
926
+ )
927
+ ),
928
+
929
+ array_type: ($) => seq($.primary_type, '[', ']'),
930
+ tuple_type: ($) => seq('[', commaSep($._tuple_type_member), optional(','), ']'),
931
+ readonly_type: ($) => seq('readonly', $.type),
932
+
933
+ union_type: ($) => prec.left(seq(optional($.type), '|', $.type)),
934
+ intersection_type: ($) => prec.left(seq(optional($.type), '&', $.type)),
935
+
936
+ function_type: ($) =>
937
+ prec.left(
938
+ seq(
939
+ field('type_parameters', optional($.type_parameters)),
940
+ field('parameters', $.formal_parameters),
941
+ '=>',
942
+ field('return_type', choice($.type, $.asserts, $.type_predicate))
943
+ )
944
+ ),
945
+
946
+ _type_identifier: ($) => alias($.identifier, $.type_identifier),
947
+
948
+ _reserved_identifier: (_, previous) =>
949
+ choice(
950
+ 'declare',
951
+ 'namespace',
952
+ 'type',
953
+ 'public',
954
+ 'private',
955
+ 'protected',
956
+ 'override',
957
+ 'readonly',
958
+ 'module',
959
+ 'any',
960
+ 'number',
961
+ 'boolean',
962
+ 'string',
963
+ 'symbol',
964
+ 'export',
965
+ 'object',
966
+ 'new',
967
+ 'readonly',
968
+ previous
969
+ ),
970
+ },
971
+ });
972
+ };
973
+
974
+ /**
975
+ * Creates a rule to match one or more of the rules separated by a comma
976
+ *
977
+ * @param {RuleOrLiteral} rule
978
+ *
979
+ * @return {SeqRule}
980
+ *
981
+ */
982
+ function commaSep1(rule) {
983
+ return sepBy1(',', rule);
984
+ }
985
+
986
+ /**
987
+ * Creates a rule to optionally match one or more of the rules separated by a comma
988
+ *
989
+ * @param {RuleOrLiteral} rule
990
+ *
991
+ * @return {SeqRule}
992
+ *
993
+ */
994
+ function commaSep(rule) {
995
+ return sepBy(',', rule);
996
+ }
997
+
998
+ /**
999
+ * Creates a rule to optionally match one or more of the rules separated by a separator
1000
+ *
1001
+ * @param {RuleOrLiteral} sep
1002
+ *
1003
+ * @param {RuleOrLiteral} rule
1004
+ *
1005
+ * @return {ChoiceRule}
1006
+ */
1007
+ function sepBy(sep, rule) {
1008
+ return optional(sepBy1(sep, rule));
1009
+ }
1010
+
1011
+ /**
1012
+ * Creates a rule to match one or more of the rules separated by a separator
1013
+ *
1014
+ * @param {RuleOrLiteral} sep
1015
+ *
1016
+ * @param {RuleOrLiteral} rule
1017
+ *
1018
+ * @return {SeqRule}
1019
+ */
1020
+ function sepBy1(sep, rule) {
1021
+ return seq(rule, repeat(seq(sep, rule)));
1022
+ }