@willbooster/tree-sitter-typescript 0.0.0-placeholder.0 → 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.
@@ -0,0 +1,1021 @@
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', '=', $.expression, $._semicolon),
292
+ seq('export', 'as', 'namespace', $.identifier, $._semicolon)
293
+ ),
294
+
295
+ non_null_expression: ($) => prec.left('unary', seq($.expression, '!')),
296
+
297
+ variable_declarator: ($) =>
298
+ choice(
299
+ seq(
300
+ field('name', choice($.identifier, $._destructuring_pattern)),
301
+ field('type', optional($.type_annotation)),
302
+ optional($._initializer)
303
+ ),
304
+ prec('declaration', seq(field('name', $.identifier), '!', field('type', $.type_annotation)))
305
+ ),
306
+
307
+ method_signature: ($) =>
308
+ seq(
309
+ optional($.accessibility_modifier),
310
+ optional('static'),
311
+ optional($.override_modifier),
312
+ optional('readonly'),
313
+ optional('async'),
314
+ optional(choice('get', 'set', '*')),
315
+ field('name', $._property_name),
316
+ optional('?'),
317
+ $._call_signature
318
+ ),
319
+
320
+ abstract_method_signature: ($) =>
321
+ seq(
322
+ optional($.accessibility_modifier),
323
+ 'abstract',
324
+ optional($.override_modifier),
325
+ optional(choice('get', 'set', '*')),
326
+ field('name', $._property_name),
327
+ optional('?'),
328
+ $._call_signature
329
+ ),
330
+
331
+ parenthesized_expression: ($) =>
332
+ seq('(', choice(seq($.expression, field('type', optional($.type_annotation))), $.sequence_expression), ')'),
333
+
334
+ _formal_parameter: ($) => choice($.required_parameter, $.optional_parameter),
335
+
336
+ function_signature: ($) =>
337
+ seq(
338
+ optional('async'),
339
+ 'function',
340
+ field('name', $.identifier),
341
+ $._call_signature,
342
+ choice($._semicolon, $._function_signature_automatic_semicolon)
343
+ ),
344
+
345
+ decorator: ($) =>
346
+ seq(
347
+ '@',
348
+ choice(
349
+ $.identifier,
350
+ alias($.decorator_member_expression, $.member_expression),
351
+ alias($.decorator_call_expression, $.call_expression),
352
+ alias($.decorator_parenthesized_expression, $.parenthesized_expression)
353
+ )
354
+ ),
355
+
356
+ decorator_call_expression: ($) =>
357
+ prec(
358
+ 'call',
359
+ seq(
360
+ field('function', choice($.identifier, alias($.decorator_member_expression, $.member_expression))),
361
+ optional(field('type_arguments', $.type_arguments)),
362
+ field('arguments', $.arguments)
363
+ )
364
+ ),
365
+
366
+ decorator_parenthesized_expression: ($) =>
367
+ seq(
368
+ '(',
369
+ choice(
370
+ $.identifier,
371
+ alias($.decorator_member_expression, $.member_expression),
372
+ alias($.decorator_call_expression, $.call_expression)
373
+ ),
374
+ ')'
375
+ ),
376
+
377
+ class_body: ($) =>
378
+ seq(
379
+ '{',
380
+ repeat(
381
+ choice(
382
+ seq(repeat(field('decorator', $.decorator)), $.method_definition, optional($._semicolon)),
383
+ // As it happens for functions, the semicolon insertion should not
384
+ // happen if a block follows the closing paren, because then it's a
385
+ // *definition*, not a declaration. Example:
386
+ // public foo()
387
+ // { <--- this brace made the method signature become a definition
388
+ // }
389
+ // The same rule applies for functions and that's why we use
390
+ // "_function_signature_automatic_semicolon".
391
+ seq($.method_signature, choice($._function_signature_automatic_semicolon, ',')),
392
+ $.class_static_block,
393
+ seq(
394
+ choice($.abstract_method_signature, $.index_signature, $.method_signature, $.public_field_definition),
395
+ choice($._semicolon, ',')
396
+ ),
397
+ ';'
398
+ )
399
+ ),
400
+ '}'
401
+ ),
402
+
403
+ method_definition: ($) =>
404
+ prec.left(
405
+ seq(
406
+ optional($.accessibility_modifier),
407
+ optional('static'),
408
+ optional($.override_modifier),
409
+ optional('readonly'),
410
+ optional('async'),
411
+ optional(choice('get', 'set', '*')),
412
+ field('name', $._property_name),
413
+ optional('?'),
414
+ $._call_signature,
415
+ field('body', $.statement_block)
416
+ )
417
+ ),
418
+
419
+ declaration: ($, previous) =>
420
+ choice(
421
+ previous,
422
+ $.function_signature,
423
+ $.abstract_class_declaration,
424
+ $.module,
425
+ prec('declaration', $.internal_module),
426
+ $.type_alias_declaration,
427
+ $.enum_declaration,
428
+ $.interface_declaration,
429
+ $.import_alias,
430
+ $.ambient_declaration
431
+ ),
432
+
433
+ type_assertion: ($) => prec.left('unary', seq($.type_arguments, $.expression)),
434
+
435
+ as_expression: ($) => prec.left('binary', seq($.expression, 'as', choice('const', $.type))),
436
+
437
+ satisfies_expression: ($) => prec.left('binary', seq($.expression, 'satisfies', $.type)),
438
+
439
+ instantiation_expression: ($) =>
440
+ prec('instantiation', seq($.expression, field('type_arguments', $.type_arguments))),
441
+
442
+ class_heritage: ($) => choice(seq($.extends_clause, optional($.implements_clause)), $.implements_clause),
443
+
444
+ import_require_clause: ($) => seq($.identifier, '=', 'require', '(', field('source', $.string), ')'),
445
+
446
+ extends_clause: ($) => seq('extends', commaSep1($._extends_clause_single)),
447
+
448
+ _extends_clause_single: ($) =>
449
+ prec('extends', seq(field('value', $.expression), field('type_arguments', optional($.type_arguments)))),
450
+
451
+ implements_clause: ($) => seq('implements', commaSep1($.type)),
452
+
453
+ ambient_declaration: ($) =>
454
+ seq(
455
+ 'declare',
456
+ choice(
457
+ $.declaration,
458
+ seq('global', $.statement_block),
459
+ seq('module', '.', alias($.identifier, $.property_identifier), ':', $.type, $._semicolon)
460
+ )
461
+ ),
462
+
463
+ class: ($) =>
464
+ prec(
465
+ 'literal',
466
+ seq(
467
+ repeat(field('decorator', $.decorator)),
468
+ 'class',
469
+ field('name', optional($._type_identifier)),
470
+ field('type_parameters', optional($.type_parameters)),
471
+ optional($.class_heritage),
472
+ field('body', $.class_body)
473
+ )
474
+ ),
475
+
476
+ abstract_class_declaration: ($) =>
477
+ prec(
478
+ 'declaration',
479
+ seq(
480
+ repeat(field('decorator', $.decorator)),
481
+ 'abstract',
482
+ 'class',
483
+ field('name', $._type_identifier),
484
+ field('type_parameters', optional($.type_parameters)),
485
+ optional($.class_heritage),
486
+ field('body', $.class_body)
487
+ )
488
+ ),
489
+
490
+ class_declaration: ($) =>
491
+ prec.left(
492
+ 'declaration',
493
+ seq(
494
+ repeat(field('decorator', $.decorator)),
495
+ 'class',
496
+ field('name', $._type_identifier),
497
+ field('type_parameters', optional($.type_parameters)),
498
+ optional($.class_heritage),
499
+ field('body', $.class_body),
500
+ optional($._automatic_semicolon)
501
+ )
502
+ ),
503
+
504
+ module: ($) => seq('module', $._module),
505
+
506
+ internal_module: ($) => seq('namespace', $._module),
507
+
508
+ _module: ($) =>
509
+ prec.right(
510
+ seq(
511
+ field('name', choice($.string, $.identifier, $.nested_identifier)),
512
+ // On .d.ts files "declare module foo" desugars to "declare module foo {}",
513
+ // hence why it is optional here
514
+ field('body', optional($.statement_block))
515
+ )
516
+ ),
517
+
518
+ import_alias: ($) => seq('import', $.identifier, '=', choice($.identifier, $.nested_identifier), $._semicolon),
519
+
520
+ nested_type_identifier: ($) =>
521
+ prec(
522
+ 'member',
523
+ seq(field('module', choice($.identifier, $.nested_identifier)), '.', field('name', $._type_identifier))
524
+ ),
525
+
526
+ interface_declaration: ($) =>
527
+ seq(
528
+ 'interface',
529
+ field('name', $._type_identifier),
530
+ field('type_parameters', optional($.type_parameters)),
531
+ optional($.extends_type_clause),
532
+ field('body', alias($.object_type, $.interface_body))
533
+ ),
534
+
535
+ extends_type_clause: ($) =>
536
+ seq('extends', commaSep1(field('type', choice($._type_identifier, $.nested_type_identifier, $.generic_type)))),
537
+
538
+ enum_declaration: ($) => seq(optional('const'), 'enum', field('name', $.identifier), field('body', $.enum_body)),
539
+
540
+ enum_body: ($) =>
541
+ seq(
542
+ '{',
543
+ optional(seq(sepBy1(',', choice(field('name', $._property_name), $.enum_assignment)), optional(','))),
544
+ '}'
545
+ ),
546
+
547
+ enum_assignment: ($) => seq(field('name', $._property_name), $._initializer),
548
+
549
+ type_alias_declaration: ($) =>
550
+ seq(
551
+ 'type',
552
+ field('name', $._type_identifier),
553
+ field('type_parameters', optional($.type_parameters)),
554
+ '=',
555
+ field('value', $.type),
556
+ $._semicolon
557
+ ),
558
+
559
+ accessibility_modifier: () => choice('public', 'private', 'protected'),
560
+
561
+ override_modifier: () => 'override',
562
+
563
+ required_parameter: ($) =>
564
+ seq($._parameter_name, field('type', optional($.type_annotation)), optional($._initializer)),
565
+
566
+ optional_parameter: ($) =>
567
+ seq($._parameter_name, '?', field('type', optional($.type_annotation)), optional($._initializer)),
568
+
569
+ _parameter_name: ($) =>
570
+ seq(
571
+ repeat(field('decorator', $.decorator)),
572
+ optional($.accessibility_modifier),
573
+ optional($.override_modifier),
574
+ optional('readonly'),
575
+ field('pattern', choice($.pattern, $.this))
576
+ ),
577
+
578
+ omitting_type_annotation: ($) => seq('-?:', $.type),
579
+ adding_type_annotation: ($) => seq('+?:', $.type),
580
+ opting_type_annotation: ($) => seq('?:', $.type),
581
+ type_annotation: ($) => seq(':', $.type),
582
+
583
+ // Oh boy
584
+ // The issue is these special type queries need a lower relative precedence than the normal ones,
585
+ // since these are used in type annotations whereas the other ones are used where `typeof` is
586
+ // required beforehand. This allows for parsing of annotations such as
587
+ // foo: import('x').y.z;
588
+ // but was a nightmare to get working.
589
+ _type_query_member_expression_in_type_annotation: ($) =>
590
+ seq(
591
+ field(
592
+ 'object',
593
+ choice(
594
+ $.import,
595
+ alias($._type_query_member_expression_in_type_annotation, $.member_expression),
596
+ alias($._type_query_call_expression_in_type_annotation, $.call_expression)
597
+ )
598
+ ),
599
+ '.',
600
+ field('property', choice($.private_property_identifier, alias($.identifier, $.property_identifier)))
601
+ ),
602
+ _type_query_call_expression_in_type_annotation: ($) =>
603
+ seq(
604
+ field(
605
+ 'function',
606
+ choice($.import, alias($._type_query_member_expression_in_type_annotation, $.member_expression))
607
+ ),
608
+ field('arguments', $.arguments)
609
+ ),
610
+
611
+ asserts: ($) => seq('asserts', choice($.type_predicate, $.identifier, $.this)),
612
+
613
+ asserts_annotation: ($) => seq(seq(':', $.asserts)),
614
+
615
+ type: ($) =>
616
+ choice(
617
+ $.primary_type,
618
+ $.function_type,
619
+ $.readonly_type,
620
+ $.constructor_type,
621
+ $.infer_type,
622
+ prec(-1, alias($._type_query_member_expression_in_type_annotation, $.member_expression)),
623
+ prec(-1, alias($._type_query_call_expression_in_type_annotation, $.call_expression))
624
+ ),
625
+
626
+ tuple_parameter: ($) =>
627
+ seq(field('name', choice($.identifier, $.rest_pattern)), field('type', $.type_annotation)),
628
+
629
+ optional_tuple_parameter: ($) => seq(field('name', $.identifier), '?', field('type', $.type_annotation)),
630
+
631
+ optional_type: ($) => seq($.type, '?'),
632
+ rest_type: ($) => seq('...', $.type),
633
+
634
+ _tuple_type_member: ($) =>
635
+ choice(
636
+ alias($.tuple_parameter, $.required_parameter),
637
+ alias($.optional_tuple_parameter, $.optional_parameter),
638
+ $.optional_type,
639
+ $.rest_type,
640
+ $.type
641
+ ),
642
+
643
+ constructor_type: ($) =>
644
+ prec.left(
645
+ seq(
646
+ optional('abstract'),
647
+ 'new',
648
+ field('type_parameters', optional($.type_parameters)),
649
+ field('parameters', $.formal_parameters),
650
+ '=>',
651
+ field('type', $.type)
652
+ )
653
+ ),
654
+
655
+ primary_type: ($) =>
656
+ choice(
657
+ $.parenthesized_type,
658
+ $.predefined_type,
659
+ $._type_identifier,
660
+ $.nested_type_identifier,
661
+ $.generic_type,
662
+ $.object_type,
663
+ $.array_type,
664
+ $.tuple_type,
665
+ $.flow_maybe_type,
666
+ $.type_query,
667
+ $.index_type_query,
668
+ alias($.this, $.this_type),
669
+ $.existential_type,
670
+ $.literal_type,
671
+ $.lookup_type,
672
+ $.conditional_type,
673
+ $.template_literal_type,
674
+ $.intersection_type,
675
+ $.union_type,
676
+ 'const'
677
+ ),
678
+
679
+ template_type: ($) => seq('${', choice($.primary_type, $.infer_type), '}'),
680
+
681
+ template_literal_type: ($) =>
682
+ seq('`', repeat(choice(alias($._template_chars, $.string_fragment), $.template_type)), '`'),
683
+
684
+ infer_type: ($) => prec.right(seq('infer', $._type_identifier, optional(seq('extends', $.type)))),
685
+
686
+ conditional_type: ($) =>
687
+ prec.right(
688
+ seq(
689
+ field('left', $.type),
690
+ 'extends',
691
+ field('right', $.type),
692
+ '?',
693
+ field('consequence', $.type),
694
+ ':',
695
+ field('alternative', $.type)
696
+ )
697
+ ),
698
+
699
+ generic_type: ($) =>
700
+ prec(
701
+ 'call',
702
+ seq(
703
+ field('name', choice($._type_identifier, $.nested_type_identifier)),
704
+ field('type_arguments', $.type_arguments)
705
+ )
706
+ ),
707
+
708
+ type_predicate: ($) =>
709
+ seq(
710
+ field(
711
+ 'name',
712
+ choice(
713
+ $.identifier,
714
+ $.this,
715
+ // Sometimes tree-sitter contextual lexing is not good enough to know
716
+ // that 'object' in ':object is foo' is really an identifier and not
717
+ // a predefined_type, so we must explicitely list all possibilities.
718
+ // TODO: should we use '_reserved_identifier'? Should all the element in
719
+ // 'predefined_type' be added to '_reserved_identifier'?
720
+ alias($.predefined_type, $.identifier)
721
+ )
722
+ ),
723
+ 'is',
724
+ field('type', $.type)
725
+ ),
726
+
727
+ type_predicate_annotation: ($) => seq(seq(':', $.type_predicate)),
728
+
729
+ // Type query expressions are more restrictive than regular expressions
730
+ _type_query_member_expression: ($) =>
731
+ seq(
732
+ field(
733
+ 'object',
734
+ choice(
735
+ $.identifier,
736
+ $.this,
737
+ alias($._type_query_subscript_expression, $.subscript_expression),
738
+ alias($._type_query_member_expression, $.member_expression),
739
+ alias($._type_query_call_expression, $.call_expression)
740
+ )
741
+ ),
742
+ choice('.', '?.'),
743
+ field('property', choice($.private_property_identifier, alias($.identifier, $.property_identifier)))
744
+ ),
745
+ _type_query_subscript_expression: ($) =>
746
+ seq(
747
+ field(
748
+ 'object',
749
+ choice(
750
+ $.identifier,
751
+ $.this,
752
+ alias($._type_query_subscript_expression, $.subscript_expression),
753
+ alias($._type_query_member_expression, $.member_expression),
754
+ alias($._type_query_call_expression, $.call_expression)
755
+ )
756
+ ),
757
+ optional('?.'),
758
+ '[',
759
+ field('index', choice($.predefined_type, $.string, $.number)),
760
+ ']'
761
+ ),
762
+ _type_query_call_expression: ($) =>
763
+ seq(
764
+ field(
765
+ 'function',
766
+ choice(
767
+ $.import,
768
+ $.identifier,
769
+ alias($._type_query_member_expression, $.member_expression),
770
+ alias($._type_query_subscript_expression, $.subscript_expression)
771
+ )
772
+ ),
773
+ field('arguments', $.arguments)
774
+ ),
775
+ _type_query_instantiation_expression: ($) =>
776
+ seq(
777
+ field(
778
+ 'function',
779
+ choice(
780
+ $.import,
781
+ $.identifier,
782
+ alias($._type_query_member_expression, $.member_expression),
783
+ alias($._type_query_subscript_expression, $.subscript_expression)
784
+ )
785
+ ),
786
+ field('type_arguments', $.type_arguments)
787
+ ),
788
+ type_query: ($) =>
789
+ prec.right(
790
+ seq(
791
+ 'typeof',
792
+ choice(
793
+ alias($._type_query_subscript_expression, $.subscript_expression),
794
+ alias($._type_query_member_expression, $.member_expression),
795
+ alias($._type_query_call_expression, $.call_expression),
796
+ alias($._type_query_instantiation_expression, $.instantiation_expression),
797
+ $.identifier,
798
+ $.this
799
+ )
800
+ )
801
+ ),
802
+
803
+ index_type_query: ($) => seq('keyof', $.primary_type),
804
+
805
+ lookup_type: ($) => seq($.primary_type, '[', $.type, ']'),
806
+
807
+ mapped_type_clause: ($) =>
808
+ seq(
809
+ field('name', $._type_identifier),
810
+ 'in',
811
+ field('type', $.type),
812
+ optional(seq('as', field('alias', $.type)))
813
+ ),
814
+
815
+ literal_type: ($) =>
816
+ choice(alias($._number, $.unary_expression), $.number, $.string, $.true, $.false, $.null, $.undefined),
817
+
818
+ _number: ($) => prec.left(1, seq(field('operator', choice('-', '+')), field('argument', $.number))),
819
+
820
+ existential_type: () => '*',
821
+
822
+ flow_maybe_type: ($) => prec.right(seq('?', $.primary_type)),
823
+
824
+ parenthesized_type: ($) => seq('(', $.type, ')'),
825
+
826
+ predefined_type: () =>
827
+ choice(
828
+ 'any',
829
+ 'number',
830
+ 'boolean',
831
+ 'string',
832
+ 'symbol',
833
+ alias(seq('unique', 'symbol'), 'unique symbol'),
834
+ 'void',
835
+ 'unknown',
836
+ 'string',
837
+ 'never',
838
+ 'object'
839
+ ),
840
+
841
+ type_arguments: ($) => seq('<', commaSep1($.type), optional(','), '>'),
842
+
843
+ object_type: ($) =>
844
+ seq(
845
+ choice('{', '{|'),
846
+ optional(
847
+ seq(
848
+ optional(choice(',', ';')),
849
+ sepBy1(
850
+ choice(',', $._semicolon),
851
+ choice(
852
+ $.export_statement,
853
+ $.property_signature,
854
+ $.call_signature,
855
+ $.construct_signature,
856
+ $.index_signature,
857
+ $.method_signature
858
+ )
859
+ ),
860
+ optional(choice(',', $._semicolon))
861
+ )
862
+ ),
863
+ choice('}', '|}')
864
+ ),
865
+
866
+ call_signature: ($) => $._call_signature,
867
+
868
+ property_signature: ($) =>
869
+ seq(
870
+ optional($.accessibility_modifier),
871
+ optional('static'),
872
+ optional($.override_modifier),
873
+ optional('readonly'),
874
+ field('name', $._property_name),
875
+ optional('?'),
876
+ field('type', optional($.type_annotation))
877
+ ),
878
+
879
+ _call_signature: ($) =>
880
+ seq(
881
+ field('type_parameters', optional($.type_parameters)),
882
+ field('parameters', $.formal_parameters),
883
+ field('return_type', optional(choice($.type_annotation, $.asserts_annotation, $.type_predicate_annotation)))
884
+ ),
885
+
886
+ type_parameters: ($) => seq('<', commaSep1($.type_parameter), optional(','), '>'),
887
+
888
+ type_parameter: ($) =>
889
+ seq(
890
+ optional('const'),
891
+ field('name', $._type_identifier),
892
+ field('constraint', optional($.constraint)),
893
+ field('value', optional($.default_type))
894
+ ),
895
+
896
+ default_type: ($) => seq('=', $.type),
897
+
898
+ constraint: ($) => seq(choice('extends', ':'), $.type),
899
+
900
+ construct_signature: ($) =>
901
+ seq(
902
+ optional('abstract'),
903
+ 'new',
904
+ field('type_parameters', optional($.type_parameters)),
905
+ field('parameters', $.formal_parameters),
906
+ field('type', optional($.type_annotation))
907
+ ),
908
+
909
+ index_signature: ($) =>
910
+ seq(
911
+ optional(seq(field('sign', optional(choice('-', '+'))), 'readonly')),
912
+ '[',
913
+ choice(
914
+ seq(
915
+ field('name', choice($.identifier, alias($._reserved_identifier, $.identifier))),
916
+ ':',
917
+ field('index_type', $.type)
918
+ ),
919
+ $.mapped_type_clause
920
+ ),
921
+ ']',
922
+ field(
923
+ 'type',
924
+ choice($.type_annotation, $.omitting_type_annotation, $.adding_type_annotation, $.opting_type_annotation)
925
+ )
926
+ ),
927
+
928
+ array_type: ($) => seq($.primary_type, '[', ']'),
929
+ tuple_type: ($) => seq('[', commaSep($._tuple_type_member), optional(','), ']'),
930
+ readonly_type: ($) => seq('readonly', $.type),
931
+
932
+ union_type: ($) => prec.left(seq(optional($.type), '|', $.type)),
933
+ intersection_type: ($) => prec.left(seq(optional($.type), '&', $.type)),
934
+
935
+ function_type: ($) =>
936
+ prec.left(
937
+ seq(
938
+ field('type_parameters', optional($.type_parameters)),
939
+ field('parameters', $.formal_parameters),
940
+ '=>',
941
+ field('return_type', choice($.type, $.asserts, $.type_predicate))
942
+ )
943
+ ),
944
+
945
+ _type_identifier: ($) => alias($.identifier, $.type_identifier),
946
+
947
+ _reserved_identifier: (_, previous) =>
948
+ choice(
949
+ 'declare',
950
+ 'namespace',
951
+ 'type',
952
+ 'public',
953
+ 'private',
954
+ 'protected',
955
+ 'override',
956
+ 'readonly',
957
+ 'module',
958
+ 'any',
959
+ 'number',
960
+ 'boolean',
961
+ 'string',
962
+ 'symbol',
963
+ 'export',
964
+ 'object',
965
+ 'new',
966
+ 'readonly',
967
+ previous
968
+ ),
969
+ },
970
+ });
971
+ };
972
+
973
+ /**
974
+ * Creates a rule to match one or more of the rules separated by a comma
975
+ *
976
+ * @param {RuleOrLiteral} rule
977
+ *
978
+ * @return {SeqRule}
979
+ *
980
+ */
981
+ function commaSep1(rule) {
982
+ return sepBy1(',', rule);
983
+ }
984
+
985
+ /**
986
+ * Creates a rule to optionally match one or more of the rules separated by a comma
987
+ *
988
+ * @param {RuleOrLiteral} rule
989
+ *
990
+ * @return {SeqRule}
991
+ *
992
+ */
993
+ function commaSep(rule) {
994
+ return sepBy(',', rule);
995
+ }
996
+
997
+ /**
998
+ * Creates a rule to optionally match one or more of the rules separated by a separator
999
+ *
1000
+ * @param {RuleOrLiteral} sep
1001
+ *
1002
+ * @param {RuleOrLiteral} rule
1003
+ *
1004
+ * @return {ChoiceRule}
1005
+ */
1006
+ function sepBy(sep, rule) {
1007
+ return optional(sepBy1(sep, rule));
1008
+ }
1009
+
1010
+ /**
1011
+ * Creates a rule to match one or more of the rules separated by a separator
1012
+ *
1013
+ * @param {RuleOrLiteral} sep
1014
+ *
1015
+ * @param {RuleOrLiteral} rule
1016
+ *
1017
+ * @return {SeqRule}
1018
+ */
1019
+ function sepBy1(sep, rule) {
1020
+ return seq(rule, repeat(seq(sep, rule)));
1021
+ }