dsh-plugin-codegraph-tree-sitter 0.1.1 → 0.1.5
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.
- package/README.md +1 -1
- package/lib/extract.d.ts +17 -0
- package/lib/extract.js +1709 -22
- package/lib/languages.d.ts +140 -1
- package/lib/languages.js +707 -2
- package/lib/resolve.d.ts +3 -0
- package/lib/resolve.js +44 -3
- package/lib/schema.js +3 -3
- package/package.json +2 -2
package/lib/languages.js
CHANGED
|
@@ -8,6 +8,88 @@
|
|
|
8
8
|
* defers until the core proves itself against real workspaces.
|
|
9
9
|
* @module dsh-plugin-codegraph-tree-sitter/languages
|
|
10
10
|
*/
|
|
11
|
+
/**
|
|
12
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose matched node has no separate
|
|
13
|
+
* name-bearing child — a bare enum member (`enum_body`'s `Red` in `enum Color { Red }`) parses as a
|
|
14
|
+
* lone `property_identifier` token with no fields of its own; the node itself, unlike every other
|
|
15
|
+
* `nameField` target, *is* the name.
|
|
16
|
+
*/
|
|
17
|
+
export const SELF_NAME_FIELD = '@self';
|
|
18
|
+
/**
|
|
19
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose name sits behind an arbitrarily deep
|
|
20
|
+
* chain of C/C++ `declarator` wrappers — `int *make(int a)`'s name is three `declarator` fields down
|
|
21
|
+
* (`pointer_declarator` → `function_declarator` → `identifier`), and a plain `int g` binds its
|
|
22
|
+
* `identifier` directly with no wrapper at all. See `declaratorName` in `extract.ts`, which this
|
|
23
|
+
* sentinel dispatches to instead of a flat `childForFieldName` lookup.
|
|
24
|
+
*/
|
|
25
|
+
export const DECLARATOR_NAME_FIELD = '@declarator';
|
|
26
|
+
/**
|
|
27
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose name is its matched node's first
|
|
28
|
+
* named child with no field name of its own — C#'s `variable_declarator` binds neither its name nor its
|
|
29
|
+
* optional initializer to a field at all (`int Field = 5;`'s `variable_declarator` has two purely
|
|
30
|
+
* positional named children, `identifier` then `equals_value_clause`), unlike every other grammar this
|
|
31
|
+
* package extracts a name from. Distinct from {@link SELF_NAME_FIELD}: the matched node's own text
|
|
32
|
+
* would include that initializer (`"Field = 5"`), not just the name. See `firstChildName` in
|
|
33
|
+
* `extract.ts`.
|
|
34
|
+
*/
|
|
35
|
+
export const FIRST_CHILD_NAME_FIELD = '@first-child';
|
|
36
|
+
/**
|
|
37
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose name is PHP-specific: a bare `name`
|
|
38
|
+
* node directly (`const_element`'s `VERSION` in `const VERSION = "1"`), or one nested a level deeper
|
|
39
|
+
* inside a `variable_name` child (`property_element`'s `$name` in `public string $name;`, and an
|
|
40
|
+
* `assignment_expression`'s `$fn` in `$fn = function () {}` — both bind their bare `name` behind the
|
|
41
|
+
* same `$`-prefixed wrapper). See `phpElementName` in `extract.ts`, which this sentinel dispatches to
|
|
42
|
+
* instead of a flat `childForFieldName` lookup — none of these three shapes bind their name to a field
|
|
43
|
+
* of its own.
|
|
44
|
+
*/
|
|
45
|
+
export const PHP_ELEMENT_NAME_FIELD = '@php-element';
|
|
46
|
+
/**
|
|
47
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Kotlin-specific: the bundled
|
|
48
|
+
* `tree-sitter-kotlin` grammar this package loads binds *no* grammar fields at all (verified against a
|
|
49
|
+
* real parse — `Language.fieldCount`/`fieldNameForId` enumerate zero for it), unlike every other grammar
|
|
50
|
+
* this package extracts from, so a plain `childForFieldName` lookup can never work here regardless of
|
|
51
|
+
* which field name is named. A `class_declaration`'s/`function_declaration`'s/`enum_entry`'s declared
|
|
52
|
+
* name is instead the first direct named child typed `type_identifier` (a class/interface/enum name) or
|
|
53
|
+
* `simple_identifier` (a function/enum-entry name) — found by type rather than by position, since an
|
|
54
|
+
* optional leading `modifiers` node (wrapping `private`/`internal`/…) would otherwise sit at index 0
|
|
55
|
+
* ahead of it. See `kotlinDeclaredName` in `extract.ts`, which this sentinel dispatches to.
|
|
56
|
+
*/
|
|
57
|
+
export const KOTLIN_NAME_FIELD = '@kotlin-name';
|
|
58
|
+
/**
|
|
59
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Swift-specific: a
|
|
60
|
+
* `property_declaration`'s own `name` field points to a `pattern` node (`var x: Int`'s `x` sits behind
|
|
61
|
+
* this wrapper, not bound to a field of `property_declaration` directly), and the actual declared
|
|
62
|
+
* identifier is one level deeper still, bound to that `pattern` node's own `bound_identifier` field.
|
|
63
|
+
* See `swiftPropertyName` in `extract.ts`, which this sentinel dispatches to instead of a flat
|
|
64
|
+
* `childForFieldName` lookup. Verified against a real parse, not guessed.
|
|
65
|
+
*/
|
|
66
|
+
export const SWIFT_PROPERTY_NAME_FIELD = '@swift-property';
|
|
67
|
+
/**
|
|
68
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Swift-specific in a
|
|
69
|
+
* different way: a `function_declaration`/`protocol_function_declaration` with an explicit return type
|
|
70
|
+
* (`func add() -> Int`) binds *two* nodes to its own `name` field in this grammar build — the declared
|
|
71
|
+
* identifier itself, and (a verified, unguessed quirk of this specific compiled grammar) its
|
|
72
|
+
* `return_type` node as well — so `childrenForFieldName('name')` returns both, failing
|
|
73
|
+
* `soleNamedField`'s "exactly one bound child" uniqueness check the same way Go's genuinely ambiguous
|
|
74
|
+
* `const a, b = 1, 2` does, and silently dropping every such function from this package's graph. Unlike
|
|
75
|
+
* that Go case, this is not a real multi-name ambiguity — the identifier always comes first in document
|
|
76
|
+
* order — so `swiftFunctionName` in `extract.ts` uses `childForFieldName('name')` (first match) instead
|
|
77
|
+
* of `soleNamedField`'s all-matches check.
|
|
78
|
+
*/
|
|
79
|
+
export const SWIFT_FUNCTION_NAME_FIELD = '@swift-function';
|
|
80
|
+
/**
|
|
81
|
+
* Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Dart-specific: a `declaration`
|
|
82
|
+
* node is how Dart spells both a class/struct field (`int x;`, wrapping an `initialized_identifier_list`
|
|
83
|
+
* of one or more `initialized_identifier` children, itself the same multi-name ambiguity Go's
|
|
84
|
+
* `const_spec`/`var_spec` already reject outright) and a constructor (wrapping a `constructor_signature`
|
|
85
|
+
* instead, handled by its own separate rule matching that inner node type directly, not this one) — with
|
|
86
|
+
* no field of its own binding either shape, so `dartFieldName` in `extract.ts` returns `undefined` for
|
|
87
|
+
* anything but the single-identifier field-list shape, the same "don't guess" precedent this file already
|
|
88
|
+
* follows elsewhere; a `declaration` wrapping a constructor simply fails to match this rule and is left
|
|
89
|
+
* for the dedicated `constructor_signature` rule to capture during the walk's ordinary recursion into it.
|
|
90
|
+
* Verified against a real parse, not guessed.
|
|
91
|
+
*/
|
|
92
|
+
export const DART_FIELD_NAME_FIELD = '@dart-field';
|
|
11
93
|
/** Definitions common to every ECMAScript-family grammar (JavaScript, JSX, TypeScript, TSX). */
|
|
12
94
|
const ECMASCRIPT_DEFINITIONS = [
|
|
13
95
|
{ nodeType: 'function_declaration', kind: 'function', nameField: 'name' },
|
|
@@ -20,6 +102,12 @@ const ECMASCRIPT_DEFINITIONS = [
|
|
|
20
102
|
nameField: 'name',
|
|
21
103
|
value: { field: 'value', types: ['arrow_function', 'function_expression', 'generator_function'] },
|
|
22
104
|
},
|
|
105
|
+
// Falls through from the function-valued rule above: any other simply-named `const`/`let`/`var`
|
|
106
|
+
// binding (`lexical_declaration` and `variable_declaration` both wrap this same node type).
|
|
107
|
+
// `nameNodeTypes` rejects a destructuring pattern (`const {a, b} = x`) rather than name it after its
|
|
108
|
+
// pattern text — the same "don't guess a name" precedent `pythonBinding`/`ecmascriptImports` already
|
|
109
|
+
// follow for shapes this package does not resolve.
|
|
110
|
+
{ nodeType: 'variable_declarator', kind: 'variable', nameField: 'name', nameNodeTypes: ['identifier'], scopeRestricted: true },
|
|
23
111
|
];
|
|
24
112
|
/** Definitions TypeScript and TSX add on top of {@link ECMASCRIPT_DEFINITIONS}. */
|
|
25
113
|
const TYPESCRIPT_DEFINITIONS = [
|
|
@@ -27,9 +115,29 @@ const TYPESCRIPT_DEFINITIONS = [
|
|
|
27
115
|
{ nodeType: 'interface_declaration', kind: 'interface', nameField: 'name' },
|
|
28
116
|
{ nodeType: 'type_alias_declaration', kind: 'type_alias', nameField: 'name' },
|
|
29
117
|
{ nodeType: 'enum_declaration', kind: 'enum', nameField: 'name' },
|
|
118
|
+
// `enum Color { Red, Green = 5 }` — a bare member (`Red`) parses as a lone `property_identifier`
|
|
119
|
+
// naming itself, tagged with `enum_body`'s own repeated `name` field; a valued member (`Green = 5`)
|
|
120
|
+
// wraps its own `property_identifier` in a distinct `enum_assignment` node instead. Both verified
|
|
121
|
+
// against a real parse, not guessed.
|
|
122
|
+
{ nodeType: 'property_identifier', kind: 'enum_member', nameField: SELF_NAME_FIELD, parentType: 'enum_body' },
|
|
123
|
+
{ nodeType: 'enum_assignment', kind: 'enum_member', nameField: 'name' },
|
|
124
|
+
// The TypeScript/TSX grammars name a class field node differently from plain JavaScript's
|
|
125
|
+
// `field_definition` (see JAVASCRIPT_DEFINITIONS) — verified against a real parse, not guessed.
|
|
126
|
+
{ nodeType: 'public_field_definition', kind: 'field', nameField: 'name', scopeRestricted: true },
|
|
127
|
+
];
|
|
128
|
+
/** Definitions JavaScript and JSX add on top of {@link ECMASCRIPT_DEFINITIONS}. */
|
|
129
|
+
const JAVASCRIPT_DEFINITIONS = [
|
|
130
|
+
...ECMASCRIPT_DEFINITIONS,
|
|
131
|
+
// The plain JavaScript grammar's class field node names its field-name field `property`, not `name`
|
|
132
|
+
// as TypeScript's `public_field_definition` does (see TYPESCRIPT_DEFINITIONS) — verified against a
|
|
133
|
+
// real parse, not guessed.
|
|
134
|
+
{ nodeType: 'field_definition', kind: 'field', nameField: 'property', scopeRestricted: true },
|
|
30
135
|
];
|
|
31
136
|
const ECMASCRIPT_CALL_TYPES = ['call_expression'];
|
|
32
137
|
const ECMASCRIPT_IMPORT_TYPES = ['import_statement'];
|
|
138
|
+
/** The ECMAScript function-value node types, matched against a real parse — see
|
|
139
|
+
* {@link LanguageSpec.bareFunctionScopeTypes}. */
|
|
140
|
+
const ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES = ['function_expression', 'arrow_function', 'generator_function'];
|
|
33
141
|
/** Every grammar this package loads, keyed by the seam language label it produces. */
|
|
34
142
|
export const LANGUAGE_TABLE = [
|
|
35
143
|
{
|
|
@@ -40,6 +148,7 @@ export const LANGUAGE_TABLE = [
|
|
|
40
148
|
callTypes: ECMASCRIPT_CALL_TYPES,
|
|
41
149
|
callFunctionField: 'function',
|
|
42
150
|
importTypes: ECMASCRIPT_IMPORT_TYPES,
|
|
151
|
+
bareFunctionScopeTypes: ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES,
|
|
43
152
|
},
|
|
44
153
|
{
|
|
45
154
|
language: 'tsx',
|
|
@@ -49,15 +158,17 @@ export const LANGUAGE_TABLE = [
|
|
|
49
158
|
callTypes: ECMASCRIPT_CALL_TYPES,
|
|
50
159
|
callFunctionField: 'function',
|
|
51
160
|
importTypes: ECMASCRIPT_IMPORT_TYPES,
|
|
161
|
+
bareFunctionScopeTypes: ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES,
|
|
52
162
|
},
|
|
53
163
|
{
|
|
54
164
|
language: 'javascript',
|
|
55
165
|
extensions: ['.js', '.mjs', '.cjs'],
|
|
56
166
|
wasmFile: 'tree-sitter-javascript.wasm',
|
|
57
|
-
definitions:
|
|
167
|
+
definitions: JAVASCRIPT_DEFINITIONS,
|
|
58
168
|
callTypes: ECMASCRIPT_CALL_TYPES,
|
|
59
169
|
callFunctionField: 'function',
|
|
60
170
|
importTypes: ECMASCRIPT_IMPORT_TYPES,
|
|
171
|
+
bareFunctionScopeTypes: ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES,
|
|
61
172
|
},
|
|
62
173
|
{
|
|
63
174
|
language: 'jsx',
|
|
@@ -65,10 +176,11 @@ export const LANGUAGE_TABLE = [
|
|
|
65
176
|
// The plain JavaScript grammar already parses JSX syntax; tree-sitter-wasms ships no separate
|
|
66
177
|
// "jsx" binary, only distinct typescript/tsx binaries.
|
|
67
178
|
wasmFile: 'tree-sitter-javascript.wasm',
|
|
68
|
-
definitions:
|
|
179
|
+
definitions: JAVASCRIPT_DEFINITIONS,
|
|
69
180
|
callTypes: ECMASCRIPT_CALL_TYPES,
|
|
70
181
|
callFunctionField: 'function',
|
|
71
182
|
importTypes: ECMASCRIPT_IMPORT_TYPES,
|
|
183
|
+
bareFunctionScopeTypes: ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES,
|
|
72
184
|
},
|
|
73
185
|
{
|
|
74
186
|
language: 'python',
|
|
@@ -77,10 +189,15 @@ export const LANGUAGE_TABLE = [
|
|
|
77
189
|
definitions: [
|
|
78
190
|
{ nodeType: 'function_definition', kind: 'function', nameField: 'name' },
|
|
79
191
|
{ nodeType: 'class_definition', kind: 'class', nameField: 'name' },
|
|
192
|
+
// Module- and class-level `x = ...`; `nameNodeTypes` rejects a tuple assignment (`a, b = 1, 2`,
|
|
193
|
+
// `left` is a `pattern_list`) and an attribute target (`self.x = 1`, `left` is an `attribute`) —
|
|
194
|
+
// verified against a real parse, not guessed.
|
|
195
|
+
{ nodeType: 'assignment', kind: 'variable', nameField: 'left', nameNodeTypes: ['identifier'], scopeRestricted: true },
|
|
80
196
|
],
|
|
81
197
|
callTypes: ['call'],
|
|
82
198
|
callFunctionField: 'function',
|
|
83
199
|
importTypes: ['import_statement', 'import_from_statement'],
|
|
200
|
+
bareFunctionScopeTypes: [],
|
|
84
201
|
},
|
|
85
202
|
{
|
|
86
203
|
language: 'go',
|
|
@@ -90,10 +207,598 @@ export const LANGUAGE_TABLE = [
|
|
|
90
207
|
{ nodeType: 'function_declaration', kind: 'function', nameField: 'name' },
|
|
91
208
|
{ nodeType: 'method_declaration', kind: 'method', nameField: 'name' },
|
|
92
209
|
{ nodeType: 'type_spec', kind: 'type_alias', nameField: 'name' },
|
|
210
|
+
// Go allows `const a, b = 1, 2` — multiple names sharing one `const_spec`/`var_spec` node, each
|
|
211
|
+
// tagged with the same `name` field. `matchDefinition`'s single-name-field requirement rejects
|
|
212
|
+
// the multi-name form entirely rather than capture only the first — a partial, silently
|
|
213
|
+
// misleading result would be worse than none, per this file's existing "don't guess" precedent.
|
|
214
|
+
{ nodeType: 'const_spec', kind: 'constant', nameField: 'name', scopeRestricted: true },
|
|
215
|
+
{ nodeType: 'var_spec', kind: 'variable', nameField: 'name', scopeRestricted: true },
|
|
216
|
+
// A struct field (`field_declaration`) and an interface method signature (`method_spec`) both sit
|
|
217
|
+
// inside a `type_spec`'s `struct_type`/`interface_type` body — `type_spec` itself (kind
|
|
218
|
+
// `type_alias`) is not scope-restricted (a Go type can be declared inside a function, like `type
|
|
219
|
+
// Local struct {...}` in `func f() {...}`), so these must not be either: a scope-restricted rule
|
|
220
|
+
// here could never fire, since the enclosing `type_spec` always pushes `'other'` for its children
|
|
221
|
+
// regardless of where it itself sits. An embedded (anonymous) field — `Nested` with no separate
|
|
222
|
+
// name — has no child bound to the `name` field at all, so `matchDefinition`'s name-arity check
|
|
223
|
+
// already excludes it without a dedicated rule; verified against a real parse, not guessed.
|
|
224
|
+
{ nodeType: 'field_declaration', kind: 'field', nameField: 'name' },
|
|
225
|
+
{ nodeType: 'method_spec', kind: 'method', nameField: 'name' },
|
|
226
|
+
],
|
|
227
|
+
callTypes: ['call_expression'],
|
|
228
|
+
callFunctionField: 'function',
|
|
229
|
+
importTypes: ['import_declaration'],
|
|
230
|
+
// A closure literal (`f := func() { ... }`) is never itself named, so it never matches a
|
|
231
|
+
// `DefinitionRule` — but a `var`/`const` inside its body is still function-local.
|
|
232
|
+
bareFunctionScopeTypes: ['func_literal'],
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
language: 'java',
|
|
236
|
+
extensions: ['.java'],
|
|
237
|
+
wasmFile: 'tree-sitter-java.wasm',
|
|
238
|
+
definitions: [
|
|
239
|
+
{ nodeType: 'class_declaration', kind: 'class', nameField: 'name' },
|
|
240
|
+
// A record has no dedicated seam kind — `class` is the closest existing fit for a concrete type
|
|
241
|
+
// declaration with a body, and (like a class) it can `implements` an interface; see
|
|
242
|
+
// `javaHeritage` in extract.ts.
|
|
243
|
+
{ nodeType: 'record_declaration', kind: 'class', nameField: 'name' },
|
|
244
|
+
{ nodeType: 'interface_declaration', kind: 'interface', nameField: 'name' },
|
|
245
|
+
{ nodeType: 'enum_declaration', kind: 'enum', nameField: 'name' },
|
|
246
|
+
// Unlike TypeScript's bare `property_identifier` enum member (see TYPESCRIPT_DEFINITIONS),
|
|
247
|
+
// Java's `enum_constant` already carries its own `name` field — verified against a real parse.
|
|
248
|
+
{ nodeType: 'enum_constant', kind: 'enum_member', nameField: 'name' },
|
|
249
|
+
{ nodeType: 'method_declaration', kind: 'method', nameField: 'name' },
|
|
250
|
+
// No dedicated `constructor` seam kind exists; a constructor is a method in every way this
|
|
251
|
+
// package's graph cares about.
|
|
252
|
+
{ nodeType: 'constructor_declaration', kind: 'method', nameField: 'name' },
|
|
253
|
+
// A field (`field_declaration`) and a local variable (`local_variable_declaration`) both wrap one
|
|
254
|
+
// or more `variable_declarator` children directly, each carrying its own `name` field — unlike
|
|
255
|
+
// Go's `const_spec`/`var_spec`, a multi-name Java declaration (`int x = 1, y = 2;`) is not one
|
|
256
|
+
// ambiguous shared name field but several independent `variable_declarator` nodes, each visited
|
|
257
|
+
// (and named) on its own, so no `nameNodeTypes`-style rejection is needed here.
|
|
258
|
+
{ nodeType: 'variable_declarator', kind: 'field', nameField: 'name', parentType: 'field_declaration', scopeRestricted: true },
|
|
259
|
+
{ nodeType: 'variable_declarator', kind: 'variable', nameField: 'name', parentType: 'local_variable_declaration', scopeRestricted: true },
|
|
260
|
+
],
|
|
261
|
+
callTypes: ['method_invocation'],
|
|
262
|
+
// Unlike the ECMAScript/Go/Python call node's `function` field (an expression this package's
|
|
263
|
+
// `calleeName` unwraps down to a simple name), Java's `method_invocation` already exposes the
|
|
264
|
+
// callee's simple name directly through its own `name` field — the receiver, if any, is a sibling
|
|
265
|
+
// `object` field extract.ts checks separately to tell a member call from a bare one. Verified
|
|
266
|
+
// against a real parse, not guessed.
|
|
267
|
+
callFunctionField: 'name',
|
|
268
|
+
importTypes: ['import_declaration'],
|
|
269
|
+
// A lambda body (`() -> { int x = 1; }`) is never itself named, so it never matches a
|
|
270
|
+
// `DefinitionRule` — but a local variable inside its block body is still function-local, the same
|
|
271
|
+
// reasoning `ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES` applies to an arrow function.
|
|
272
|
+
bareFunctionScopeTypes: ['lambda_expression'],
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
language: 'c',
|
|
276
|
+
extensions: ['.c', '.h'],
|
|
277
|
+
wasmFile: 'tree-sitter-c.wasm',
|
|
278
|
+
definitions: [
|
|
279
|
+
// No dedicated `union` seam kind exists; `struct` is the closest existing fit for a
|
|
280
|
+
// concrete-layout aggregate type, matching Java's record→`class` precedent.
|
|
281
|
+
{ nodeType: 'struct_specifier', kind: 'struct', nameField: 'name' },
|
|
282
|
+
{ nodeType: 'union_specifier', kind: 'struct', nameField: 'name' },
|
|
283
|
+
{ nodeType: 'enum_specifier', kind: 'enum', nameField: 'name' },
|
|
284
|
+
// `enumerator` carries its own `name` field directly, unlike TypeScript's bare enum member —
|
|
285
|
+
// verified against a real parse, not guessed.
|
|
286
|
+
{ nodeType: 'enumerator', kind: 'enum_member', nameField: 'name' },
|
|
287
|
+
// A typedef's `declarator` names the alias directly (`typedef struct Point PointT;`'s
|
|
288
|
+
// `declarator` is the plain `type_identifier` "PointT", no wrapper) — unlike a function or
|
|
289
|
+
// variable declarator, verified against a real parse, not guessed.
|
|
290
|
+
{ nodeType: 'type_definition', kind: 'type_alias', nameField: 'declarator' },
|
|
291
|
+
// `function_definition`'s name sits behind a `pointer_declarator`/`function_declarator` chain of
|
|
292
|
+
// arbitrary depth — see `DECLARATOR_NAME_FIELD`.
|
|
293
|
+
{ nodeType: 'function_definition', kind: 'function', nameField: DECLARATOR_NAME_FIELD },
|
|
294
|
+
// A struct/union member (`field_declaration`) — same declarator-nesting rule as a top-level
|
|
295
|
+
// variable, minus the multi-declarator ambiguity Go's `field_declaration` has none of either.
|
|
296
|
+
{ nodeType: 'field_declaration', kind: 'field', nameField: DECLARATOR_NAME_FIELD },
|
|
297
|
+
// A top-level or function-local `int g = 1;`/`int x;` — both parse as `declaration`, distinguished
|
|
298
|
+
// only by where the walk currently sits, the same convention JS/Python/Go's local-variable rules
|
|
299
|
+
// already follow.
|
|
300
|
+
{ nodeType: 'declaration', kind: 'variable', nameField: DECLARATOR_NAME_FIELD, scopeRestricted: true },
|
|
301
|
+
],
|
|
302
|
+
callTypes: ['call_expression'],
|
|
303
|
+
callFunctionField: 'function',
|
|
304
|
+
importTypes: ['preproc_include'],
|
|
305
|
+
bareFunctionScopeTypes: [],
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
language: 'cpp',
|
|
309
|
+
extensions: ['.cpp', '.cc', '.cxx', '.hpp', '.hh', '.hxx'],
|
|
310
|
+
wasmFile: 'tree-sitter-cpp.wasm',
|
|
311
|
+
definitions: [
|
|
312
|
+
{ nodeType: 'class_specifier', kind: 'class', nameField: 'name' },
|
|
313
|
+
{ nodeType: 'struct_specifier', kind: 'struct', nameField: 'name' },
|
|
314
|
+
{ nodeType: 'union_specifier', kind: 'struct', nameField: 'name' },
|
|
315
|
+
{ nodeType: 'enum_specifier', kind: 'enum', nameField: 'name' },
|
|
316
|
+
{ nodeType: 'enumerator', kind: 'enum_member', nameField: 'name' },
|
|
317
|
+
{ nodeType: 'type_definition', kind: 'type_alias', nameField: 'declarator' },
|
|
318
|
+
// A method (including a constructor/destructor) is a `function_definition` directly inside a
|
|
319
|
+
// class/struct's `field_declaration_list` — the same node type a free function uses, so this rule
|
|
320
|
+
// (tried first) must claim that shape before the unrestricted `function` rule below falls through
|
|
321
|
+
// to everything else. Verified against a real parse, not guessed.
|
|
322
|
+
{ nodeType: 'function_definition', kind: 'method', nameField: DECLARATOR_NAME_FIELD, parentType: 'field_declaration_list' },
|
|
323
|
+
{ nodeType: 'function_definition', kind: 'function', nameField: DECLARATOR_NAME_FIELD },
|
|
324
|
+
// `field_declaration` doubles as a pure-virtual method signature (`virtual void v() = 0;` is still
|
|
325
|
+
// a `field_declaration`, just with a `function_declarator` for its `declarator`) — the same
|
|
326
|
+
// function-valued guard `ECMASCRIPT_DEFINITIONS`'s `variable_declarator` rule uses, tried first.
|
|
327
|
+
{ nodeType: 'field_declaration', kind: 'method', nameField: DECLARATOR_NAME_FIELD, value: { field: 'declarator', types: ['function_declarator'] } },
|
|
328
|
+
{ nodeType: 'field_declaration', kind: 'field', nameField: DECLARATOR_NAME_FIELD },
|
|
329
|
+
{ nodeType: 'declaration', kind: 'variable', nameField: DECLARATOR_NAME_FIELD, scopeRestricted: true },
|
|
330
|
+
],
|
|
331
|
+
callTypes: ['call_expression'],
|
|
332
|
+
callFunctionField: 'function',
|
|
333
|
+
importTypes: ['preproc_include'],
|
|
334
|
+
// A lambda body (`[](){ int x = 1; }`) is never itself named, so it never matches a `DefinitionRule`
|
|
335
|
+
// — but a local variable inside its block body is still function-local.
|
|
336
|
+
bareFunctionScopeTypes: ['lambda_expression'],
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
language: 'csharp',
|
|
340
|
+
extensions: ['.cs'],
|
|
341
|
+
wasmFile: 'tree-sitter-c_sharp.wasm',
|
|
342
|
+
definitions: [
|
|
343
|
+
{ nodeType: 'class_declaration', kind: 'class', nameField: 'name' },
|
|
344
|
+
{ nodeType: 'struct_declaration', kind: 'struct', nameField: 'name' },
|
|
345
|
+
// No dedicated seam kind exists for a record; `class` is the closest existing fit, matching Java's
|
|
346
|
+
// record→`class` precedent.
|
|
347
|
+
{ nodeType: 'record_declaration', kind: 'class', nameField: 'name' },
|
|
348
|
+
{ nodeType: 'interface_declaration', kind: 'interface', nameField: 'name' },
|
|
349
|
+
{ nodeType: 'enum_declaration', kind: 'enum', nameField: 'name' },
|
|
350
|
+
{ nodeType: 'enum_member_declaration', kind: 'enum_member', nameField: 'name' },
|
|
351
|
+
{ nodeType: 'method_declaration', kind: 'method', nameField: 'name' },
|
|
352
|
+
// No dedicated `constructor` seam kind exists; both are a method in every way this package's graph
|
|
353
|
+
// cares about, matching Java's constructor_declaration→`method` precedent.
|
|
354
|
+
{ nodeType: 'constructor_declaration', kind: 'method', nameField: 'name' },
|
|
355
|
+
{ nodeType: 'destructor_declaration', kind: 'method', nameField: 'name' },
|
|
356
|
+
{ nodeType: 'property_declaration', kind: 'property', nameField: 'name' },
|
|
357
|
+
// A field (`variable_declarator` two levels under a `field_declaration`) and a local variable
|
|
358
|
+
// (`variable_declarator` two levels under a `local_declaration_statement`) parse identically one
|
|
359
|
+
// level up (`variable_declaration`) — only the grandparent tells them apart. See
|
|
360
|
+
// `DefinitionRule.grandparentType`. Verified against a real parse, not guessed.
|
|
361
|
+
{ nodeType: 'variable_declarator', kind: 'field', nameField: FIRST_CHILD_NAME_FIELD, grandparentType: 'field_declaration', scopeRestricted: true },
|
|
362
|
+
{ nodeType: 'variable_declarator', kind: 'variable', nameField: FIRST_CHILD_NAME_FIELD, grandparentType: 'local_declaration_statement', scopeRestricted: true },
|
|
363
|
+
],
|
|
364
|
+
callTypes: ['invocation_expression'],
|
|
365
|
+
callFunctionField: 'function',
|
|
366
|
+
importTypes: ['using_directive'],
|
|
367
|
+
// A lambda body (`() => { int x = 1; }`) is never itself named, so it never matches a
|
|
368
|
+
// `DefinitionRule` — but a local variable inside its block body is still function-local.
|
|
369
|
+
bareFunctionScopeTypes: ['lambda_expression', 'anonymous_method_expression'],
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
language: 'php',
|
|
373
|
+
extensions: ['.php'],
|
|
374
|
+
wasmFile: 'tree-sitter-php.wasm',
|
|
375
|
+
definitions: [
|
|
376
|
+
{ nodeType: 'function_definition', kind: 'function', nameField: 'name' },
|
|
377
|
+
{ nodeType: 'method_declaration', kind: 'method', nameField: 'name' },
|
|
378
|
+
{ nodeType: 'class_declaration', kind: 'class', nameField: 'name' },
|
|
379
|
+
{ nodeType: 'interface_declaration', kind: 'interface', nameField: 'name' },
|
|
380
|
+
{ nodeType: 'trait_declaration', kind: 'trait', nameField: 'name' },
|
|
381
|
+
{ nodeType: 'enum_declaration', kind: 'enum', nameField: 'name' },
|
|
382
|
+
// `enum_case` carries its own `name` field directly, unlike TypeScript's bare enum member —
|
|
383
|
+
// verified against a real parse, not guessed.
|
|
384
|
+
{ nodeType: 'enum_case', kind: 'enum_member', nameField: 'name' },
|
|
385
|
+
// `const_element` (`const VERSION = "1"`) and `property_element` (`public string $name;`) neither
|
|
386
|
+
// bind their name to a field of their own — see `PHP_ELEMENT_NAME_FIELD`. Unlike a JS/Go/Python
|
|
387
|
+
// local binding, neither is `scopeRestricted`: a PHP `const`/property only legitimately appears at
|
|
388
|
+
// namespace scope or directly inside a class/interface/trait/enum body, and every non-class body
|
|
389
|
+
// here (`interface`/`trait`/`enum`) pushes `'other'` scope, not `'class'` — the same "must not be
|
|
390
|
+
// scopeRestricted" reasoning Go's struct-field rule documents, since a restricted rule could never
|
|
391
|
+
// fire inside one. The one shape this misses is already invalid PHP the grammar merely tolerates
|
|
392
|
+
// (a `const`/property statement directly inside a function body), so capturing it there costs
|
|
393
|
+
// nothing in practice.
|
|
394
|
+
{ nodeType: 'const_element', kind: 'constant', nameField: PHP_ELEMENT_NAME_FIELD },
|
|
395
|
+
{ nodeType: 'property_element', kind: 'field', nameField: PHP_ELEMENT_NAME_FIELD },
|
|
396
|
+
// `$fn = function () {}` / `$fn = fn($a) => $a` — the same function-valued-binding rule
|
|
397
|
+
// ECMASCRIPT_DEFINITIONS's `variable_declarator` follows, captured at any depth like a named
|
|
398
|
+
// function declaration (not `scopeRestricted`) since a named closure is as much a workspace symbol
|
|
399
|
+
// as one. Unlike ECMASCRIPT_DEFINITIONS, no bare-variable fallback rule follows it: PHP draws no
|
|
400
|
+
// `const`/`let`-style distinction for `$x = 5;` — it is an unremarkable, ubiquitous assignment, and
|
|
401
|
+
// capturing every one would flood `resolve.ts`'s cross-file name index with noise no caller wants.
|
|
402
|
+
{
|
|
403
|
+
nodeType: 'assignment_expression',
|
|
404
|
+
kind: 'function',
|
|
405
|
+
nameField: PHP_ELEMENT_NAME_FIELD,
|
|
406
|
+
value: { field: 'right', types: ['anonymous_function_creation_expression', 'arrow_function'] },
|
|
407
|
+
},
|
|
408
|
+
],
|
|
409
|
+
callTypes: ['function_call_expression', 'member_call_expression', 'scoped_call_expression'],
|
|
410
|
+
callFunctionField: 'function',
|
|
411
|
+
// `member_call_expression` ($obj->method()) and `scoped_call_expression` (Class::method()) both name
|
|
412
|
+
// their callee through a `name` field, not `function` — verified against a real parse, not guessed.
|
|
413
|
+
callFunctionFieldByType: { member_call_expression: 'name', scoped_call_expression: 'name' },
|
|
414
|
+
importTypes: ['namespace_use_declaration'],
|
|
415
|
+
// A closure's block body (`function () { ... }`) can contain a statement, so it must flip scope like
|
|
416
|
+
// JS's `function_expression`; an arrow function's body is always a single expression (like Python's
|
|
417
|
+
// `lambda`, never a block), so it is omitted, matching that same precedent.
|
|
418
|
+
bareFunctionScopeTypes: ['anonymous_function_creation_expression'],
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
language: 'rust',
|
|
422
|
+
extensions: ['.rs'],
|
|
423
|
+
wasmFile: 'tree-sitter-rust.wasm',
|
|
424
|
+
definitions: [
|
|
425
|
+
{ nodeType: 'struct_item', kind: 'struct', nameField: 'name' },
|
|
426
|
+
// No dedicated `union` seam kind exists; `struct` is the closest existing fit, matching C/C++'s
|
|
427
|
+
// same union→`struct` precedent — a Rust `union_item` shares `struct_item`'s exact body shape
|
|
428
|
+
// (`field_declaration_list`), verified against a real parse.
|
|
429
|
+
{ nodeType: 'union_item', kind: 'struct', nameField: 'name' },
|
|
430
|
+
{ nodeType: 'enum_item', kind: 'enum', nameField: 'name' },
|
|
431
|
+
// `enum_variant` carries its own `name` field directly, unlike TypeScript's bare enum member —
|
|
432
|
+
// verified against a real parse, not guessed.
|
|
433
|
+
{ nodeType: 'enum_variant', kind: 'enum_member', nameField: 'name' },
|
|
434
|
+
{ nodeType: 'trait_item', kind: 'trait', nameField: 'name' },
|
|
435
|
+
{ nodeType: 'mod_item', kind: 'namespace', nameField: 'name' },
|
|
436
|
+
{ nodeType: 'type_item', kind: 'type_alias', nameField: 'name' },
|
|
437
|
+
// A method — including a trait's default-body method — is a `function_item` directly inside an
|
|
438
|
+
// `impl_item`'s or `trait_item`'s `declaration_list`, the same node type a free function uses;
|
|
439
|
+
// mod's `declaration_list` shares that exact node type too, so only the grandparent (not the
|
|
440
|
+
// immediate parent) tells a method apart from a module-level function. Tried first, before the
|
|
441
|
+
// unrestricted `function` rule below falls through to everything else — the same precedent C++'s
|
|
442
|
+
// method rule follows for its own shared `function_definition` node type. Verified against a real
|
|
443
|
+
// parse, not guessed.
|
|
444
|
+
{ nodeType: 'function_item', kind: 'method', nameField: 'name', grandparentType: 'impl_item' },
|
|
445
|
+
{ nodeType: 'function_item', kind: 'method', nameField: 'name', grandparentType: 'trait_item' },
|
|
446
|
+
{ nodeType: 'function_item', kind: 'function', nameField: 'name' },
|
|
447
|
+
// A trait method declared with no body (`fn area(&self) -> f64;`) parses as a distinct node type
|
|
448
|
+
// from one with a body, and only ever appears directly inside a trait's `declaration_list` — an
|
|
449
|
+
// `impl_item` must supply a body for every method it defines. Verified against a real parse.
|
|
450
|
+
{ nodeType: 'function_signature_item', kind: 'method', nameField: 'name', grandparentType: 'trait_item' },
|
|
451
|
+
// A struct/union member — verified against a real parse, not guessed; unlike Go's/C++'s field
|
|
452
|
+
// rule this needs no declarator-unwrapping helper, since `field_declaration` binds its name
|
|
453
|
+
// directly to a `name` field.
|
|
454
|
+
{ nodeType: 'field_declaration', kind: 'field', nameField: 'name' },
|
|
455
|
+
// A top-level, associated (inside `impl`/`trait`), or function-local `const`/`static` all parse
|
|
456
|
+
// identically — `scopeRestricted` excludes only the function-local case, the same convention
|
|
457
|
+
// Go's `const_spec`/`var_spec` already follow. No dedicated seam kind distinguishes a `static`
|
|
458
|
+
// from a `const`; `static` maps to `variable` (it names a single mutable-or-shared storage
|
|
459
|
+
// location, unlike a `const`'s compile-time-inlined value).
|
|
460
|
+
{ nodeType: 'const_item', kind: 'constant', nameField: 'name', scopeRestricted: true },
|
|
461
|
+
{ nodeType: 'static_item', kind: 'variable', nameField: 'name', scopeRestricted: true },
|
|
462
|
+
],
|
|
463
|
+
callTypes: ['call_expression'],
|
|
464
|
+
callFunctionField: 'function',
|
|
465
|
+
importTypes: ['use_declaration'],
|
|
466
|
+
// A closure's body can be a block containing a statement (`|x| { let y = x; y }`) — unlike an
|
|
467
|
+
// ECMAScript arrow function, a bare-expression closure body (`|x| x`) is indistinguishable by node
|
|
468
|
+
// type alone (both are plain `closure_expression`), so this is not split into two cases; a
|
|
469
|
+
// function-local binding inside a bare-expression body is impossible syntactically anyway (no
|
|
470
|
+
// statement can appear there), so flipping scope unconditionally costs nothing. Verified against a
|
|
471
|
+
// real parse, not guessed.
|
|
472
|
+
bareFunctionScopeTypes: ['closure_expression'],
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
language: 'ruby',
|
|
476
|
+
extensions: ['.rb'],
|
|
477
|
+
wasmFile: 'tree-sitter-ruby.wasm',
|
|
478
|
+
definitions: [
|
|
479
|
+
// Every `def` — top-level, module-level, or inside a class body — defines a method (a top-level
|
|
480
|
+
// `def` becomes a private instance method of `Object`), so this package uses kind `method`
|
|
481
|
+
// uniformly rather than split a `function`/`method` distinction the language itself does not
|
|
482
|
+
// draw; `singleton_method` (`def self.foo`/`def Klass.foo`) is a class/singleton method, same
|
|
483
|
+
// kind. Verified against a real parse, not guessed.
|
|
484
|
+
{ nodeType: 'method', kind: 'method', nameField: 'name' },
|
|
485
|
+
{ nodeType: 'singleton_method', kind: 'method', nameField: 'name' },
|
|
486
|
+
{ nodeType: 'class', kind: 'class', nameField: 'name' },
|
|
487
|
+
// No dedicated `namespace` handling exists elsewhere but Rust's `mod_item`; a Ruby `module` is the
|
|
488
|
+
// closest existing fit — both are a purely lexical/organizational container with no instance
|
|
489
|
+
// semantics of their own, matching that same precedent.
|
|
490
|
+
{ nodeType: 'module', kind: 'namespace', nameField: 'name' },
|
|
491
|
+
// `my_lambda = ->(x) { x + 1 }` — the only anonymous-function *literal* shape this grammar has;
|
|
492
|
+
// `proc { ... }`/`Proc.new { ... }` parse as an ordinary `call` with a block argument, structurally
|
|
493
|
+
// indistinguishable from any other block-taking method call, so they are not treated as a
|
|
494
|
+
// function-valued binding — the same "don't guess" precedent this file already follows elsewhere.
|
|
495
|
+
// Tried first, before the unrestricted `variable` rule below falls through to everything else —
|
|
496
|
+
// the same precedent ECMASCRIPT_DEFINITIONS's `variable_declarator` rule follows.
|
|
497
|
+
{ nodeType: 'assignment', kind: 'function', nameField: 'left', nameNodeTypes: ['identifier'], value: { field: 'right', types: ['lambda'] } },
|
|
498
|
+
// `CONST = 1` — a bare uppercase-leading `constant` node is Ruby's own real distinction (the
|
|
499
|
+
// grammar itself lexes an uppercase-leading bare word as a distinct `constant` token, not merely an
|
|
500
|
+
// `identifier`), so no `scopeRestricted` is needed: a dynamic constant assignment inside a method
|
|
501
|
+
// body is a Ruby `SyntaxError`, the parser never produces this shape nested in one. Verified
|
|
502
|
+
// against a real parse, not guessed.
|
|
503
|
+
{ nodeType: 'assignment', kind: 'constant', nameField: 'left', nameNodeTypes: ['constant'] },
|
|
504
|
+
// A bare lowercase local variable assignment — `nameNodeTypes` rejects Ruby's other `assignment`
|
|
505
|
+
// left-hand shapes (`left_assignment_list` for `a, b = 1, 2`, a `call` for `self.x = 1`, an
|
|
506
|
+
// `element_reference` for `arr[0] = 1`), none of which name a single declared identifier, verified
|
|
507
|
+
// against a real parse, not guessed. An instance variable (`@name = ...`) is deliberately not
|
|
508
|
+
// captured at all — unlike every other language this package extracts a `field` kind from, Ruby has
|
|
509
|
+
// no declarative field syntax; an instance variable is conventionally *assigned* inside `initialize`
|
|
510
|
+
// (method-body scope), and this file's scope model has no way to mark that assignment a class-level
|
|
511
|
+
// symbol without also flooding `resolve.ts`'s name index with every ordinary method-local variable —
|
|
512
|
+
// the same "don't guess" precedent this file already follows for a shape it cannot cleanly resolve.
|
|
513
|
+
{ nodeType: 'assignment', kind: 'variable', nameField: 'left', nameNodeTypes: ['identifier'], scopeRestricted: true },
|
|
514
|
+
],
|
|
515
|
+
// A bare, receiver-less, paren-less, arg-less method call (`other_call`) parses as a plain
|
|
516
|
+
// `identifier` — syntactically identical to a local-variable read — so it is not (and cannot safely
|
|
517
|
+
// be) captured as a call site; only a `call` node (a receiver, an argument list, or a block present)
|
|
518
|
+
// is. Verified against a real parse, not guessed.
|
|
519
|
+
callTypes: ['call'],
|
|
520
|
+
callFunctionField: 'method',
|
|
521
|
+
// Ruby's grammar has no dedicated import-statement node type at all — `require '...'` and
|
|
522
|
+
// `require_relative '...'` are ordinary method calls (see `rubyRequireImport` in extract.ts, wired
|
|
523
|
+
// through a dedicated dispatch branch the same way `commonJsRequireImport` is for CommonJS, rather
|
|
524
|
+
// than through this table, which has no node type to name here).
|
|
525
|
+
importTypes: [],
|
|
526
|
+
// A `{ ... }`/`do ... end` block attached to a call, and a `->() { ... }` lambda's own block body
|
|
527
|
+
// (itself a `block` node), can all contain a statement — a `var`/`local` inside one is still
|
|
528
|
+
// block-local, not a workspace symbol, the same reasoning `ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES`
|
|
529
|
+
// applies to a callback. Verified against a real parse, not guessed.
|
|
530
|
+
bareFunctionScopeTypes: ['block', 'do_block', 'lambda'],
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
language: 'zig',
|
|
534
|
+
extensions: ['.zig'],
|
|
535
|
+
wasmFile: 'tree-sitter-zig.wasm',
|
|
536
|
+
definitions: [
|
|
537
|
+
// A method is a `function_declaration` directly inside a struct/enum/union's own body — the same
|
|
538
|
+
// node type a free function uses (Zig draws no separate node type the way most languages with a
|
|
539
|
+
// dedicated method/function split do), so each container kind gets its own `parentType`-guarded
|
|
540
|
+
// rule, tried before the unrestricted `function` rule below falls through to everything else — the
|
|
541
|
+
// same precedent C++'s method rule follows for its own shared `function_definition` node type.
|
|
542
|
+
// Verified against a real parse, not guessed.
|
|
543
|
+
{ nodeType: 'function_declaration', kind: 'method', nameField: 'name', parentType: 'struct_declaration' },
|
|
544
|
+
{ nodeType: 'function_declaration', kind: 'method', nameField: 'name', parentType: 'enum_declaration' },
|
|
545
|
+
{ nodeType: 'function_declaration', kind: 'method', nameField: 'name', parentType: 'union_declaration' },
|
|
546
|
+
{ nodeType: 'function_declaration', kind: 'function', nameField: 'name' },
|
|
547
|
+
// An enum member and a struct/union member share the very same `container_field` node type —
|
|
548
|
+
// unlike every other language's dedicated bare-enum-member shape, Zig draws no grammar-level
|
|
549
|
+
// distinction at all, so this is the one `parentType` this file needs to split them back apart;
|
|
550
|
+
// tried first, before the unrestricted `field` rule below falls through to a struct/union member.
|
|
551
|
+
// Verified against a real parse, not guessed.
|
|
552
|
+
{ nodeType: 'container_field', kind: 'enum_member', nameField: 'name', parentType: 'enum_declaration' },
|
|
553
|
+
{ nodeType: 'container_field', kind: 'field', nameField: 'name' },
|
|
554
|
+
// Zig has no dedicated struct/enum/union *statement* the way C/C++/Rust/Java do — a named
|
|
555
|
+
// container type is always a plain `const`/`var` declaration whose value happens to be a
|
|
556
|
+
// `struct_declaration`/`enum_declaration`/`union_declaration` literal (`const Point = struct {
|
|
557
|
+
// ... };`), and this same node type is also how Zig spells an ordinary top-level constant, a
|
|
558
|
+
// mutable global, *and* a std-library import (`const std = @import("std");`) — verified against a
|
|
559
|
+
// real parse. `variable_declaration` binds neither its name nor its value to a field at all (both
|
|
560
|
+
// are purely positional children, unlike every other grammar this package extracts a name from),
|
|
561
|
+
// so this uses `FIRST_CHILD_NAME_FIELD` for the name; the reported `kind` (`struct`/`enum`/
|
|
562
|
+
// `constant`/`variable`) is not fixed by this one static rule at all — `DefinitionRule.kind` has no
|
|
563
|
+
// way to vary by a value's shape the way this needs, so `extractFile` computes it per node via
|
|
564
|
+
// `zigDeclarationKind` instead (see there), and an `@import(...)` value is additionally recorded as
|
|
565
|
+
// an import binding via `zigImportBinding`, the same "also captured as an ordinary variable"
|
|
566
|
+
// precedent CommonJS's `require()` already sets. `scopeRestricted` applies uniformly to every kind
|
|
567
|
+
// this rule can produce, including a locally-declared struct/enum/union — unlike a Rust `fn` nested
|
|
568
|
+
// in another `fn` (still captured at any depth, since Rust's grammar gives a nested function its
|
|
569
|
+
// own distinct, unambiguous node type), Zig's local type declaration shares its node type with an
|
|
570
|
+
// ordinary local variable with no structural way to split the two without inspecting the value
|
|
571
|
+
// first, and this file's `scopeRestricted` gate runs before that inspection — a local type
|
|
572
|
+
// declaration inside a function is rare enough in idiomatic Zig that this file accepts missing it,
|
|
573
|
+
// the same "prefer a clean uniform rule over a fiddly special case" precedent already guiding this
|
|
574
|
+
// package's simpler choices elsewhere.
|
|
575
|
+
{ nodeType: 'variable_declaration', kind: 'variable', nameField: FIRST_CHILD_NAME_FIELD, scopeRestricted: true },
|
|
576
|
+
],
|
|
577
|
+
callTypes: ['call_expression'],
|
|
578
|
+
callFunctionField: 'function',
|
|
579
|
+
// No dedicated import-statement node type exists — `@import(...)` is an ordinary builtin-function
|
|
580
|
+
// call bound through the same `variable_declaration` shape the type/constant/variable rule above
|
|
581
|
+
// already matches (see `zigImportBinding` in extract.ts), not a distinct node type this table could
|
|
582
|
+
// name here.
|
|
583
|
+
importTypes: [],
|
|
584
|
+
// `test "name" { ... }` and `comptime { ... }` are Zig's own top-level block constructs — neither is
|
|
585
|
+
// itself captured as a definition (matching this file's existing "block, not a symbol" treatment of
|
|
586
|
+
// an anonymous callback), but a `const`/`var` directly inside either is still block-local, not a
|
|
587
|
+
// workspace symbol, so both push `'other'` scope for their body the same way a callback's function
|
|
588
|
+
// value does elsewhere in this file. Verified against a real parse, not guessed.
|
|
589
|
+
bareFunctionScopeTypes: ['test_declaration', 'comptime_declaration'],
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
language: 'kotlin',
|
|
593
|
+
extensions: ['.kt', '.kts'],
|
|
594
|
+
wasmFile: 'tree-sitter-kotlin.wasm',
|
|
595
|
+
definitions: [
|
|
596
|
+
// Kotlin's grammar gives `class`/`interface`/`enum class` the very same `class_declaration` node
|
|
597
|
+
// type, distinguished only by a bare `interface`/`enum` keyword among its own children (`interface
|
|
598
|
+
// Shape {}` carries a bare `interface` token, `enum class Color {}` carries both a bare `enum` and
|
|
599
|
+
// a bare `class` token, a plain `class Foo {}` carries only `class`) — no rule here can vary `kind`
|
|
600
|
+
// by a keyword the way this needs, so `extractFile` computes it via `kotlinClassKind` instead (see
|
|
601
|
+
// there), the same "kind computed per node, not fixed per rule" precedent Zig's `variable_declaration`
|
|
602
|
+
// entry already establishes above. Verified against a real parse, not guessed.
|
|
603
|
+
{ nodeType: 'class_declaration', kind: 'class', nameField: KOTLIN_NAME_FIELD },
|
|
604
|
+
// A method is a `function_declaration` directly inside a `class_body` — the same node type a
|
|
605
|
+
// top-level function uses (including one inside a `companion_object`'s own nested `class_body`,
|
|
606
|
+
// still reported as a method of the enclosing type) — tried first, before the unrestricted
|
|
607
|
+
// `function` rule below falls through to everything else. Verified against a real parse.
|
|
608
|
+
{ nodeType: 'function_declaration', kind: 'method', nameField: KOTLIN_NAME_FIELD, parentType: 'class_body' },
|
|
609
|
+
{ nodeType: 'function_declaration', kind: 'function', nameField: KOTLIN_NAME_FIELD },
|
|
610
|
+
// An enum constant — verified against a real parse, not guessed; can only ever appear directly
|
|
611
|
+
// inside an `enum_class_body`, so — like Go's/Rust's/Zig's own field rules — no
|
|
612
|
+
// `scopeRestricted`/`parentType` guard is needed: the node type itself is unambiguous.
|
|
613
|
+
{ nodeType: 'enum_entry', kind: 'enum_member', nameField: KOTLIN_NAME_FIELD },
|
|
614
|
+
// Deliberately no `field`/`property`/`variable`/`constant` kind at all: a `property_declaration`
|
|
615
|
+
// (`val`/`var`, at class-member, top-level, or local scope) binds its declared name two levels
|
|
616
|
+
// down, inside its own nested `variable_declaration` child, itself positioned after an optional
|
|
617
|
+
// leading `modifiers` node the same way a captured declaration is — extracting it cleanly would
|
|
618
|
+
// need its own multi-level, fully positional (there being no fields at all) navigation on top of
|
|
619
|
+
// everything `KOTLIN_NAME_FIELD` already handles, and this file's "don't guess/don't overreach"
|
|
620
|
+
// precedent (already applied to Lua's/Ruby's own locally-bound values) draws the line here instead.
|
|
621
|
+
],
|
|
622
|
+
// `call_expression`'s callee is never bound to a field either — see `kotlinCallee` in extract.ts,
|
|
623
|
+
// consulted directly by a dedicated dispatch branch in `extractFile` rather than through
|
|
624
|
+
// `callFunctionField`, which (like every other field name) can never resolve anything for this
|
|
625
|
+
// grammar. `function` is kept only as a placeholder so this table entry still type-checks as a
|
|
626
|
+
// normal `LanguageSpec`; it is never actually read for Kotlin.
|
|
627
|
+
callTypes: ['call_expression'],
|
|
628
|
+
callFunctionField: 'function',
|
|
629
|
+
importTypes: ['import_header'],
|
|
630
|
+
// No anonymous-function-literal shape needs special-casing: a lambda's body is a `{ ... }` block
|
|
631
|
+
// that can contain a statement, exactly like every captured `function_declaration`'s own body, but
|
|
632
|
+
// this file already declines to capture any local `val`/`var` at all for Kotlin (see above), so
|
|
633
|
+
// there is currently no scope-restricted rule this could matter to.
|
|
634
|
+
bareFunctionScopeTypes: [],
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
language: 'swift',
|
|
638
|
+
extensions: ['.swift'],
|
|
639
|
+
wasmFile: 'tree-sitter-swift.wasm',
|
|
640
|
+
definitions: [
|
|
641
|
+
// `struct`/`class`/`enum` all share this one node type, distinguished by a `declaration_kind`
|
|
642
|
+
// field whose value node's own type is directly `struct`/`class`/`enum` (an unusual but verified
|
|
643
|
+
// shape — no other grammar this package extracts from promotes a bare keyword to its own field
|
|
644
|
+
// value this way) — no rule can vary `kind` by that field's value, so `extractFile` computes it
|
|
645
|
+
// via `swiftDeclarationKind` instead, the same "kind computed per node" precedent Zig's
|
|
646
|
+
// `variable_declaration`/Kotlin's `class_declaration` entries already establish above. A
|
|
647
|
+
// `protocol` is Swift's own separate `protocol_declaration` node type instead — verified against a
|
|
648
|
+
// real parse, not guessed.
|
|
649
|
+
{ nodeType: 'class_declaration', kind: 'class', nameField: 'name' },
|
|
650
|
+
{ nodeType: 'protocol_declaration', kind: 'interface', nameField: 'name' },
|
|
651
|
+
// A method is a `function_declaration` directly inside a `class_body` — the same node type a
|
|
652
|
+
// top-level function uses — tried first, before the unrestricted `function` rule below falls
|
|
653
|
+
// through to everything else. A protocol's own method *signature* (`func area() -> Double`, no
|
|
654
|
+
// body) is a distinct node type, `protocol_function_declaration`, always directly inside a
|
|
655
|
+
// `protocol_body` — unambiguous, so no `parentType` guard is needed for it. Both use
|
|
656
|
+
// `SWIFT_FUNCTION_NAME_FIELD`, not a plain `'name'` field, because either one with an explicit
|
|
657
|
+
// return type binds two nodes to that field (see `SWIFT_FUNCTION_NAME_FIELD`'s own doc comment) —
|
|
658
|
+
// verified against a real parse, not guessed.
|
|
659
|
+
{ nodeType: 'function_declaration', kind: 'method', nameField: SWIFT_FUNCTION_NAME_FIELD, parentType: 'class_body' },
|
|
660
|
+
{ nodeType: 'function_declaration', kind: 'function', nameField: SWIFT_FUNCTION_NAME_FIELD },
|
|
661
|
+
{ nodeType: 'protocol_function_declaration', kind: 'method', nameField: SWIFT_FUNCTION_NAME_FIELD },
|
|
662
|
+
// An enum case — verified against a real parse, not guessed; can only ever appear directly inside
|
|
663
|
+
// an `enum_class_body`, so — like every other language's own unambiguous member node type — no
|
|
664
|
+
// `scopeRestricted`/`parentType` guard is needed.
|
|
665
|
+
{ nodeType: 'enum_entry', kind: 'enum_member', nameField: 'name' },
|
|
666
|
+
// A struct/class stored property (`var x: Int`/`let x: Int` directly inside a `class_body`) —
|
|
667
|
+
// `property_declaration` is also how Swift spells a top-level or function-local `var`/`let`
|
|
668
|
+
// binding (the very same node type, see the fallback rule below), so this is tried first, guarded
|
|
669
|
+
// to only the class-member shape; a property can never legitimately sit anywhere a
|
|
670
|
+
// `scopeRestricted` gate would exclude it (a class/struct body is never treated as `'other'`
|
|
671
|
+
// scope), so this rule itself needs no such gate either.
|
|
672
|
+
{ nodeType: 'property_declaration', kind: 'field', nameField: SWIFT_PROPERTY_NAME_FIELD, parentType: 'class_body' },
|
|
673
|
+
// A top-level or function-local `var`/`let` binding — `DefinitionRule.kind` cannot vary by the
|
|
674
|
+
// `value_binding_pattern` child's own keyword the way this needs, so `extractFile` computes
|
|
675
|
+
// `constant`/`variable` via `swiftDeclarationKind` (the same function also reports `field` for the
|
|
676
|
+
// rule above's match, since it inspects the node's actual parent rather than trusting which rule
|
|
677
|
+
// fired — see there). `scopeRestricted` excludes a function-local binding, matching every other
|
|
678
|
+
// language's own local-variable precedent.
|
|
679
|
+
{ nodeType: 'property_declaration', kind: 'variable', nameField: SWIFT_PROPERTY_NAME_FIELD, scopeRestricted: true },
|
|
680
|
+
],
|
|
681
|
+
// `call_expression` binds no field for its callee at all (verified against a real parse) — see
|
|
682
|
+
// `swiftCallee` in extract.ts, consulted directly by a dedicated dispatch branch in `extractFile`
|
|
683
|
+
// rather than through `callFunctionField`, which can never resolve anything for this node type.
|
|
684
|
+
// `target` is kept only as a placeholder so this table entry still type-checks as a normal
|
|
685
|
+
// `LanguageSpec`; it is never actually read for Swift.
|
|
686
|
+
callTypes: ['call_expression'],
|
|
687
|
+
callFunctionField: 'target',
|
|
688
|
+
importTypes: ['import_declaration'],
|
|
689
|
+
// A closure literal (`{ (x: Int) -> Int in ... }`, e.g. a callback argument) is never itself
|
|
690
|
+
// captured as a definition — but a `let`/`var` inside its body is still closure-local, not a
|
|
691
|
+
// workspace symbol, the same reasoning `ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES` applies to a callback.
|
|
692
|
+
// Verified against a real parse, not guessed.
|
|
693
|
+
bareFunctionScopeTypes: ['lambda_literal'],
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
language: 'dart',
|
|
697
|
+
extensions: ['.dart'],
|
|
698
|
+
wasmFile: 'tree-sitter-dart.wasm',
|
|
699
|
+
definitions: [
|
|
700
|
+
{ nodeType: 'class_definition', kind: 'class', nameField: 'name' },
|
|
701
|
+
// A method's `function_signature` sits directly inside a `method_signature` wrapper; an abstract
|
|
702
|
+
// method (interface-only) signature (`double area();`, no body) instead sits inside a plain
|
|
703
|
+
// `declaration` whose own parent is the `class_body` — both tried before the unrestricted
|
|
704
|
+
// `function` rule below falls through to a top-level function. Verified against a real parse, not
|
|
705
|
+
// guessed.
|
|
706
|
+
{ nodeType: 'function_signature', kind: 'method', nameField: 'name', parentType: 'method_signature' },
|
|
707
|
+
{ nodeType: 'function_signature', kind: 'method', nameField: 'name', parentType: 'declaration', grandparentType: 'class_body' },
|
|
708
|
+
{ nodeType: 'function_signature', kind: 'function', nameField: 'name' },
|
|
709
|
+
// A constructor (`Point(this.x, this.y);`) is its own node type, `constructor_signature`, wrapped
|
|
710
|
+
// by the very same `declaration` node type a field uses — matched directly here regardless of that
|
|
711
|
+
// wrapper (see `DART_FIELD_NAME_FIELD`'s doc comment). No dedicated `constructor` seam kind exists;
|
|
712
|
+
// a constructor is a method in every way this package's graph cares about, matching Java's/C#'s own
|
|
713
|
+
// constructor→`method` precedent.
|
|
714
|
+
{ nodeType: 'constructor_signature', kind: 'method', nameField: 'name' },
|
|
715
|
+
{ nodeType: 'enum_declaration', kind: 'enum', nameField: 'name' },
|
|
716
|
+
// An enum case — verified against a real parse, not guessed; can only ever appear directly inside
|
|
717
|
+
// an `enum_body`, so — like every other language's own unambiguous member node type — no
|
|
718
|
+
// `scopeRestricted`/`parentType` guard is needed.
|
|
719
|
+
{ nodeType: 'enum_constant', kind: 'enum_member', nameField: 'name' },
|
|
720
|
+
// A class/struct field — see `DART_FIELD_NAME_FIELD`. Restricted to a direct `class_body` child
|
|
721
|
+
// since Dart uses an entirely different, already-unambiguous node type for a local variable
|
|
722
|
+
// (`local_variable_declaration`), so no `scopeRestricted` gate is needed either — this rule simply
|
|
723
|
+
// never matches one. A top-level `declaration` (Dart also allows a bare top-level `var`/`final`)
|
|
724
|
+
// is deliberately not captured at all — same "don't overreach" precedent this file already applies
|
|
725
|
+
// to a comparably rare shape elsewhere.
|
|
726
|
+
{ nodeType: 'declaration', kind: 'field', nameField: DART_FIELD_NAME_FIELD, parentType: 'class_body' },
|
|
727
|
+
],
|
|
728
|
+
// Dart's grammar has no call-expression node type at all — a call is a flat `identifier` followed by
|
|
729
|
+
// zero or more `selector` children, where a call is whichever `selector` happens to be an
|
|
730
|
+
// `argument_part` rather than a `.property` access; resolving its callee means walking backward
|
|
731
|
+
// through preceding siblings, not reading a field off a single call node the way every other
|
|
732
|
+
// language's `RawCall` extraction in this file works. Capturing this would need a structurally new,
|
|
733
|
+
// sibling-walking resolution strategy this package's call model does not support today, so this
|
|
734
|
+
// package captures no call sites for Dart at all — a real, verified limitation, not a guess. `name`
|
|
735
|
+
// is kept only as a placeholder so this table entry still type-checks as a normal `LanguageSpec`; it
|
|
736
|
+
// is never read, since `callTypes` is empty.
|
|
737
|
+
callTypes: [],
|
|
738
|
+
callFunctionField: 'name',
|
|
739
|
+
// Targets `import_specification` directly (nested inside `import_or_export` → `library_import`)
|
|
740
|
+
// rather than either wrapper — the walk reaches it regardless during ordinary recursion. A Dart
|
|
741
|
+
// `export` statement (`import_or_export` → `library_export`) is deliberately not captured: unlike an
|
|
742
|
+
// import, it re-exports the current file's own symbols to *its* importers, a different relationship
|
|
743
|
+
// than the "this file's own binding" every other `RawImport` in this package represents.
|
|
744
|
+
importTypes: ['import_specification'],
|
|
745
|
+
bareFunctionScopeTypes: [],
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
language: 'scala',
|
|
749
|
+
extensions: ['.scala', '.sc'],
|
|
750
|
+
wasmFile: 'tree-sitter-scala.wasm',
|
|
751
|
+
definitions: [
|
|
752
|
+
{ nodeType: 'class_definition', kind: 'class', nameField: 'name' },
|
|
753
|
+
// A singleton `object` has no dedicated seam kind of its own; `class` is the closest existing fit —
|
|
754
|
+
// it shares `class_definition`'s exact shape (a `template_body`, an optional `extend` clause) and
|
|
755
|
+
// behaves like an ordinary class with a single implicit instance, matching Java's/C#'s own
|
|
756
|
+
// record→`class` precedent for a related-but-distinct construct.
|
|
757
|
+
{ nodeType: 'object_definition', kind: 'class', nameField: 'name' },
|
|
758
|
+
{ nodeType: 'trait_definition', kind: 'trait', nameField: 'name' },
|
|
759
|
+
// A method is a `function_definition`/`function_declaration` directly inside a `template_body` —
|
|
760
|
+
// the same node type a top-level function uses — tried first, before the unrestricted `function`
|
|
761
|
+
// rule below falls through to everything else. A trait's own method *signature* (`def area():
|
|
762
|
+
// Double`, no body) is `function_declaration`, always directly inside a `template_body` too (a
|
|
763
|
+
// trait's own), so no `parentType` guard is needed for that one — unambiguous by node type alone.
|
|
764
|
+
// Verified against a real parse, not guessed.
|
|
765
|
+
{ nodeType: 'function_definition', kind: 'method', nameField: 'name', parentType: 'template_body' },
|
|
766
|
+
{ nodeType: 'function_definition', kind: 'function', nameField: 'name' },
|
|
767
|
+
{ nodeType: 'function_declaration', kind: 'method', nameField: 'name' },
|
|
768
|
+
// A class/trait/object member (`val x = 1` directly inside a `template_body`) — tried first, since
|
|
769
|
+
// this same node type is also how Scala spells a top-level or function-local immutable binding
|
|
770
|
+
// (the fallback rule below). `nameNodeTypes` rejects a destructuring pattern (`val (a, b) = ...`,
|
|
771
|
+
// `pattern` binds a `tuple_pattern`, not a bare `identifier`) rather than name it after a shape this
|
|
772
|
+
// package does not attempt to resolve, the same "don't guess" precedent `pythonBinding`/
|
|
773
|
+
// `ecmascriptImports` already follow. `var_definition` (a mutable binding) follows the identical
|
|
774
|
+
// split, reporting `variable` instead of `constant` for its own module/local-scope fallback.
|
|
775
|
+
// Verified against a real parse, not guessed.
|
|
776
|
+
{ nodeType: 'val_definition', kind: 'field', nameField: 'pattern', nameNodeTypes: ['identifier'], parentType: 'template_body' },
|
|
777
|
+
{ nodeType: 'val_definition', kind: 'constant', nameField: 'pattern', nameNodeTypes: ['identifier'], scopeRestricted: true },
|
|
778
|
+
{ nodeType: 'var_definition', kind: 'field', nameField: 'pattern', nameNodeTypes: ['identifier'], parentType: 'template_body' },
|
|
779
|
+
{ nodeType: 'var_definition', kind: 'variable', nameField: 'pattern', nameNodeTypes: ['identifier'], scopeRestricted: true },
|
|
780
|
+
// A primary constructor parameter (`class Point(val x: Int, val y: Int)`) — a very common Scala
|
|
781
|
+
// idiom for declaring fields directly in the class header instead of the body. Can only ever
|
|
782
|
+
// appear inside a `class_parameters` list, so — like every other language's own unambiguous member
|
|
783
|
+
// node type — no `scopeRestricted`/`parentType` guard is needed. Verified against a real parse,
|
|
784
|
+
// not guessed.
|
|
785
|
+
{ nodeType: 'class_parameter', kind: 'field', nameField: 'name' },
|
|
93
786
|
],
|
|
787
|
+
// `call_expression`'s callee sits in its own `function` field directly — a bare call
|
|
788
|
+
// (`add(1, 2)`)'s field value is a plain `identifier`; a member call (`p.length()`)'s is a
|
|
789
|
+
// `field_expression` instead, whose own `field` field names the callee and whose `value` field holds
|
|
790
|
+
// the receiver — both already handled by this file's existing generic `calleeName`/`isBareCallee`
|
|
791
|
+
// logic (the same `field` fallback Rust's `field_expression` already uses), so this language needs no
|
|
792
|
+
// call-specific dispatch of its own, unlike Kotlin/Swift/Lua/Ruby. Verified against a real parse, not
|
|
793
|
+
// guessed.
|
|
94
794
|
callTypes: ['call_expression'],
|
|
95
795
|
callFunctionField: 'function',
|
|
96
796
|
importTypes: ['import_declaration'],
|
|
797
|
+
// No anonymous-function-literal shape is special-cased here — this file's own attempt to write one
|
|
798
|
+
// parsed ambiguously as an `infix_expression` rather than a dedicated node type, an inconclusive
|
|
799
|
+
// result this package declines to guess a rule from; the practical impact is limited to a `val`/`var`
|
|
800
|
+
// inside a closure literal passed as a module-level argument, a rare pattern in idiomatic Scala.
|
|
801
|
+
bareFunctionScopeTypes: [],
|
|
97
802
|
},
|
|
98
803
|
];
|
|
99
804
|
/**
|