summaryrefslogtreecommitdiff
path: root/stag/src/scopes.scm
diff options
context:
space:
mode:
Diffstat (limited to 'stag/src/scopes.scm')
-rw-r--r--stag/src/scopes.scm463
1 files changed, 463 insertions, 0 deletions
diff --git a/stag/src/scopes.scm b/stag/src/scopes.scm
new file mode 100644
index 0000000..8a5c385
--- /dev/null
+++ b/stag/src/scopes.scm
@@ -0,0 +1,463 @@
1;; see tree-sitter-rust/src/grammar.json for an exhaustive list of productions
2
3;; scopes
4(block) @local.scope ; { ... }
5(function_item) @local.scope
6(declaration_list) @local.scope ; mod { ... }
7
8;; impl items can define types and lifetimes:
9;;
10;; impl<'a, T> Trait for Struct { .. }
11;;
12;; in order to constrain those to the impl block,
13;; we add a local scope here:
14(impl_item) @local.scope
15(struct_item) @local.scope
16(enum_item) @local.scope
17(union_item) @local.scope
18(type_item) @local.scope
19(trait_item) @local.scope
20
21;; let expressions create scopes
22(if_expression
23 [(let_condition)
24 (let_chain)]) @local.scope
25
26;; each match arm can bind variables with
27;; patterns, without creating a block scope;
28;;
29;; match _ {
30;; (a, b) => a,
31;; }
32;;
33;; The bindings for a, b are constrained to
34;; the match arm.
35(match_arm) @local.scope
36
37;; loop labels are defs that are available only
38;; within the scope they create:
39;;
40;; 'outer: loop {
41;; let x = 2;
42;; };
43;; let y = 2;
44;;
45;; Produces a scope graph like so:
46;;
47;; {
48;; defs: [ y ],
49;; scopes: [
50;; {
51;; defs: [ 'outer ],
52;; scopes: [
53;; {
54;; defs: [ x ]
55;; }
56;; ]
57;; }
58;; ]
59;; }
60;;
61(loop_expression) @local.scope
62(for_expression) @local.scope
63(while_expression) @local.scope
64
65
66;; defs
67
68;; let x = ...;
69(let_declaration
70 pattern: (identifier) @local.definition.variable)
71
72;; if let x = ...;
73;; while let x = ...;
74(let_condition
75 .
76 (identifier) @local.definition.variable)
77
78;; let (a, b, ...) = ..;
79;; if let (a, b, ...) = {}
80;; while let (a, b, ...) = {}
81;; match _ { (a, b) => { .. } }
82(tuple_pattern (identifier) @local.definition.variable)
83
84;; Some(a)
85(tuple_struct_pattern
86 type: (_)
87 (identifier) @local.definition.variable)
88
89;; let S { field: a } = ..;
90(struct_pattern
91 (field_pattern
92 (identifier) @local.definition.variable))
93
94;; let S { a, b } = ..;
95(struct_pattern
96 (field_pattern
97 (shorthand_field_identifier) @local.definition.variable))
98
99;; (mut x: T)
100(mut_pattern (identifier) @local.definition.variable)
101
102;; (ref x: T)
103(ref_pattern (identifier) @local.definition.variable)
104
105;; const x = ...;
106(const_item (identifier) @local.definition.const)
107
108;; static x = ...;
109(static_item (identifier) @local.definition.const)
110
111;; fn _(x: _)
112(parameters
113 (parameter
114 pattern: (identifier) @local.definition.variable))
115;; fn _(self)
116(parameters
117 (self_parameter
118 (self) @local.definition.variable))
119
120;; type parameters
121(type_parameters
122 (type_identifier) @local.definition.typedef)
123(type_parameters
124 (lifetime) @local.definition.lifetime)
125(constrained_type_parameter
126 left: (type_identifier) @local.definition.typedef)
127
128;; |x| { ... }
129;; no type
130(closure_parameters (identifier) @local.definition.variable)
131
132;; |x: T| { ... }
133;; with type
134(closure_parameters
135 (parameter
136 (identifier) @local.definition.variable))
137
138;;fn x(..)
139(function_item (identifier) @hoist.definition.function)
140
141;; 'outer: loop { .. }
142(loop_expression
143 (loop_label) @local.definition.label)
144
145;; `for` exprs create two defs: a label (if any) and the
146;; loop variable
147(for_expression . (identifier) @local.definition.variable)
148(for_expression (loop_label) @local.definition.label)
149
150;; 'label: while cond { .. }
151(while_expression
152 (loop_label) @local.definition.label)
153
154;; type definitions
155(struct_item (type_identifier) @hoist.definition.struct)
156(enum_item (type_identifier) @hoist.definition.enum)
157(union_item (type_identifier) @hoist.definition.union)
158(type_item . (type_identifier) @hoist.definition.typedef)
159(trait_item (type_identifier) @hoist.definition.interface)
160
161;; struct and union fields
162(field_declaration_list
163 (field_declaration
164 (field_identifier) @local.definition.field))
165
166;; enum variants
167(enum_variant_list
168 (enum_variant
169 (identifier) @local.definition.enumerator))
170
171;; mod x;
172(mod_item (identifier) @local.definition.module)
173
174;; use statements
175
176;; use item;
177(use_declaration
178 (identifier) @local.import)
179
180;; use path as item;
181(use_as_clause
182 alias: (identifier) @local.import)
183
184;; use path::item;
185(use_declaration
186 (scoped_identifier
187 name: (identifier) @local.import))
188
189;; use module::{member1, member2, member3};
190(use_list
191 (identifier) @local.import)
192(use_list
193 (scoped_identifier
194 name: (identifier) @local.import))
195
196
197;; refs
198
199;; !x
200(unary_expression (identifier) @local.reference)
201
202;; &x
203(reference_expression (identifier) @local.reference)
204
205;; (x)
206(parenthesized_expression (identifier) @local.reference)
207
208;; x?
209(try_expression (identifier) @local.reference)
210
211;; a = b
212(assignment_expression (identifier) @local.reference)
213
214;; a op b
215(binary_expression (identifier) @local.reference)
216
217;; a op= b
218(compound_assignment_expr (identifier) @local.reference)
219
220;; a as b
221(type_cast_expression (identifier) @local.reference)
222
223;; a()
224(call_expression (identifier) @local.reference)
225
226;; Self::foo()
227;;
228;; `foo` can be resolved
229(call_expression
230 (scoped_identifier
231 (identifier) @_self_type
232 (identifier) @local.reference)
233 (#match? @_self_type "Self"))
234
235;; self.foo()
236;;
237;; `foo` can be resolved
238(call_expression
239 (field_expression
240 (self)
241 (field_identifier) @local.reference))
242
243;; return a
244(return_expression (identifier) @local.reference)
245
246;; break a
247(break_expression (identifier) @local.reference)
248
249;; break 'label
250(break_expression (loop_label) @local.reference)
251
252;; continue 'label;
253(continue_expression (loop_label) @local.reference)
254
255;; yield x;
256(yield_expression (identifier) @local.reference)
257
258;; await a
259(await_expression (identifier) @local.reference)
260
261;; (a, b)
262(tuple_expression (identifier) @local.reference)
263
264;; a[]
265(index_expression (identifier) @local.reference)
266
267;; ident;
268(expression_statement (identifier) @local.reference)
269
270;; a..b
271(range_expression (identifier) @local.reference)
272
273;; [ident; N]
274(array_expression (identifier) @local.reference)
275
276;; path::to::item
277;;
278;; `path` is a ref
279(scoped_identifier
280 path: (identifier) @local.reference)
281
282;; rhs of let decls
283(let_declaration
284 value: (identifier) @local.reference)
285
286;; type T = [T; N]
287;;
288;; N is a ident ref
289(array_type
290 length: (identifier) @local.reference)
291
292;; S { _ }
293(struct_expression
294 (type_identifier) @local.reference)
295
296;; S { a }
297(struct_expression
298 (field_initializer_list
299 (shorthand_field_initializer
300 (identifier) @local.reference)))
301
302;; S { a: value }
303(struct_expression
304 (field_initializer_list
305 (field_initializer
306 (identifier) @local.reference)))
307
308;; S { ..a }
309(struct_expression
310 (field_initializer_list
311 (base_field_initializer
312 (identifier) @local.reference)))
313
314;; if a {}
315(if_expression (identifier) @local.reference)
316
317;; for pattern in value {}
318;;
319;; `value` is a ref
320(for_expression
321 value: (identifier) @local.reference)
322
323;; while a {}
324(while_expression (identifier) @local.reference)
325
326;; if let _ = a {}
327;;
328;; the ident following the `=` is a ref
329;; the ident preceding the `=` is a def
330;; while let _ = a {}
331(let_condition
332 "="
333 (identifier) @local.reference)
334
335
336;; match a
337(match_expression (identifier) @local.reference)
338
339;; match _ {
340;; pattern => a,
341;; }
342;;
343;; this `a` is somehow not any expression form
344(match_arm (identifier) @local.reference)
345
346;; a.b
347;;
348;; `b` is ignored
349(field_expression
350 (identifier) @local.reference)
351
352;; { stmt; foo }
353(block
354 (identifier) @local.reference)
355
356;; arguments to method calls or function calls
357(arguments
358 (identifier) @local.reference)
359
360;; impl S { .. }
361(impl_item (type_identifier) @local.reference)
362
363;; where T: ...
364(where_predicate
365 left: (type_identifier) @local.reference)
366
367;; trait bounds
368(trait_bounds
369 (type_identifier) @local.reference)
370(trait_bounds
371 (lifetime) @local.reference)
372
373;; idents in macros
374(token_tree
375 (identifier) @local.reference)
376
377;; types
378
379;; (T, U)
380(tuple_type
381 (type_identifier) @local.reference)
382
383;; &T
384(reference_type
385 (type_identifier) @local.reference)
386
387;; &'a T
388(reference_type
389 (lifetime) @local.reference)
390
391;; &'a self
392(self_parameter
393 (lifetime) @local.reference)
394
395;; *mut T
396;; *const T
397(pointer_type
398 (type_identifier) @local.reference)
399
400;; A<_>
401(generic_type
402 (type_identifier) @local.reference)
403
404;; _<V>
405(type_arguments
406 (type_identifier) @local.reference)
407(type_arguments
408 (lifetime) @local.reference)
409
410;; T<U = V>
411;;
412;; U is ignored
413;; V is a ref
414(type_binding
415 name: (_)
416 type: (type_identifier) @local.reference)
417
418;; [T]
419(array_type
420 (type_identifier) @local.reference)
421
422;; type T = U;
423;;
424;; T is a def
425;; U is a ref
426(type_item
427 name: (_)
428 type: (type_identifier) @local.reference)
429
430(function_item
431 return_type: (type_identifier) @local.reference)
432
433;; type refs in params
434;;
435;; fn _(_: T)
436(parameters
437 (parameter
438 type: (type_identifier) @local.reference))
439
440;; dyn T
441(dynamic_type
442 (type_identifier) @local.reference)
443
444;; <T>::call()
445(bracketed_type
446 (type_identifier) @local.reference)
447
448;; T as Trait
449(qualified_type
450 (type_identifier) @local.reference)
451
452;; module::T
453;;
454;; `module` is a def
455;; `T` is a ref
456(scoped_type_identifier
457 path: (identifier) @local.reference)
458
459;; struct _ { field: Type }
460;; `Type` is a ref
461 (field_declaration
462 name: (_)
463 type: (type_identifier) @local.reference)