@mrclrchtr/supi-tree-sitter 10.0.0 → 11.0.0
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 +63 -17
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/LICENSE +21 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/README.md +743 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/index.js +17 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/lib/constants.js +184 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/lib/parse.js +1425 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/lib/picomatch.js +361 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/lib/scan.js +403 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/lib/utils.js +72 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/package.json +83 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/picomatch/posix.js +3 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +4 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +11 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/file-associations.ts +190 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +22 -0
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/package.json +3 -3
- package/src/language.ts +16 -10
- package/src/operation-support.ts +13 -6
- package/src/provider/tree-sitter-provider.ts +19 -1
- package/src/session/runtime-controller.ts +18 -4
- package/src/session/session.ts +10 -3
- package/src/session/structural-worker-client.ts +17 -2
- package/src/session/structural-worker-process.ts +22 -5
- package/src/session/structural-worker-protocol.ts +36 -1
- package/src/syntax-errors.ts +73 -0
- package/src/syntax-node.ts +4 -0
- package/src/tool/call-sites.ts +15 -9
- package/src/tool/callees.ts +24 -15
- package/src/tool/exports.ts +8 -1
- package/src/tool/imports.ts +233 -7
- package/src/tool/node-at.ts +7 -3
- package/src/tool/outline-expansion.ts +78 -0
- package/src/tool/outline-jvm.ts +25 -4
- package/src/tool/outline-nested.ts +390 -0
- package/src/tool/outline.ts +49 -28
- package/src/types.ts +16 -0
- package/src/worker/process-host.mjs +61 -24
- package/src/worker/runtime.ts +44 -10
- package/src/worker/service.ts +13 -9
- package/src/worker/worker-main.ts +15 -2
package/src/tool/outline-jvm.ts
CHANGED
|
@@ -20,6 +20,15 @@ export function extractJvmOutlineItems(
|
|
|
20
20
|
return one(javaContainerItem(node, "interface", source));
|
|
21
21
|
case "module_declaration":
|
|
22
22
|
return one(javaNamed(node, "module", source));
|
|
23
|
+
case "method_declaration":
|
|
24
|
+
return one(javaNamed(node, "method", source));
|
|
25
|
+
case "constructor_declaration":
|
|
26
|
+
return one(javaNamed(node, "method", source, "constructor"));
|
|
27
|
+
case "field_declaration":
|
|
28
|
+
case "constant_declaration":
|
|
29
|
+
return javaVariables(node, "field", source);
|
|
30
|
+
case "enum_constant":
|
|
31
|
+
return one(javaNamed(node, "enum-member", source));
|
|
23
32
|
case "object_declaration":
|
|
24
33
|
return one(kotlinObject(node, source));
|
|
25
34
|
case "function_declaration":
|
|
@@ -113,9 +122,16 @@ function javaMemberItems(node: SyntaxNodeLike, ownerName: string, source: string
|
|
|
113
122
|
case "constant_declaration":
|
|
114
123
|
return javaVariables(node, "field", source);
|
|
115
124
|
case "constructor_declaration":
|
|
116
|
-
return one(javaNamed(node, "method", source));
|
|
125
|
+
return one(javaNamed(node, "method", source, "constructor"));
|
|
117
126
|
case "compact_constructor_declaration":
|
|
118
|
-
return [
|
|
127
|
+
return [
|
|
128
|
+
{
|
|
129
|
+
name: ownerName,
|
|
130
|
+
kind: "method",
|
|
131
|
+
nativeKind: "constructor",
|
|
132
|
+
range: nodeToRange(node, source),
|
|
133
|
+
},
|
|
134
|
+
];
|
|
119
135
|
case "method_declaration":
|
|
120
136
|
case "annotation_type_element_declaration":
|
|
121
137
|
return one(javaNamed(node, "method", source));
|
|
@@ -150,9 +166,14 @@ function javaVariables(node: SyntaxNodeLike, kind: string, source: string): Outl
|
|
|
150
166
|
});
|
|
151
167
|
}
|
|
152
168
|
|
|
153
|
-
function javaNamed(
|
|
169
|
+
function javaNamed(
|
|
170
|
+
node: SyntaxNodeLike,
|
|
171
|
+
kind: string,
|
|
172
|
+
source: string,
|
|
173
|
+
nativeKind = kind,
|
|
174
|
+
): OutlineItem | null {
|
|
154
175
|
const name = node.childForFieldName("name");
|
|
155
|
-
return name ? { name: name.text, kind, range: nodeToRange(node, source) } : null;
|
|
176
|
+
return name ? { name: name.text, kind, nativeKind, range: nodeToRange(node, source) } : null;
|
|
156
177
|
}
|
|
157
178
|
|
|
158
179
|
function kotlinClass(node: SyntaxNodeLike, source: string): OutlineItem | null {
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
// Nested declaration expansion and native-kind metadata for selected grammars.
|
|
2
|
+
|
|
3
|
+
import type { SyntaxNodeLike } from "../syntax-node.ts";
|
|
4
|
+
import type { GrammarId, OutlineItem } from "../types.ts";
|
|
5
|
+
|
|
6
|
+
type NestedOutlineOptions = {
|
|
7
|
+
readonly items: OutlineItem[];
|
|
8
|
+
readonly node: SyntaxNodeLike;
|
|
9
|
+
readonly source: string;
|
|
10
|
+
readonly lineStarts: readonly number[];
|
|
11
|
+
readonly grammarId?: GrammarId;
|
|
12
|
+
readonly extractItemsForNode: (node: SyntaxNodeLike) => OutlineItem[] | null;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** Add named nested declarations while preserving the current shallow outline contract. */
|
|
16
|
+
export function expandNestedItems(options: NestedOutlineOptions): OutlineItem[] {
|
|
17
|
+
const { items, node, source, lineStarts, grammarId } = options;
|
|
18
|
+
if (!grammarId || !EXPANDED_OUTLINE_GRAMMARS.has(grammarId)) return items;
|
|
19
|
+
return items.map((item) => {
|
|
20
|
+
const nativeKind = item.nativeKind ?? nativeDeclarationKind(item, node, grammarId);
|
|
21
|
+
const nested = NESTED_SCOPE_OWNER_TYPES[grammarId]?.has(node.type)
|
|
22
|
+
? collectNestedDeclarations({
|
|
23
|
+
owner: node,
|
|
24
|
+
source,
|
|
25
|
+
lineStarts,
|
|
26
|
+
grammarId,
|
|
27
|
+
extractItemsForNode: options.extractItemsForNode,
|
|
28
|
+
})
|
|
29
|
+
: [];
|
|
30
|
+
const children = mergeOutlineChildren(item.children ?? [], nested).map(addDefaultNativeKind);
|
|
31
|
+
return {
|
|
32
|
+
...item,
|
|
33
|
+
nativeKind,
|
|
34
|
+
...(children.length > 0 ? { children } : {}),
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function collectNestedDeclarations(options: {
|
|
40
|
+
readonly owner: SyntaxNodeLike;
|
|
41
|
+
readonly source: string;
|
|
42
|
+
readonly lineStarts: readonly number[];
|
|
43
|
+
readonly grammarId: GrammarId;
|
|
44
|
+
readonly extractItemsForNode: (node: SyntaxNodeLike) => OutlineItem[] | null;
|
|
45
|
+
}): OutlineItem[] {
|
|
46
|
+
const { owner, source, lineStarts, grammarId, extractItemsForNode } = options;
|
|
47
|
+
const result: OutlineItem[] = [];
|
|
48
|
+
const visit = (node: SyntaxNodeLike): void => {
|
|
49
|
+
for (const child of node.children) {
|
|
50
|
+
if (isNestedDeclaration(child, owner, grammarId)) {
|
|
51
|
+
const items = extractItemsForNode(child);
|
|
52
|
+
const namedItems = (items ?? []).filter(
|
|
53
|
+
(item) => item.name.length > 0 && item.name !== "<anonymous>",
|
|
54
|
+
);
|
|
55
|
+
if (namedItems.length > 0) {
|
|
56
|
+
result.push(
|
|
57
|
+
...expandNestedItems({
|
|
58
|
+
items: namedItems,
|
|
59
|
+
node: child,
|
|
60
|
+
source,
|
|
61
|
+
lineStarts,
|
|
62
|
+
grammarId,
|
|
63
|
+
extractItemsForNode,
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
visit(child);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
visit(owner);
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function isNestedDeclaration(
|
|
77
|
+
node: SyntaxNodeLike,
|
|
78
|
+
owner: SyntaxNodeLike,
|
|
79
|
+
grammarId: GrammarId,
|
|
80
|
+
): boolean {
|
|
81
|
+
const allowed = NESTED_DECLARATION_TYPES[grammarId];
|
|
82
|
+
if (!allowed?.has(node.type)) return false;
|
|
83
|
+
if (grammarId === "java" && node.type === "field_declaration") {
|
|
84
|
+
return isJavaAnonymousClassField(node, owner);
|
|
85
|
+
}
|
|
86
|
+
if (node.type === "declaration" && (grammarId === "c" || grammarId === "cpp")) {
|
|
87
|
+
let parent = node.parent;
|
|
88
|
+
while (parent && parent !== owner) {
|
|
89
|
+
if (
|
|
90
|
+
[
|
|
91
|
+
"field_declaration_list",
|
|
92
|
+
"field_declaration_list_item",
|
|
93
|
+
"class_specifier",
|
|
94
|
+
"struct_specifier",
|
|
95
|
+
"union_specifier",
|
|
96
|
+
].includes(parent.type)
|
|
97
|
+
) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
parent = parent.parent;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Named class fields are already in the shallow outline; add only anonymous-class fields here. */
|
|
108
|
+
function isJavaAnonymousClassField(node: SyntaxNodeLike, owner: SyntaxNodeLike): boolean {
|
|
109
|
+
let parent = node.parent;
|
|
110
|
+
while (parent && parent !== owner) {
|
|
111
|
+
if (parent.type === "class_body") {
|
|
112
|
+
const container = parent.parent?.type;
|
|
113
|
+
return container === "object_creation_expression" || container === "enum_constant";
|
|
114
|
+
}
|
|
115
|
+
parent = parent.parent;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function mergeOutlineChildren(
|
|
121
|
+
existing: readonly OutlineItem[],
|
|
122
|
+
nested: readonly OutlineItem[],
|
|
123
|
+
): OutlineItem[] {
|
|
124
|
+
const merged = [...existing];
|
|
125
|
+
for (const item of nested) {
|
|
126
|
+
const index = merged.findIndex((entry) => sameOutlineSource(entry, item));
|
|
127
|
+
if (index < 0) merged.push(item);
|
|
128
|
+
else {
|
|
129
|
+
const previous = merged[index];
|
|
130
|
+
merged[index] = {
|
|
131
|
+
...previous,
|
|
132
|
+
nativeKind: item.nativeKind ?? previous.nativeKind,
|
|
133
|
+
...(item.children?.length
|
|
134
|
+
? { children: mergeOutlineChildren(previous.children ?? [], item.children) }
|
|
135
|
+
: {}),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return merged.sort(
|
|
140
|
+
(left, right) =>
|
|
141
|
+
left.range.startLine - right.range.startLine ||
|
|
142
|
+
left.range.startCharacter - right.range.startCharacter,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function addDefaultNativeKind(item: OutlineItem): OutlineItem {
|
|
147
|
+
return {
|
|
148
|
+
...item,
|
|
149
|
+
nativeKind: item.nativeKind ?? item.kind,
|
|
150
|
+
...(item.children ? { children: item.children.map(addDefaultNativeKind) } : {}),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function sameOutlineSource(left: OutlineItem, right: OutlineItem): boolean {
|
|
155
|
+
return (
|
|
156
|
+
left.name === right.name &&
|
|
157
|
+
left.range.startLine === right.range.startLine &&
|
|
158
|
+
left.range.startCharacter === right.range.startCharacter &&
|
|
159
|
+
left.range.endLine === right.range.endLine &&
|
|
160
|
+
left.range.endCharacter === right.range.endCharacter
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function nativeDeclarationKind(
|
|
165
|
+
item: OutlineItem,
|
|
166
|
+
node: SyntaxNodeLike,
|
|
167
|
+
grammarId: GrammarId,
|
|
168
|
+
): string {
|
|
169
|
+
if (grammarId === "rust" && node.type === "trait_item") return "trait";
|
|
170
|
+
if (grammarId === "java" && node.type === "record_declaration") return "record";
|
|
171
|
+
if (grammarId === "go" && node.type === "type_spec") {
|
|
172
|
+
const definition = node.childForFieldName("type");
|
|
173
|
+
if (definition?.type === "struct_type") return "struct";
|
|
174
|
+
if (definition?.type === "interface_type") return "interface";
|
|
175
|
+
}
|
|
176
|
+
const nativeKinds: Readonly<Record<string, string>> = {
|
|
177
|
+
function_definition: "function",
|
|
178
|
+
function_declaration: "function",
|
|
179
|
+
function_item: "function",
|
|
180
|
+
class_declaration: "class",
|
|
181
|
+
class_definition: "class",
|
|
182
|
+
class_specifier: "class",
|
|
183
|
+
struct_item: "struct",
|
|
184
|
+
struct_specifier: "struct",
|
|
185
|
+
union_item: "union",
|
|
186
|
+
union_specifier: "union",
|
|
187
|
+
enum_item: "enum",
|
|
188
|
+
enum_specifier: "enum",
|
|
189
|
+
interface_declaration: "interface",
|
|
190
|
+
method_declaration: "method",
|
|
191
|
+
method_definition: "method",
|
|
192
|
+
constructor_declaration: "constructor",
|
|
193
|
+
type_alias: "type alias",
|
|
194
|
+
type_item: "type alias",
|
|
195
|
+
type_alias_declaration: "type alias",
|
|
196
|
+
alias_declaration: "type alias",
|
|
197
|
+
type_definition: "typedef",
|
|
198
|
+
};
|
|
199
|
+
return nativeKinds[node.type] ?? item.kind;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const EXPANDED_OUTLINE_GRAMMARS: ReadonlySet<GrammarId> = new Set([
|
|
203
|
+
"javascript",
|
|
204
|
+
"typescript",
|
|
205
|
+
"tsx",
|
|
206
|
+
"python",
|
|
207
|
+
"java",
|
|
208
|
+
"go",
|
|
209
|
+
"rust",
|
|
210
|
+
"c",
|
|
211
|
+
"cpp",
|
|
212
|
+
]);
|
|
213
|
+
|
|
214
|
+
const NESTED_SCOPE_OWNER_TYPES: Partial<Record<GrammarId, ReadonlySet<string>>> = {
|
|
215
|
+
javascript: new Set([
|
|
216
|
+
"field_definition",
|
|
217
|
+
"function_declaration",
|
|
218
|
+
"generator_function_declaration",
|
|
219
|
+
"function_expression",
|
|
220
|
+
"generator_function",
|
|
221
|
+
"arrow_function",
|
|
222
|
+
"class_declaration",
|
|
223
|
+
"abstract_class_declaration",
|
|
224
|
+
"class_expression",
|
|
225
|
+
"method_definition",
|
|
226
|
+
"interface_declaration",
|
|
227
|
+
"enum_declaration",
|
|
228
|
+
"internal_module",
|
|
229
|
+
"module",
|
|
230
|
+
"variable_declarator",
|
|
231
|
+
]),
|
|
232
|
+
typescript: new Set([
|
|
233
|
+
"public_field_definition",
|
|
234
|
+
"function_declaration",
|
|
235
|
+
"generator_function_declaration",
|
|
236
|
+
"function_expression",
|
|
237
|
+
"generator_function",
|
|
238
|
+
"arrow_function",
|
|
239
|
+
"class_declaration",
|
|
240
|
+
"abstract_class_declaration",
|
|
241
|
+
"class_expression",
|
|
242
|
+
"method_definition",
|
|
243
|
+
"interface_declaration",
|
|
244
|
+
"enum_declaration",
|
|
245
|
+
"internal_module",
|
|
246
|
+
"module",
|
|
247
|
+
"variable_declarator",
|
|
248
|
+
]),
|
|
249
|
+
tsx: new Set([
|
|
250
|
+
"public_field_definition",
|
|
251
|
+
"function_declaration",
|
|
252
|
+
"generator_function_declaration",
|
|
253
|
+
"function_expression",
|
|
254
|
+
"generator_function",
|
|
255
|
+
"arrow_function",
|
|
256
|
+
"class_declaration",
|
|
257
|
+
"abstract_class_declaration",
|
|
258
|
+
"class_expression",
|
|
259
|
+
"method_definition",
|
|
260
|
+
"interface_declaration",
|
|
261
|
+
"enum_declaration",
|
|
262
|
+
"internal_module",
|
|
263
|
+
"module",
|
|
264
|
+
"variable_declarator",
|
|
265
|
+
]),
|
|
266
|
+
python: new Set(["function_definition", "class_definition"]),
|
|
267
|
+
java: new Set([
|
|
268
|
+
"class_declaration",
|
|
269
|
+
"interface_declaration",
|
|
270
|
+
"enum_declaration",
|
|
271
|
+
"record_declaration",
|
|
272
|
+
"annotation_type_declaration",
|
|
273
|
+
"method_declaration",
|
|
274
|
+
"constructor_declaration",
|
|
275
|
+
]),
|
|
276
|
+
go: new Set(["function_declaration", "method_declaration", "type_spec"]),
|
|
277
|
+
rust: new Set([
|
|
278
|
+
"function_item",
|
|
279
|
+
"struct_item",
|
|
280
|
+
"union_item",
|
|
281
|
+
"enum_item",
|
|
282
|
+
"trait_item",
|
|
283
|
+
"impl_item",
|
|
284
|
+
"mod_item",
|
|
285
|
+
]),
|
|
286
|
+
c: new Set([
|
|
287
|
+
"function_definition",
|
|
288
|
+
"class_specifier",
|
|
289
|
+
"struct_specifier",
|
|
290
|
+
"union_specifier",
|
|
291
|
+
"enum_specifier",
|
|
292
|
+
]),
|
|
293
|
+
cpp: new Set([
|
|
294
|
+
"function_definition",
|
|
295
|
+
"class_specifier",
|
|
296
|
+
"struct_specifier",
|
|
297
|
+
"union_specifier",
|
|
298
|
+
"enum_specifier",
|
|
299
|
+
"namespace_definition",
|
|
300
|
+
]),
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
const NESTED_DECLARATION_TYPES: Partial<Record<GrammarId, ReadonlySet<string>>> = {
|
|
304
|
+
javascript: new Set([
|
|
305
|
+
"field_definition",
|
|
306
|
+
"function_declaration",
|
|
307
|
+
"generator_function_declaration",
|
|
308
|
+
"class_declaration",
|
|
309
|
+
"abstract_class_declaration",
|
|
310
|
+
"interface_declaration",
|
|
311
|
+
"type_alias_declaration",
|
|
312
|
+
"enum_declaration",
|
|
313
|
+
"method_definition",
|
|
314
|
+
"public_field_definition",
|
|
315
|
+
"function_signature",
|
|
316
|
+
"internal_module",
|
|
317
|
+
"module",
|
|
318
|
+
]),
|
|
319
|
+
typescript: new Set([
|
|
320
|
+
"function_declaration",
|
|
321
|
+
"generator_function_declaration",
|
|
322
|
+
"class_declaration",
|
|
323
|
+
"abstract_class_declaration",
|
|
324
|
+
"interface_declaration",
|
|
325
|
+
"type_alias_declaration",
|
|
326
|
+
"enum_declaration",
|
|
327
|
+
"method_definition",
|
|
328
|
+
"public_field_definition",
|
|
329
|
+
"function_signature",
|
|
330
|
+
"internal_module",
|
|
331
|
+
"module",
|
|
332
|
+
]),
|
|
333
|
+
tsx: new Set([
|
|
334
|
+
"function_declaration",
|
|
335
|
+
"generator_function_declaration",
|
|
336
|
+
"class_declaration",
|
|
337
|
+
"abstract_class_declaration",
|
|
338
|
+
"interface_declaration",
|
|
339
|
+
"type_alias_declaration",
|
|
340
|
+
"enum_declaration",
|
|
341
|
+
"method_definition",
|
|
342
|
+
"public_field_definition",
|
|
343
|
+
"function_signature",
|
|
344
|
+
"internal_module",
|
|
345
|
+
"module",
|
|
346
|
+
]),
|
|
347
|
+
python: new Set(["function_definition", "class_definition"]),
|
|
348
|
+
java: new Set([
|
|
349
|
+
"class_declaration",
|
|
350
|
+
"interface_declaration",
|
|
351
|
+
"enum_declaration",
|
|
352
|
+
"record_declaration",
|
|
353
|
+
"annotation_type_declaration",
|
|
354
|
+
"method_declaration",
|
|
355
|
+
"constructor_declaration",
|
|
356
|
+
"field_declaration",
|
|
357
|
+
]),
|
|
358
|
+
go: new Set(["function_declaration", "method_declaration", "type_spec", "type_alias"]),
|
|
359
|
+
rust: new Set([
|
|
360
|
+
"function_item",
|
|
361
|
+
"struct_item",
|
|
362
|
+
"union_item",
|
|
363
|
+
"enum_item",
|
|
364
|
+
"trait_item",
|
|
365
|
+
"impl_item",
|
|
366
|
+
"const_item",
|
|
367
|
+
"static_item",
|
|
368
|
+
"type_item",
|
|
369
|
+
"mod_item",
|
|
370
|
+
]),
|
|
371
|
+
c: new Set([
|
|
372
|
+
"function_definition",
|
|
373
|
+
"class_specifier",
|
|
374
|
+
"struct_specifier",
|
|
375
|
+
"union_specifier",
|
|
376
|
+
"enum_specifier",
|
|
377
|
+
"type_definition",
|
|
378
|
+
]),
|
|
379
|
+
cpp: new Set([
|
|
380
|
+
"function_definition",
|
|
381
|
+
"class_specifier",
|
|
382
|
+
"struct_specifier",
|
|
383
|
+
"union_specifier",
|
|
384
|
+
"enum_specifier",
|
|
385
|
+
"type_definition",
|
|
386
|
+
"alias_declaration",
|
|
387
|
+
"concept_definition",
|
|
388
|
+
"namespace_definition",
|
|
389
|
+
]),
|
|
390
|
+
};
|
package/src/tool/outline.ts
CHANGED
|
@@ -2,30 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { nodeToRange } from "../coordinates.ts";
|
|
4
4
|
import type { SyntaxNodeLike } from "../syntax-node.ts";
|
|
5
|
-
import type { OutlineItem } from "../types.ts";
|
|
5
|
+
import type { GrammarId, OutlineItem } from "../types.ts";
|
|
6
6
|
import { extractBindingIdentifiers } from "./js-binding-pattern.ts";
|
|
7
|
+
import { expandExtractedItems, OUTLINE_DECLARATION_NODE_TYPES } from "./outline-expansion.ts";
|
|
7
8
|
import { extractPolyglotOutlineItems } from "./outline-polyglot.ts";
|
|
8
9
|
|
|
9
|
-
/** Node types that can be extracted directly as outline items. */
|
|
10
|
-
const OUTLINE_DECLARATION_NODE_TYPES = new Set([
|
|
11
|
-
"function_declaration",
|
|
12
|
-
"generator_function_declaration",
|
|
13
|
-
"class_declaration",
|
|
14
|
-
"abstract_class_declaration",
|
|
15
|
-
"class",
|
|
16
|
-
"interface_declaration",
|
|
17
|
-
"type_alias_declaration",
|
|
18
|
-
"enum_declaration",
|
|
19
|
-
"method_definition",
|
|
20
|
-
"public_field_definition",
|
|
21
|
-
"variable_declarator",
|
|
22
|
-
"lexical_declaration",
|
|
23
|
-
"ambient_declaration",
|
|
24
|
-
"internal_module",
|
|
25
|
-
"module",
|
|
26
|
-
"function_signature",
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
10
|
function sourceLineStarts(source: string): number[] {
|
|
30
11
|
const starts = [0];
|
|
31
12
|
for (let index = 0; index < source.length; index += 1) {
|
|
@@ -37,27 +18,55 @@ function sourceLineStarts(source: string): number[] {
|
|
|
37
18
|
}
|
|
38
19
|
|
|
39
20
|
/** Extract a structural outline from a parsed tree. */
|
|
40
|
-
export function collectOutline(
|
|
41
|
-
|
|
21
|
+
export function collectOutline(
|
|
22
|
+
rootNode: SyntaxNodeLike,
|
|
23
|
+
source: string,
|
|
24
|
+
grammarId?: GrammarId,
|
|
25
|
+
): OutlineItem[] {
|
|
26
|
+
return collectItems(rootNode, source, sourceLineStarts(source), grammarId);
|
|
42
27
|
}
|
|
43
28
|
|
|
44
29
|
function collectItems(
|
|
45
30
|
node: SyntaxNodeLike,
|
|
46
31
|
source: string,
|
|
47
32
|
lineStarts: readonly number[],
|
|
33
|
+
grammarId?: GrammarId,
|
|
48
34
|
): OutlineItem[] {
|
|
49
35
|
const items: OutlineItem[] = [];
|
|
50
36
|
|
|
51
37
|
for (const child of node.children) {
|
|
52
38
|
const polyglotItems = extractPolyglotOutlineItems(child, source, lineStarts);
|
|
53
39
|
if (polyglotItems) {
|
|
54
|
-
items.push(
|
|
40
|
+
items.push(
|
|
41
|
+
...expandExtractedItems({
|
|
42
|
+
items: polyglotItems,
|
|
43
|
+
node: child,
|
|
44
|
+
source,
|
|
45
|
+
lineStarts,
|
|
46
|
+
grammarId,
|
|
47
|
+
extractItemsForNode: (nested) =>
|
|
48
|
+
extractPolyglotOutlineItems(nested, source, lineStarts) ?? extractItems(nested, source),
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
55
51
|
continue;
|
|
56
52
|
}
|
|
57
53
|
|
|
58
54
|
const extractedItems = extractItems(child, source);
|
|
59
|
-
if (extractedItems)
|
|
60
|
-
|
|
55
|
+
if (extractedItems) {
|
|
56
|
+
items.push(
|
|
57
|
+
...expandExtractedItems({
|
|
58
|
+
items: extractedItems,
|
|
59
|
+
node: child,
|
|
60
|
+
source,
|
|
61
|
+
lineStarts,
|
|
62
|
+
grammarId,
|
|
63
|
+
extractItemsForNode: (nested) =>
|
|
64
|
+
extractPolyglotOutlineItems(nested, source, lineStarts) ?? extractItems(nested, source),
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
} else {
|
|
68
|
+
items.push(...collectItems(child, source, lineStarts, grammarId));
|
|
69
|
+
}
|
|
61
70
|
}
|
|
62
71
|
|
|
63
72
|
return items;
|
|
@@ -93,6 +102,7 @@ function extractItem(node: SyntaxNodeLike, source: string): OutlineItem | null {
|
|
|
93
102
|
case "method_definition":
|
|
94
103
|
return extractNamedDeclaration(node, "method", source);
|
|
95
104
|
case "public_field_definition":
|
|
105
|
+
case "field_definition":
|
|
96
106
|
return extractFieldDefinition(node, source);
|
|
97
107
|
case "variable_declarator":
|
|
98
108
|
return extractVariableDeclaratorItems(node, source)[0] ?? null;
|
|
@@ -113,7 +123,14 @@ function extractExportStatement(node: SyntaxNodeLike, source: string): OutlineIt
|
|
|
113
123
|
if (decl.type === "lexical_declaration") return extractLexicalDeclarationItems(decl, source);
|
|
114
124
|
if (decl.type === "ambient_declaration") return extractAmbientDeclarationItems(decl, source);
|
|
115
125
|
const item = extractItem(decl, source);
|
|
116
|
-
if (item)
|
|
126
|
+
if (item) {
|
|
127
|
+
return [
|
|
128
|
+
{
|
|
129
|
+
...item,
|
|
130
|
+
nativeKind: decl.type === "type_alias_declaration" ? "type alias" : item.kind,
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
}
|
|
117
134
|
}
|
|
118
135
|
|
|
119
136
|
if (hasDefaultKeyword(node)) {
|
|
@@ -232,7 +249,11 @@ function collectClassMembers(node: SyntaxNodeLike, source: string): OutlineItem[
|
|
|
232
249
|
|
|
233
250
|
const items: OutlineItem[] = [];
|
|
234
251
|
for (const child of body.children) {
|
|
235
|
-
if (
|
|
252
|
+
if (
|
|
253
|
+
!["method_definition", "public_field_definition", "field_definition"].includes(child.type)
|
|
254
|
+
) {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
236
257
|
const item = extractItem(child, source);
|
|
237
258
|
if (item) items.push(item);
|
|
238
259
|
}
|
package/src/types.ts
CHANGED
|
@@ -13,6 +13,16 @@ export interface SourceRange {
|
|
|
13
13
|
/** Discriminated result union for all service operations. */
|
|
14
14
|
export type TreeSitterResult<T> =
|
|
15
15
|
| { kind: "success"; data: T }
|
|
16
|
+
| {
|
|
17
|
+
kind: "partial";
|
|
18
|
+
data: T;
|
|
19
|
+
/** Affected source file. */
|
|
20
|
+
file: string;
|
|
21
|
+
/** Why recovered syntax may hide structural evidence. */
|
|
22
|
+
reason: string;
|
|
23
|
+
/** Available syntax error and missing-node ranges, in 1-based UTF-16 coordinates. */
|
|
24
|
+
errorRanges: SourceRange[];
|
|
25
|
+
}
|
|
16
26
|
| { kind: "unsupported-language"; file: string; message: string }
|
|
17
27
|
| { kind: "file-access-error"; file: string; message: string }
|
|
18
28
|
| { kind: "validation-error"; message: string }
|
|
@@ -21,7 +31,10 @@ export type TreeSitterResult<T> =
|
|
|
21
31
|
/** Structural outline item. */
|
|
22
32
|
export interface OutlineItem {
|
|
23
33
|
name: string;
|
|
34
|
+
/** Common structural search category. */
|
|
24
35
|
kind: string;
|
|
36
|
+
/** Source-language declaration kind, separate from common search category. */
|
|
37
|
+
nativeKind?: string;
|
|
25
38
|
range: SourceRange;
|
|
26
39
|
/** Exact 1-based start of the declaration name, when available. */
|
|
27
40
|
nameAnchor?: { line: number; character: number };
|
|
@@ -79,6 +92,9 @@ export interface QueryCapture {
|
|
|
79
92
|
export interface CallSiteMatch {
|
|
80
93
|
name: string;
|
|
81
94
|
startLine: number;
|
|
95
|
+
startCharacter: number;
|
|
96
|
+
endLine: number;
|
|
97
|
+
endCharacter: number;
|
|
82
98
|
}
|
|
83
99
|
|
|
84
100
|
/**
|