0
# Query
1
2
Pattern-based querying for complex syntax tree analysis and extraction. Queries use S-expression patterns to match specific structures in syntax trees and extract relevant nodes with named captures.
3
4
## Capabilities
5
6
### Query Creation
7
8
Create queries from S-expression pattern strings.
9
10
```typescript { .api }
11
/**
12
* Create a new query from S-expression patterns
13
* @param language - Language the query is associated with
14
* @param source - Query source containing one or more S-expression patterns
15
*/
16
constructor(language: Language, source: string);
17
18
/**
19
* Delete the query and free its resources
20
*/
21
delete(): void;
22
```
23
24
**Usage Example:**
25
26
```typescript
27
import { Query, Language } from "web-tree-sitter";
28
29
const language = await Language.load("/tree-sitter-javascript.wasm");
30
31
// Create query to find function declarations with their names
32
const query = new Query(language, `
33
(function_declaration
34
name: (identifier) @function-name
35
parameters: (formal_parameters) @params)
36
37
(variable_declarator
38
name: (identifier) @var-name
39
value: (arrow_function) @arrow-func)
40
`);
41
```
42
43
### Pattern Matching
44
45
Execute queries to find matching patterns in syntax trees.
46
47
```typescript { .api }
48
/**
49
* Get all matches in the order they were found
50
* @param node - Root node to execute the query on
51
* @param options - Query execution options
52
* @returns Array of matches with pattern indices and captures
53
*/
54
matches(node: Node, options?: QueryOptions): QueryMatch[];
55
56
/**
57
* Get all individual captures in the order they appear
58
* @param node - Root node to execute the query on
59
* @param options - Query execution options
60
* @returns Array of captures without grouping by match
61
*/
62
captures(node: Node, options?: QueryOptions): QueryCapture[];
63
```
64
65
**Usage Examples:**
66
67
```typescript
68
const tree = parser.parse(`
69
function add(a, b) { return a + b; }
70
const multiply = (x, y) => x * y;
71
`);
72
73
// Get all matches
74
const matches = query.matches(tree.rootNode);
75
console.log(`Found ${matches.length} matches`);
76
77
matches.forEach((match, i) => {
78
console.log(`Match ${i} (pattern ${match.patternIndex}):`);
79
match.captures.forEach(capture => {
80
console.log(` ${capture.name}: ${capture.node.text}`);
81
});
82
});
83
84
// Get just the captures
85
const captures = query.captures(tree.rootNode);
86
captures.forEach(capture => {
87
console.log(`${capture.name}: ${capture.node.text}`);
88
});
89
```
90
91
### Query Metadata
92
93
Access information about query patterns and captures.
94
95
```typescript { .api }
96
/** The names of the captures used in the query */
97
readonly captureNames: string[];
98
99
/** The quantifiers of the captures used in the query */
100
readonly captureQuantifiers: CaptureQuantifier[][];
101
102
/** The predicates associated with each pattern index */
103
readonly predicates: QueryPredicate[][];
104
105
/** Properties for predicates with the operator 'set!' */
106
readonly setProperties: QueryProperties[];
107
108
/** Properties for predicates with the operator 'is?' */
109
readonly assertedProperties: QueryProperties[];
110
111
/** Properties for predicates with the operator 'is-not?' */
112
readonly refutedProperties: QueryProperties[];
113
```
114
115
**Usage Example:**
116
117
```typescript
118
console.log("Capture names:", query.captureNames);
119
console.log("Pattern count:", query.patternCount());
120
121
// Check predicates for first pattern
122
const predicates = query.predicatesForPattern(0);
123
console.log("Predicates for pattern 0:", predicates);
124
```
125
126
### Pattern Information
127
128
Get detailed information about individual patterns.
129
130
```typescript { .api }
131
/**
132
* Get the predicates for a given pattern
133
* @param patternIndex - Index of the pattern
134
* @returns Array of predicates for the pattern
135
*/
136
predicatesForPattern(patternIndex: number): QueryPredicate[];
137
138
/**
139
* Get the byte offset where the given pattern starts in the query's source
140
* @param patternIndex - Index of the pattern
141
* @returns Start byte offset in query source
142
*/
143
startIndexForPattern(patternIndex: number): number;
144
145
/**
146
* Get the byte offset where the given pattern ends in the query's source
147
* @param patternIndex - Index of the pattern
148
* @returns End byte offset in query source
149
*/
150
endIndexForPattern(patternIndex: number): number;
151
152
/**
153
* Get the number of patterns in the query
154
* @returns Total number of patterns
155
*/
156
patternCount(): number;
157
```
158
159
### Capture Management
160
161
Work with named captures in the query.
162
163
```typescript { .api }
164
/**
165
* Get the index for a given capture name
166
* @param captureName - Name of the capture to look up
167
* @returns Index of the capture or -1 if not found
168
*/
169
captureIndexForName(captureName: string): number;
170
171
/**
172
* Disable a certain capture within a query
173
* @param captureName - Name of the capture to disable
174
*/
175
disableCapture(captureName: string): void;
176
```
177
178
**Usage Example:**
179
180
```typescript
181
// Disable a specific capture to improve performance
182
query.disableCapture("params");
183
184
// Get capture index
185
const nameIndex = query.captureIndexForName("function-name");
186
console.log("Function name capture index:", nameIndex);
187
```
188
189
### Pattern Control
190
191
Control pattern execution and analysis.
192
193
```typescript { .api }
194
/**
195
* Disable a certain pattern within a query
196
* @param patternIndex - Index of the pattern to disable
197
*/
198
disablePattern(patternIndex: number): void;
199
200
/**
201
* Check if a given pattern within a query has a single root node
202
* @param patternIndex - Index of the pattern to check
203
* @returns True if pattern has single root node
204
*/
205
isPatternRooted(patternIndex: number): boolean;
206
207
/**
208
* Check if a given pattern within a query is non-local
209
* @param patternIndex - Index of the pattern to check
210
* @returns True if pattern is non-local
211
*/
212
isPatternNonLocal(patternIndex: number): boolean;
213
214
/**
215
* Check if a given step in a query is 'definite'
216
* @param byteIndex - Byte index in the query source
217
* @returns True if step is guaranteed to match
218
*/
219
isPatternGuaranteedAtStep(byteIndex: number): boolean;
220
```
221
222
### Match Limits and Performance
223
224
Control query execution limits and check performance metrics.
225
226
```typescript { .api }
227
/** The maximum number of in-progress matches for this query */
228
matchLimit?: number;
229
230
/**
231
* Check if, on its last execution, this cursor exceeded its maximum number of in-progress matches
232
* @returns True if match limit was exceeded
233
*/
234
didExceedMatchLimit(): boolean;
235
```
236
237
**Usage Example:**
238
239
```typescript
240
// Set match limit for performance
241
query.matchLimit = 1000;
242
243
const matches = query.matches(tree.rootNode);
244
245
if (query.didExceedMatchLimit()) {
246
console.warn("Query exceeded match limit, results may be incomplete");
247
}
248
```
249
250
## Types
251
252
```typescript { .api }
253
interface QueryOptions {
254
/** The start position of the range to query */
255
startPosition?: Point;
256
/** The end position of the range to query */
257
endPosition?: Point;
258
/** The start index of the range to query */
259
startIndex?: number;
260
/** The end index of the range to query */
261
endIndex?: number;
262
/** The maximum number of in-progress matches (1-65536) */
263
matchLimit?: number;
264
/** The maximum start depth for query cursor */
265
maxStartDepth?: number;
266
/** Maximum execution time in microseconds */
267
timeoutMicros?: number;
268
/** Progress callback for monitoring/cancelling execution */
269
progressCallback?: (state: QueryState) => void;
270
}
271
272
interface QueryState {
273
/** The byte offset in the document that the query is at */
274
currentOffset: number;
275
}
276
277
/** Key-value pairs associated with a pattern */
278
type QueryProperties = Record<string, string | null>;
279
280
interface QueryPredicate {
281
/** The operator of the predicate (match?, eq?, set!, etc.) */
282
operator: string;
283
/** The operands of the predicate (captures or strings) */
284
operands: PredicateStep[];
285
}
286
287
interface QueryCapture {
288
/** The index of the pattern that matched */
289
patternIndex: number;
290
/** The name of the capture */
291
name: string;
292
/** The captured node */
293
node: Node;
294
/** Properties for predicates declared with 'set!' */
295
setProperties?: QueryProperties;
296
/** Properties for predicates declared with 'is?' */
297
assertedProperties?: QueryProperties;
298
/** Properties for predicates declared with 'is-not?' */
299
refutedProperties?: QueryProperties;
300
}
301
302
interface QueryMatch {
303
/** @deprecated Use patternIndex instead */
304
pattern: number;
305
/** The index of the pattern that matched */
306
patternIndex: number;
307
/** The captures associated with the match */
308
captures: QueryCapture[];
309
/** Properties for predicates declared with 'set!' */
310
setProperties?: QueryProperties;
311
/** Properties for predicates declared with 'is?' */
312
assertedProperties?: QueryProperties;
313
/** Properties for predicates declared with 'is-not?' */
314
refutedProperties?: QueryProperties;
315
}
316
317
/** Quantifiers for captures */
318
const CaptureQuantifier: {
319
readonly Zero: 0;
320
readonly ZeroOrOne: 1;
321
readonly ZeroOrMore: 2;
322
readonly One: 3;
323
readonly OneOrMore: 4;
324
};
325
326
type CaptureQuantifier = typeof CaptureQuantifier[keyof typeof CaptureQuantifier];
327
328
/** Steps in predicates - either captures or strings */
329
type PredicateStep = CapturePredicateStep | StringPredicateStep;
330
331
interface CapturePredicateStep {
332
type: 'capture';
333
name: string;
334
}
335
336
interface StringPredicateStep {
337
type: 'string';
338
value: string;
339
}
340
```
341
342
## Query Examples
343
344
### Basic Pattern Matching
345
346
```typescript
347
// Find all function calls
348
const callQuery = new Query(language, `
349
(call_expression
350
function: (identifier) @function-name
351
arguments: (arguments) @args)
352
`);
353
354
// Find all string literals
355
const stringQuery = new Query(language, `
356
(string) @string-literal
357
`);
358
```
359
360
### Advanced Patterns with Predicates
361
362
```typescript
363
// Find functions with specific names
364
const specificFuncQuery = new Query(language, `
365
(function_declaration
366
name: (identifier) @name
367
(#match? @name "^(test|spec)"))
368
`);
369
370
// Find variable declarations with initialization
371
const varQuery = new Query(language, `
372
(variable_declarator
373
name: (identifier) @var-name
374
value: (_) @initial-value)
375
`);
376
```
377
378
### Complex Structural Patterns
379
380
```typescript
381
// Find nested function calls
382
const nestedQuery = new Query(language, `
383
(call_expression
384
function: (member_expression
385
object: (identifier) @object
386
property: (property_identifier) @method)
387
arguments: (arguments
388
(call_expression) @nested-call))
389
`);
390
```