@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,665 @@
1
+ import { Node } from "../tree_sitter/node.js";
2
+ import { Parser } from "../tree_sitter/parser.js";
3
+ import { BaseNode, _shadows } from "./base_node.js";
4
+ import { WhitespaceNode } from "./whitespace_node.js";
5
+ import { SoftTextNode } from "./soft_text_node.js";
6
+ import { Query, QueryError } from "../tree_sitter/query.js";
7
+ import { _getQueryCaptureTargets } from "../extras/misc.js";
8
+ import { Tree } from "../tree_sitter/tree.js";
9
+ // NOTE: the tree override is in here because it has a circular type dependency on HardNode
10
+ const realRootNodeGetter = Object.getOwnPropertyDescriptor(Tree.prototype, "rootNode").get;
11
+ //
12
+ // complicated override in order to make the root node pretend to contain soft nodes (ex: leading and trailing whitespace)
13
+ //
14
+ // hard because a normal change to .startIndex/.endIndex breaks internal methods, so we have to selectively choose who sees the real/faked .startIndex/.endIndex
15
+ Object.defineProperty(Tree.prototype, "rootNode", {
16
+ get() {
17
+ const rootNode = realRootNodeGetter.call(this);
18
+ const rootShadow = {};
19
+ Object.setPrototypeOf(rootShadow, Object.getPrototypeOf(rootNode));
20
+ const descriptors = Object.assign(Object.getOwnPropertyDescriptors(Node.prototype), Object.getOwnPropertyDescriptors(rootNode));
21
+ const newDescriptors = {};
22
+ for (const [key, setting] of Object.entries(descriptors)) {
23
+ if (key == "startIndex" || key == "startPosition") {
24
+ continue;
25
+ }
26
+ else if (key == "text" || key == "replaceInnards") {
27
+ // use the faked .startIndex for these methods/getters
28
+ newDescriptors[key] = setting;
29
+ }
30
+ else {
31
+ // use the real .startIndex for these methods/getters (get it from the real thing)
32
+ // (otherwise stuff breaks when there is a whitespace prefix)
33
+ newDescriptors[key] = {
34
+ get: () => {
35
+ const output = rootNode[key];
36
+ if (typeof output == "function") {
37
+ return (...args) => output.apply(rootNode, args);
38
+ }
39
+ return output;
40
+ },
41
+ set: (value) => rootNode[key] = value,
42
+ enumerable: setting.enumerable,
43
+ configurable: setting.configurable,
44
+ };
45
+ }
46
+ }
47
+ Object.setPrototypeOf(rootShadow, Node.prototype);
48
+ Object.defineProperties(rootShadow, newDescriptors);
49
+ rootShadow.startIndex = 0;
50
+ rootShadow.startPosition = { row: 0, column: 0 };
51
+ // if the original file is just whitespace or non-matched text, then fill it with soft nodes even though it'd normally have no children
52
+ if (rootShadow.children.length == 0 && rootShadow.endIndex != 0) {
53
+ rootShadow._children = _childrenWithSoftNodes(rootShadow, [{ startIndex: rootShadow.endIndex, endIndex: rootShadow.endIndex, endPosition: rootShadow.endPosition }], rootNode.tree.codeString).slice(0, -1);
54
+ }
55
+ _shadows[rootNode.id] = rootShadow;
56
+ return rootShadow;
57
+ }
58
+ });
59
+ // this only exists to help with type hints
60
+ export class ExtendedTree extends Tree {
61
+ constructor() {
62
+ super(...arguments);
63
+ /** @type {HardNode} */
64
+ Object.defineProperty(this, "rootNode", {
65
+ enumerable: true,
66
+ configurable: true,
67
+ writable: true,
68
+ value: void 0
69
+ });
70
+ }
71
+ }
72
+ // this only exists to help with type hints
73
+ class Position {
74
+ constructor() {
75
+ /** @type {number} */
76
+ Object.defineProperty(this, "row", {
77
+ enumerable: true,
78
+ configurable: true,
79
+ writable: true,
80
+ value: void 0
81
+ });
82
+ /** @type {number} */
83
+ Object.defineProperty(this, "column", {
84
+ enumerable: true,
85
+ configurable: true,
86
+ writable: true,
87
+ value: void 0
88
+ });
89
+ }
90
+ }
91
+ const originalDescriptors = Object.getOwnPropertyDescriptors(Node.prototype);
92
+ const originalChildrenGetter = originalDescriptors.children.get;
93
+ const originalEndIndex = originalDescriptors.endIndex.get;
94
+ const originalEndPosition = originalDescriptors.endPosition.get;
95
+ const originalParent = originalDescriptors.parent.get;
96
+ const originalTextGetter = originalDescriptors.text.get;
97
+ const originalEquals = originalDescriptors.equals.value;
98
+ const originalToString = originalDescriptors.toString.value;
99
+ export class HardNode extends BaseNode {
100
+ constructor() {
101
+ super(...arguments);
102
+ /** @internal */
103
+ Object.defineProperty(this, "_children", {
104
+ enumerable: true,
105
+ configurable: true,
106
+ writable: true,
107
+ value: void 0
108
+ });
109
+ /** @internal */
110
+ Object.defineProperty(this, "_fields", {
111
+ enumerable: true,
112
+ configurable: true,
113
+ writable: true,
114
+ value: void 0
115
+ });
116
+ /** @internal */
117
+ Object.defineProperty(this, "_depth", {
118
+ enumerable: true,
119
+ configurable: true,
120
+ writable: true,
121
+ value: void 0
122
+ });
123
+ /** @type {number} */
124
+ Object.defineProperty(this, "id", {
125
+ enumerable: true,
126
+ configurable: true,
127
+ writable: true,
128
+ value: void 0
129
+ });
130
+ /** @type {number} */
131
+ Object.defineProperty(this, "startIndex", {
132
+ enumerable: true,
133
+ configurable: true,
134
+ writable: true,
135
+ value: void 0
136
+ });
137
+ /** @type {Position} */
138
+ Object.defineProperty(this, "startPosition", {
139
+ enumerable: true,
140
+ configurable: true,
141
+ writable: true,
142
+ value: void 0
143
+ });
144
+ /** @type {ExtendedTree} */
145
+ Object.defineProperty(this, "tree", {
146
+ enumerable: true,
147
+ configurable: true,
148
+ writable: true,
149
+ value: void 0
150
+ });
151
+ /** @type {string} */
152
+ Object.defineProperty(this, "type", {
153
+ enumerable: true,
154
+ configurable: true,
155
+ writable: true,
156
+ value: void 0
157
+ });
158
+ /** @type {Boolean} */
159
+ Object.defineProperty(this, "isExtra", {
160
+ enumerable: true,
161
+ configurable: true,
162
+ writable: true,
163
+ value: void 0
164
+ });
165
+ /** @type {Boolean} */
166
+ Object.defineProperty(this, "isError", {
167
+ enumerable: true,
168
+ configurable: true,
169
+ writable: true,
170
+ value: void 0
171
+ });
172
+ /** @type {Boolean} */
173
+ Object.defineProperty(this, "isMissing", {
174
+ enumerable: true,
175
+ configurable: true,
176
+ writable: true,
177
+ value: void 0
178
+ });
179
+ /** @type {Boolean} */
180
+ Object.defineProperty(this, "hasChanges", {
181
+ enumerable: true,
182
+ configurable: true,
183
+ writable: true,
184
+ value: void 0
185
+ });
186
+ /** @type {Boolean} */
187
+ Object.defineProperty(this, "hasError", {
188
+ enumerable: true,
189
+ configurable: true,
190
+ writable: true,
191
+ value: void 0
192
+ });
193
+ /**
194
+ * @param {HardNode} other -
195
+ * @returns {Boolean} output -
196
+ */
197
+ Object.defineProperty(this, "equals", {
198
+ enumerable: true,
199
+ configurable: true,
200
+ writable: true,
201
+ value: originalEquals
202
+ });
203
+ }
204
+ /** @type {HardNode} */
205
+ get parent() {
206
+ const rawParent = originalParent.call(this);
207
+ return _shadows[rawParent?.id] || rawParent;
208
+ }
209
+ /** @type {string} */
210
+ get text() {
211
+ return originalTextGetter.call(_shadows[this.id] || this);
212
+ }
213
+ /** @type {Number} */
214
+ get endIndex() {
215
+ if (this.depth == 0) {
216
+ return this.tree.codeString.length;
217
+ }
218
+ return originalEndIndex.call(this);
219
+ }
220
+ /** @type {Position} */
221
+ get endPosition() {
222
+ if (this.depth == 0) {
223
+ const rowIndex = (this.tree.codeString.match(/\n/g) || []).length;
224
+ const columnIndex = this.tree.codeString.match(new RegExp(`^(?:.*\\r?\\n){${rowIndex}}(.*)`))[1].length;
225
+ return { row: rowIndex, column: columnIndex };
226
+ }
227
+ return originalEndPosition.call(this);
228
+ }
229
+ /** @type {Array<HardNode|SoftNode>} */
230
+ get children() {
231
+ if (!this._children) {
232
+ // will set this._children
233
+ this._children = originalChildrenGetter.call(this);
234
+ // add soft nodes if needed
235
+ if (this.tree._enableSoftNodes) {
236
+ this._children = _childrenWithSoftNodes(this, this._children || [], this.tree.codeString);
237
+ }
238
+ }
239
+ return this._children || [];
240
+ }
241
+ set children(value) {
242
+ this._children = value;
243
+ }
244
+ /**
245
+ * Yields each child
246
+ *
247
+ * @generator
248
+ * @yields {HardNode} The current child or grandchild in the structure.
249
+ */
250
+ *traverse(arg = { _parentNodes: [] }) {
251
+ const { _parentNodes } = arg;
252
+ const parentNodes = [this, ..._parentNodes];
253
+ if (this.children?.length == 0) {
254
+ yield [_parentNodes, this, "-"];
255
+ }
256
+ else {
257
+ yield [_parentNodes, this, "->"];
258
+ for (const each of this.children || []) {
259
+ if (each instanceof Node) {
260
+ for (const eachInner of each.traverse({ _parentNodes: parentNodes })) {
261
+ yield eachInner;
262
+ }
263
+ }
264
+ else {
265
+ yield [parentNodes, each, "-"];
266
+ }
267
+ }
268
+ yield [_parentNodes, this, "<-"];
269
+ }
270
+ }
271
+ /**
272
+ * A generator function that flattens the hierarchical structure of `children` and their descendants.
273
+ * It yields each child and their flattened descendants recursively.
274
+ *
275
+ * @param {Function} opts.filter - A function to filter the flattened elements.
276
+ * @param {Boolean} opts.includeSelf -
277
+ * @generator
278
+ * @yields {HardNode} The current child or grandchild in the structure.
279
+ */
280
+ *iterFlattened({ filter, includeSelf = false } = {}) {
281
+ if (includeSelf) {
282
+ yield this;
283
+ }
284
+ if (typeof filter == "function") {
285
+ for (const each of this.children || []) {
286
+ if (filter(each)) {
287
+ yield each;
288
+ }
289
+ for (const eachGrandChild of each.iterFlattened({ filter })) {
290
+ yield eachGrandChild;
291
+ }
292
+ }
293
+ }
294
+ else {
295
+ for (const each of this.children || []) {
296
+ yield each;
297
+ for (const eachGrandChild of each.iterFlattened({ filter })) {
298
+ yield eachGrandChild;
299
+ }
300
+ }
301
+ }
302
+ }
303
+ /** @internal */
304
+ iterFlatten() {
305
+ throw Error(`did you mean iterFlattened instead of iterFlatten?`);
306
+ }
307
+ /**
308
+ * Flattens the structure of `children` using the provided filter function.
309
+ * This method returns an array containing the flattened elements.
310
+ *
311
+ * @param {Function} opts.filter - A function to filter the flattened elements.
312
+ * @param {Boolean} opts.includeSelf -
313
+ * @returns {Array} An array containing the flattened elements that pass the filter.
314
+ */
315
+ flattened({ filter, includeSelf = false } = {}) {
316
+ return [...this.iterFlattened({ filter, includeSelf })];
317
+ }
318
+ /** @internal */
319
+ flatten() {
320
+ throw Error(`did you mean flattened instead of flatten?`);
321
+ }
322
+ /**
323
+ * Query
324
+ *
325
+ * @example
326
+ * ```js
327
+ * import { createParser } from "https://deno.land/x/deno_tree_sitter/main/main.js"
328
+ * import javascript from "https://github.com/jeff-hykin/common_tree_sitter_languages/raw/4d8a6d34d7f6263ff570f333cdcf5ded6be89e3d/main/javascript.js"
329
+ * const parser = await createParser(javascript) // path or Uint8Array
330
+ * const tree = parser.parse('let a = 1;let b = 1;let c = 1;')
331
+ *
332
+ * tree.rootNode.query(`(identifier) @blahBlahBlah`, {matchLimit: 2})
333
+ * // returns:
334
+ * [
335
+ * {
336
+ * pattern: 0,
337
+ * captures: [
338
+ * {
339
+ * name: "blahBlahBlah",
340
+ * node: {
341
+ * type: "identifier",
342
+ * typeId: 1,
343
+ * startPosition: { row: 0, column: 4 },
344
+ * startIndex: 4,
345
+ * endPosition: { row: 0, column: 5 },
346
+ * endIndex: 5,
347
+ * indent: undefined,
348
+ * hasChildren: false,
349
+ * children: []
350
+ * }
351
+ * }
352
+ * ]
353
+ * },
354
+ * {
355
+ * pattern: 0,
356
+ * captures: [
357
+ * {
358
+ * name: "blahBlahBlah",
359
+ * node: {
360
+ * type: "identifier",
361
+ * typeId: 1,
362
+ * startPosition: { row: 0, column: 14 },
363
+ * startIndex: 14,
364
+ * endPosition: { row: 0, column: 15 },
365
+ * endIndex: 15,
366
+ * indent: undefined,
367
+ * hasChildren: false,
368
+ * children: []
369
+ * }
370
+ * }
371
+ * ]
372
+ * },
373
+ * {
374
+ * pattern: 0,
375
+ * captures: [
376
+ * {
377
+ * name: "blahBlahBlah",
378
+ * node: {
379
+ * type: "identifier",
380
+ * typeId: 1,
381
+ * startPosition: { row: 0, column: 24 },
382
+ * startIndex: 24,
383
+ * endPosition: { row: 0, column: 25 },
384
+ * endIndex: 25,
385
+ * indent: undefined,
386
+ * hasChildren: false,
387
+ * children: []
388
+ * }
389
+ * }
390
+ * ]
391
+ * }
392
+ * ]
393
+ * ```
394
+ *
395
+ * @param {String} queryString - see https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax
396
+ * @param options.matchLimit - max number of results
397
+ * @param options.startPosition - {row: Number, column: number}
398
+ * @param options.endPosition - {row: Number, column: number}
399
+ * @param options.maxResultDepth - depth relative to the current node (1 = direct children, 2 = grandchildren, etc)
400
+ * @returns {[Object]} output
401
+ *
402
+ */
403
+ query(queryString, options) {
404
+ const { matchLimit, startPosition, endPosition, maxResultDepth } = options || {};
405
+ const realMaxResultDepth = maxResultDepth == null ? Infinity : maxResultDepth;
406
+ let query;
407
+ try {
408
+ query = new Query(this.tree.language, queryString);
409
+ }
410
+ catch (error) {
411
+ if (error instanceof QueryError) {
412
+ error.message = `${error.message} in the following query: ${JSON.stringify(queryString)}`;
413
+ }
414
+ throw error;
415
+ }
416
+ const result = query.matches(this, startPosition || this.startPosition, endPosition || this.endPosition, matchLimit);
417
+ const results = result.filter((each) => each.captures.every((each) => each.node.depth - this.depth <= realMaxResultDepth));
418
+ const codeOrCallback = this.tree.codeString;
419
+ // without this soft nodes will be missing
420
+ for (const eachResult of results) {
421
+ for (const eachCapture of eachResult.captures) {
422
+ eachCapture.node.children = _childrenWithSoftNodes(eachCapture.node, eachCapture.node.children, codeOrCallback);
423
+ }
424
+ }
425
+ return result.filter((each) => each.captures.every((each) => each.node.depth - this.depth <= realMaxResultDepth));
426
+ }
427
+ /**
428
+ * quickQuery
429
+ *
430
+ * @example
431
+ * ```js
432
+ * import { createParser } from "https://deno.land/x/deno_tree_sitter/main/main.js"
433
+ * import javascript from "https://github.com/jeff-hykin/common_tree_sitter_languages/raw/676ffa3b93768b8ac628fd5c61656f7dc41ba413/main/javascript.js"
434
+ * const parser = await createParser(javascript) // path or Uint8Array
435
+ * const tree = parser.parse('let a = 1;let b = 1;let c = 1;')
436
+ * // ex1: no capture names
437
+ * const nodes = tree.rootNode.quickQuery(
438
+ * `(identifier)`, {matchLimit: 2}
439
+ * )
440
+ * // ex2: with capture names
441
+ * const groups = tree.rootNode.quickQuery(
442
+ * `'(binding (attrpath) @myKey (list_expression) @myList ("\\"")? @optionalThing )`
443
+ * )
444
+ * groups[0].myKey // node
445
+ * groups[0].myList // node
446
+ * groups[0].optionalThing // node or null
447
+ * groups[0][0] // node (the whole match)
448
+ * ```
449
+ *
450
+ * @param {String} queryString - see https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax
451
+ * @param options.matchLimit - max number of results
452
+ * @param options.startPosition - {row: Number, column: number}
453
+ * @param options.endPosition - {row: Number, column: number}
454
+ * @param options.maxResultDepth - depth relative to the current node (1 = direct children, 2 = grandchildren, etc)
455
+ * @returns {Array<HardNode|Record<any, HardNode>>} nodesOrObjsOfNodes
456
+ */
457
+ quickQuery(queryString, options) {
458
+ const possibleCaptureTargets = _getQueryCaptureTargets(queryString);
459
+ //
460
+ // get a base capture name
461
+ //
462
+ let baseCaptureName = "_";
463
+ while (possibleCaptureTargets.includes(baseCaptureName)) {
464
+ // append until it doesn't conflict
465
+ baseCaptureName = `${baseCaptureName}_`;
466
+ }
467
+ // add the base capture always
468
+ queryString = `${queryString} @${baseCaptureName}`;
469
+ const output = this.query(queryString, options).map((each) => {
470
+ const nodesByCaptureName = Object.fromEntries(each.captures.map((each) => [each.name, each.node]));
471
+ // no capture targets means just return the base
472
+ if (possibleCaptureTargets.length == 0) {
473
+ return nodesByCaptureName[baseCaptureName];
474
+ // return named targets
475
+ }
476
+ else {
477
+ // 0 is not allowed as a capture name, so it will never conflict
478
+ nodesByCaptureName[0] = nodesByCaptureName[baseCaptureName];
479
+ delete nodesByCaptureName[baseCaptureName];
480
+ return nodesByCaptureName;
481
+ }
482
+ });
483
+ return output;
484
+ }
485
+ /**
486
+ * quickQueryFirst
487
+ *
488
+ * @example
489
+ * ```js
490
+ * import { createParser } from "https://deno.land/x/deno_tree_sitter/main/main.js"
491
+ * import javascript from "https://github.com/jeff-hykin/common_tree_sitter_languages/raw/4d8a6d34d7f6263ff570f333cdcf5ded6be89e3d/main/javascript.js"
492
+ * const parser = await createParser(javascript) // path or Uint8Array
493
+ * const tree = parser.parse('let a = 1;let b = 1;let c = 1;')
494
+ *
495
+ * // ex1: no capture names
496
+ * const node = tree.rootNode.quickQueryFirst(`(identifier)`)
497
+ *
498
+ * // ex2: with capture names
499
+ * const { myKey, myList, optionalThing } = tree.rootNode.quickQueryFirst(
500
+ * `'(binding (attrpath) @myKey (list_expression) @myList ("\\"")? @optionalThing )`
501
+ * )
502
+ * myKey // node
503
+ * myList // node
504
+ * optionalThing // node or null
505
+ * ```
506
+ *
507
+ * @param {String} queryString - see https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax
508
+ * @param options.startPosition - {row: Number, column: number}
509
+ * @param options.endPosition - {row: Number, column: number}
510
+ * @param options.maxResultDepth - depth relative to the current node (1 = direct children, 2 = grandchildren, etc)
511
+ * @returns {HardNode|Record<any,HardNode>|null} nodeOrObjOfNodes
512
+ */
513
+ quickQueryFirst(queryString, options) {
514
+ return this.quickQuery(queryString, { ...options, matchLimit: 1 })[0];
515
+ }
516
+ get fields() {
517
+ if (!this._fields) {
518
+ this._fields = {};
519
+ let index = -1;
520
+ for (let each of this.children || []) {
521
+ // skip soft nodes
522
+ if (each.typeId <= 0) {
523
+ continue;
524
+ }
525
+ index++;
526
+ const name = this.fieldNameForChild(index);
527
+ if (name) {
528
+ this._fields[name] = each;
529
+ }
530
+ }
531
+ }
532
+ return this._fields;
533
+ }
534
+ get fieldNames() {
535
+ return Object.keys(this.fields);
536
+ }
537
+ getQueryForSelf() {
538
+ let current = this;
539
+ let chunks = [];
540
+ while (current) {
541
+ if (current.type) {
542
+ if (current.isNamed) {
543
+ if (current.type.match(/^([a-zA-Z0-9.\-_\$]+)$/)) {
544
+ chunks.push(current.type);
545
+ }
546
+ else {
547
+ chunks.push(JSON.stringify(current.type));
548
+ }
549
+ }
550
+ else {
551
+ // TODO: this might not always be correct. Probably should be JSON.stringify(current.text) but theres a risk of .text being massive
552
+ chunks.push(JSON.stringify(current.type));
553
+ }
554
+ }
555
+ current = current.parent;
556
+ }
557
+ return "(" + chunks.reverse().join(" (") + ")".repeat(chunks.length);
558
+ }
559
+ /** @returns {string} */
560
+ asLispString() {
561
+ return originalToString.call(this);
562
+ }
563
+ }
564
+ // patch Node with all HardNode properties
565
+ const descriptors = Object.getOwnPropertyDescriptors(HardNode.prototype);
566
+ delete descriptors.constructor;
567
+ Object.defineProperties(Node.prototype, descriptors);
568
+ // force it to inherit from BaseNode
569
+ Object.setPrototypeOf(Node.prototype, BaseNode.prototype);
570
+ export { Node };
571
+ // helper
572
+ export const _childrenWithSoftNodes = (node, children, string) => {
573
+ if (children?.length > 0) {
574
+ const newChildren = [];
575
+ const childrenCopy = [...children];
576
+ let firstChild = childrenCopy.shift();
577
+ // helper
578
+ const handleGaps = (gapText, getReferencePoint, parentNode) => {
579
+ const { index, position } = getReferencePoint();
580
+ let start = index;
581
+ let startPosition = position;
582
+ const chunks = gapText.split(/(?<!\s)(?=\s+)/g);
583
+ let colOffset = startPosition.column;
584
+ let rowOffset = startPosition.row;
585
+ for (const eachGap of chunks) {
586
+ if (eachGap.length == 0) {
587
+ continue;
588
+ }
589
+ const end = start + eachGap.length;
590
+ if (eachGap.match(/^\s/)) {
591
+ const rowOffsetBefore = rowOffset;
592
+ const colOffsetBefore = colOffset;
593
+ rowOffset += (eachGap.match(/\n/g) || []).length;
594
+ // reset column offset on new row
595
+ if (rowOffsetBefore != rowOffset) {
596
+ colOffset = eachGap.split("\n").slice(-1)[0].length;
597
+ }
598
+ else {
599
+ colOffset += eachGap.length;
600
+ }
601
+ newChildren.push(new WhitespaceNode({
602
+ tree: node.tree,
603
+ parent: parentNode,
604
+ getReferencePoint,
605
+ text: eachGap,
606
+ _startIndexOffset: start - index,
607
+ _startRowOffset: rowOffsetBefore - position.row,
608
+ _startColOffset: colOffsetBefore - position.column,
609
+ _endIndexOffset: end - index,
610
+ _endRowOffset: rowOffset - position.row,
611
+ _endColOffset: colOffset - position.column,
612
+ children: [],
613
+ }));
614
+ // sometimes the gap isn't always whitespace
615
+ }
616
+ else {
617
+ const colOffsetBefore = colOffset;
618
+ colOffset += eachGap.length;
619
+ newChildren.push(new SoftTextNode({
620
+ tree: node.tree,
621
+ parent: parentNode,
622
+ getReferencePoint,
623
+ text: eachGap,
624
+ _startIndexOffset: start - index,
625
+ _startRowOffset: rowOffset - position.row,
626
+ _startColOffset: colOffsetBefore - position.column,
627
+ _endIndexOffset: end - index,
628
+ _endRowOffset: rowOffset - position.row,
629
+ _endColOffset: colOffset - position.column,
630
+ children: [],
631
+ }));
632
+ }
633
+ start = end;
634
+ }
635
+ };
636
+ // preceding whitespace
637
+ if (node.startIndex != firstChild.startIndex) {
638
+ const gapText = string.slice(node.startIndex, firstChild.startIndex);
639
+ const thisNode = node;
640
+ // whitespace and non-whitespace chunks
641
+ handleGaps(gapText, () => ({ index: thisNode.startIndex, position: thisNode.startPosition }), node);
642
+ }
643
+ // firstChild.indent = indent
644
+ newChildren.push(firstChild);
645
+ // gaps between sibilings
646
+ let prevChild = firstChild;
647
+ for (const eachSecondaryNode of childrenCopy) {
648
+ if (prevChild.endIndex != eachSecondaryNode.startIndex) {
649
+ const gapText = string.slice(prevChild.endIndex, eachSecondaryNode.startIndex);
650
+ const thisChild = prevChild;
651
+ handleGaps(gapText, () => ({ index: thisChild.endIndex, position: thisChild.endPosition }), node);
652
+ }
653
+ // eachSecondaryNode.indent = indent
654
+ newChildren.push(eachSecondaryNode);
655
+ prevChild = eachSecondaryNode;
656
+ }
657
+ // gap between last child and parent
658
+ if (prevChild.endIndex != node.endIndex) {
659
+ const gapText = string.slice(prevChild.endIndex, node.endIndex);
660
+ const thisChild = prevChild;
661
+ handleGaps(gapText, () => ({ index: thisChild.endIndex, position: thisChild.endPosition }), node);
662
+ }
663
+ return newChildren;
664
+ }
665
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Creates and returns a new parser instance, loading a language from a WebAssembly binary or file path.
3
+ * Optionally, the parser can be configured to disable soft nodes.
4
+ *
5
+ * @async
6
+ * @param {Uint8Array|string} wasmUint8ArrayOrFilePath - The WebAssembly binary as a `Uint8Array` or a file path to load the language.
7
+ * @param {Object} [options] - Optional configuration options.
8
+ * @param {boolean} [options.disableSoftNodes=false] - Whether to disable soft nodes in the parser (default is `false`).
9
+ * @returns {Promise<ExtendedParser>} A promise that resolves to the created parser instance.
10
+ */
11
+ export function createParser(wasmUint8ArrayOrFilePath: Uint8Array | string, { disableSoftNodes, moduleOptions }?: {
12
+ disableSoftNodes?: boolean | undefined;
13
+ }): Promise<ExtendedParser>;
14
+ declare class ExtendedParser extends Parser {
15
+ /**
16
+ * Parse a slice of UTF8 text.
17
+ *
18
+ * @param {string | ParseCallback} callback - Source code to parse
19
+ *
20
+ * @param {Tree | null} [oldTree] - A previous syntax tree parsed from the same document. If the text of the
21
+ * document has changed since `oldTree` was created, then you must edit `oldTree` to match
22
+ * the new text using {@link Tree#edit}.
23
+ *
24
+ * @param {ParseOptions} [options] - Options for parsing the text.
25
+ * This can be used to set the included ranges, or a progress callback.
26
+ *
27
+ * @returns {ExtendedTree | null} A {@link Tree} if parsing succeeded, or `null` if:
28
+ * - The parser has not yet had a language assigned with {@link Parser#setLanguage}.
29
+ * - The progress callback returned true.
30
+ */
31
+ parse(inputString: any, oldTree?: Tree | null, options?: ParseOptions): ExtendedTree | null;
32
+ }
33
+ import { Parser } from "../tree_sitter/parser.js";
34
+ import { Tree } from "../tree_sitter/tree.js";
35
+ import { ExtendedTree } from "./node_extended.js";
36
+ export {};
37
+ //# sourceMappingURL=parser.d.ts.map