@mrclrchtr/supi-code-intelligence 4.0.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 (68) hide show
  1. package/README.md +8 -3
  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/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +1 -0
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +9 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
  6. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  7. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  8. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +1 -0
  9. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +9 -0
  10. package/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
  11. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -5
  12. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +1 -0
  13. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +9 -0
  14. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
  15. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  16. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  17. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +1 -0
  18. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +9 -0
  19. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
  20. package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
  21. package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +2 -2
  22. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +5 -5
  23. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -5
  24. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +1 -0
  25. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +9 -0
  26. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
  27. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  28. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  29. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +1 -0
  30. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +9 -0
  31. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
  32. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
  33. package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +2 -1
  34. package/node_modules/@mrclrchtr/supi-tree-sitter/src/operation-support.ts +19 -0
  35. package/node_modules/@mrclrchtr/supi-tree-sitter/src/syntax-node.ts +1 -0
  36. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-c-family.ts +230 -0
  37. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-html-sql.ts +186 -0
  38. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-jvm.ts +311 -0
  39. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-polyglot.ts +218 -0
  40. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-scripting.ts +307 -0
  41. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline.ts +9 -5
  42. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +6 -2
  43. package/package.json +6 -5
  44. package/src/analysis/search/pattern.ts +2 -2
  45. package/src/analysis/target/symbol.ts +5 -2
  46. package/src/app/app.ts +4 -1
  47. package/src/extension.ts +6 -84
  48. package/src/headless.ts +41 -0
  49. package/src/session/orientation/collect.ts +134 -180
  50. package/src/session/orientation/context-sections.ts +14 -48
  51. package/src/session/orientation-types.ts +14 -4
  52. package/src/session/orientation-workflow.ts +20 -48
  53. package/src/substrate/lsp/lifecycle.ts +25 -39
  54. package/src/substrate/lsp/state.ts +3 -0
  55. package/src/substrate/workspace-provider-host.ts +129 -0
  56. package/src/tool/graph/execute.ts +1 -1
  57. package/src/tool/graph/markdown.ts +222 -0
  58. package/src/tool/orientation/markdown.ts +66 -11
  59. package/src/tool/register.ts +10 -0
  60. package/src/ui/markdown/overview-data.ts +3 -15
  61. package/src/ui/markdown/overview.ts +4 -10
  62. package/src/ui/markdown/types.ts +0 -1
  63. package/src/substrate/tree-sitter/lifecycle.ts +0 -52
  64. package/src/tool/graph/calls-md.ts +0 -41
  65. package/src/tool/graph/implementations-md.ts +0 -57
  66. package/src/tool/graph/markdown-base.ts +0 -88
  67. package/src/tool/graph/provider-location-md.ts +0 -9
  68. package/src/tool/graph/references-md.ts +0 -41
@@ -10,4 +10,5 @@ export interface SyntaxNodeLike {
10
10
  startPosition: { row: number; column: number };
11
11
  endPosition: { row: number; column: number };
12
12
  childForFieldName(name: string): SyntaxNodeLike | null;
13
+ childrenForFieldName(name: string): SyntaxNodeLike[];
13
14
  }
@@ -0,0 +1,230 @@
1
+ import { nodeToRange } from "../coordinates.ts";
2
+ import type { SyntaxNodeLike } from "../syntax-node.ts";
3
+ import type { OutlineItem } from "../types.ts";
4
+
5
+ /** Extract C and C++ declarations from their grammar-specific node shapes. */
6
+ export function extractCFamilyOutlineItems(
7
+ node: SyntaxNodeLike,
8
+ source: string,
9
+ ): OutlineItem[] | undefined {
10
+ switch (node.type) {
11
+ case "class_specifier":
12
+ return one(typeContainer(node, "class", source));
13
+ case "struct_specifier":
14
+ return one(typeContainer(node, "struct", source));
15
+ case "union_specifier":
16
+ return one(typeContainer(node, "union", source));
17
+ case "enum_specifier":
18
+ return one(enumContainer(node, source));
19
+ case "type_definition":
20
+ return typeDefinitions(node, source);
21
+ case "alias_declaration":
22
+ return one(named(node, "type", source));
23
+ case "concept_definition":
24
+ return one(named(node, "concept", source));
25
+ case "namespace_definition": {
26
+ const item = namespaceItem(node, source);
27
+ return item ? [item] : collectDeclarations(node.childForFieldName("body"), source);
28
+ }
29
+ case "function_definition":
30
+ return one(declaratorItem(node, "function", source));
31
+ case "declaration":
32
+ return declarationItems(node, "variable", "function", source);
33
+ default:
34
+ return undefined;
35
+ }
36
+ }
37
+
38
+ function one(item: OutlineItem | null): OutlineItem[] {
39
+ return item ? [item] : [];
40
+ }
41
+
42
+ function named(node: SyntaxNodeLike, kind: string, source: string): OutlineItem | null {
43
+ const name = node.childForFieldName("name");
44
+ return name ? { name: name.text, kind, range: nodeToRange(node, source) } : null;
45
+ }
46
+
47
+ function typeContainer(
48
+ node: SyntaxNodeLike,
49
+ kind: "class" | "struct" | "union",
50
+ source: string,
51
+ ): OutlineItem | null {
52
+ const name = node.childForFieldName("name");
53
+ if (!name) return null;
54
+ return {
55
+ name: name.text,
56
+ kind,
57
+ range: nodeToRange(node, source),
58
+ children: collectTypeMembers(node.childForFieldName("body"), source),
59
+ };
60
+ }
61
+
62
+ function enumContainer(node: SyntaxNodeLike, source: string): OutlineItem | null {
63
+ const name = node.childForFieldName("name");
64
+ if (!name) return null;
65
+ return {
66
+ name: name.text,
67
+ kind: "enum",
68
+ range: nodeToRange(node, source),
69
+ children: enumMembers(node, source),
70
+ };
71
+ }
72
+
73
+ function enumMembers(node: SyntaxNodeLike, source: string): OutlineItem[] {
74
+ const body = node.childForFieldName("body");
75
+ return (
76
+ body?.children.flatMap((child) =>
77
+ child.type === "enumerator" ? one(named(child, "enum-member", source)) : [],
78
+ ) ?? []
79
+ );
80
+ }
81
+
82
+ function typeDefinitions(node: SyntaxNodeLike, source: string): OutlineItem[] {
83
+ const type = node.childForFieldName("type");
84
+ const kind = cTypeKind(type?.type);
85
+ const aliases = declaratorNodes(node).flatMap((declarator) => declaratorNames(declarator));
86
+ if (aliases.length === 0) return [];
87
+ const range = nodeToRange(node, source);
88
+ const children =
89
+ kind === "enum" && type
90
+ ? enumMembers(type, source)
91
+ : type
92
+ ? collectTypeMembers(type.childForFieldName("body"), source)
93
+ : undefined;
94
+ return aliases.map((name) => ({ name, kind, range, ...(children ? { children } : {}) }));
95
+ }
96
+
97
+ function cTypeKind(type: string | undefined): string {
98
+ switch (type) {
99
+ case "class_specifier":
100
+ return "class";
101
+ case "struct_specifier":
102
+ return "struct";
103
+ case "union_specifier":
104
+ return "union";
105
+ case "enum_specifier":
106
+ return "enum";
107
+ default:
108
+ return "type";
109
+ }
110
+ }
111
+
112
+ function namespaceItem(node: SyntaxNodeLike, source: string): OutlineItem | null {
113
+ const name = node.childForFieldName("name");
114
+ if (!name) return null;
115
+ return {
116
+ name: name.text,
117
+ kind: "namespace",
118
+ range: nodeToRange(node, source),
119
+ children: collectDeclarations(node.childForFieldName("body"), source),
120
+ };
121
+ }
122
+
123
+ function collectDeclarations(
124
+ parent: SyntaxNodeLike | null | undefined,
125
+ source: string,
126
+ ): OutlineItem[] {
127
+ if (!parent) return [];
128
+ return parent.children.flatMap((child) => {
129
+ const items = extractCFamilyOutlineItems(child, source);
130
+ return items ?? collectDeclarations(child, source);
131
+ });
132
+ }
133
+
134
+ function collectTypeMembers(
135
+ body: SyntaxNodeLike | null | undefined,
136
+ source: string,
137
+ ): OutlineItem[] {
138
+ if (!body) return [];
139
+ return body.children.flatMap((child) => typeMemberItems(child, source));
140
+ }
141
+
142
+ function typeMemberItems(node: SyntaxNodeLike, source: string): OutlineItem[] {
143
+ switch (node.type) {
144
+ case "field_declaration":
145
+ case "declaration":
146
+ return declarationItems(node, "field", "method", source);
147
+ case "function_definition":
148
+ return one(declaratorItem(node, "method", source));
149
+ case "class_specifier":
150
+ return one(typeContainer(node, "class", source));
151
+ case "struct_specifier":
152
+ return one(typeContainer(node, "struct", source));
153
+ case "union_specifier":
154
+ return one(typeContainer(node, "union", source));
155
+ case "enum_specifier":
156
+ return one(enumContainer(node, source));
157
+ case "type_definition":
158
+ return typeDefinitions(node, source);
159
+ case "alias_declaration":
160
+ return one(named(node, "type", source));
161
+ case "friend_declaration":
162
+ return [];
163
+ default:
164
+ return node.children.flatMap((child) => typeMemberItems(child, source));
165
+ }
166
+ }
167
+
168
+ function declarationItems(
169
+ node: SyntaxNodeLike,
170
+ valueKind: string,
171
+ functionKind: string,
172
+ source: string,
173
+ ): OutlineItem[] {
174
+ const range = nodeToRange(node, source);
175
+ return declaratorNodes(node).flatMap((declarator) =>
176
+ declaratorNames(declarator).map((name) => ({
177
+ name,
178
+ kind: isFunctionDeclarator(declarator) ? functionKind : valueKind,
179
+ range,
180
+ })),
181
+ );
182
+ }
183
+
184
+ function declaratorItem(node: SyntaxNodeLike, kind: string, source: string): OutlineItem | null {
185
+ const declarator = node.childForFieldName("declarator");
186
+ const name = declarator ? declaratorNames(declarator)[0] : undefined;
187
+ return name ? { name, kind, range: nodeToRange(node, source) } : null;
188
+ }
189
+
190
+ function declaratorNodes(node: SyntaxNodeLike): SyntaxNodeLike[] {
191
+ const declarators = node.childrenForFieldName("declarator");
192
+ if (declarators.length > 0) return declarators;
193
+ const declarator = node.childForFieldName("declarator");
194
+ return declarator ? [declarator] : [];
195
+ }
196
+
197
+ function declaratorNames(node: SyntaxNodeLike): string[] {
198
+ if (DECLARATOR_NAME_TYPES.has(node.type)) return [node.text];
199
+ if (node.type === "structured_binding_declarator") {
200
+ return node.children.filter((child) => child.type === "identifier").map((child) => child.text);
201
+ }
202
+ const nested = node.childrenForFieldName("declarator");
203
+ if (nested.length > 0) return nested.flatMap(declaratorNames);
204
+ const declarator = node.childForFieldName("declarator");
205
+ return declarator ? declaratorNames(declarator) : [];
206
+ }
207
+
208
+ function isFunctionDeclarator(node: SyntaxNodeLike): boolean {
209
+ if (node.type === "function_declarator") {
210
+ const subject = node.childForFieldName("declarator");
211
+ return subject?.type !== "parenthesized_declarator" || !containsPointer(subject);
212
+ }
213
+ const declarator = node.childForFieldName("declarator");
214
+ return declarator ? isFunctionDeclarator(declarator) : false;
215
+ }
216
+
217
+ function containsPointer(node: SyntaxNodeLike): boolean {
218
+ if (node.type === "pointer_declarator" || node.type === "reference_declarator") return true;
219
+ return node.children.some(containsPointer);
220
+ }
221
+
222
+ const DECLARATOR_NAME_TYPES = new Set([
223
+ "identifier",
224
+ "field_identifier",
225
+ "type_identifier",
226
+ "qualified_identifier",
227
+ "template_function",
228
+ "operator_name",
229
+ "destructor_name",
230
+ ]);
@@ -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
+ ]);