@willbooster/tree-sitter-typescript 1.2.13 → 1.3.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/README.md +6 -1
- package/common/defineGrammar.js +102 -15
- package/package.json +11 -8
- package/queries/highlights.scm +3 -0
- package/tree-sitter-tsx.wasm +0 -0
- package/tree-sitter-typescript.wasm +0 -0
- package/tree-sitter.json +1 -1
- package/tsx/src/node-types.json +9 -1
- package/typescript/src/node-types.json +9 -1
package/README.md
CHANGED
|
@@ -108,7 +108,12 @@ runtime this package ships. The first run downloads that CLI from its GitHub Rel
|
|
|
108
108
|
`cargo` (with the `cmake` that `mise.toml` pins) when the download fails or the release has no binary that runs here.
|
|
109
109
|
|
|
110
110
|
`bun run test/ci-setup` installs Chromium for the browser tests. `bun run build/ci` regenerates `typescript/src/` and
|
|
111
|
-
`tsx/src/` and builds both Wasm files.
|
|
111
|
+
`tsx/src/` and builds both Wasm files. It also refreshes `common/typeScriptKeywords.h` from the pinned
|
|
112
|
+
`typescript-reference` API (TypeScript 5.9.3), which supplies the global-augmentation lookahead vocabulary.
|
|
113
|
+
The native TypeScript package remains the type checker. Run `bun run generate-keywords` after changing the reference;
|
|
114
|
+
verification checks the committed header with `bun run check-keywords`.
|
|
115
|
+
|
|
116
|
+
`bun run test` runs:
|
|
112
117
|
|
|
113
118
|
- the corpus in `test/corpus`, with the native build and with the Wasm build (the first run downloads the WASI SDK).
|
|
114
119
|
Cases run with the `typescript` grammar unless they carry `:language(tsx)`;
|
package/common/defineGrammar.js
CHANGED
|
@@ -4,6 +4,7 @@ const JavaScript = require('@willbooster/tree-sitter-javascript/grammar');
|
|
|
4
4
|
// Words that are keywords only in some positions and identifiers elsewhere, besides the JavaScript grammar's.
|
|
5
5
|
const TYPESCRIPT_CONTEXTUAL_KEYWORDS = [
|
|
6
6
|
'declare',
|
|
7
|
+
'global',
|
|
7
8
|
'namespace',
|
|
8
9
|
'type',
|
|
9
10
|
'public',
|
|
@@ -18,6 +19,7 @@ const TYPESCRIPT_CONTEXTUAL_KEYWORDS = [
|
|
|
18
19
|
'string',
|
|
19
20
|
'symbol',
|
|
20
21
|
'object',
|
|
22
|
+
'out',
|
|
21
23
|
'new',
|
|
22
24
|
];
|
|
23
25
|
|
|
@@ -64,6 +66,8 @@ module.exports = function defineGrammar(dialect) {
|
|
|
64
66
|
$._type_arguments_end,
|
|
65
67
|
$._type_arguments_end_before_expression,
|
|
66
68
|
$._new_type_arguments_end,
|
|
69
|
+
$._global_declaration_start,
|
|
70
|
+
$._global_declaration_end,
|
|
67
71
|
$.__error_recovery,
|
|
68
72
|
],
|
|
69
73
|
|
|
@@ -118,7 +122,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
118
122
|
[$.type_query, $._type_query_subscript_expression],
|
|
119
123
|
[$.nested_type_identifier, $.generic_type, $.primary_type, $.lookup_type, $.index_type_query, $.type],
|
|
120
124
|
// A qualified type name takes every `.` and name that follow it: `x as a.b.C` is not `(x as a.b).C`.
|
|
121
|
-
[$.nested_identifier, $.nested_type_identifier],
|
|
125
|
+
[$.nested_identifier, $._in_nested_identifier, $.nested_type_identifier],
|
|
122
126
|
[$.as_expression, $.satisfies_expression, $.primary_type],
|
|
123
127
|
[$._type_query_member_expression, $.member_expression],
|
|
124
128
|
[$.member_expression, $._type_query_member_expression_in_type_annotation],
|
|
@@ -189,6 +193,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
189
193
|
? [[$.primary_type, $.type_parameter]]
|
|
190
194
|
: [
|
|
191
195
|
[$.jsx_opening_element, $.type_parameter],
|
|
196
|
+
[$.jsx_opening_element, $.jsx_self_closing_element, $.type_parameter],
|
|
192
197
|
[$.jsx_namespace_name, $.primary_type],
|
|
193
198
|
]),
|
|
194
199
|
[
|
|
@@ -205,6 +210,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
205
210
|
inline: ($, previous) => [
|
|
206
211
|
...previous.filter((rule) => !['_formal_parameter', '_call_signature'].includes(rule.name)),
|
|
207
212
|
$._type_identifier,
|
|
213
|
+
$._type_reference_identifier,
|
|
208
214
|
$._jsx_start_opening_element,
|
|
209
215
|
],
|
|
210
216
|
|
|
@@ -410,6 +416,35 @@ module.exports = function defineGrammar(dialect) {
|
|
|
410
416
|
return choice(...choices);
|
|
411
417
|
},
|
|
412
418
|
|
|
419
|
+
_jsx_identifier: ($, previous) => choice(previous, alias(choice('in', 'out'), $.identifier)),
|
|
420
|
+
|
|
421
|
+
nested_identifier: ($) =>
|
|
422
|
+
prec(
|
|
423
|
+
'member',
|
|
424
|
+
seq(
|
|
425
|
+
field(
|
|
426
|
+
'object',
|
|
427
|
+
choice(
|
|
428
|
+
reserved('properties', $.identifier),
|
|
429
|
+
alias('out', $.identifier),
|
|
430
|
+
alias($.nested_identifier, $.member_expression)
|
|
431
|
+
)
|
|
432
|
+
),
|
|
433
|
+
...nestedIdentifierTail($)
|
|
434
|
+
)
|
|
435
|
+
),
|
|
436
|
+
|
|
437
|
+
_in_nested_identifier: ($) =>
|
|
438
|
+
prec(
|
|
439
|
+
'member',
|
|
440
|
+
seq(
|
|
441
|
+
field('object', choice(alias('in', $.identifier), alias($._in_nested_identifier, $.member_expression))),
|
|
442
|
+
...nestedIdentifierTail($)
|
|
443
|
+
)
|
|
444
|
+
),
|
|
445
|
+
|
|
446
|
+
_jsx_element_name: ($, previous) => choice(previous, alias($._in_nested_identifier, $.member_expression)),
|
|
447
|
+
|
|
413
448
|
_jsx_start_opening_element: ($) =>
|
|
414
449
|
seq(
|
|
415
450
|
'<',
|
|
@@ -418,7 +453,14 @@ module.exports = function defineGrammar(dialect) {
|
|
|
418
453
|
choice(
|
|
419
454
|
field('name', choice($._jsx_identifier, $.jsx_namespace_name)),
|
|
420
455
|
seq(
|
|
421
|
-
field(
|
|
456
|
+
field(
|
|
457
|
+
'name',
|
|
458
|
+
choice(
|
|
459
|
+
$._jsx_identifier,
|
|
460
|
+
alias($.nested_identifier, $.member_expression),
|
|
461
|
+
alias($._in_nested_identifier, $.member_expression)
|
|
462
|
+
)
|
|
463
|
+
),
|
|
422
464
|
field('type_arguments', optional($.type_arguments))
|
|
423
465
|
)
|
|
424
466
|
),
|
|
@@ -473,6 +515,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
473
515
|
export_statement: ($, previous) =>
|
|
474
516
|
choice(
|
|
475
517
|
previous,
|
|
518
|
+
seq('export', field('declaration', alias($.global_declaration, $.internal_module))),
|
|
476
519
|
seq('export', 'type', $.export_clause, optional($._from_clause), $._semicolon),
|
|
477
520
|
seq('export', 'type', choice('*', $.namespace_export), $._from_clause, $._semicolon),
|
|
478
521
|
seq('export', '=', $.expression, $._semicolon),
|
|
@@ -649,6 +692,8 @@ module.exports = function defineGrammar(dialect) {
|
|
|
649
692
|
)
|
|
650
693
|
),
|
|
651
694
|
|
|
695
|
+
statement: ($, previous) => choice(previous, alias($.global_declaration, $.internal_module)),
|
|
696
|
+
|
|
652
697
|
declaration: ($, previous) =>
|
|
653
698
|
choice(
|
|
654
699
|
previous,
|
|
@@ -706,7 +751,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
706
751
|
'declare',
|
|
707
752
|
choice(
|
|
708
753
|
$.declaration,
|
|
709
|
-
seq('global', $.statement_block),
|
|
754
|
+
seq(alias($._global_declaration_start, 'global'), choice($.statement_block, $._global_declaration_end)),
|
|
710
755
|
seq('module', '.', alias($.identifier, $.property_identifier), ':', $.type, $._semicolon)
|
|
711
756
|
)
|
|
712
757
|
),
|
|
@@ -756,22 +801,50 @@ module.exports = function defineGrammar(dialect) {
|
|
|
756
801
|
|
|
757
802
|
internal_module: ($) => seq('namespace', $._module),
|
|
758
803
|
|
|
804
|
+
global_declaration: ($) =>
|
|
805
|
+
seq(
|
|
806
|
+
field('name', alias($._global_declaration_start, $.identifier)),
|
|
807
|
+
choice(field('body', $.statement_block), $._global_declaration_end)
|
|
808
|
+
),
|
|
809
|
+
|
|
759
810
|
_module: ($) =>
|
|
760
811
|
prec.right(
|
|
761
812
|
seq(
|
|
762
|
-
field(
|
|
813
|
+
field(
|
|
814
|
+
'name',
|
|
815
|
+
choice($.string, reserved('properties', $.identifier), alias('out', $.identifier), $.nested_identifier)
|
|
816
|
+
),
|
|
763
817
|
// On .d.ts files "declare module foo" desugars to "declare module foo {}",
|
|
764
818
|
// hence why it is optional here
|
|
765
819
|
field('body', optional($.statement_block))
|
|
766
820
|
)
|
|
767
821
|
),
|
|
768
822
|
|
|
769
|
-
import_alias: ($) =>
|
|
823
|
+
import_alias: ($) =>
|
|
824
|
+
seq(
|
|
825
|
+
'import',
|
|
826
|
+
$.identifier,
|
|
827
|
+
'=',
|
|
828
|
+
choice($.identifier, alias('out', $.identifier), $.nested_identifier),
|
|
829
|
+
$._semicolon
|
|
830
|
+
),
|
|
770
831
|
|
|
771
832
|
nested_type_identifier: ($) =>
|
|
772
833
|
prec(
|
|
773
834
|
'member',
|
|
774
|
-
seq(
|
|
835
|
+
seq(
|
|
836
|
+
field(
|
|
837
|
+
'module',
|
|
838
|
+
choice(
|
|
839
|
+
$.identifier,
|
|
840
|
+
alias(choice('in', 'out'), $.identifier),
|
|
841
|
+
$.nested_identifier,
|
|
842
|
+
alias($._in_nested_identifier, $.nested_identifier)
|
|
843
|
+
)
|
|
844
|
+
),
|
|
845
|
+
'.',
|
|
846
|
+
field('name', $._type_reference_identifier)
|
|
847
|
+
)
|
|
775
848
|
),
|
|
776
849
|
|
|
777
850
|
interface_declaration: ($) =>
|
|
@@ -862,7 +935,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
862
935
|
field('arguments', $.arguments)
|
|
863
936
|
),
|
|
864
937
|
|
|
865
|
-
asserts: ($) => seq('asserts', choice($.type_predicate, $.identifier, $.this)),
|
|
938
|
+
asserts: ($) => seq('asserts', choice($.type_predicate, $.identifier, alias('out', $.identifier), $.this)),
|
|
866
939
|
|
|
867
940
|
asserts_annotation: ($) => seq(seq(':', $.asserts)),
|
|
868
941
|
|
|
@@ -885,11 +958,8 @@ module.exports = function defineGrammar(dialect) {
|
|
|
885
958
|
|
|
886
959
|
optional_tuple_parameter: ($) => seq(field('name', $._tuple_label), '?', field('type', $.type_annotation)),
|
|
887
960
|
|
|
888
|
-
_tuple_rest_label: ($) => seq('...', $._tuple_label),
|
|
961
|
+
_tuple_rest_label: ($) => seq('...', choice($._tuple_label, alias('in', $.identifier))),
|
|
889
962
|
|
|
890
|
-
// TypeScript accepts any identifier name as a tuple label, but where a tuple member begins, the keywords that
|
|
891
|
-
// can begin a type are lexed as those keywords, so they are listed here. Keywords that are rules of their own
|
|
892
|
-
// are aliased as rules: repeating their strings would turn those rules into nodes that wrap a token.
|
|
893
963
|
_tuple_label: ($) =>
|
|
894
964
|
choice(
|
|
895
965
|
$.identifier,
|
|
@@ -905,6 +975,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
905
975
|
'never',
|
|
906
976
|
'object',
|
|
907
977
|
'readonly',
|
|
978
|
+
'out',
|
|
908
979
|
'keyof',
|
|
909
980
|
'infer',
|
|
910
981
|
'typeof',
|
|
@@ -948,7 +1019,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
948
1019
|
choice(
|
|
949
1020
|
$.parenthesized_type,
|
|
950
1021
|
$.predefined_type,
|
|
951
|
-
$.
|
|
1022
|
+
$._type_reference_identifier,
|
|
952
1023
|
$.nested_type_identifier,
|
|
953
1024
|
$.generic_type,
|
|
954
1025
|
$.object_type,
|
|
@@ -995,7 +1066,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
995
1066
|
field(
|
|
996
1067
|
'name',
|
|
997
1068
|
choice(
|
|
998
|
-
$.
|
|
1069
|
+
$._type_reference_identifier,
|
|
999
1070
|
$.nested_type_identifier,
|
|
1000
1071
|
alias($._type_query_member_expression_in_type_annotation, $.member_expression)
|
|
1001
1072
|
)
|
|
@@ -1010,6 +1081,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
1010
1081
|
'name',
|
|
1011
1082
|
choice(
|
|
1012
1083
|
$.identifier,
|
|
1084
|
+
alias('out', $.identifier),
|
|
1013
1085
|
$.this,
|
|
1014
1086
|
// Sometimes tree-sitter contextual lexing is not good enough to know
|
|
1015
1087
|
// that 'object' in ':object is foo' is really an identifier and not
|
|
@@ -1189,7 +1261,7 @@ module.exports = function defineGrammar(dialect) {
|
|
|
1189
1261
|
|
|
1190
1262
|
type_parameter: ($) =>
|
|
1191
1263
|
seq(
|
|
1192
|
-
|
|
1264
|
+
repeat(choice('const', 'in', 'out')),
|
|
1193
1265
|
field('name', $._type_identifier),
|
|
1194
1266
|
field('constraint', optional($.constraint)),
|
|
1195
1267
|
field('value', optional($.default_type))
|
|
@@ -1252,13 +1324,28 @@ module.exports = function defineGrammar(dialect) {
|
|
|
1252
1324
|
|
|
1253
1325
|
// A type name may be a reserved word, which TypeScript reports only as a semantic error. The reserved words must be
|
|
1254
1326
|
// allowed on the identifier inside the alias: around the alias, the keyword token still wins in the lexer.
|
|
1255
|
-
_type_identifier: ($) => alias(reserved('properties', $.identifier), $.type_identifier),
|
|
1327
|
+
_type_identifier: ($) => alias(choice(reserved('properties', $.identifier), 'out'), $.type_identifier),
|
|
1328
|
+
|
|
1329
|
+
_type_reference_identifier: ($) => choice($._type_identifier, alias('in', $.type_identifier)),
|
|
1256
1330
|
|
|
1257
1331
|
_reserved_identifier: (_, previous) => choice(...TYPESCRIPT_CONTEXTUAL_KEYWORDS, previous),
|
|
1258
1332
|
},
|
|
1259
1333
|
});
|
|
1260
1334
|
};
|
|
1261
1335
|
|
|
1336
|
+
function nestedIdentifierTail($) {
|
|
1337
|
+
return [
|
|
1338
|
+
'.',
|
|
1339
|
+
field(
|
|
1340
|
+
'property',
|
|
1341
|
+
choice(
|
|
1342
|
+
reserved('properties', alias($.identifier, $.property_identifier)),
|
|
1343
|
+
alias(choice('in', 'out'), $.property_identifier)
|
|
1344
|
+
)
|
|
1345
|
+
),
|
|
1346
|
+
];
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1262
1349
|
/**
|
|
1263
1350
|
* Creates a rule to match one or more of the rules separated by a comma
|
|
1264
1351
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@willbooster/tree-sitter-typescript",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "TypeScript and TSX grammars for tree-sitter",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"incremental",
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
30
|
"build-wasm": "script/tree-sitter build --wasm typescript && script/tree-sitter build --wasm tsx",
|
|
31
|
-
"build/ci": "script/tree-sitter generate typescript/grammar.js && script/tree-sitter generate tsx/grammar.js && bun run build-wasm",
|
|
32
|
-
"
|
|
31
|
+
"build/ci": "bun run generate-keywords && script/tree-sitter generate typescript/grammar.js && script/tree-sitter generate tsx/grammar.js && bun run build-wasm",
|
|
32
|
+
"check-keywords": "bun scripts/generateGlobalKeywords.ts --check",
|
|
33
|
+
"cleanup": "bun run check-keywords && bun wb lint --fix --format",
|
|
33
34
|
"format": "bun wb lint --format",
|
|
35
|
+
"generate-keywords": "bun scripts/generateGlobalKeywords.ts",
|
|
34
36
|
"lint": "bun wb lint",
|
|
35
37
|
"lint-fix": "bun wb lint --fix",
|
|
36
38
|
"prepare": "(bun lefthook install || true) && (test ! -f .lefthook/normalize-bun-lockfile.sh || bash .lefthook/normalize-bun-lockfile.sh)",
|
|
@@ -48,24 +50,25 @@
|
|
|
48
50
|
"devDependencies": {
|
|
49
51
|
"@tsconfig/bun": "1.0.11",
|
|
50
52
|
"@types/bun": "1.4.2",
|
|
51
|
-
"@vitest/browser-playwright": "5.0.
|
|
53
|
+
"@vitest/browser-playwright": "5.0.2",
|
|
52
54
|
"@willbooster/oxfmt-config": "1.2.2",
|
|
53
55
|
"@willbooster/oxlint-config": "1.4.8",
|
|
54
56
|
"@willbooster/tree-sitter-javascript": "1.0.21",
|
|
55
|
-
"@willbooster/wb": "22.
|
|
57
|
+
"@willbooster/wb": "22.18.0",
|
|
56
58
|
"@willbooster/web-tree-sitter": "1.0.17",
|
|
57
59
|
"conventional-changelog-conventionalcommits": "10.4.0",
|
|
58
60
|
"lefthook": "2.1.14",
|
|
59
61
|
"oxfmt": "0.70.0",
|
|
60
62
|
"oxlint": "1.85.0",
|
|
61
|
-
"oxlint-tsgolint": "7.0.
|
|
63
|
+
"oxlint-tsgolint": "7.0.2003",
|
|
62
64
|
"playwright": "1.63.0",
|
|
63
65
|
"semantic-release": "25.0.9",
|
|
64
66
|
"sort-package-json": "4.0.0",
|
|
65
67
|
"typescript": "7.0.2",
|
|
68
|
+
"typescript-reference": "npm:typescript@5.9.3",
|
|
66
69
|
"vite": "8.3.0",
|
|
67
|
-
"vitest": "5.0.
|
|
68
|
-
"wrangler": "4.
|
|
70
|
+
"vitest": "5.0.2",
|
|
71
|
+
"wrangler": "4.141.0"
|
|
69
72
|
},
|
|
70
73
|
"peerDependencies": {
|
|
71
74
|
"@willbooster/web-tree-sitter": "^1.0.0"
|
package/queries/highlights.scm
CHANGED
package/tree-sitter-tsx.wasm
CHANGED
|
Binary file
|
|
Binary file
|
package/tree-sitter.json
CHANGED
package/tsx/src/node-types.json
CHANGED
|
@@ -413,6 +413,10 @@
|
|
|
413
413
|
"type": "import_statement",
|
|
414
414
|
"named": true
|
|
415
415
|
},
|
|
416
|
+
{
|
|
417
|
+
"type": "internal_module",
|
|
418
|
+
"named": true
|
|
419
|
+
},
|
|
416
420
|
{
|
|
417
421
|
"type": "labeled_statement",
|
|
418
422
|
"named": true
|
|
@@ -647,7 +651,7 @@
|
|
|
647
651
|
"fields": {},
|
|
648
652
|
"children": {
|
|
649
653
|
"multiple": true,
|
|
650
|
-
"required":
|
|
654
|
+
"required": false,
|
|
651
655
|
"types": [
|
|
652
656
|
{
|
|
653
657
|
"type": "declaration",
|
|
@@ -6238,6 +6242,10 @@
|
|
|
6238
6242
|
"type": "optional_chain",
|
|
6239
6243
|
"named": true
|
|
6240
6244
|
},
|
|
6245
|
+
{
|
|
6246
|
+
"type": "out",
|
|
6247
|
+
"named": false
|
|
6248
|
+
},
|
|
6241
6249
|
{
|
|
6242
6250
|
"type": "override",
|
|
6243
6251
|
"named": false
|
|
@@ -409,6 +409,10 @@
|
|
|
409
409
|
"type": "import_statement",
|
|
410
410
|
"named": true
|
|
411
411
|
},
|
|
412
|
+
{
|
|
413
|
+
"type": "internal_module",
|
|
414
|
+
"named": true
|
|
415
|
+
},
|
|
412
416
|
{
|
|
413
417
|
"type": "labeled_statement",
|
|
414
418
|
"named": true
|
|
@@ -643,7 +647,7 @@
|
|
|
643
647
|
"fields": {},
|
|
644
648
|
"children": {
|
|
645
649
|
"multiple": true,
|
|
646
|
-
"required":
|
|
650
|
+
"required": false,
|
|
647
651
|
"types": [
|
|
648
652
|
{
|
|
649
653
|
"type": "declaration",
|
|
@@ -5988,6 +5992,10 @@
|
|
|
5988
5992
|
"type": "optional_chain",
|
|
5989
5993
|
"named": true
|
|
5990
5994
|
},
|
|
5995
|
+
{
|
|
5996
|
+
"type": "out",
|
|
5997
|
+
"named": false
|
|
5998
|
+
},
|
|
5991
5999
|
{
|
|
5992
6000
|
"type": "override",
|
|
5993
6001
|
"named": false
|