@konomanoasa/tree-sitter-query 0.1.0 → 0.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/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "konomanoasa-tree-sitter-query"
3
- version = "0.1.0"
3
+ version = "0.3.0"
4
4
  edition = "2024"
5
5
  description = "Tree-sitter grammar for Tree-sitter Query."
6
6
  readme = "README.md"
package/README.md CHANGED
@@ -15,7 +15,7 @@ npm install @konomanoasa/tree-sitter-query
15
15
 
16
16
  ## Development
17
17
 
18
- Development uses Node.js 24 or later.
18
+ Development uses Node.js 24.21.0 or later.
19
19
 
20
20
  ```sh
21
21
  npm install
package/grammar.js CHANGED
@@ -1,4 +1,4 @@
1
- const name = /[A-Za-z0-9_-][A-Za-z0-9_.-]*/;
1
+ const namePattern = /[A-Za-z0-9_-][A-Za-z0-9_.-]*/;
2
2
  const stringContent = /[^"\\\n]+/;
3
3
 
4
4
  const postfixed = ($, body) =>
@@ -24,10 +24,9 @@ const fieldConstraint = ($, target) =>
24
24
  field("pattern", target),
25
25
  );
26
26
 
27
- // The Query API accepts no layout or comment around the subtype separator.
28
- const subtyped = ($, name) =>
27
+ const subtyped = ($, supertype) =>
29
28
  seq(
30
- field("supertype", name),
29
+ field("supertype", supertype),
31
30
  token.immediate("/"),
32
31
  field(
33
32
  "subtype",
@@ -52,10 +51,12 @@ export default grammar({
52
51
  name: "query",
53
52
  extras: ($) => [/[ \t\r\n\v\f]/, $.comment],
54
53
  rules: {
55
- query: ($) => repeat($._member),
54
+ query: ($) => optional($._members),
55
+ _members: ($) => seq($._member, optional($._members)),
56
56
  _member: ($) => choice($._child_pattern, $._call),
57
- _call_only_member: ($) => choice($._call_only_child_pattern, $._call),
58
57
  _call: ($) => choice($.predicate, $.directive),
58
+ _call_only_member: ($) => choice($._call_only_child_pattern, $._call),
59
+
59
60
  pattern: ($) => postfixed($, choice($._delimited, $.string, $.wildcard)),
60
61
  _call_only_pattern: ($) =>
61
62
  postfixed(
@@ -65,9 +66,16 @@ export default grammar({
65
66
  alias($._call_only_alternation, $.alternation),
66
67
  ),
67
68
  ),
68
- // "(_" always opens a node pattern, so a group never starts with a bare wildcard.
69
- _group_pattern: ($) => postfixed($, choice($._delimited, $.string)),
70
69
  _delimited: ($) => choice($.node_pattern, $.group, $.alternation),
70
+ _child_pattern: ($) =>
71
+ choice($._matching_child_pattern, $._call_only_child_pattern),
72
+ _matching_child_pattern: ($) => choice($.pattern, $.field_constraint),
73
+ _call_only_child_pattern: ($) =>
74
+ choice(
75
+ alias($._call_only_pattern, $.pattern),
76
+ alias($._call_only_field_constraint, $.field_constraint),
77
+ ),
78
+
71
79
  node_pattern: ($) =>
72
80
  seq(
73
81
  "(",
@@ -95,20 +103,14 @@ export default grammar({
95
103
  ),
96
104
  ")",
97
105
  ),
98
- _child_pattern: ($) =>
99
- choice($._matching_child_pattern, $._call_only_child_pattern),
100
- _matching_child_pattern: ($) => choice($.pattern, $.field_constraint),
101
- _call_only_child_pattern: ($) =>
102
- choice(
103
- alias($._call_only_pattern, $.pattern),
104
- alias($._call_only_field_constraint, $.field_constraint),
105
- ),
106
106
  _node_annotation: ($) =>
107
107
  choice(anchored($, $._call_only_member), $.negated_field),
108
+
108
109
  field_constraint: ($) => fieldConstraint($, $._matching_child_pattern),
109
110
  _call_only_field_constraint: ($) =>
110
111
  fieldConstraint($, $._call_only_child_pattern),
111
112
  negated_field: ($) => seq("!", field("name", $._name)),
113
+
112
114
  supertype: ($) =>
113
115
  subtyped($, choice($.identifier, alias($.wildcard, $.identifier))),
114
116
  _untyped_missing_node: () => "MISSING",
@@ -121,6 +123,7 @@ export default grammar({
121
123
  ),
122
124
  ),
123
125
  _missing_supertype: ($) => subtyped($, $._name),
126
+
124
127
  group: ($) =>
125
128
  seq(
126
129
  "(",
@@ -135,6 +138,7 @@ export default grammar({
135
138
  repeat(anchored($, $._member)),
136
139
  ")",
137
140
  ),
141
+ _group_pattern: ($) => postfixed($, choice($._delimited, $.string)),
138
142
  _call_only_group: ($) =>
139
143
  seq(
140
144
  "(",
@@ -144,6 +148,7 @@ export default grammar({
144
148
  ),
145
149
  _call_only_group_start: ($) =>
146
150
  choice($._call, alias($._call_only_pattern, $.pattern)),
151
+
147
152
  alternation: ($) =>
148
153
  seq(
149
154
  "[",
@@ -153,30 +158,35 @@ export default grammar({
153
158
  "]",
154
159
  ),
155
160
  _call_only_alternation: ($) => seq("[", repeat1($._call_only_member), "]"),
161
+
156
162
  quantifier: () => token(choice("+", "*", "?")),
157
163
  anchor: () => ".",
164
+ wildcard: () => "_",
158
165
  capture: ($) =>
159
166
  seq("@", field("name", alias($._immediate_identifier, $.identifier))),
167
+
160
168
  predicate: ($) => call($, "?"),
161
169
  directive: ($) => call($, "!"),
162
- identifier: () => name,
170
+
171
+ identifier: () => namePattern,
163
172
  _field_identifier: () => /[A-Za-z0-9-][A-Za-z0-9_.-]*/,
164
- _immediate_identifier: () => token.immediate(name),
173
+ _immediate_identifier: () => token.immediate(namePattern),
165
174
  _name: ($) =>
166
175
  choice(
167
176
  $.identifier,
168
177
  alias($.wildcard, $.identifier),
169
178
  alias("MISSING", $.identifier),
170
179
  ),
171
- wildcard: () => "_",
180
+
172
181
  string: ($) => seq('"', $._string_tail),
173
182
  _immediate_string: ($) => seq(token.immediate('"'), $._string_tail),
174
183
  _string_tail: ($) =>
175
184
  seq(
176
185
  repeat(choice($.string_content, $.escape_sequence)),
177
- token.immediate('"'),
186
+ choice(token.immediate('"'), seq($._string_line_break, $._unmatchable)),
178
187
  ),
179
- // Content outranks the comment extra so that ; stays inside the string.
188
+ _string_line_break: () => token.immediate(/\n/),
189
+ _unmatchable: () => token(seq("\\", /[^\s\S]/)),
180
190
  string_content: () =>
181
191
  token.immediate(
182
192
  prec(
@@ -184,8 +194,9 @@ export default grammar({
184
194
  repeat1(choice(stringContent, seq("\0", optional(stringContent)))),
185
195
  ),
186
196
  ),
187
- // Distinct NUL transitions prevent the generated lexer from treating it as EOF.
197
+ // Keep NUL distinct from EOF in the generated lexer.
188
198
  escape_sequence: () => token.immediate(choice(/\\(.|\n)/, prec(1, "\\\0"))),
199
+
189
200
  comment: () => /;[^\r\n]*(\r+[^\r\n]+)*/,
190
201
  },
191
202
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konomanoasa/tree-sitter-query",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Tree-sitter grammar for Tree-sitter Query.",
6
6
  "license": "MIT",
@@ -21,11 +21,11 @@
21
21
  },
22
22
  "scripts": {
23
23
  "build": "npm run tree-sitter -- build-all",
24
- "check": "biome check . && node scripts/check-generated.js && npm test",
25
- "format": "biome check --write .",
24
+ "check": "biome check . && tsc --noEmit",
25
+ "check:queries": "npm run tree-sitter -- check-queries",
26
+ "format": "biome format --write .",
26
27
  "generate": "npm run tree-sitter -- generate-all",
27
28
  "test": "npm run tree-sitter -- test-corpus --rebuild && node --test --test-concurrency=1 \"test/*.test.js\"",
28
- "test:bindings": "cargo test --locked",
29
29
  "test:fuzz": "node --test --test-name-pattern=\"fixed-seed generated histories\" test/incremental.test.js",
30
30
  "test:fuzz:corpus": "npm run tree-sitter -- fuzz-all --iterations 100 --edits 5",
31
31
  "test:highlights": "node --test test/highlight.test.js",
@@ -35,7 +35,8 @@
35
35
  "devDependencies": {
36
36
  "@biomejs/biome": "2.5.14",
37
37
  "@types/node": "26.5.1",
38
- "tree-sitter-cli": "0.27.0"
38
+ "tree-sitter-cli": "0.27.0",
39
+ "typescript": "7.0.2"
39
40
  },
40
41
  "allowScripts": {
41
42
  "tree-sitter-cli": true
package/src/grammar.json CHANGED
@@ -3,31 +3,44 @@
3
3
  "name": "query",
4
4
  "rules": {
5
5
  "query": {
6
- "type": "REPEAT",
7
- "content": {
8
- "type": "SYMBOL",
9
- "name": "_member"
10
- }
11
- },
12
- "_member": {
13
6
  "type": "CHOICE",
14
7
  "members": [
15
8
  {
16
9
  "type": "SYMBOL",
17
- "name": "_child_pattern"
10
+ "name": "_members"
18
11
  },
12
+ {
13
+ "type": "BLANK"
14
+ }
15
+ ]
16
+ },
17
+ "_members": {
18
+ "type": "SEQ",
19
+ "members": [
19
20
  {
20
21
  "type": "SYMBOL",
21
- "name": "_call"
22
+ "name": "_member"
23
+ },
24
+ {
25
+ "type": "CHOICE",
26
+ "members": [
27
+ {
28
+ "type": "SYMBOL",
29
+ "name": "_members"
30
+ },
31
+ {
32
+ "type": "BLANK"
33
+ }
34
+ ]
22
35
  }
23
36
  ]
24
37
  },
25
- "_call_only_member": {
38
+ "_member": {
26
39
  "type": "CHOICE",
27
40
  "members": [
28
41
  {
29
42
  "type": "SYMBOL",
30
- "name": "_call_only_child_pattern"
43
+ "name": "_child_pattern"
31
44
  },
32
45
  {
33
46
  "type": "SYMBOL",
@@ -48,6 +61,19 @@
48
61
  }
49
62
  ]
50
63
  },
64
+ "_call_only_member": {
65
+ "type": "CHOICE",
66
+ "members": [
67
+ {
68
+ "type": "SYMBOL",
69
+ "name": "_call_only_child_pattern"
70
+ },
71
+ {
72
+ "type": "SYMBOL",
73
+ "name": "_call"
74
+ }
75
+ ]
76
+ },
51
77
  "pattern": {
52
78
  "type": "SEQ",
53
79
  "members": [
@@ -154,66 +180,69 @@
154
180
  }
155
181
  ]
156
182
  },
157
- "_group_pattern": {
158
- "type": "SEQ",
183
+ "_delimited": {
184
+ "type": "CHOICE",
159
185
  "members": [
160
186
  {
161
- "type": "FIELD",
162
- "name": "body",
163
- "content": {
164
- "type": "CHOICE",
165
- "members": [
166
- {
167
- "type": "SYMBOL",
168
- "name": "_delimited"
169
- },
170
- {
171
- "type": "SYMBOL",
172
- "name": "string"
173
- }
174
- ]
175
- }
187
+ "type": "SYMBOL",
188
+ "name": "node_pattern"
176
189
  },
177
190
  {
178
- "type": "REPEAT",
179
- "content": {
180
- "type": "CHOICE",
181
- "members": [
182
- {
183
- "type": "FIELD",
184
- "name": "capture",
185
- "content": {
186
- "type": "SYMBOL",
187
- "name": "capture"
188
- }
189
- },
190
- {
191
- "type": "FIELD",
192
- "name": "quantifier",
193
- "content": {
194
- "type": "SYMBOL",
195
- "name": "quantifier"
196
- }
197
- }
198
- ]
199
- }
191
+ "type": "SYMBOL",
192
+ "name": "group"
193
+ },
194
+ {
195
+ "type": "SYMBOL",
196
+ "name": "alternation"
200
197
  }
201
198
  ]
202
199
  },
203
- "_delimited": {
200
+ "_child_pattern": {
204
201
  "type": "CHOICE",
205
202
  "members": [
206
203
  {
207
204
  "type": "SYMBOL",
208
- "name": "node_pattern"
205
+ "name": "_matching_child_pattern"
209
206
  },
210
207
  {
211
208
  "type": "SYMBOL",
212
- "name": "group"
209
+ "name": "_call_only_child_pattern"
210
+ }
211
+ ]
212
+ },
213
+ "_matching_child_pattern": {
214
+ "type": "CHOICE",
215
+ "members": [
216
+ {
217
+ "type": "SYMBOL",
218
+ "name": "pattern"
213
219
  },
214
220
  {
215
221
  "type": "SYMBOL",
216
- "name": "alternation"
222
+ "name": "field_constraint"
223
+ }
224
+ ]
225
+ },
226
+ "_call_only_child_pattern": {
227
+ "type": "CHOICE",
228
+ "members": [
229
+ {
230
+ "type": "ALIAS",
231
+ "content": {
232
+ "type": "SYMBOL",
233
+ "name": "_call_only_pattern"
234
+ },
235
+ "named": true,
236
+ "value": "pattern"
237
+ },
238
+ {
239
+ "type": "ALIAS",
240
+ "content": {
241
+ "type": "SYMBOL",
242
+ "name": "_call_only_field_constraint"
243
+ },
244
+ "named": true,
245
+ "value": "field_constraint"
217
246
  }
218
247
  ]
219
248
  },
@@ -364,55 +393,6 @@
364
393
  }
365
394
  ]
366
395
  },
367
- "_child_pattern": {
368
- "type": "CHOICE",
369
- "members": [
370
- {
371
- "type": "SYMBOL",
372
- "name": "_matching_child_pattern"
373
- },
374
- {
375
- "type": "SYMBOL",
376
- "name": "_call_only_child_pattern"
377
- }
378
- ]
379
- },
380
- "_matching_child_pattern": {
381
- "type": "CHOICE",
382
- "members": [
383
- {
384
- "type": "SYMBOL",
385
- "name": "pattern"
386
- },
387
- {
388
- "type": "SYMBOL",
389
- "name": "field_constraint"
390
- }
391
- ]
392
- },
393
- "_call_only_child_pattern": {
394
- "type": "CHOICE",
395
- "members": [
396
- {
397
- "type": "ALIAS",
398
- "content": {
399
- "type": "SYMBOL",
400
- "name": "_call_only_pattern"
401
- },
402
- "named": true,
403
- "value": "pattern"
404
- },
405
- {
406
- "type": "ALIAS",
407
- "content": {
408
- "type": "SYMBOL",
409
- "name": "_call_only_field_constraint"
410
- },
411
- "named": true,
412
- "value": "field_constraint"
413
- }
414
- ]
415
- },
416
396
  "_node_annotation": {
417
397
  "type": "CHOICE",
418
398
  "members": [
@@ -800,6 +780,52 @@
800
780
  }
801
781
  ]
802
782
  },
783
+ "_group_pattern": {
784
+ "type": "SEQ",
785
+ "members": [
786
+ {
787
+ "type": "FIELD",
788
+ "name": "body",
789
+ "content": {
790
+ "type": "CHOICE",
791
+ "members": [
792
+ {
793
+ "type": "SYMBOL",
794
+ "name": "_delimited"
795
+ },
796
+ {
797
+ "type": "SYMBOL",
798
+ "name": "string"
799
+ }
800
+ ]
801
+ }
802
+ },
803
+ {
804
+ "type": "REPEAT",
805
+ "content": {
806
+ "type": "CHOICE",
807
+ "members": [
808
+ {
809
+ "type": "FIELD",
810
+ "name": "capture",
811
+ "content": {
812
+ "type": "SYMBOL",
813
+ "name": "capture"
814
+ }
815
+ },
816
+ {
817
+ "type": "FIELD",
818
+ "name": "quantifier",
819
+ "content": {
820
+ "type": "SYMBOL",
821
+ "name": "quantifier"
822
+ }
823
+ }
824
+ ]
825
+ }
826
+ }
827
+ ]
828
+ },
803
829
  "_call_only_group": {
804
830
  "type": "SEQ",
805
831
  "members": [
@@ -934,6 +960,10 @@
934
960
  "type": "STRING",
935
961
  "value": "."
936
962
  },
963
+ "wildcard": {
964
+ "type": "STRING",
965
+ "value": "_"
966
+ },
937
967
  "capture": {
938
968
  "type": "SEQ",
939
969
  "members": [
@@ -1120,10 +1150,6 @@
1120
1150
  }
1121
1151
  ]
1122
1152
  },
1123
- "wildcard": {
1124
- "type": "STRING",
1125
- "value": "_"
1126
- },
1127
1153
  "string": {
1128
1154
  "type": "SEQ",
1129
1155
  "members": [
@@ -1173,14 +1199,55 @@
1173
1199
  }
1174
1200
  },
1175
1201
  {
1176
- "type": "IMMEDIATE_TOKEN",
1177
- "content": {
1178
- "type": "STRING",
1179
- "value": "\""
1180
- }
1202
+ "type": "CHOICE",
1203
+ "members": [
1204
+ {
1205
+ "type": "IMMEDIATE_TOKEN",
1206
+ "content": {
1207
+ "type": "STRING",
1208
+ "value": "\""
1209
+ }
1210
+ },
1211
+ {
1212
+ "type": "SEQ",
1213
+ "members": [
1214
+ {
1215
+ "type": "SYMBOL",
1216
+ "name": "_string_line_break"
1217
+ },
1218
+ {
1219
+ "type": "SYMBOL",
1220
+ "name": "_unmatchable"
1221
+ }
1222
+ ]
1223
+ }
1224
+ ]
1181
1225
  }
1182
1226
  ]
1183
1227
  },
1228
+ "_string_line_break": {
1229
+ "type": "IMMEDIATE_TOKEN",
1230
+ "content": {
1231
+ "type": "PATTERN",
1232
+ "value": "\\n"
1233
+ }
1234
+ },
1235
+ "_unmatchable": {
1236
+ "type": "TOKEN",
1237
+ "content": {
1238
+ "type": "SEQ",
1239
+ "members": [
1240
+ {
1241
+ "type": "STRING",
1242
+ "value": "\\"
1243
+ },
1244
+ {
1245
+ "type": "PATTERN",
1246
+ "value": "[^\\s\\S]"
1247
+ }
1248
+ ]
1249
+ }
1250
+ },
1184
1251
  "string_content": {
1185
1252
  "type": "IMMEDIATE_TOKEN",
1186
1253
  "content": {
@@ -5,7 +5,7 @@
5
5
  "fields": {},
6
6
  "children": {
7
7
  "multiple": true,
8
- "required": false,
8
+ "required": true,
9
9
  "types": [
10
10
  {
11
11
  "type": "directive",