@mrclrchtr/supi-code-intelligence 4.1.0 → 4.2.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.
Files changed (43) hide show
  1. package/README.md +4 -2
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  3. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  4. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  5. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  6. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  7. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  8. package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
  9. package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +2 -2
  10. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +5 -5
  11. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  12. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  13. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  14. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
  15. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +2 -1
  16. package/node_modules/@mrclrchtr/supi-tree-sitter/src/operation-support.ts +19 -0
  17. package/node_modules/@mrclrchtr/supi-tree-sitter/src/syntax-node.ts +1 -0
  18. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-c-family.ts +230 -0
  19. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-html-sql.ts +186 -0
  20. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-jvm.ts +311 -0
  21. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-polyglot.ts +218 -0
  22. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-scripting.ts +307 -0
  23. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline.ts +9 -5
  24. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +6 -2
  25. package/package.json +5 -5
  26. package/src/analysis/search/pattern.ts +2 -2
  27. package/src/analysis/target/symbol.ts +5 -2
  28. package/src/session/orientation/collect.ts +134 -180
  29. package/src/session/orientation/context-sections.ts +14 -48
  30. package/src/session/orientation-types.ts +14 -4
  31. package/src/session/orientation-workflow.ts +20 -48
  32. package/src/tool/graph/execute.ts +1 -1
  33. package/src/tool/graph/markdown.ts +222 -0
  34. package/src/tool/orientation/markdown.ts +66 -11
  35. package/src/tool/register.ts +10 -0
  36. package/src/ui/markdown/overview-data.ts +3 -15
  37. package/src/ui/markdown/overview.ts +4 -10
  38. package/src/ui/markdown/types.ts +0 -1
  39. package/src/tool/graph/calls-md.ts +0 -41
  40. package/src/tool/graph/implementations-md.ts +0 -57
  41. package/src/tool/graph/markdown-base.ts +0 -88
  42. package/src/tool/graph/provider-location-md.ts +0 -9
  43. package/src/tool/graph/references-md.ts +0 -41
@@ -0,0 +1,186 @@
1
+ import { nodeToRange } from "../coordinates.ts";
2
+ import type { SyntaxNodeLike } from "../syntax-node.ts";
3
+ import type { OutlineItem } from "../types.ts";
4
+
5
+ /** Extract HTML id declarations and SQL schema declarations. */
6
+ export function extractHtmlSqlOutlineItems(
7
+ node: SyntaxNodeLike,
8
+ source: string,
9
+ ): OutlineItem[] | undefined {
10
+ if (HTML_ELEMENT_TYPES.has(node.type)) return htmlElementItems(node, source);
11
+
12
+ switch (node.type) {
13
+ case "create_schema":
14
+ return one(sqlItem(node, "schema", source, sqlSchemaChildren(node, source)));
15
+ case "create_type":
16
+ return one(sqlType(node, source));
17
+ case "create_table":
18
+ return one(sqlItem(node, "table", source, sqlColumns(node, source)));
19
+ case "create_view":
20
+ case "create_materialized_view":
21
+ return one(sqlItem(node, "view", source));
22
+ case "create_index":
23
+ return one(sqlItem(node, "index", source));
24
+ case "create_sequence":
25
+ return one(sqlItem(node, "sequence", source));
26
+ case "create_function":
27
+ return one(sqlItem(node, "function", source));
28
+ case "create_trigger":
29
+ return one(sqlItem(node, "trigger", source));
30
+ case "create_database":
31
+ return one(sqlItem(node, "database", source));
32
+ case "create_role":
33
+ return one(sqlItem(node, "role", source));
34
+ case "create_extension":
35
+ return one(sqlItem(node, "extension", source));
36
+ default:
37
+ return undefined;
38
+ }
39
+ }
40
+
41
+ function htmlElementItems(node: SyntaxNodeLike, source: string): OutlineItem[] {
42
+ const children = node.children.flatMap((child) =>
43
+ HTML_ELEMENT_TYPES.has(child.type) ? htmlElementItems(child, source) : [],
44
+ );
45
+ const tag = node.type === "self_closing_tag" ? node : directChild(node, "start_tag");
46
+ const id = tag && htmlId(tag);
47
+ if (!id) return children;
48
+ return [
49
+ {
50
+ name: id,
51
+ kind: "element",
52
+ range: nodeToRange(node, source),
53
+ children,
54
+ },
55
+ ];
56
+ }
57
+
58
+ function htmlId(tag: SyntaxNodeLike): string | null {
59
+ for (const attribute of tag.children) {
60
+ if (attribute.type !== "attribute") continue;
61
+ const name = directChild(attribute, "attribute_name");
62
+ if (name?.text.toLowerCase() !== "id") continue;
63
+ return firstDescendant(attribute, "attribute_value")?.text || null;
64
+ }
65
+ return null;
66
+ }
67
+
68
+ function firstDescendant(node: SyntaxNodeLike, type: string): SyntaxNodeLike | null {
69
+ for (const child of node.children) {
70
+ if (child.type === type) return child;
71
+ const nested = firstDescendant(child, type);
72
+ if (nested) return nested;
73
+ }
74
+ return null;
75
+ }
76
+
77
+ function sqlType(node: SyntaxNodeLike, source: string): OutlineItem | null {
78
+ const enumElements = directChild(node, "enum_elements");
79
+ const children = enumElements
80
+ ? enumElements.children
81
+ .filter((child) => child.type === "literal")
82
+ .map((child) => ({
83
+ name: stripSqlQuotes(child.text),
84
+ kind: "enum-member",
85
+ range: nodeToRange(child, source),
86
+ }))
87
+ : sqlColumns(node, source);
88
+ return sqlItem(node, enumElements ? "enum" : "type", source, children);
89
+ }
90
+
91
+ function sqlColumns(node: SyntaxNodeLike, source: string): OutlineItem[] {
92
+ const definitions = node.children.flatMap((child) => {
93
+ if (child.type === "column_definitions") return [child];
94
+ if (child.type !== "table_partition") return [];
95
+ return child.children.filter((nested) => nested.type === "column_definitions");
96
+ });
97
+ return definitions.flatMap((group) =>
98
+ group.children.flatMap((child) => {
99
+ if (child.type === "column_definition") {
100
+ return [...one(sqlMember(child, "field", source)), ...sqlInlineConstraints(child, source)];
101
+ }
102
+ if (child.type === "constraints") {
103
+ return child.children.flatMap((constraint) =>
104
+ constraint.type === "constraint" ? one(sqlMember(constraint, "constraint", source)) : [],
105
+ );
106
+ }
107
+ return [];
108
+ }),
109
+ );
110
+ }
111
+
112
+ function sqlInlineConstraints(node: SyntaxNodeLike, source: string): OutlineItem[] {
113
+ const marker = node.children.findIndex((child) => child.type === "keyword_constraint");
114
+ if (marker < 0) return [];
115
+ const name = node.children.slice(marker + 1).find((child) => child.type === "literal");
116
+ return name
117
+ ? [{ name: stripSqlQuotes(name.text), kind: "constraint", range: nodeToRange(name, source) }]
118
+ : [];
119
+ }
120
+
121
+ function sqlSchemaChildren(node: SyntaxNodeLike, source: string): OutlineItem[] {
122
+ return node.children.flatMap((child) => extractHtmlSqlOutlineItems(child, source) ?? []);
123
+ }
124
+
125
+ function sqlItem(
126
+ node: SyntaxNodeLike,
127
+ kind: string,
128
+ source: string,
129
+ children?: OutlineItem[],
130
+ ): OutlineItem | null {
131
+ const name = sqlDeclarationName(node);
132
+ if (!name) return null;
133
+ return {
134
+ name,
135
+ kind,
136
+ range: nodeToRange(node, source),
137
+ ...(children ? { children } : {}),
138
+ };
139
+ }
140
+
141
+ function sqlMember(node: SyntaxNodeLike, kind: string, source: string): OutlineItem | null {
142
+ const name = node.childForFieldName("name") ?? directChild(node, "identifier");
143
+ return name ? { name: stripSqlQuotes(name.text), kind, range: nodeToRange(node, source) } : null;
144
+ }
145
+
146
+ function sqlDeclarationName(node: SyntaxNodeLike): string | null {
147
+ if (node.type === "create_index") {
148
+ const indexName = node.childForFieldName("column");
149
+ return indexName ? stripSqlQuotes(indexName.text) : null;
150
+ }
151
+ const reference = directChild(node, "object_reference");
152
+ if (reference) {
153
+ const name = reference.childForFieldName("name") ?? lastDirectChild(reference, "identifier");
154
+ if (name) return name.text;
155
+ }
156
+ return directChild(node, "identifier")?.text ?? null;
157
+ }
158
+
159
+ function directChild(node: SyntaxNodeLike, type: string): SyntaxNodeLike | null {
160
+ return node.children.find((child) => child.type === type) ?? null;
161
+ }
162
+
163
+ function lastDirectChild(node: SyntaxNodeLike, type: string): SyntaxNodeLike | null {
164
+ for (let index = node.children.length - 1; index >= 0; index -= 1) {
165
+ const child = node.children[index];
166
+ if (child?.type === type) return child;
167
+ }
168
+ return null;
169
+ }
170
+
171
+ function stripSqlQuotes(value: string): string {
172
+ return value.startsWith("'") && value.endsWith("'")
173
+ ? value.slice(1, -1).replaceAll("''", "'")
174
+ : value;
175
+ }
176
+
177
+ function one(item: OutlineItem | null): OutlineItem[] {
178
+ return item ? [item] : [];
179
+ }
180
+
181
+ const HTML_ELEMENT_TYPES = new Set([
182
+ "element",
183
+ "script_element",
184
+ "self_closing_tag",
185
+ "style_element",
186
+ ]);
@@ -0,0 +1,311 @@
1
+ import { nodeToRange } from "../coordinates.ts";
2
+ import type { SyntaxNodeLike } from "../syntax-node.ts";
3
+ import type { OutlineItem } from "../types.ts";
4
+
5
+ /** Extract Java and Kotlin declarations from their grammar-specific node shapes. */
6
+ export function extractJvmOutlineItems(
7
+ node: SyntaxNodeLike,
8
+ source: string,
9
+ ): OutlineItem[] | undefined {
10
+ switch (node.type) {
11
+ case "class_declaration":
12
+ return classDeclaration(node, source);
13
+ case "interface_declaration":
14
+ return javaContainer(node, "interface", source);
15
+ case "enum_declaration":
16
+ return javaContainer(node, "enum", source);
17
+ case "record_declaration":
18
+ return one(javaRecord(node, source));
19
+ case "annotation_type_declaration":
20
+ return one(javaContainerItem(node, "interface", source));
21
+ case "module_declaration":
22
+ return one(javaNamed(node, "module", source));
23
+ case "object_declaration":
24
+ return one(kotlinObject(node, source));
25
+ case "function_declaration":
26
+ return kotlinFunction(node, "function", source);
27
+ case "property_declaration":
28
+ return kotlinProperties(node, undefined, source);
29
+ default:
30
+ return undefined;
31
+ }
32
+ }
33
+
34
+ function one(item: OutlineItem | null): OutlineItem[] {
35
+ return item ? [item] : [];
36
+ }
37
+
38
+ function classDeclaration(node: SyntaxNodeLike, source: string): OutlineItem[] | undefined {
39
+ if (!node.childForFieldName("name") && directChild(node, "type_identifier")) {
40
+ return one(kotlinClass(node, source));
41
+ }
42
+ const body = node.childForFieldName("body");
43
+ if (!body?.children.some((child) => JAVA_CLASS_MEMBER_TYPES.has(child.type))) {
44
+ return undefined;
45
+ }
46
+ return one(javaContainerItem(node, "class", source));
47
+ }
48
+
49
+ function javaContainer(
50
+ node: SyntaxNodeLike,
51
+ kind: "interface" | "enum",
52
+ source: string,
53
+ ): OutlineItem[] | undefined {
54
+ const body = node.childForFieldName("body");
55
+ if (!body?.children.some((child) => JAVA_CONTAINER_MEMBER_TYPES.has(child.type))) {
56
+ return undefined;
57
+ }
58
+ return one(javaContainerItem(node, kind, source));
59
+ }
60
+
61
+ function javaContainerItem(
62
+ node: SyntaxNodeLike,
63
+ kind: "class" | "interface" | "enum",
64
+ source: string,
65
+ ): OutlineItem | null {
66
+ const name = node.childForFieldName("name");
67
+ if (!name) return null;
68
+ return {
69
+ name: name.text,
70
+ kind,
71
+ range: nodeToRange(node, source),
72
+ children: javaMembers(node.childForFieldName("body"), name.text, source),
73
+ };
74
+ }
75
+
76
+ function javaRecord(node: SyntaxNodeLike, source: string): OutlineItem | null {
77
+ const name = node.childForFieldName("name");
78
+ if (!name) return null;
79
+ return {
80
+ name: name.text,
81
+ kind: "record",
82
+ range: nodeToRange(node, source),
83
+ children: [
84
+ ...javaRecordFields(node.childForFieldName("parameters"), source),
85
+ ...javaMembers(node.childForFieldName("body"), name.text, source),
86
+ ],
87
+ };
88
+ }
89
+
90
+ function javaRecordFields(
91
+ parameters: SyntaxNodeLike | null | undefined,
92
+ source: string,
93
+ ): OutlineItem[] {
94
+ if (!parameters) return [];
95
+ return parameters.children.flatMap((child) => {
96
+ if (child.type !== "formal_parameter" && child.type !== "spread_parameter") return [];
97
+ return one(javaNamed(child, "field", source));
98
+ });
99
+ }
100
+
101
+ function javaMembers(
102
+ parent: SyntaxNodeLike | null | undefined,
103
+ ownerName: string,
104
+ source: string,
105
+ ): OutlineItem[] {
106
+ if (!parent) return [];
107
+ return parent.children.flatMap((child) => javaMemberItems(child, ownerName, source));
108
+ }
109
+
110
+ function javaMemberItems(node: SyntaxNodeLike, ownerName: string, source: string): OutlineItem[] {
111
+ switch (node.type) {
112
+ case "field_declaration":
113
+ case "constant_declaration":
114
+ return javaVariables(node, "field", source);
115
+ case "constructor_declaration":
116
+ return one(javaNamed(node, "method", source));
117
+ case "compact_constructor_declaration":
118
+ return [{ name: ownerName, kind: "method", range: nodeToRange(node, source) }];
119
+ case "method_declaration":
120
+ case "annotation_type_element_declaration":
121
+ return one(javaNamed(node, "method", source));
122
+ case "enum_constant":
123
+ return one(javaNamed(node, "enum-member", source));
124
+ case "enum_body_declarations":
125
+ return javaMembers(node, ownerName, source);
126
+ case "class_declaration":
127
+ return one(javaContainerItem(node, "class", source) ?? javaNamed(node, "class", source));
128
+ case "interface_declaration":
129
+ return one(
130
+ javaContainerItem(node, "interface", source) ?? javaNamed(node, "interface", source),
131
+ );
132
+ case "enum_declaration":
133
+ return one(javaContainerItem(node, "enum", source) ?? javaNamed(node, "enum", source));
134
+ case "record_declaration":
135
+ return one(javaRecord(node, source));
136
+ case "annotation_type_declaration":
137
+ return one(
138
+ javaContainerItem(node, "interface", source) ?? javaNamed(node, "interface", source),
139
+ );
140
+ default:
141
+ return [];
142
+ }
143
+ }
144
+
145
+ function javaVariables(node: SyntaxNodeLike, kind: string, source: string): OutlineItem[] {
146
+ const range = nodeToRange(node, source);
147
+ return node.childrenForFieldName("declarator").flatMap((declarator) => {
148
+ const name = declarator.childForFieldName("name");
149
+ return name ? [{ name: name.text, kind, range }] : [];
150
+ });
151
+ }
152
+
153
+ function javaNamed(node: SyntaxNodeLike, kind: string, source: string): OutlineItem | null {
154
+ const name = node.childForFieldName("name");
155
+ return name ? { name: name.text, kind, range: nodeToRange(node, source) } : null;
156
+ }
157
+
158
+ function kotlinClass(node: SyntaxNodeLike, source: string): OutlineItem | null {
159
+ const name = directChild(node, "type_identifier");
160
+ if (!name) return null;
161
+ const kind = hasDirectToken(node, "interface")
162
+ ? "interface"
163
+ : hasDirectToken(node, "enum")
164
+ ? "enum"
165
+ : "class";
166
+ const body = node.children.find(
167
+ (child) => child.type === "class_body" || child.type === "enum_class_body",
168
+ );
169
+ return {
170
+ name: name.text,
171
+ kind,
172
+ range: nodeToRange(node, source),
173
+ children: [...kotlinConstructorFields(node, source), ...kotlinMembers(body, name.text, source)],
174
+ };
175
+ }
176
+
177
+ function kotlinObject(node: SyntaxNodeLike, source: string): OutlineItem | null {
178
+ const name = directChild(node, "type_identifier");
179
+ if (!name) return null;
180
+ const body = directChild(node, "class_body");
181
+ return {
182
+ name: name.text,
183
+ kind: "object",
184
+ range: nodeToRange(node, source),
185
+ children: kotlinMembers(body, name.text, source),
186
+ };
187
+ }
188
+
189
+ function kotlinCompanion(node: SyntaxNodeLike, source: string): OutlineItem {
190
+ const name = directChild(node, "type_identifier")?.text ?? "Companion";
191
+ return {
192
+ name,
193
+ kind: "object",
194
+ range: nodeToRange(node, source),
195
+ children: kotlinMembers(directChild(node, "class_body"), name, source),
196
+ };
197
+ }
198
+
199
+ function kotlinMembers(
200
+ parent: SyntaxNodeLike | null | undefined,
201
+ ownerName: string,
202
+ source: string,
203
+ ): OutlineItem[] {
204
+ if (!parent) return [];
205
+ return parent.children.flatMap((child) => {
206
+ switch (child.type) {
207
+ case "property_declaration":
208
+ return kotlinProperties(child, "field", source);
209
+ case "function_declaration":
210
+ return kotlinFunction(child, "method", source) ?? [];
211
+ case "secondary_constructor":
212
+ return [{ name: ownerName, kind: "method", range: nodeToRange(child, source) }];
213
+ case "class_declaration":
214
+ return one(kotlinClass(child, source));
215
+ case "object_declaration":
216
+ return one(kotlinObject(child, source));
217
+ case "companion_object":
218
+ return [kotlinCompanion(child, source)];
219
+ case "type_alias":
220
+ return one(kotlinTypeAlias(child, source));
221
+ case "enum_entry":
222
+ return one(kotlinSimpleNamed(child, "enum-member", source));
223
+ default:
224
+ return [];
225
+ }
226
+ });
227
+ }
228
+
229
+ function kotlinConstructorFields(node: SyntaxNodeLike, source: string): OutlineItem[] {
230
+ const primaryConstructor = directChild(node, "primary_constructor");
231
+ if (!primaryConstructor) return [];
232
+ return primaryConstructor.children.flatMap((child) => {
233
+ if (child.type !== "class_parameter" || !directChild(child, "binding_pattern_kind")) return [];
234
+ return one(kotlinSimpleNamed(child, "field", source));
235
+ });
236
+ }
237
+
238
+ function kotlinFunction(
239
+ node: SyntaxNodeLike,
240
+ kind: "function" | "method",
241
+ source: string,
242
+ ): OutlineItem[] | undefined {
243
+ if (node.childForFieldName("name")) return undefined;
244
+ return one(kotlinSimpleNamed(node, kind, source));
245
+ }
246
+
247
+ function kotlinProperties(
248
+ node: SyntaxNodeLike,
249
+ memberKind: "field" | undefined,
250
+ source: string,
251
+ ): OutlineItem[] {
252
+ const kind = memberKind ?? (containsToken(node, "const") ? "constant" : "variable");
253
+ const declarations = node.children.filter(
254
+ (child) => child.type === "variable_declaration" || child.type === "multi_variable_declaration",
255
+ );
256
+ const range = nodeToRange(node, source);
257
+ return declarations.flatMap((declaration) =>
258
+ simpleIdentifiers(declaration).map((name) => ({ name, kind, range })),
259
+ );
260
+ }
261
+
262
+ function kotlinTypeAlias(node: SyntaxNodeLike, source: string): OutlineItem | null {
263
+ const name = directChild(node, "type_identifier");
264
+ return name ? { name: name.text, kind: "type", range: nodeToRange(node, source) } : null;
265
+ }
266
+
267
+ function kotlinSimpleNamed(node: SyntaxNodeLike, kind: string, source: string): OutlineItem | null {
268
+ const name = directChild(node, "simple_identifier");
269
+ return name ? { name: name.text, kind, range: nodeToRange(node, source) } : null;
270
+ }
271
+
272
+ function simpleIdentifiers(node: SyntaxNodeLike): string[] {
273
+ if (node.type === "simple_identifier") return [node.text];
274
+ return node.children.flatMap(simpleIdentifiers);
275
+ }
276
+
277
+ function directChild(node: SyntaxNodeLike, type: string): SyntaxNodeLike | null {
278
+ return node.children.find((child) => child.type === type) ?? null;
279
+ }
280
+
281
+ function hasDirectToken(node: SyntaxNodeLike, type: string): boolean {
282
+ return node.children.some((child) => child.type === type);
283
+ }
284
+
285
+ function containsToken(node: SyntaxNodeLike, type: string): boolean {
286
+ return (
287
+ node.type === type ||
288
+ (node.children.length === 0 && node.text === type) ||
289
+ node.children.some((child) => containsToken(child, type))
290
+ );
291
+ }
292
+
293
+ const JAVA_CLASS_MEMBER_TYPES = new Set([
294
+ "annotation_type_declaration",
295
+ "class_declaration",
296
+ "compact_constructor_declaration",
297
+ "constructor_declaration",
298
+ "enum_declaration",
299
+ "field_declaration",
300
+ "interface_declaration",
301
+ "method_declaration",
302
+ "record_declaration",
303
+ ]);
304
+
305
+ const JAVA_CONTAINER_MEMBER_TYPES = new Set([
306
+ ...JAVA_CLASS_MEMBER_TYPES,
307
+ "constant_declaration",
308
+ "enum_body_declarations",
309
+ "enum_constant",
310
+ "annotation_type_element_declaration",
311
+ ]);