@mrclrchtr/supi-code-intelligence 4.1.0 → 4.3.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 +4 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/utils.ts +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +5 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/language.ts +2 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/operation-support.ts +19 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/syntax-node.ts +1 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-c-family.ts +230 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-html-sql.ts +186 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-jvm.ts +311 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-polyglot.ts +218 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline-scripting.ts +307 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/outline.ts +9 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +6 -2
- package/package.json +5 -5
- package/src/analysis/search/pattern.ts +2 -2
- package/src/analysis/target/symbol.ts +5 -2
- package/src/extension.ts +5 -1
- package/src/session/orientation/collect.ts +134 -180
- package/src/session/orientation/context-sections.ts +14 -48
- package/src/session/orientation-types.ts +14 -4
- package/src/session/orientation-workflow.ts +20 -48
- package/src/substrate/lsp/lifecycle.ts +55 -3
- package/src/substrate/lsp/state.ts +6 -0
- package/src/tool/graph/execute.ts +1 -1
- package/src/tool/graph/markdown.ts +222 -0
- package/src/tool/orientation/markdown.ts +66 -11
- package/src/tool/register.ts +10 -0
- package/src/ui/footer.ts +33 -8
- package/src/ui/markdown/overview-data.ts +3 -15
- package/src/ui/markdown/overview.ts +4 -10
- package/src/ui/markdown/types.ts +0 -1
- package/src/tool/graph/calls-md.ts +0 -41
- package/src/tool/graph/implementations-md.ts +0 -57
- package/src/tool/graph/markdown-base.ts +0 -88
- package/src/tool/graph/provider-location-md.ts +0 -9
- package/src/tool/graph/references-md.ts +0 -41
package/README.md
CHANGED
|
@@ -41,6 +41,8 @@ The extension detects project languages and starts matching language servers. In
|
|
|
41
41
|
| Kotlin | `kotlin-lsp` |
|
|
42
42
|
| R | `R` with `languageserver` |
|
|
43
43
|
|
|
44
|
+
Semantic and structural support intentionally differ where the syntax differs: Ruby LSP handles ERB templates, and gopls handles `go.mod`, while AST search excludes both rather than parsing them with the wrong Tree-sitter grammar. Ruby gemspecs and KornShell files use the existing Ruby and Bash structural grammars.
|
|
45
|
+
|
|
44
46
|
Check runtime status with:
|
|
45
47
|
|
|
46
48
|
```text
|
|
@@ -64,7 +66,7 @@ The extension registers exactly eight `code_*` tools:
|
|
|
64
66
|
|
|
65
67
|
`code_impact`, `code_context`, `code_brief`, `code_references`, `code_calls`, and `code_implementations` are not compatibility aliases.
|
|
66
68
|
|
|
67
|
-
A
|
|
69
|
+
A complete manifest-derived architecture overview is injected once near session start when a project model is available; discovered modules, descriptions, entrypoints, and relationships are not truncated.
|
|
68
70
|
|
|
69
71
|
## Exact-one target selectors
|
|
70
72
|
|
|
@@ -157,7 +159,7 @@ code_find({ query: "@scope/package", mode: "ast", kind: "import", scope: ["src"]
|
|
|
157
159
|
|
|
158
160
|
Use PI's `grep` tool for literal or regex source search when it is active. `code_find` does not redirect removed text/regex calls to another tool.
|
|
159
161
|
|
|
160
|
-
AST `kind` accepts exactly `definition`, `import`, `export`, `call`, `type`, `interface`, `class`, `method`, and `enum`. AST `call` finds written call-site names, not symbol identity. Use `code_graph` references on a resolved target for symbol-identity relationships.
|
|
162
|
+
AST `kind` accepts exactly `definition`, `import`, `export`, `call`, `type`, `interface`, `class`, `method`, and `enum`. Outline-backed kinds support every vendored grammar family; HTML definitions are elements with non-empty `id` attributes, while SQL definitions are supported `CREATE` declarations and shallow table/type members. Imports and exports remain JavaScript/TypeScript-only. AST `call` finds written call-site names, not symbol identity. Use `code_graph` references on a resolved target for symbol-identity relationships.
|
|
161
163
|
|
|
162
164
|
#### AST Scan universe
|
|
163
165
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-code-runtime",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "SuPi code-runtime — shared workspace context, capability contracts, and canonical types for the code-understanding stack",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"!__tests__"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@mrclrchtr/supi-core": "4.
|
|
32
|
+
"@mrclrchtr/supi-core": "4.3.0"
|
|
33
33
|
},
|
|
34
34
|
"bundledDependencies": [
|
|
35
35
|
"@mrclrchtr/supi-core"
|
package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-code-runtime",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "SuPi code-runtime — shared workspace context, capability contracts, and canonical types for the code-understanding stack",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"!__tests__"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@mrclrchtr/supi-core": "4.
|
|
32
|
+
"@mrclrchtr/supi-core": "4.3.0"
|
|
33
33
|
},
|
|
34
34
|
"bundledDependencies": [
|
|
35
35
|
"@mrclrchtr/supi-core"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-lsp",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "SuPi LSP runtime — Language Server Protocol integration library for pi",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"vscode-jsonrpc": "^9.0.0",
|
|
38
38
|
"vscode-languageserver-protocol": "^3.17.5",
|
|
39
39
|
"vscode-languageserver-types": "^3.17.5",
|
|
40
|
-
"@mrclrchtr/supi-code-runtime": "4.
|
|
41
|
-
"@mrclrchtr/supi-core": "4.
|
|
40
|
+
"@mrclrchtr/supi-code-runtime": "4.3.0",
|
|
41
|
+
"@mrclrchtr/supi-core": "4.3.0"
|
|
42
42
|
},
|
|
43
43
|
"bundledDependencies": [
|
|
44
44
|
"@mrclrchtr/supi-code-runtime",
|
|
@@ -24,7 +24,7 @@ const EXT_TO_LANGUAGE: Record<string, string> = {
|
|
|
24
24
|
pyi: "python",
|
|
25
25
|
rs: "rust",
|
|
26
26
|
go: "go",
|
|
27
|
-
mod: "go",
|
|
27
|
+
mod: "go.mod",
|
|
28
28
|
c: "c",
|
|
29
29
|
h: "c",
|
|
30
30
|
cpp: "cpp",
|
|
@@ -52,7 +52,7 @@ const EXT_TO_LANGUAGE: Record<string, string> = {
|
|
|
52
52
|
sql: "sql",
|
|
53
53
|
r: "r",
|
|
54
54
|
rb: "ruby",
|
|
55
|
-
erb: "
|
|
55
|
+
erb: "erb",
|
|
56
56
|
gemspec: "ruby",
|
|
57
57
|
java: "java",
|
|
58
58
|
kt: "kotlin",
|
|
@@ -40,17 +40,17 @@ Coordinates in the library APIs use **1-based** line and character columns. Char
|
|
|
40
40
|
- JavaScript / TypeScript (`.js`, `.jsx`, `.ts`, `.tsx`, `.mjs`, `.cjs`, `.mts`, `.cts`)
|
|
41
41
|
- Python (`.py`, `.pyi`)
|
|
42
42
|
- Rust (`.rs`)
|
|
43
|
-
- Go (`.go
|
|
43
|
+
- Go (`.go`)
|
|
44
44
|
- C / C++ (`.c`, `.h`, `.cpp`, `.hpp`, `.cc`, `.cxx`, `.hxx`, `.c++`, `.h++`)
|
|
45
45
|
- Java (`.java`)
|
|
46
46
|
- Kotlin (`.kt`, `.kts`)
|
|
47
|
-
- Ruby (`.rb`)
|
|
48
|
-
- Bash / shell (`.sh`, `.bash`, `.zsh`)
|
|
47
|
+
- Ruby (`.rb`, `.gemspec`)
|
|
48
|
+
- Bash / shell (`.sh`, `.bash`, `.zsh`, `.ksh`)
|
|
49
49
|
- HTML (`.html`, `.htm`, `.xhtml`)
|
|
50
50
|
- R (`.r`)
|
|
51
51
|
- SQL (`.sql`)
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Outline collection supports every listed family. HTML outlines contain elements with non-empty `id` attributes; SQL outlines contain `CREATE` declarations and shallow table/type members. Import and export collection remains JavaScript/TypeScript-only, and call-site collection supports every listed family except HTML and SQL. Go module manifests and ERB templates are intentionally excluded because the Go and Ruby grammars do not parse those mixed or separate syntaxes; `supi-lsp` still handles them semantically. Consumers performing a bulk structural scan should use `getStructuralSearchSupportedExtensions(operation)` rather than treating parser support as operation support.
|
|
54
54
|
|
|
55
55
|
## Architecture
|
|
56
56
|
|
|
@@ -107,4 +107,4 @@ if (state.kind === "ready") {
|
|
|
107
107
|
- `src/operation-support.ts` — authoritative operation-specific extension support
|
|
108
108
|
- `src/session/service-registry.ts` — shared session-scoped structural service registry
|
|
109
109
|
- `src/provider/tree-sitter-provider.ts` — `StructuralProvider` adapter consumed by `@mrclrchtr/supi-code-intelligence`
|
|
110
|
-
- `src/tool/outline.ts`, `src/tool/imports.ts`, `src/tool/exports.ts`, `src/tool/node-at.ts`, `src/tool/callees.ts`, `src/tool/call-sites.ts` — structural analyses exposed through the library surface
|
|
110
|
+
- `src/tool/outline.ts`, `src/tool/outline-*.ts`, `src/tool/imports.ts`, `src/tool/exports.ts`, `src/tool/node-at.ts`, `src/tool/callees.ts`, `src/tool/call-sites.ts` — structural analyses exposed through the library surface
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-code-runtime",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "SuPi code-runtime — shared workspace context, capability contracts, and canonical types for the code-understanding stack",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"!__tests__"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@mrclrchtr/supi-core": "4.
|
|
32
|
+
"@mrclrchtr/supi-core": "4.3.0"
|
|
33
33
|
},
|
|
34
34
|
"bundledDependencies": [
|
|
35
35
|
"@mrclrchtr/supi-core"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrclrchtr/supi-tree-sitter",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "SuPi Tree-sitter library — structural AST analysis for pi",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"web-tree-sitter": "^0.26.8",
|
|
37
|
-
"@mrclrchtr/supi-code-runtime": "4.
|
|
38
|
-
"@mrclrchtr/supi-core": "4.
|
|
37
|
+
"@mrclrchtr/supi-code-runtime": "4.3.0",
|
|
38
|
+
"@mrclrchtr/supi-core": "4.3.0"
|
|
39
39
|
},
|
|
40
40
|
"bundledDependencies": [
|
|
41
41
|
"@mrclrchtr/supi-code-runtime",
|
|
@@ -25,7 +25,6 @@ const EXTENSION_GRAMMAR: Record<string, GrammarId> = {
|
|
|
25
25
|
".pyi": "python",
|
|
26
26
|
".rs": "rust",
|
|
27
27
|
".go": "go",
|
|
28
|
-
".mod": "go",
|
|
29
28
|
".c": "c",
|
|
30
29
|
".h": "c",
|
|
31
30
|
".cpp": "cpp",
|
|
@@ -39,9 +38,11 @@ const EXTENSION_GRAMMAR: Record<string, GrammarId> = {
|
|
|
39
38
|
".kt": "kotlin",
|
|
40
39
|
".kts": "kotlin",
|
|
41
40
|
".rb": "ruby",
|
|
41
|
+
".gemspec": "ruby",
|
|
42
42
|
".sh": "bash",
|
|
43
43
|
".bash": "bash",
|
|
44
44
|
".zsh": "bash",
|
|
45
|
+
".ksh": "bash",
|
|
45
46
|
".html": "html",
|
|
46
47
|
".htm": "html",
|
|
47
48
|
".xhtml": "html",
|
|
@@ -2,6 +2,24 @@ import { getSupportedExtensionGrammarEntries, isJsTsGrammar } from "./language.t
|
|
|
2
2
|
import { supportsCallSitesGrammar } from "./tool/call-sites.ts";
|
|
3
3
|
import type { GrammarId, SupportedExtension } from "./types.ts";
|
|
4
4
|
|
|
5
|
+
const OUTLINE_GRAMMARS: ReadonlySet<GrammarId> = new Set([
|
|
6
|
+
"javascript",
|
|
7
|
+
"typescript",
|
|
8
|
+
"tsx",
|
|
9
|
+
"python",
|
|
10
|
+
"rust",
|
|
11
|
+
"go",
|
|
12
|
+
"c",
|
|
13
|
+
"cpp",
|
|
14
|
+
"java",
|
|
15
|
+
"kotlin",
|
|
16
|
+
"ruby",
|
|
17
|
+
"bash",
|
|
18
|
+
"html",
|
|
19
|
+
"r",
|
|
20
|
+
"sql",
|
|
21
|
+
]);
|
|
22
|
+
|
|
5
23
|
/** Structural collection operations whose language support defines an AST Scan universe. */
|
|
6
24
|
const STRUCTURAL_SEARCH_OPERATIONS = ["outline", "imports", "exports", "call-sites"] as const;
|
|
7
25
|
|
|
@@ -31,6 +49,7 @@ export function supportsGrammarOperation(
|
|
|
31
49
|
case "call-sites":
|
|
32
50
|
return supportsCallSitesGrammar(grammar);
|
|
33
51
|
case "outline":
|
|
52
|
+
return OUTLINE_GRAMMARS.has(grammar);
|
|
34
53
|
case "imports":
|
|
35
54
|
case "exports":
|
|
36
55
|
return isJsTsGrammar(grammar);
|
|
@@ -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
|
+
]);
|