@optave/codegraph 3.10.0 → 3.11.1
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 +40 -33
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +91 -60
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/rules/index.d.ts.map +1 -1
- package/dist/ast-analysis/rules/index.js +77 -0
- package/dist/ast-analysis/rules/index.js.map +1 -1
- package/dist/ast-analysis/visitor-utils.d.ts +3 -0
- package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
- package/dist/ast-analysis/visitor-utils.js +83 -49
- package/dist/ast-analysis/visitor-utils.js.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.js +78 -62
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.js +61 -42
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/audit.js +1 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +2 -0
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/check.js +1 -1
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/children.js +1 -1
- package/dist/cli/commands/children.js.map +1 -1
- package/dist/cli/commands/diff-impact.js +1 -1
- package/dist/cli/commands/diff-impact.js.map +1 -1
- package/dist/cli/commands/embed.d.ts.map +1 -1
- package/dist/cli/commands/embed.js +49 -4
- package/dist/cli/commands/embed.js.map +1 -1
- package/dist/cli/commands/roles.js +1 -1
- package/dist/cli/commands/roles.js.map +1 -1
- package/dist/cli/commands/structure.js +1 -1
- package/dist/cli/commands/structure.js.map +1 -1
- package/dist/cli/shared/options.js +1 -1
- package/dist/cli/shared/options.js.map +1 -1
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +8 -0
- package/dist/db/connection.js.map +1 -1
- package/dist/domain/analysis/dependencies.d.ts.map +1 -1
- package/dist/domain/analysis/dependencies.js +106 -80
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
- package/dist/domain/analysis/fn-impact.js +77 -52
- package/dist/domain/analysis/fn-impact.js.map +1 -1
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +132 -121
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/graph/builder/helpers.d.ts +4 -4
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
- package/dist/domain/graph/builder/helpers.js +47 -33
- package/dist/domain/graph/builder/helpers.js.map +1 -1
- package/dist/domain/graph/builder/incremental.d.ts +6 -6
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
- package/dist/domain/graph/builder/incremental.js +148 -99
- package/dist/domain/graph/builder/incremental.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts +1 -0
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +23 -637
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.js +141 -98
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.js +82 -65
- package/dist/domain/graph/builder/stages/build-structure.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +84 -56
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +60 -51
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts +8 -6
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.js +107 -122
- package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
- package/dist/domain/graph/builder/stages/native-db-lifecycle.d.ts +14 -0
- package/dist/domain/graph/builder/stages/native-db-lifecycle.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/native-db-lifecycle.js +77 -0
- package/dist/domain/graph/builder/stages/native-db-lifecycle.js.map +1 -0
- package/dist/domain/graph/builder/stages/native-orchestrator.d.ts +62 -0
- package/dist/domain/graph/builder/stages/native-orchestrator.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/native-orchestrator.js +747 -0
- package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -0
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +73 -22
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/cycles.d.ts +6 -4
- package/dist/domain/graph/cycles.d.ts.map +1 -1
- package/dist/domain/graph/cycles.js +50 -55
- package/dist/domain/graph/cycles.js.map +1 -1
- package/dist/domain/graph/journal.d.ts.map +1 -1
- package/dist/domain/graph/journal.js +89 -70
- package/dist/domain/graph/journal.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +28 -20
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +12 -23
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +153 -80
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/search/generator.d.ts +3 -1
- package/dist/domain/search/generator.d.ts.map +1 -1
- package/dist/domain/search/generator.js +68 -45
- package/dist/domain/search/generator.js.map +1 -1
- package/dist/domain/search/models.d.ts +18 -0
- package/dist/domain/search/models.d.ts.map +1 -1
- package/dist/domain/search/models.js +72 -4
- package/dist/domain/search/models.js.map +1 -1
- package/dist/domain/search/search/hybrid.d.ts.map +1 -1
- package/dist/domain/search/search/hybrid.js +49 -40
- package/dist/domain/search/search/hybrid.js.map +1 -1
- package/dist/domain/search/search/semantic.d.ts.map +1 -1
- package/dist/domain/search/search/semantic.js +69 -49
- package/dist/domain/search/search/semantic.js.map +1 -1
- package/dist/domain/wasm-worker-entry.js +209 -137
- package/dist/domain/wasm-worker-entry.js.map +1 -1
- package/dist/extractors/c.js +25 -6
- package/dist/extractors/c.js.map +1 -1
- package/dist/extractors/cpp.js +47 -6
- package/dist/extractors/cpp.js.map +1 -1
- package/dist/extractors/cuda.js +90 -14
- package/dist/extractors/cuda.js.map +1 -1
- package/dist/extractors/elixir.js +108 -4
- package/dist/extractors/elixir.js.map +1 -1
- package/dist/extractors/erlang.js +56 -20
- package/dist/extractors/erlang.js.map +1 -1
- package/dist/extractors/fsharp.d.ts +7 -0
- package/dist/extractors/fsharp.d.ts.map +1 -1
- package/dist/extractors/fsharp.js +94 -0
- package/dist/extractors/fsharp.js.map +1 -1
- package/dist/extractors/gleam.d.ts.map +1 -1
- package/dist/extractors/gleam.js +29 -33
- package/dist/extractors/gleam.js.map +1 -1
- package/dist/extractors/groovy.js +41 -1
- package/dist/extractors/groovy.js.map +1 -1
- package/dist/extractors/haskell.js +48 -4
- package/dist/extractors/haskell.js.map +1 -1
- package/dist/extractors/helpers.d.ts +79 -1
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +137 -0
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/java.d.ts.map +1 -1
- package/dist/extractors/java.js +37 -49
- package/dist/extractors/java.js.map +1 -1
- package/dist/extractors/javascript.d.ts.map +1 -1
- package/dist/extractors/javascript.js +44 -44
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/julia.js +198 -74
- package/dist/extractors/julia.js.map +1 -1
- package/dist/extractors/kotlin.js +4 -0
- package/dist/extractors/kotlin.js.map +1 -1
- package/dist/extractors/objc.js +184 -47
- package/dist/extractors/objc.js.map +1 -1
- package/dist/extractors/python.js +7 -4
- package/dist/extractors/python.js.map +1 -1
- package/dist/extractors/r.d.ts.map +1 -1
- package/dist/extractors/r.js +103 -87
- package/dist/extractors/r.js.map +1 -1
- package/dist/extractors/scala.d.ts.map +1 -1
- package/dist/extractors/scala.js +18 -32
- package/dist/extractors/scala.js.map +1 -1
- package/dist/extractors/solidity.d.ts.map +1 -1
- package/dist/extractors/solidity.js +55 -69
- package/dist/extractors/solidity.js.map +1 -1
- package/dist/extractors/verilog.js +80 -15
- package/dist/extractors/verilog.js.map +1 -1
- package/dist/features/boundaries.d.ts.map +1 -1
- package/dist/features/boundaries.js +49 -39
- package/dist/features/boundaries.js.map +1 -1
- package/dist/features/cfg.d.ts.map +1 -1
- package/dist/features/cfg.js +90 -63
- package/dist/features/cfg.js.map +1 -1
- package/dist/features/check.d.ts.map +1 -1
- package/dist/features/check.js +43 -34
- package/dist/features/check.js.map +1 -1
- package/dist/features/cochange.d.ts.map +1 -1
- package/dist/features/cochange.js +68 -56
- package/dist/features/cochange.js.map +1 -1
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +105 -75
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +37 -29
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/flow.d.ts.map +1 -1
- package/dist/features/flow.js +31 -22
- package/dist/features/flow.js.map +1 -1
- package/dist/features/graph-enrichment.d.ts.map +1 -1
- package/dist/features/graph-enrichment.js +77 -70
- package/dist/features/graph-enrichment.js.map +1 -1
- package/dist/features/owners.d.ts +17 -26
- package/dist/features/owners.d.ts.map +1 -1
- package/dist/features/owners.js +120 -109
- package/dist/features/owners.js.map +1 -1
- package/dist/features/sequence.d.ts.map +1 -1
- package/dist/features/sequence.js +59 -54
- package/dist/features/sequence.js.map +1 -1
- package/dist/features/structure-query.d.ts.map +1 -1
- package/dist/features/structure-query.js +60 -60
- package/dist/features/structure-query.js.map +1 -1
- package/dist/features/structure.js +28 -36
- package/dist/features/structure.js.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.js +100 -69
- package/dist/graph/algorithms/leiden/optimiser.js.map +1 -1
- package/dist/graph/classifiers/roles.d.ts.map +1 -1
- package/dist/graph/classifiers/roles.js +63 -59
- package/dist/graph/classifiers/roles.js.map +1 -1
- package/dist/infrastructure/config.d.ts +1 -1
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +1 -1
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/mcp/tool-registry.d.ts.map +1 -1
- package/dist/mcp/tool-registry.js +4 -0
- package/dist/mcp/tool-registry.js.map +1 -1
- package/dist/mcp/tools/semantic-search.d.ts +1 -0
- package/dist/mcp/tools/semantic-search.d.ts.map +1 -1
- package/dist/mcp/tools/semantic-search.js +1 -0
- package/dist/mcp/tools/semantic-search.js.map +1 -1
- package/dist/presentation/cfg.d.ts.map +1 -1
- package/dist/presentation/cfg.js +44 -29
- package/dist/presentation/cfg.js.map +1 -1
- package/dist/presentation/flow.d.ts.map +1 -1
- package/dist/presentation/flow.js +58 -38
- package/dist/presentation/flow.js.map +1 -1
- package/dist/types.d.ts +16 -2
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-erlang.wasm +0 -0
- package/grammars/tree-sitter-fsharp.wasm +0 -0
- package/grammars/tree-sitter-fsharp_signature.wasm +0 -0
- package/grammars/tree-sitter-gleam.wasm +0 -0
- package/package.json +10 -10
- package/src/ast-analysis/engine.ts +145 -61
- package/src/ast-analysis/rules/index.ts +87 -0
- package/src/ast-analysis/visitor-utils.ts +86 -46
- package/src/ast-analysis/visitors/ast-store-visitor.ts +104 -69
- package/src/ast-analysis/visitors/dataflow-visitor.ts +86 -47
- package/src/cli/commands/audit.ts +1 -1
- package/src/cli/commands/build.ts +2 -0
- package/src/cli/commands/check.ts +1 -1
- package/src/cli/commands/children.ts +1 -1
- package/src/cli/commands/diff-impact.ts +1 -1
- package/src/cli/commands/embed.ts +54 -4
- package/src/cli/commands/roles.ts +1 -1
- package/src/cli/commands/structure.ts +1 -1
- package/src/cli/shared/options.ts +1 -1
- package/src/db/connection.ts +8 -0
- package/src/domain/analysis/dependencies.ts +166 -85
- package/src/domain/analysis/fn-impact.ts +120 -50
- package/src/domain/analysis/module-map.ts +175 -140
- package/src/domain/graph/builder/helpers.ts +85 -76
- package/src/domain/graph/builder/incremental.ts +223 -131
- package/src/domain/graph/builder/pipeline.ts +32 -785
- package/src/domain/graph/builder/stages/build-edges.ts +207 -142
- package/src/domain/graph/builder/stages/build-structure.ts +115 -82
- package/src/domain/graph/builder/stages/detect-changes.ts +107 -64
- package/src/domain/graph/builder/stages/finalize.ts +72 -70
- package/src/domain/graph/builder/stages/insert-nodes.ts +154 -120
- package/src/domain/graph/builder/stages/native-db-lifecycle.ts +74 -0
- package/src/domain/graph/builder/stages/native-orchestrator.ts +942 -0
- package/src/domain/graph/builder/stages/resolve-imports.ts +79 -25
- package/src/domain/graph/cycles.ts +51 -49
- package/src/domain/graph/journal.ts +84 -69
- package/src/domain/graph/watcher.ts +29 -25
- package/src/domain/parser.ts +170 -67
- package/src/domain/search/generator.ts +132 -74
- package/src/domain/search/models.ts +75 -4
- package/src/domain/search/search/hybrid.ts +53 -42
- package/src/domain/search/search/semantic.ts +105 -65
- package/src/domain/wasm-worker-entry.ts +243 -153
- package/src/extractors/c.ts +27 -8
- package/src/extractors/cpp.ts +50 -8
- package/src/extractors/cuda.ts +90 -16
- package/src/extractors/elixir.ts +103 -4
- package/src/extractors/erlang.ts +63 -20
- package/src/extractors/fsharp.ts +104 -0
- package/src/extractors/gleam.ts +40 -39
- package/src/extractors/groovy.ts +45 -1
- package/src/extractors/haskell.ts +45 -4
- package/src/extractors/helpers.ts +205 -1
- package/src/extractors/java.ts +42 -45
- package/src/extractors/javascript.ts +44 -43
- package/src/extractors/julia.ts +191 -77
- package/src/extractors/kotlin.ts +4 -0
- package/src/extractors/objc.ts +171 -47
- package/src/extractors/python.ts +5 -3
- package/src/extractors/r.ts +104 -82
- package/src/extractors/scala.ts +24 -36
- package/src/extractors/solidity.ts +59 -78
- package/src/extractors/verilog.ts +83 -15
- package/src/features/boundaries.ts +64 -46
- package/src/features/cfg.ts +145 -74
- package/src/features/check.ts +60 -43
- package/src/features/cochange.ts +95 -72
- package/src/features/complexity.ts +134 -79
- package/src/features/dataflow.ts +57 -34
- package/src/features/flow.ts +48 -24
- package/src/features/graph-enrichment.ts +105 -70
- package/src/features/owners.ts +186 -146
- package/src/features/sequence.ts +99 -69
- package/src/features/structure-query.ts +94 -79
- package/src/features/structure.ts +56 -56
- package/src/graph/algorithms/leiden/optimiser.ts +142 -87
- package/src/graph/classifiers/roles.ts +64 -54
- package/src/infrastructure/config.ts +1 -1
- package/src/mcp/tool-registry.ts +5 -0
- package/src/mcp/tools/semantic-search.ts +2 -0
- package/src/presentation/cfg.ts +48 -32
- package/src/presentation/flow.ts +100 -52
- package/src/types.ts +16 -1
package/src/extractors/scala.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Call,
|
|
3
|
+
Definition,
|
|
3
4
|
ExtractorOutput,
|
|
4
5
|
SubDeclaration,
|
|
5
6
|
TreeSitterNode,
|
|
@@ -59,52 +60,37 @@ function walkScalaNode(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
59
60
|
// ── Walk-path per-node-type handlers ────────────────────────────────────────
|
|
60
61
|
|
|
61
62
|
function handleScalaClassDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
62
|
-
|
|
63
|
-
if (!nameNode) return;
|
|
64
|
-
const name = nameNode.text;
|
|
65
|
-
const children = extractScalaBodyMembers(node, name, ctx);
|
|
66
|
-
|
|
67
|
-
ctx.definitions.push({
|
|
68
|
-
name,
|
|
69
|
-
kind: 'class',
|
|
70
|
-
line: node.startPosition.row + 1,
|
|
71
|
-
endLine: nodeEndLine(node),
|
|
72
|
-
children: children.length > 0 ? children : undefined,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
extractScalaInheritance(node, name, ctx);
|
|
63
|
+
emitScalaTypeDef(node, ctx, 'class');
|
|
76
64
|
}
|
|
77
65
|
|
|
78
66
|
function handleScalaTraitDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
79
|
-
|
|
80
|
-
if (!nameNode) return;
|
|
81
|
-
const name = nameNode.text;
|
|
82
|
-
const children = extractScalaBodyMembers(node, name, ctx);
|
|
83
|
-
|
|
84
|
-
ctx.definitions.push({
|
|
85
|
-
name,
|
|
86
|
-
kind: 'interface',
|
|
87
|
-
line: node.startPosition.row + 1,
|
|
88
|
-
endLine: nodeEndLine(node),
|
|
89
|
-
children: children.length > 0 ? children : undefined,
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
extractScalaInheritance(node, name, ctx);
|
|
67
|
+
emitScalaTypeDef(node, ctx, 'interface');
|
|
93
68
|
}
|
|
94
69
|
|
|
95
70
|
function handleScalaObjectDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
71
|
+
emitScalaTypeDef(node, ctx, 'class');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function emitScalaTypeDef(
|
|
75
|
+
node: TreeSitterNode,
|
|
76
|
+
ctx: ExtractorOutput,
|
|
77
|
+
kind: 'class' | 'interface',
|
|
78
|
+
): void {
|
|
96
79
|
const nameNode = node.childForFieldName('name');
|
|
97
80
|
if (!nameNode) return;
|
|
98
81
|
const name = nameNode.text;
|
|
99
|
-
const children =
|
|
82
|
+
const { children, methods } = collectScalaBodyMembers(node, name);
|
|
100
83
|
|
|
84
|
+
// Push the type def before its methods so the definition order follows
|
|
85
|
+
// source-line order (matches native, which walks depth-first).
|
|
101
86
|
ctx.definitions.push({
|
|
102
87
|
name,
|
|
103
|
-
kind
|
|
88
|
+
kind,
|
|
104
89
|
line: node.startPosition.row + 1,
|
|
105
90
|
endLine: nodeEndLine(node),
|
|
106
91
|
children: children.length > 0 ? children : undefined,
|
|
107
92
|
});
|
|
93
|
+
for (const m of methods) ctx.definitions.push(m);
|
|
108
94
|
|
|
109
95
|
extractScalaInheritance(node, name, ctx);
|
|
110
96
|
}
|
|
@@ -224,14 +210,14 @@ function extractScalaInheritance(node: TreeSitterNode, name: string, ctx: Extrac
|
|
|
224
210
|
|
|
225
211
|
// ── Body member extraction ──────────────────────────────────────────────────
|
|
226
212
|
|
|
227
|
-
function
|
|
213
|
+
function collectScalaBodyMembers(
|
|
228
214
|
parentNode: TreeSitterNode,
|
|
229
215
|
parentName: string,
|
|
230
|
-
|
|
231
|
-
): SubDeclaration[] {
|
|
216
|
+
): { children: SubDeclaration[]; methods: Definition[] } {
|
|
232
217
|
const children: SubDeclaration[] = [];
|
|
218
|
+
const methods: Definition[] = [];
|
|
233
219
|
const body = findChild(parentNode, 'template_body');
|
|
234
|
-
if (!body) return children;
|
|
220
|
+
if (!body) return { children, methods };
|
|
235
221
|
|
|
236
222
|
for (let i = 0; i < body.childCount; i++) {
|
|
237
223
|
const member = body.child(i);
|
|
@@ -240,12 +226,14 @@ function extractScalaBodyMembers(
|
|
|
240
226
|
if (member.type === 'function_definition') {
|
|
241
227
|
const methName = member.childForFieldName('name');
|
|
242
228
|
if (methName) {
|
|
243
|
-
|
|
229
|
+
const params = extractScalaParameters(member);
|
|
230
|
+
methods.push({
|
|
244
231
|
name: `${parentName}.${methName.text}`,
|
|
245
232
|
kind: 'method',
|
|
246
233
|
line: member.startPosition.row + 1,
|
|
247
234
|
endLine: member.endPosition.row + 1,
|
|
248
235
|
visibility: extractModifierVisibility(member),
|
|
236
|
+
children: params.length > 0 ? params : undefined,
|
|
249
237
|
});
|
|
250
238
|
}
|
|
251
239
|
} else if (member.type === 'val_definition' || member.type === 'var_definition') {
|
|
@@ -264,7 +252,7 @@ function extractScalaBodyMembers(
|
|
|
264
252
|
}
|
|
265
253
|
}
|
|
266
254
|
|
|
267
|
-
return children;
|
|
255
|
+
return { children, methods };
|
|
268
256
|
}
|
|
269
257
|
|
|
270
258
|
// ── Parameter extraction ────────────────────────────────────────────────────
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Call,
|
|
3
|
-
ExtractorOutput,
|
|
4
|
-
SubDeclaration,
|
|
5
|
-
TreeSitterNode,
|
|
6
|
-
TreeSitterTree,
|
|
7
|
-
} from '../types.js';
|
|
1
|
+
import type { ExtractorOutput, SubDeclaration, TreeSitterNode, TreeSitterTree } from '../types.js';
|
|
8
2
|
import {
|
|
9
3
|
extractModifierVisibility,
|
|
4
|
+
extractSimpleParameters,
|
|
10
5
|
findChild,
|
|
6
|
+
findFirstChildOfTypes,
|
|
11
7
|
findParentNode,
|
|
12
8
|
nodeEndLine,
|
|
9
|
+
nodeStartLine,
|
|
10
|
+
pushCall,
|
|
11
|
+
pushImport,
|
|
13
12
|
stripQuotes,
|
|
14
13
|
} from './helpers.js';
|
|
15
14
|
|
|
@@ -103,7 +102,7 @@ function handleContractDecl(
|
|
|
103
102
|
ctx.definitions.push({
|
|
104
103
|
name,
|
|
105
104
|
kind,
|
|
106
|
-
line: node
|
|
105
|
+
line: nodeStartLine(node),
|
|
107
106
|
endLine: nodeEndLine(node),
|
|
108
107
|
children: members.length > 0 ? members : undefined,
|
|
109
108
|
});
|
|
@@ -125,7 +124,7 @@ function extractContractMembers(body: TreeSitterNode): SubDeclaration[] {
|
|
|
125
124
|
|
|
126
125
|
/** Map a single contract body child to a SubDeclaration, or null if not a recognized member. */
|
|
127
126
|
function extractContractMember(child: TreeSitterNode): SubDeclaration | null {
|
|
128
|
-
const line = child
|
|
127
|
+
const line = nodeStartLine(child);
|
|
129
128
|
switch (child.type) {
|
|
130
129
|
case 'function_definition': {
|
|
131
130
|
const fnName = child.childForFieldName('name');
|
|
@@ -156,15 +155,24 @@ function extractContractMember(child: TreeSitterNode): SubDeclaration | null {
|
|
|
156
155
|
}
|
|
157
156
|
}
|
|
158
157
|
|
|
159
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* Extract inheritance (extends) relationships from a contract node.
|
|
160
|
+
*
|
|
161
|
+
* Each parent in `contract A is B, C, D { }` is its own `inheritance_specifier`
|
|
162
|
+
* sibling under the contract node (see tree-sitter-solidity grammar:
|
|
163
|
+
* `_class_heritage: "is" commaSep1($.inheritance_specifier)`), so we must walk
|
|
164
|
+
* all direct children rather than stopping at the first match.
|
|
165
|
+
*/
|
|
160
166
|
function extractInheritance(node: TreeSitterNode, name: string, ctx: ExtractorOutput): void {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
167
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
168
|
+
const inheritance = node.child(i);
|
|
169
|
+
if (!inheritance || inheritance.type !== 'inheritance_specifier') continue;
|
|
170
|
+
for (let j = 0; j < inheritance.childCount; j++) {
|
|
171
|
+
const child = inheritance.child(j);
|
|
172
|
+
if (!child) continue;
|
|
173
|
+
if (child.type === 'user_defined_type' || child.type === 'identifier') {
|
|
174
|
+
ctx.classes.push({ name, extends: child.text, line: nodeStartLine(node) });
|
|
175
|
+
}
|
|
168
176
|
}
|
|
169
177
|
}
|
|
170
178
|
}
|
|
@@ -182,19 +190,16 @@ function handleStructDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
182
190
|
members.push({
|
|
183
191
|
name: memberName.text,
|
|
184
192
|
kind: 'property',
|
|
185
|
-
line: child
|
|
193
|
+
line: nodeStartLine(child),
|
|
186
194
|
});
|
|
187
195
|
}
|
|
188
196
|
}
|
|
189
197
|
}
|
|
190
198
|
|
|
191
|
-
const parent = findParentNode(node, SOL_PARENT_TYPES);
|
|
192
|
-
const fullName = parent ? `${parent}.${nameNode.text}` : nameNode.text;
|
|
193
|
-
|
|
194
199
|
ctx.definitions.push({
|
|
195
|
-
name:
|
|
200
|
+
name: qualifyWithParent(node, nameNode.text),
|
|
196
201
|
kind: 'struct',
|
|
197
|
-
line: node
|
|
202
|
+
line: nodeStartLine(node),
|
|
198
203
|
endLine: nodeEndLine(node),
|
|
199
204
|
children: members.length > 0 ? members : undefined,
|
|
200
205
|
});
|
|
@@ -208,17 +213,14 @@ function handleEnumDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
208
213
|
for (let i = 0; i < node.childCount; i++) {
|
|
209
214
|
const child = node.child(i);
|
|
210
215
|
if (child && child.type === 'enum_value') {
|
|
211
|
-
members.push({ name: child.text, kind: 'constant', line: child
|
|
216
|
+
members.push({ name: child.text, kind: 'constant', line: nodeStartLine(child) });
|
|
212
217
|
}
|
|
213
218
|
}
|
|
214
219
|
|
|
215
|
-
const parent = findParentNode(node, SOL_PARENT_TYPES);
|
|
216
|
-
const fullName = parent ? `${parent}.${nameNode.text}` : nameNode.text;
|
|
217
|
-
|
|
218
220
|
ctx.definitions.push({
|
|
219
|
-
name:
|
|
221
|
+
name: qualifyWithParent(node, nameNode.text),
|
|
220
222
|
kind: 'enum',
|
|
221
|
-
line: node
|
|
223
|
+
line: nodeStartLine(node),
|
|
222
224
|
endLine: nodeEndLine(node),
|
|
223
225
|
children: members.length > 0 ? members : undefined,
|
|
224
226
|
});
|
|
@@ -235,7 +237,7 @@ function handleFunctionDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
235
237
|
ctx.definitions.push({
|
|
236
238
|
name: fullName,
|
|
237
239
|
kind,
|
|
238
|
-
line: node
|
|
240
|
+
line: nodeStartLine(node),
|
|
239
241
|
endLine: nodeEndLine(node),
|
|
240
242
|
children: params.length > 0 ? params : undefined,
|
|
241
243
|
visibility: extractSolVisibility(node),
|
|
@@ -245,13 +247,10 @@ function handleFunctionDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
245
247
|
function handleModifierDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
246
248
|
const nameNode = node.childForFieldName('name');
|
|
247
249
|
if (!nameNode) return;
|
|
248
|
-
const parent = findParentNode(node, SOL_PARENT_TYPES);
|
|
249
|
-
const fullName = parent ? `${parent}.${nameNode.text}` : nameNode.text;
|
|
250
|
-
|
|
251
250
|
ctx.definitions.push({
|
|
252
|
-
name:
|
|
251
|
+
name: qualifyWithParent(node, nameNode.text),
|
|
253
252
|
kind: 'function',
|
|
254
|
-
line: node
|
|
253
|
+
line: nodeStartLine(node),
|
|
255
254
|
endLine: nodeEndLine(node),
|
|
256
255
|
decorators: ['modifier'],
|
|
257
256
|
});
|
|
@@ -260,13 +259,10 @@ function handleModifierDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
260
259
|
function handleEventDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
261
260
|
const nameNode = node.childForFieldName('name');
|
|
262
261
|
if (!nameNode) return;
|
|
263
|
-
const parent = findParentNode(node, SOL_PARENT_TYPES);
|
|
264
|
-
const fullName = parent ? `${parent}.${nameNode.text}` : nameNode.text;
|
|
265
|
-
|
|
266
262
|
ctx.definitions.push({
|
|
267
|
-
name:
|
|
263
|
+
name: qualifyWithParent(node, nameNode.text),
|
|
268
264
|
kind: 'type',
|
|
269
|
-
line: node
|
|
265
|
+
line: nodeStartLine(node),
|
|
270
266
|
endLine: nodeEndLine(node),
|
|
271
267
|
decorators: ['event'],
|
|
272
268
|
});
|
|
@@ -275,13 +271,10 @@ function handleEventDef(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
275
271
|
function handleErrorDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
276
272
|
const nameNode = node.childForFieldName('name');
|
|
277
273
|
if (!nameNode) return;
|
|
278
|
-
const parent = findParentNode(node, SOL_PARENT_TYPES);
|
|
279
|
-
const fullName = parent ? `${parent}.${nameNode.text}` : nameNode.text;
|
|
280
|
-
|
|
281
274
|
ctx.definitions.push({
|
|
282
|
-
name:
|
|
275
|
+
name: qualifyWithParent(node, nameNode.text),
|
|
283
276
|
kind: 'type',
|
|
284
|
-
line: node
|
|
277
|
+
line: nodeStartLine(node),
|
|
285
278
|
endLine: nodeEndLine(node),
|
|
286
279
|
decorators: ['error'],
|
|
287
280
|
});
|
|
@@ -290,18 +283,21 @@ function handleErrorDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
290
283
|
function handleStateVarDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
291
284
|
const nameNode = node.childForFieldName('name');
|
|
292
285
|
if (!nameNode) return;
|
|
293
|
-
const parent = findParentNode(node, SOL_PARENT_TYPES);
|
|
294
|
-
const fullName = parent ? `${parent}.${nameNode.text}` : nameNode.text;
|
|
295
|
-
|
|
296
286
|
ctx.definitions.push({
|
|
297
|
-
name:
|
|
287
|
+
name: qualifyWithParent(node, nameNode.text),
|
|
298
288
|
kind: 'variable',
|
|
299
|
-
line: node
|
|
289
|
+
line: nodeStartLine(node),
|
|
300
290
|
endLine: nodeEndLine(node),
|
|
301
291
|
visibility: extractSolVisibility(node),
|
|
302
292
|
});
|
|
303
293
|
}
|
|
304
294
|
|
|
295
|
+
/** Qualify `name` with the nearest contract/interface/library, if any. */
|
|
296
|
+
function qualifyWithParent(node: TreeSitterNode, name: string): string {
|
|
297
|
+
const parent = findParentNode(node, SOL_PARENT_TYPES);
|
|
298
|
+
return parent ? `${parent}.${name}` : name;
|
|
299
|
+
}
|
|
300
|
+
|
|
305
301
|
function handleImportDirective(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
306
302
|
// import "path"; or import { X } from "path"; or import "path" as Alias;
|
|
307
303
|
for (let i = 0; i < node.childCount; i++) {
|
|
@@ -319,22 +315,17 @@ function handleImportDirective(node: TreeSitterNode, ctx: ExtractorOutput): void
|
|
|
319
315
|
if (id) names.push(id.text);
|
|
320
316
|
}
|
|
321
317
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
});
|
|
318
|
+
// Preserve the explicit `['*']` fallback — pushImport's default uses the
|
|
319
|
+
// source basename, but Solidity's convention here is to mark unqualified
|
|
320
|
+
// imports as `*`.
|
|
321
|
+
pushImport(ctx, node, source, names.length > 0 ? names : ['*']);
|
|
327
322
|
return;
|
|
328
323
|
}
|
|
329
324
|
// source_import: handles `import * as X from "path"`
|
|
330
325
|
if (child.type === 'source_import' || child.type === 'import_clause') {
|
|
331
|
-
const strNode =
|
|
326
|
+
const strNode = findFirstChildOfTypes(child, ['string', 'string_literal']);
|
|
332
327
|
if (strNode) {
|
|
333
|
-
ctx.
|
|
334
|
-
source: stripQuotes(strNode.text),
|
|
335
|
-
names: ['*'],
|
|
336
|
-
line: node.startPosition.row + 1,
|
|
337
|
-
});
|
|
328
|
+
pushImport(ctx, node, stripQuotes(strNode.text), ['*']);
|
|
338
329
|
return;
|
|
339
330
|
}
|
|
340
331
|
}
|
|
@@ -345,35 +336,25 @@ function handleCallExpression(node: TreeSitterNode, ctx: ExtractorOutput): void
|
|
|
345
336
|
const funcNode = node.childForFieldName('function') || node.childForFieldName('callee');
|
|
346
337
|
if (!funcNode) return;
|
|
347
338
|
|
|
348
|
-
|
|
339
|
+
let name = '';
|
|
340
|
+
let receiver: string | undefined;
|
|
349
341
|
if (funcNode.type === 'member_expression' || funcNode.type === 'member_access') {
|
|
350
342
|
const prop = funcNode.childForFieldName('property') || funcNode.childForFieldName('member');
|
|
351
343
|
const obj = funcNode.childForFieldName('object') || funcNode.childForFieldName('expression');
|
|
352
|
-
if (prop)
|
|
353
|
-
if (obj)
|
|
344
|
+
if (prop) name = prop.text;
|
|
345
|
+
if (obj) receiver = obj.text;
|
|
354
346
|
} else {
|
|
355
|
-
|
|
347
|
+
name = funcNode.text;
|
|
356
348
|
}
|
|
357
|
-
if (
|
|
349
|
+
if (name) pushCall(ctx, node, name, receiver !== undefined ? { receiver } : {});
|
|
358
350
|
}
|
|
359
351
|
|
|
360
352
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
361
353
|
|
|
362
354
|
function extractSolParams(funcNode: TreeSitterNode): SubDeclaration[] {
|
|
363
|
-
const params: SubDeclaration[] = [];
|
|
364
355
|
const paramList =
|
|
365
356
|
funcNode.childForFieldName('parameters') || findChild(funcNode, 'parameter_list');
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
for (let i = 0; i < paramList.childCount; i++) {
|
|
369
|
-
const param = paramList.child(i);
|
|
370
|
-
if (!param || param.type !== 'parameter') continue;
|
|
371
|
-
const nameNode = param.childForFieldName('name');
|
|
372
|
-
if (nameNode) {
|
|
373
|
-
params.push({ name: nameNode.text, kind: 'parameter', line: param.startPosition.row + 1 });
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return params;
|
|
357
|
+
return extractSimpleParameters(paramList, { paramTypes: ['parameter'] });
|
|
377
358
|
}
|
|
378
359
|
|
|
379
360
|
function extractSolVisibility(
|
|
@@ -99,27 +99,60 @@ function handlePackageDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
function handleClassDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
// tree-sitter-verilog exposes no field names on `class_declaration`. The
|
|
103
|
+
// class name lives under a `class_identifier > simple_identifier` chain, and
|
|
104
|
+
// the superclass appears as a `class_type` child (no `superclass` field).
|
|
105
|
+
// The Rust extractor in `crates/codegraph-core/src/extractors/verilog.rs`
|
|
106
|
+
// uses the same structural lookups so both engines emit identical class
|
|
107
|
+
// definitions and `extends` relations.
|
|
108
|
+
const name = findClassName(node);
|
|
109
|
+
if (!name) return;
|
|
104
110
|
|
|
105
111
|
ctx.definitions.push({
|
|
106
|
-
name
|
|
112
|
+
name,
|
|
107
113
|
kind: 'class',
|
|
108
114
|
line: node.startPosition.row + 1,
|
|
109
115
|
endLine: nodeEndLine(node),
|
|
110
116
|
});
|
|
111
117
|
|
|
112
|
-
|
|
113
|
-
const superclass = node.childForFieldName('superclass');
|
|
118
|
+
const superclass = findClassSuperclass(node);
|
|
114
119
|
if (superclass) {
|
|
115
120
|
ctx.classes.push({
|
|
116
|
-
name
|
|
117
|
-
extends: superclass
|
|
121
|
+
name,
|
|
122
|
+
extends: superclass,
|
|
118
123
|
line: node.startPosition.row + 1,
|
|
119
124
|
});
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
|
|
128
|
+
function findClassName(node: TreeSitterNode): string | null {
|
|
129
|
+
const fieldName = node.childForFieldName('name');
|
|
130
|
+
if (fieldName) return fieldName.text;
|
|
131
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
132
|
+
const child = node.child(i);
|
|
133
|
+
if (child && child.type === 'class_identifier') {
|
|
134
|
+
const simple = findChild(child, 'simple_identifier');
|
|
135
|
+
return (simple ?? child).text.trim();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function findClassSuperclass(node: TreeSitterNode): string | null {
|
|
142
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
143
|
+
const child = node.child(i);
|
|
144
|
+
if (child && child.type === 'class_type') {
|
|
145
|
+
const id = findChild(child, 'class_identifier');
|
|
146
|
+
if (id) {
|
|
147
|
+
const simple = findChild(id, 'simple_identifier');
|
|
148
|
+
return (simple ?? id).text.trim();
|
|
149
|
+
}
|
|
150
|
+
return child.text.trim();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
123
156
|
function handleFunctionDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
124
157
|
const nameNode = findFunctionOrTaskName(node, 'function_identifier');
|
|
125
158
|
if (!nameNode) return;
|
|
@@ -151,8 +184,12 @@ function handleTaskDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
151
184
|
}
|
|
152
185
|
|
|
153
186
|
function handleModuleInstantiation(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
154
|
-
// Module instantiations are like function calls: `ModuleName instance_name(...)
|
|
155
|
-
|
|
187
|
+
// Module instantiations are like function calls: `ModuleName instance_name(...);`.
|
|
188
|
+
// The module type identifier is the first *named* child; using
|
|
189
|
+
// `namedChild(0)` (instead of `child(0)`) skips anonymous tokens like a
|
|
190
|
+
// leading `#` parameter-override punctuation so we never capture that as a
|
|
191
|
+
// call name. The Rust extractor uses the same lookup for parity.
|
|
192
|
+
const moduleType = node.childForFieldName('type') ?? node.namedChild(0);
|
|
156
193
|
if (!moduleType) return;
|
|
157
194
|
|
|
158
195
|
ctx.calls.push({
|
|
@@ -169,7 +206,10 @@ function handlePackageImport(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
169
206
|
if (child.type === 'package_import_item') {
|
|
170
207
|
const text = child.text;
|
|
171
208
|
const parts = text.split('::');
|
|
172
|
-
|
|
209
|
+
// `String.split('::')` always yields at least one element — when the
|
|
210
|
+
// delimiter is absent the whole string is the sole item, so the
|
|
211
|
+
// empty-string fallback is unreachable in practice.
|
|
212
|
+
const pkg = parts[0] ?? '';
|
|
173
213
|
const item = parts[1] ?? '*';
|
|
174
214
|
ctx.imports.push({
|
|
175
215
|
source: pkg,
|
|
@@ -182,9 +222,18 @@ function handlePackageImport(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
182
222
|
|
|
183
223
|
function handleIncludeDirective(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
184
224
|
// `include "file.vh"
|
|
225
|
+
// Mirrors the Rust `handle_include_directive` which checks all three node
|
|
226
|
+
// kinds — tree-sitter-verilog has emitted `double_quoted_string` in some
|
|
227
|
+
// grammar revisions, and missing it would silently drop the import in WASM
|
|
228
|
+
// while the native engine still records it.
|
|
185
229
|
for (let i = 0; i < node.childCount; i++) {
|
|
186
230
|
const child = node.child(i);
|
|
187
|
-
if (
|
|
231
|
+
if (
|
|
232
|
+
child &&
|
|
233
|
+
(child.type === 'string_literal' ||
|
|
234
|
+
child.type === 'quoted_string' ||
|
|
235
|
+
child.type === 'double_quoted_string')
|
|
236
|
+
) {
|
|
188
237
|
const source = child.text.replace(/^["']|["']$/g, '');
|
|
189
238
|
ctx.imports.push({
|
|
190
239
|
source,
|
|
@@ -266,8 +315,14 @@ function findVerilogParent(node: TreeSitterNode): string | null {
|
|
|
266
315
|
current.type === 'package_declaration' ||
|
|
267
316
|
current.type === 'class_declaration'
|
|
268
317
|
) {
|
|
269
|
-
|
|
270
|
-
|
|
318
|
+
// `class_declaration` wraps its name in `class_identifier >
|
|
319
|
+
// simple_identifier`; `findDeclName` / `findModuleName` only look at
|
|
320
|
+
// bare `simple_identifier`/`identifier` children, so they miss it.
|
|
321
|
+
// `findClassName` already handles the wrapper, so consult it last to
|
|
322
|
+
// qualify tasks/functions nested inside a SystemVerilog class.
|
|
323
|
+
const nameNode = findDeclName(current) || findModuleName(current);
|
|
324
|
+
if (nameNode) return nameNode.text;
|
|
325
|
+
return findClassName(current);
|
|
271
326
|
}
|
|
272
327
|
current = current.parent;
|
|
273
328
|
}
|
|
@@ -292,17 +347,30 @@ function extractPorts(moduleNode: TreeSitterNode): SubDeclaration[] {
|
|
|
292
347
|
) {
|
|
293
348
|
const nameNode =
|
|
294
349
|
child.childForFieldName('name') ||
|
|
350
|
+
findChild(child, 'port_identifier') ||
|
|
295
351
|
findChild(child, 'simple_identifier') ||
|
|
296
352
|
findChild(child, 'identifier');
|
|
297
353
|
if (nameNode) {
|
|
298
|
-
|
|
354
|
+
// `port_identifier` wraps a `simple_identifier`; descend to the
|
|
355
|
+
// innermost identifier for a clean, whitespace-free name.
|
|
356
|
+
const inner =
|
|
357
|
+
findChild(nameNode, 'simple_identifier') ||
|
|
358
|
+
findChild(nameNode, 'identifier') ||
|
|
359
|
+
nameNode;
|
|
360
|
+
ports.push({ name: inner.text, kind: 'property', line: child.startPosition.row + 1 });
|
|
299
361
|
}
|
|
300
362
|
}
|
|
301
363
|
|
|
302
|
-
// Recurse into port list containers
|
|
364
|
+
// Recurse into port list containers. `module_ansi_header` wraps the
|
|
365
|
+
// ANSI-style declarations emitted by tree-sitter-verilog (e.g.
|
|
366
|
+
// `module top(input clk, output reg q);`) — without this branch the
|
|
367
|
+
// WASM engine returns an empty children array while the native engine
|
|
368
|
+
// (which includes the same kind in its CONTAINER_KINDS list) returns
|
|
369
|
+
// the correct ports, breaking engine parity.
|
|
303
370
|
if (
|
|
304
371
|
child.type === 'list_of_port_declarations' ||
|
|
305
372
|
child.type === 'module_header' ||
|
|
373
|
+
child.type === 'module_ansi_header' ||
|
|
306
374
|
child.type === 'port_declaration_list'
|
|
307
375
|
) {
|
|
308
376
|
collectFromNode(child);
|