diff options
author | Akshay <[email protected]> | 2024-01-16 21:18:52 +0000 |
---|---|---|
committer | Akshay <[email protected]> | 2024-01-16 21:18:52 +0000 |
commit | be60a9f66d1c01b15ddc3a56bca0416ce8dee0fd (patch) | |
tree | 159f9afd776f4881f1312d5b36384b8d0533904b /stag/src/scopes.scm | |
parent | f99715d8805a18dc7c16f17275a85a0724e01db9 (diff) |
begin work on stag
Diffstat (limited to 'stag/src/scopes.scm')
-rw-r--r-- | stag/src/scopes.scm | 463 |
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) | ||