@kerebron/tree-sitter 0.4.6

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.
Files changed (70) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +4 -0
  3. package/esm/_dnt.polyfills.d.ts +101 -0
  4. package/esm/_dnt.polyfills.d.ts.map +1 -0
  5. package/esm/_dnt.polyfills.js +127 -0
  6. package/esm/deno-tree-sitter/main/extended/base_node.d.ts +48 -0
  7. package/esm/deno-tree-sitter/main/extended/base_node.d.ts.map +1 -0
  8. package/esm/deno-tree-sitter/main/extended/base_node.js +154 -0
  9. package/esm/deno-tree-sitter/main/extended/node_extended.d.ts +237 -0
  10. package/esm/deno-tree-sitter/main/extended/node_extended.d.ts.map +1 -0
  11. package/esm/deno-tree-sitter/main/extended/node_extended.js +665 -0
  12. package/esm/deno-tree-sitter/main/extended/parser.d.ts +37 -0
  13. package/esm/deno-tree-sitter/main/extended/parser.d.ts.map +1 -0
  14. package/esm/deno-tree-sitter/main/extended/parser.js +86 -0
  15. package/esm/deno-tree-sitter/main/extended/soft_node.d.ts +15 -0
  16. package/esm/deno-tree-sitter/main/extended/soft_node.d.ts.map +1 -0
  17. package/esm/deno-tree-sitter/main/extended/soft_node.js +32 -0
  18. package/esm/deno-tree-sitter/main/extended/soft_text_node.d.ts +10 -0
  19. package/esm/deno-tree-sitter/main/extended/soft_text_node.d.ts.map +1 -0
  20. package/esm/deno-tree-sitter/main/extended/soft_text_node.js +10 -0
  21. package/esm/deno-tree-sitter/main/extended/whitespace_node.d.ts +10 -0
  22. package/esm/deno-tree-sitter/main/extended/whitespace_node.d.ts.map +1 -0
  23. package/esm/deno-tree-sitter/main/extended/whitespace_node.js +10 -0
  24. package/esm/deno-tree-sitter/main/extras/misc.d.ts +2 -0
  25. package/esm/deno-tree-sitter/main/extras/misc.d.ts.map +1 -0
  26. package/esm/deno-tree-sitter/main/extras/misc.js +13 -0
  27. package/esm/deno-tree-sitter/main/tree_sitter/bindings.d.ts +14 -0
  28. package/esm/deno-tree-sitter/main/tree_sitter/bindings.d.ts.map +1 -0
  29. package/esm/deno-tree-sitter/main/tree_sitter/bindings.js +21 -0
  30. package/esm/deno-tree-sitter/main/tree_sitter/constants.d.ts +60 -0
  31. package/esm/deno-tree-sitter/main/tree_sitter/constants.d.ts.map +1 -0
  32. package/esm/deno-tree-sitter/main/tree_sitter/constants.js +66 -0
  33. package/esm/deno-tree-sitter/main/tree_sitter/language.d.ts +137 -0
  34. package/esm/deno-tree-sitter/main/tree_sitter/language.d.ts.map +1 -0
  35. package/esm/deno-tree-sitter/main/tree_sitter/language.js +296 -0
  36. package/esm/deno-tree-sitter/main/tree_sitter/lookahead_iterator.d.ts +41 -0
  37. package/esm/deno-tree-sitter/main/tree_sitter/lookahead_iterator.d.ts.map +1 -0
  38. package/esm/deno-tree-sitter/main/tree_sitter/lookahead_iterator.js +75 -0
  39. package/esm/deno-tree-sitter/main/tree_sitter/marshal.d.ts +85 -0
  40. package/esm/deno-tree-sitter/main/tree_sitter/marshal.d.ts.map +1 -0
  41. package/esm/deno-tree-sitter/main/tree_sitter/marshal.js +173 -0
  42. package/esm/deno-tree-sitter/main/tree_sitter/node.d.ts +260 -0
  43. package/esm/deno-tree-sitter/main/tree_sitter/node.d.ts.map +1 -0
  44. package/esm/deno-tree-sitter/main/tree_sitter/node.js +592 -0
  45. package/esm/deno-tree-sitter/main/tree_sitter/parser.d.ts +124 -0
  46. package/esm/deno-tree-sitter/main/tree_sitter/parser.d.ts.map +1 -0
  47. package/esm/deno-tree-sitter/main/tree_sitter/parser.js +272 -0
  48. package/esm/deno-tree-sitter/main/tree_sitter/query.d.ts +134 -0
  49. package/esm/deno-tree-sitter/main/tree_sitter/query.d.ts.map +1 -0
  50. package/esm/deno-tree-sitter/main/tree_sitter/query.js +670 -0
  51. package/esm/deno-tree-sitter/main/tree_sitter/tree.d.ts +49 -0
  52. package/esm/deno-tree-sitter/main/tree_sitter/tree.d.ts.map +1 -0
  53. package/esm/deno-tree-sitter/main/tree_sitter/tree.js +145 -0
  54. package/esm/deno-tree-sitter/main/tree_sitter/tree_cursor.d.ts +165 -0
  55. package/esm/deno-tree-sitter/main/tree_sitter/tree_cursor.d.ts.map +1 -0
  56. package/esm/deno-tree-sitter/main/tree_sitter/tree_cursor.js +305 -0
  57. package/esm/deno-tree-sitter/main/tree_sitter_wasm.d.ts +3 -0
  58. package/esm/deno-tree-sitter/main/tree_sitter_wasm.d.ts.map +1 -0
  59. package/esm/deno-tree-sitter/main/tree_sitter_wasm.js +0 -0
  60. package/esm/deno-tree-sitter/main/wasm_loader.d.ts +29 -0
  61. package/esm/deno-tree-sitter/main/wasm_loader.d.ts.map +1 -0
  62. package/esm/deno-tree-sitter/main/wasm_loader.js +1709 -0
  63. package/esm/deno-tree-sitter/main/wasm_loader_with_defaults.d.ts +3 -0
  64. package/esm/deno-tree-sitter/main/wasm_loader_with_defaults.d.ts.map +1 -0
  65. package/esm/deno-tree-sitter/main/wasm_loader_with_defaults.js +8 -0
  66. package/esm/mod.d.ts +8 -0
  67. package/esm/mod.d.ts.map +1 -0
  68. package/esm/mod.js +8 -0
  69. package/esm/package.json +3 -0
  70. package/package.json +16 -0
@@ -0,0 +1,670 @@
1
+ import { ZERO_POINT, SIZE_OF_INT, C } from "./constants.js";
2
+ import { Node } from "./node.js";
3
+ import { marshalNode, unmarshalCaptures } from "./marshal.js";
4
+ import { TRANSFER_BUFFER } from "./parser.js";
5
+ import { Language } from "./language.js";
6
+ const PREDICATE_STEP_TYPE_CAPTURE = 1;
7
+ const PREDICATE_STEP_TYPE_STRING = 2;
8
+ const QUERY_WORD_REGEX = /[\w-]+/g;
9
+ /**
10
+ * Options for query execution
11
+ */
12
+ /**
13
+ * A stateful object that is passed into the progress callback {@link QueryOptions#progressCallback}
14
+ * to provide the current state of the query.
15
+ */
16
+ /** A record of key-value pairs associated with a particular pattern in a {@link Query}. */
17
+ /**
18
+ * A predicate that contains an operator and list of operands.
19
+ */
20
+ /**
21
+ * A particular {@link Node} that has been captured with a particular name within a
22
+ * {@link Query}.
23
+ */
24
+ /** A match of a {@link Query} to a particular set of {@link Node}s. */
25
+ /** A quantifier for captures */
26
+ export const CaptureQuantifier = {
27
+ Zero: 0,
28
+ ZeroOrOne: 1,
29
+ ZeroOrMore: 2,
30
+ One: 3,
31
+ OneOrMore: 4,
32
+ };
33
+ /** A quantifier for captures */
34
+ /**
35
+ * Predicates are represented as a single array of steps. There are two
36
+ * types of steps, which correspond to the two legal values for
37
+ * the `type` field:
38
+ *
39
+ * - `CapturePredicateStep` - Steps with this type represent names
40
+ * of captures.
41
+ *
42
+ * - `StringPredicateStep` - Steps with this type represent literal
43
+ * strings.
44
+ */
45
+ /**
46
+ * A step in a predicate that refers to a capture.
47
+ *
48
+ * The `name` field is the name of the capture.
49
+ */
50
+ /**
51
+ * A step in a predicate that refers to a string.
52
+ *
53
+ * The `value` field is the string value.
54
+ */
55
+ const isCaptureStep = (step) => step.type === "capture";
56
+ const isStringStep = (step) => step.type === "string";
57
+ /**
58
+ * @internal
59
+ *
60
+ * A function that checks if a given set of captures matches a particular
61
+ * condition. This is used in the built-in `eq?`, `match?`, and `any-of?`
62
+ * predicates.
63
+ */
64
+ /** Error codes returned from tree-sitter query parsing */
65
+ export const QueryErrorKind = {
66
+ Syntax: 1,
67
+ NodeName: 2,
68
+ FieldName: 3,
69
+ CaptureName: 4,
70
+ PatternStructure: 5,
71
+ };
72
+ /** An error that occurred while parsing a query string. */
73
+ /** Information about a {@link QueryError}. */
74
+ /** Error thrown when parsing a tree-sitter query fails */
75
+ export class QueryError extends Error {
76
+ constructor(kind, info, index, length) {
77
+ super(QueryError.formatMessage(kind, info));
78
+ this.name = "QueryError";
79
+ }
80
+ /** Formats an error message based on the error kind and info */
81
+ static formatMessage(kind, info) {
82
+ switch (kind) {
83
+ case QueryErrorKind.NodeName:
84
+ return `Bad node name '${info.word}'`;
85
+ case QueryErrorKind.FieldName:
86
+ return `Bad field name '${info.word}'`;
87
+ case QueryErrorKind.CaptureName:
88
+ return `Bad capture name @${info.word}`;
89
+ case QueryErrorKind.PatternStructure:
90
+ return `Bad pattern structure at offset ${info.suffix}`;
91
+ case QueryErrorKind.Syntax:
92
+ return `Bad syntax at offset ${info.suffix}`;
93
+ }
94
+ }
95
+ }
96
+ /**
97
+ * Parses the `eq?` and `not-eq?` predicates in a query, and updates the text predicates.
98
+ */
99
+ function parseAnyPredicate(steps, index, operator, textPredicates) {
100
+ if (steps.length !== 3) {
101
+ throw new Error(`Wrong number of arguments to \`#${operator}\` predicate. Expected 2, got ${steps.length - 1}`);
102
+ }
103
+ if (!isCaptureStep(steps[1])) {
104
+ throw new Error(`First argument of \`#${operator}\` predicate must be a capture. Got "${steps[1].value}"`);
105
+ }
106
+ const isPositive = operator === "eq?" || operator === "any-eq?";
107
+ const matchAll = !operator.startsWith("any-");
108
+ if (isCaptureStep(steps[2])) {
109
+ const captureName1 = steps[1].name;
110
+ const captureName2 = steps[2].name;
111
+ textPredicates[index].push((captures) => {
112
+ const nodes1 = [];
113
+ const nodes2 = [];
114
+ for (const c of captures) {
115
+ if (c.name === captureName1)
116
+ nodes1.push(c.node);
117
+ if (c.name === captureName2)
118
+ nodes2.push(c.node);
119
+ }
120
+ const compare = (n1, n2, positive) => {
121
+ return positive ? n1.text === n2.text : n1.text !== n2.text;
122
+ };
123
+ return matchAll ? nodes1.every((n1) => nodes2.some((n2) => compare(n1, n2, isPositive))) : nodes1.some((n1) => nodes2.some((n2) => compare(n1, n2, isPositive)));
124
+ });
125
+ }
126
+ else {
127
+ const captureName = steps[1].name;
128
+ const stringValue = steps[2].value;
129
+ const matches = (n) => n.text === stringValue;
130
+ const doesNotMatch = (n) => n.text !== stringValue;
131
+ textPredicates[index].push((captures) => {
132
+ const nodes = [];
133
+ for (const c of captures) {
134
+ if (c.name === captureName)
135
+ nodes.push(c.node);
136
+ }
137
+ const test = isPositive ? matches : doesNotMatch;
138
+ return matchAll ? nodes.every(test) : nodes.some(test);
139
+ });
140
+ }
141
+ }
142
+ /**
143
+ * Parses the `match?` and `not-match?` predicates in a query, and updates the text predicates.
144
+ */
145
+ function parseMatchPredicate(steps, index, operator, textPredicates) {
146
+ if (steps.length !== 3) {
147
+ throw new Error(`Wrong number of arguments to \`#${operator}\` predicate. Expected 2, got ${steps.length - 1}.`);
148
+ }
149
+ if (steps[1].type !== "capture") {
150
+ throw new Error(`First argument of \`#${operator}\` predicate must be a capture. Got "${steps[1].value}".`);
151
+ }
152
+ if (steps[2].type !== "string") {
153
+ throw new Error(`Second argument of \`#${operator}\` predicate must be a string. Got @${steps[2].name}.`);
154
+ }
155
+ const isPositive = operator === "match?" || operator === "any-match?";
156
+ const matchAll = !operator.startsWith("any-");
157
+ const captureName = steps[1].name;
158
+ const regex = new RegExp(steps[2].value);
159
+ textPredicates[index].push((captures) => {
160
+ const nodes = [];
161
+ for (const c of captures) {
162
+ if (c.name === captureName)
163
+ nodes.push(c.node.text);
164
+ }
165
+ const test = (text, positive) => {
166
+ return positive ? regex.test(text) : !regex.test(text);
167
+ };
168
+ if (nodes.length === 0)
169
+ return !isPositive;
170
+ return matchAll ? nodes.every((text) => test(text, isPositive)) : nodes.some((text) => test(text, isPositive));
171
+ });
172
+ }
173
+ /**
174
+ * Parses the `any-of?` and `not-any-of?` predicates in a query, and updates the text predicates.
175
+ */
176
+ function parseAnyOfPredicate(steps, index, operator, textPredicates) {
177
+ if (steps.length < 2) {
178
+ throw new Error(`Wrong number of arguments to \`#${operator}\` predicate. Expected at least 1. Got ${steps.length - 1}.`);
179
+ }
180
+ if (steps[1].type !== "capture") {
181
+ throw new Error(`First argument of \`#${operator}\` predicate must be a capture. Got "${steps[1].value}".`);
182
+ }
183
+ const isPositive = operator === "any-of?";
184
+ const captureName = steps[1].name;
185
+ const stringSteps = steps.slice(2);
186
+ if (!stringSteps.every(isStringStep)) {
187
+ throw new Error(`Arguments to \`#${operator}\` predicate must be strings.".`);
188
+ }
189
+ const values = stringSteps.map((s) => s.value);
190
+ textPredicates[index].push((captures) => {
191
+ const nodes = [];
192
+ for (const c of captures) {
193
+ if (c.name === captureName)
194
+ nodes.push(c.node.text);
195
+ }
196
+ if (nodes.length === 0)
197
+ return !isPositive;
198
+ return nodes.every((text) => values.includes(text)) === isPositive;
199
+ });
200
+ }
201
+ /**
202
+ * Parses the `is?` and `is-not?` predicates in a query, and updates the asserted or refuted properties,
203
+ * depending on if the operator is positive or negative.
204
+ */
205
+ function parseIsPredicate(steps, index, operator, assertedProperties, refutedProperties) {
206
+ if (steps.length < 2 || steps.length > 3) {
207
+ throw new Error(`Wrong number of arguments to \`#${operator}\` predicate. Expected 1 or 2. Got ${steps.length - 1}.`);
208
+ }
209
+ if (!steps.every(isStringStep)) {
210
+ throw new Error(`Arguments to \`#${operator}\` predicate must be strings.".`);
211
+ }
212
+ const properties = operator === "is?" ? assertedProperties : refutedProperties;
213
+ if (!properties[index])
214
+ properties[index] = {};
215
+ properties[index][steps[1].value] = steps[2]?.value ?? null;
216
+ }
217
+ /**
218
+ * Parses the `set!` directive in a query, and updates the set properties.
219
+ */
220
+ function parseSetDirective(steps, index, setProperties) {
221
+ if (steps.length < 2 || steps.length > 3) {
222
+ throw new Error(`Wrong number of arguments to \`#set!\` predicate. Expected 1 or 2. Got ${steps.length - 1}.`);
223
+ }
224
+ if (!steps.every(isStringStep)) {
225
+ throw new Error(`Arguments to \`#set!\` predicate must be strings.".`);
226
+ }
227
+ if (!setProperties[index])
228
+ setProperties[index] = {};
229
+ setProperties[index][steps[1].value] = steps[2]?.value ?? null;
230
+ }
231
+ /**
232
+ * Parses the predicate at a given step in a pattern, and updates the appropriate
233
+ * predicates or properties.
234
+ */
235
+ function parsePattern(index, stepType, stepValueId, captureNames, stringValues, steps, textPredicates, predicates, setProperties, assertedProperties, refutedProperties) {
236
+ if (stepType === PREDICATE_STEP_TYPE_CAPTURE) {
237
+ const name = captureNames[stepValueId];
238
+ steps.push({ type: "capture", name });
239
+ }
240
+ else if (stepType === PREDICATE_STEP_TYPE_STRING) {
241
+ steps.push({ type: "string", value: stringValues[stepValueId] });
242
+ }
243
+ else if (steps.length > 0) {
244
+ if (steps[0].type !== "string") {
245
+ throw new Error("Predicates must begin with a literal value");
246
+ }
247
+ const operator = steps[0].value;
248
+ switch (operator) {
249
+ case "any-not-eq?":
250
+ case "not-eq?":
251
+ case "any-eq?":
252
+ case "eq?":
253
+ parseAnyPredicate(steps, index, operator, textPredicates);
254
+ break;
255
+ case "any-not-match?":
256
+ case "not-match?":
257
+ case "any-match?":
258
+ case "match?":
259
+ parseMatchPredicate(steps, index, operator, textPredicates);
260
+ break;
261
+ case "not-any-of?":
262
+ case "any-of?":
263
+ parseAnyOfPredicate(steps, index, operator, textPredicates);
264
+ break;
265
+ case "is?":
266
+ case "is-not?":
267
+ parseIsPredicate(steps, index, operator, assertedProperties, refutedProperties);
268
+ break;
269
+ case "set!":
270
+ parseSetDirective(steps, index, setProperties);
271
+ break;
272
+ default:
273
+ predicates[index].push({ operator, operands: steps.slice(1) });
274
+ }
275
+ steps.length = 0;
276
+ }
277
+ }
278
+ export class Query {
279
+ /**
280
+ * Create a new query from a string containing one or more S-expression
281
+ * patterns.
282
+ *
283
+ * The query is associated with a particular language, and can only be run
284
+ * on syntax nodes parsed with that language. References to Queries can be
285
+ * shared between multiple threads.
286
+ *
287
+ * @link {@see https://tree-sitter.github.io/tree-sitter/using-parsers/queries}
288
+ */
289
+ constructor(language, source) {
290
+ /** @internal */
291
+ Object.defineProperty(this, 0, {
292
+ enumerable: true,
293
+ configurable: true,
294
+ writable: true,
295
+ value: 0
296
+ }); // Internal handle for Wasm
297
+ /** @internal */
298
+ Object.defineProperty(this, "exceededMatchLimit", {
299
+ enumerable: true,
300
+ configurable: true,
301
+ writable: true,
302
+ value: void 0
303
+ });
304
+ /** @internal */
305
+ Object.defineProperty(this, "textPredicates", {
306
+ enumerable: true,
307
+ configurable: true,
308
+ writable: true,
309
+ value: void 0
310
+ });
311
+ /** The names of the captures used in the query. */
312
+ Object.defineProperty(this, "captureNames", {
313
+ enumerable: true,
314
+ configurable: true,
315
+ writable: true,
316
+ value: void 0
317
+ });
318
+ /** The quantifiers of the captures used in the query. */
319
+ Object.defineProperty(this, "captureQuantifiers", {
320
+ enumerable: true,
321
+ configurable: true,
322
+ writable: true,
323
+ value: void 0
324
+ });
325
+ /**
326
+ * The other user-defined predicates associated with the given index.
327
+ *
328
+ * This includes predicates with operators other than:
329
+ * - `match?`
330
+ * - `eq?` and `not-eq?`
331
+ * - `any-of?` and `not-any-of?`
332
+ * - `is?` and `is-not?`
333
+ * - `set!`
334
+ */
335
+ Object.defineProperty(this, "predicates", {
336
+ enumerable: true,
337
+ configurable: true,
338
+ writable: true,
339
+ value: void 0
340
+ });
341
+ /** The properties for predicates with the operator `set!`. */
342
+ Object.defineProperty(this, "setProperties", {
343
+ enumerable: true,
344
+ configurable: true,
345
+ writable: true,
346
+ value: void 0
347
+ });
348
+ /** The properties for predicates with the operator `is?`. */
349
+ Object.defineProperty(this, "assertedProperties", {
350
+ enumerable: true,
351
+ configurable: true,
352
+ writable: true,
353
+ value: void 0
354
+ });
355
+ /** The properties for predicates with the operator `is-not?`. */
356
+ Object.defineProperty(this, "refutedProperties", {
357
+ enumerable: true,
358
+ configurable: true,
359
+ writable: true,
360
+ value: void 0
361
+ });
362
+ /** The maximum number of in-progress matches for this cursor. */
363
+ Object.defineProperty(this, "matchLimit", {
364
+ enumerable: true,
365
+ configurable: true,
366
+ writable: true,
367
+ value: void 0
368
+ });
369
+ const sourceLength = C.lengthBytesUTF8(source);
370
+ const sourceAddress = C._malloc(sourceLength + 1);
371
+ C.stringToUTF8(source, sourceAddress, sourceLength + 1);
372
+ const address = C._ts_query_new(language[0], sourceAddress, sourceLength, TRANSFER_BUFFER, TRANSFER_BUFFER + SIZE_OF_INT);
373
+ if (!address) {
374
+ const errorId = C.getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32");
375
+ const errorByte = C.getValue(TRANSFER_BUFFER, "i32");
376
+ const errorIndex = C.UTF8ToString(sourceAddress, errorByte).length;
377
+ const suffix = source.slice(errorIndex, errorIndex + 100).split("\n")[0];
378
+ const word = suffix.match(QUERY_WORD_REGEX)?.[0] ?? "";
379
+ C._free(sourceAddress);
380
+ switch (errorId) {
381
+ case QueryErrorKind.Syntax:
382
+ throw new QueryError(QueryErrorKind.Syntax, { suffix: `${errorIndex}: '${suffix}'...` }, errorIndex, 0);
383
+ case QueryErrorKind.NodeName:
384
+ throw new QueryError(errorId, { word }, errorIndex, word.length);
385
+ case QueryErrorKind.FieldName:
386
+ throw new QueryError(errorId, { word }, errorIndex, word.length);
387
+ case QueryErrorKind.CaptureName:
388
+ throw new QueryError(errorId, { word }, errorIndex, word.length);
389
+ case QueryErrorKind.PatternStructure:
390
+ throw new QueryError(errorId, { suffix: `${errorIndex}: '${suffix}'...` }, errorIndex, 0);
391
+ }
392
+ }
393
+ const stringCount = C._ts_query_string_count(address);
394
+ const captureCount = C._ts_query_capture_count(address);
395
+ const patternCount = C._ts_query_pattern_count(address);
396
+ const captureNames = new Array(captureCount);
397
+ const captureQuantifiers = new Array(patternCount);
398
+ const stringValues = new Array(stringCount);
399
+ // Fill in the capture names
400
+ for (let i = 0; i < captureCount; i++) {
401
+ const nameAddress = C._ts_query_capture_name_for_id(address, i, TRANSFER_BUFFER);
402
+ const nameLength = C.getValue(TRANSFER_BUFFER, "i32");
403
+ captureNames[i] = C.UTF8ToString(nameAddress, nameLength);
404
+ }
405
+ // Fill in the capture quantifiers
406
+ for (let i = 0; i < patternCount; i++) {
407
+ const captureQuantifiersArray = new Array(captureCount);
408
+ for (let j = 0; j < captureCount; j++) {
409
+ const quantifier = C._ts_query_capture_quantifier_for_id(address, i, j);
410
+ captureQuantifiersArray[j] = quantifier;
411
+ }
412
+ captureQuantifiers[i] = captureQuantifiersArray;
413
+ }
414
+ // Fill in the string values
415
+ for (let i = 0; i < stringCount; i++) {
416
+ const valueAddress = C._ts_query_string_value_for_id(address, i, TRANSFER_BUFFER);
417
+ const nameLength = C.getValue(TRANSFER_BUFFER, "i32");
418
+ stringValues[i] = C.UTF8ToString(valueAddress, nameLength);
419
+ }
420
+ const setProperties = new Array(patternCount);
421
+ const assertedProperties = new Array(patternCount);
422
+ const refutedProperties = new Array(patternCount);
423
+ const predicates = new Array(patternCount);
424
+ const textPredicates = new Array(patternCount);
425
+ // Parse the predicates, and add the appropriate predicates or properties
426
+ for (let i = 0; i < patternCount; i++) {
427
+ const predicatesAddress = C._ts_query_predicates_for_pattern(address, i, TRANSFER_BUFFER);
428
+ const stepCount = C.getValue(TRANSFER_BUFFER, "i32");
429
+ predicates[i] = [];
430
+ textPredicates[i] = [];
431
+ const steps = new Array();
432
+ let stepAddress = predicatesAddress;
433
+ for (let j = 0; j < stepCount; j++) {
434
+ const stepType = C.getValue(stepAddress, "i32");
435
+ stepAddress += SIZE_OF_INT;
436
+ const stepValueId = C.getValue(stepAddress, "i32");
437
+ stepAddress += SIZE_OF_INT;
438
+ parsePattern(i, stepType, stepValueId, captureNames, stringValues, steps, textPredicates, predicates, setProperties, assertedProperties, refutedProperties);
439
+ }
440
+ Object.freeze(textPredicates[i]);
441
+ Object.freeze(predicates[i]);
442
+ Object.freeze(setProperties[i]);
443
+ Object.freeze(assertedProperties[i]);
444
+ Object.freeze(refutedProperties[i]);
445
+ }
446
+ C._free(sourceAddress);
447
+ this[0] = address;
448
+ this.captureNames = captureNames;
449
+ this.captureQuantifiers = captureQuantifiers;
450
+ this.textPredicates = textPredicates;
451
+ this.predicates = predicates;
452
+ this.setProperties = setProperties;
453
+ this.assertedProperties = assertedProperties;
454
+ this.refutedProperties = refutedProperties;
455
+ this.exceededMatchLimit = false;
456
+ }
457
+ /** Delete the query, freeing its resources. */
458
+ delete() {
459
+ C._ts_query_delete(this[0]);
460
+ this[0] = 0;
461
+ }
462
+ /**
463
+ * Iterate over all of the matches in the order that they were found.
464
+ *
465
+ * Each match contains the index of the pattern that matched, and a list of
466
+ * captures. Because multiple patterns can match the same set of nodes,
467
+ * one match may contain captures that appear *before* some of the
468
+ * captures from a previous match.
469
+ *
470
+ * @param {Node} node - The node to execute the query on.
471
+ *
472
+ * @param {QueryOptions} options - Options for query execution.
473
+ */
474
+ matches(node, options = {}) {
475
+ const startPosition = options.startPosition ?? ZERO_POINT;
476
+ const endPosition = options.endPosition ?? ZERO_POINT;
477
+ const startIndex = options.startIndex ?? 0;
478
+ const endIndex = options.endIndex ?? 0;
479
+ const matchLimit = options.matchLimit ?? 0xffffffff;
480
+ const maxStartDepth = options.maxStartDepth ?? 0xffffffff;
481
+ const timeoutMicros = options.timeoutMicros ?? 0;
482
+ const progressCallback = options.progressCallback;
483
+ if (typeof matchLimit !== "number") {
484
+ throw new Error("Arguments must be numbers");
485
+ }
486
+ this.matchLimit = matchLimit;
487
+ if (endIndex !== 0 && startIndex > endIndex) {
488
+ throw new Error("`startIndex` cannot be greater than `endIndex`");
489
+ }
490
+ if (endPosition !== ZERO_POINT && (startPosition.row > endPosition.row || (startPosition.row === endPosition.row && startPosition.column > endPosition.column))) {
491
+ throw new Error("`startPosition` cannot be greater than `endPosition`");
492
+ }
493
+ if (progressCallback) {
494
+ C.currentQueryProgressCallback = progressCallback;
495
+ }
496
+ marshalNode(node);
497
+ C._ts_query_matches_wasm(this[0], node.tree[0], startPosition.row, startPosition.column, endPosition.row, endPosition.column, startIndex, endIndex, matchLimit, maxStartDepth, timeoutMicros);
498
+ const rawCount = C.getValue(TRANSFER_BUFFER, "i32");
499
+ const startAddress = C.getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32");
500
+ const didExceedMatchLimit = C.getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32");
501
+ const result = new Array(rawCount);
502
+ this.exceededMatchLimit = Boolean(didExceedMatchLimit);
503
+ let filteredCount = 0;
504
+ let address = startAddress;
505
+ for (let i = 0; i < rawCount; i++) {
506
+ const patternIndex = C.getValue(address, "i32");
507
+ address += SIZE_OF_INT;
508
+ const captureCount = C.getValue(address, "i32");
509
+ address += SIZE_OF_INT;
510
+ const captures = new Array(captureCount);
511
+ address = unmarshalCaptures(this, node.tree, address, patternIndex, captures);
512
+ if (this.textPredicates[patternIndex].every((p) => p(captures))) {
513
+ result[filteredCount] = { pattern: patternIndex, patternIndex, captures };
514
+ const setProperties = this.setProperties[patternIndex];
515
+ result[filteredCount].setProperties = setProperties;
516
+ const assertedProperties = this.assertedProperties[patternIndex];
517
+ result[filteredCount].assertedProperties = assertedProperties;
518
+ const refutedProperties = this.refutedProperties[patternIndex];
519
+ result[filteredCount].refutedProperties = refutedProperties;
520
+ filteredCount++;
521
+ }
522
+ }
523
+ result.length = filteredCount;
524
+ C._free(startAddress);
525
+ C.currentQueryProgressCallback = null;
526
+ return result;
527
+ }
528
+ /**
529
+ * Iterate over all of the individual captures in the order that they
530
+ * appear.
531
+ *
532
+ * This is useful if you don't care about which pattern matched, and just
533
+ * want a single, ordered sequence of captures.
534
+ *
535
+ * @param {Node} node - The node to execute the query on.
536
+ *
537
+ * @param {QueryOptions} options - Options for query execution.
538
+ */
539
+ captures(node, options = {}) {
540
+ const startPosition = options.startPosition ?? ZERO_POINT;
541
+ const endPosition = options.endPosition ?? ZERO_POINT;
542
+ const startIndex = options.startIndex ?? 0;
543
+ const endIndex = options.endIndex ?? 0;
544
+ const matchLimit = options.matchLimit ?? 0xffffffff;
545
+ const maxStartDepth = options.maxStartDepth ?? 0xffffffff;
546
+ const timeoutMicros = options.timeoutMicros ?? 0;
547
+ const progressCallback = options.progressCallback;
548
+ if (typeof matchLimit !== "number") {
549
+ throw new Error("Arguments must be numbers");
550
+ }
551
+ this.matchLimit = matchLimit;
552
+ if (endIndex !== 0 && startIndex > endIndex) {
553
+ throw new Error("`startIndex` cannot be greater than `endIndex`");
554
+ }
555
+ if (endPosition !== ZERO_POINT && (startPosition.row > endPosition.row || (startPosition.row === endPosition.row && startPosition.column > endPosition.column))) {
556
+ throw new Error("`startPosition` cannot be greater than `endPosition`");
557
+ }
558
+ if (progressCallback) {
559
+ C.currentQueryProgressCallback = progressCallback;
560
+ }
561
+ marshalNode(node);
562
+ C._ts_query_captures_wasm(this[0], node.tree[0], startPosition.row, startPosition.column, endPosition.row, endPosition.column, startIndex, endIndex, matchLimit, maxStartDepth, timeoutMicros);
563
+ const count = C.getValue(TRANSFER_BUFFER, "i32");
564
+ const startAddress = C.getValue(TRANSFER_BUFFER + SIZE_OF_INT, "i32");
565
+ const didExceedMatchLimit = C.getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, "i32");
566
+ const result = new Array();
567
+ this.exceededMatchLimit = Boolean(didExceedMatchLimit);
568
+ const captures = new Array();
569
+ let address = startAddress;
570
+ for (let i = 0; i < count; i++) {
571
+ const patternIndex = C.getValue(address, "i32");
572
+ address += SIZE_OF_INT;
573
+ const captureCount = C.getValue(address, "i32");
574
+ address += SIZE_OF_INT;
575
+ const captureIndex = C.getValue(address, "i32");
576
+ address += SIZE_OF_INT;
577
+ captures.length = captureCount;
578
+ address = unmarshalCaptures(this, node.tree, address, patternIndex, captures);
579
+ if (this.textPredicates[patternIndex].every((p) => p(captures))) {
580
+ const capture = captures[captureIndex];
581
+ const setProperties = this.setProperties[patternIndex];
582
+ capture.setProperties = setProperties;
583
+ const assertedProperties = this.assertedProperties[patternIndex];
584
+ capture.assertedProperties = assertedProperties;
585
+ const refutedProperties = this.refutedProperties[patternIndex];
586
+ capture.refutedProperties = refutedProperties;
587
+ result.push(capture);
588
+ }
589
+ }
590
+ C._free(startAddress);
591
+ C.currentQueryProgressCallback = null;
592
+ return result;
593
+ }
594
+ /** Get the predicates for a given pattern. */
595
+ predicatesForPattern(patternIndex) {
596
+ return this.predicates[patternIndex];
597
+ }
598
+ /**
599
+ * Disable a certain capture within a query.
600
+ *
601
+ * This prevents the capture from being returned in matches, and also
602
+ * avoids any resource usage associated with recording the capture.
603
+ */
604
+ disableCapture(captureName) {
605
+ const captureNameLength = C.lengthBytesUTF8(captureName);
606
+ const captureNameAddress = C._malloc(captureNameLength + 1);
607
+ C.stringToUTF8(captureName, captureNameAddress, captureNameLength + 1);
608
+ C._ts_query_disable_capture(this[0], captureNameAddress, captureNameLength);
609
+ C._free(captureNameAddress);
610
+ }
611
+ /**
612
+ * Disable a certain pattern within a query.
613
+ *
614
+ * This prevents the pattern from matching, and also avoids any resource
615
+ * usage associated with the pattern. This throws an error if the pattern
616
+ * index is out of bounds.
617
+ */
618
+ disablePattern(patternIndex) {
619
+ if (patternIndex >= this.predicates.length) {
620
+ throw new Error(`Pattern index is ${patternIndex} but the pattern count is ${this.predicates.length}`);
621
+ }
622
+ C._ts_query_disable_pattern(this[0], patternIndex);
623
+ }
624
+ /**
625
+ * Check if, on its last execution, this cursor exceeded its maximum number
626
+ * of in-progress matches.
627
+ */
628
+ didExceedMatchLimit() {
629
+ return this.exceededMatchLimit;
630
+ }
631
+ /** Get the byte offset where the given pattern starts in the query's source. */
632
+ startIndexForPattern(patternIndex) {
633
+ if (patternIndex >= this.predicates.length) {
634
+ throw new Error(`Pattern index is ${patternIndex} but the pattern count is ${this.predicates.length}`);
635
+ }
636
+ return C._ts_query_start_byte_for_pattern(this[0], patternIndex);
637
+ }
638
+ /** Get the byte offset where the given pattern ends in the query's source. */
639
+ endIndexForPattern(patternIndex) {
640
+ if (patternIndex >= this.predicates.length) {
641
+ throw new Error(`Pattern index is ${patternIndex} but the pattern count is ${this.predicates.length}`);
642
+ }
643
+ return C._ts_query_end_byte_for_pattern(this[0], patternIndex);
644
+ }
645
+ /** Get the number of patterns in the query. */
646
+ patternCount() {
647
+ return C._ts_query_pattern_count(this[0]);
648
+ }
649
+ /** Get the index for a given capture name. */
650
+ captureIndexForName(captureName) {
651
+ return this.captureNames.indexOf(captureName);
652
+ }
653
+ /** Check if a given pattern within a query has a single root node. */
654
+ isPatternRooted(patternIndex) {
655
+ return C._ts_query_is_pattern_rooted(this[0], patternIndex) === 1;
656
+ }
657
+ /** Check if a given pattern within a query has a single root node. */
658
+ isPatternNonLocal(patternIndex) {
659
+ return C._ts_query_is_pattern_non_local(this[0], patternIndex) === 1;
660
+ }
661
+ /**
662
+ * Check if a given step in a query is 'definite'.
663
+ *
664
+ * A query step is 'definite' if its parent pattern will be guaranteed to
665
+ * match successfully once it reaches the step.
666
+ */
667
+ isPatternGuaranteedAtStep(byteIndex) {
668
+ return C._ts_query_is_pattern_guaranteed_at_step(this[0], byteIndex) === 1;
669
+ }
670
+ }