@optave/codegraph 3.8.0 → 3.8.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 +9 -8
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +95 -87
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/metrics.d.ts +0 -3
- package/dist/ast-analysis/metrics.d.ts.map +1 -1
- package/dist/ast-analysis/metrics.js +30 -13
- package/dist/ast-analysis/metrics.js.map +1 -1
- package/dist/ast-analysis/shared.d.ts.map +1 -1
- package/dist/ast-analysis/shared.js +24 -19
- package/dist/ast-analysis/shared.js.map +1 -1
- package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
- package/dist/ast-analysis/visitor-utils.js +55 -39
- package/dist/ast-analysis/visitor-utils.js.map +1 -1
- package/dist/ast-analysis/visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitor.js +91 -70
- package/dist/ast-analysis/visitor.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 +54 -58
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js +32 -39
- package/dist/ast-analysis/visitors/complexity-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 +57 -38
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +16 -2
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +29 -26
- package/dist/db/connection.js.map +1 -1
- package/dist/db/query-builder.d.ts.map +1 -1
- package/dist/db/query-builder.js +16 -5
- package/dist/db/query-builder.js.map +1 -1
- package/dist/db/repository/base.d.ts +10 -0
- package/dist/db/repository/base.d.ts.map +1 -1
- package/dist/db/repository/base.js +17 -0
- package/dist/db/repository/base.js.map +1 -1
- package/dist/db/repository/native-repository.d.ts +6 -1
- package/dist/db/repository/native-repository.d.ts.map +1 -1
- package/dist/db/repository/native-repository.js +77 -1
- package/dist/db/repository/native-repository.js.map +1 -1
- package/dist/db/repository/nodes.d.ts.map +1 -1
- package/dist/db/repository/nodes.js +8 -4
- package/dist/db/repository/nodes.js.map +1 -1
- package/dist/db/repository/sqlite-repository.d.ts +3 -0
- package/dist/db/repository/sqlite-repository.d.ts.map +1 -1
- package/dist/db/repository/sqlite-repository.js +26 -0
- package/dist/db/repository/sqlite-repository.js.map +1 -1
- package/dist/domain/analysis/brief.d.ts.map +1 -1
- package/dist/domain/analysis/brief.js +13 -17
- package/dist/domain/analysis/brief.js.map +1 -1
- package/dist/domain/analysis/context.d.ts.map +1 -1
- package/dist/domain/analysis/context.js +14 -11
- package/dist/domain/analysis/context.js.map +1 -1
- package/dist/domain/analysis/dependencies.d.ts.map +1 -1
- package/dist/domain/analysis/dependencies.js +53 -52
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/analysis/fn-impact.d.ts +2 -7
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
- package/dist/domain/analysis/fn-impact.js +33 -31
- package/dist/domain/analysis/fn-impact.js.map +1 -1
- package/dist/domain/analysis/implementations.d.ts.map +1 -1
- package/dist/domain/analysis/implementations.js +11 -19
- package/dist/domain/analysis/implementations.js.map +1 -1
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +55 -76
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/analysis/query-helpers.d.ts +7 -0
- package/dist/domain/analysis/query-helpers.d.ts.map +1 -1
- package/dist/domain/analysis/query-helpers.js +15 -1
- package/dist/domain/analysis/query-helpers.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +255 -105
- 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 +22 -17
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +2 -2
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +2 -2
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.js +32 -21
- package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +95 -84
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/cycles.d.ts +6 -0
- package/dist/domain/graph/cycles.d.ts.map +1 -1
- package/dist/domain/graph/cycles.js +114 -22
- package/dist/domain/graph/cycles.js.map +1 -1
- package/dist/domain/graph/resolve.js +1 -1
- package/dist/domain/graph/resolve.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts +2 -0
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +170 -75
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +0 -5
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +13 -28
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/search/generator.js +1 -1
- package/dist/domain/search/generator.js.map +1 -1
- package/dist/domain/search/models.d.ts +4 -3
- package/dist/domain/search/models.d.ts.map +1 -1
- package/dist/domain/search/models.js +18 -5
- 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 +29 -18
- package/dist/domain/search/search/hybrid.js.map +1 -1
- package/dist/extractors/go.js +36 -33
- package/dist/extractors/go.js.map +1 -1
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +40 -29
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/java.js +58 -46
- package/dist/extractors/java.js.map +1 -1
- package/dist/extractors/javascript.js +46 -45
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/kotlin.js +84 -78
- package/dist/extractors/kotlin.js.map +1 -1
- package/dist/extractors/python.js +29 -24
- package/dist/extractors/python.js.map +1 -1
- package/dist/extractors/rust.js +41 -32
- package/dist/extractors/rust.js.map +1 -1
- package/dist/extractors/solidity.js +58 -67
- package/dist/extractors/solidity.js.map +1 -1
- package/dist/extractors/swift.js +83 -81
- package/dist/extractors/swift.js.map +1 -1
- package/dist/extractors/zig.js +58 -60
- package/dist/extractors/zig.js.map +1 -1
- package/dist/features/ast.d.ts +16 -14
- package/dist/features/ast.d.ts.map +1 -1
- package/dist/features/ast.js +83 -81
- package/dist/features/ast.js.map +1 -1
- package/dist/features/audit.d.ts.map +1 -1
- package/dist/features/audit.js +8 -6
- package/dist/features/audit.js.map +1 -1
- package/dist/features/branch-compare.d.ts.map +1 -1
- package/dist/features/branch-compare.js +69 -72
- package/dist/features/branch-compare.js.map +1 -1
- package/dist/features/communities.d.ts.map +1 -1
- package/dist/features/communities.js +19 -7
- package/dist/features/communities.js.map +1 -1
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +120 -125
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +136 -137
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/flow.d.ts.map +1 -1
- package/dist/features/flow.js +84 -79
- package/dist/features/flow.js.map +1 -1
- package/dist/features/structure-query.d.ts.map +1 -1
- package/dist/features/structure-query.js +69 -65
- package/dist/features/structure-query.js.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/optimiser.js +70 -55
- package/dist/graph/algorithms/leiden/optimiser.js.map +1 -1
- package/dist/graph/algorithms/leiden/partition.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/partition.js +288 -266
- package/dist/graph/algorithms/leiden/partition.js.map +1 -1
- package/dist/graph/model.d.ts.map +1 -1
- package/dist/graph/model.js +5 -1
- package/dist/graph/model.js.map +1 -1
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +6 -4
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/suppress.d.ts +25 -0
- package/dist/infrastructure/suppress.d.ts.map +1 -0
- package/dist/infrastructure/suppress.js +43 -0
- package/dist/infrastructure/suppress.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +29 -24
- package/dist/mcp/server.js.map +1 -1
- package/dist/presentation/dataflow.d.ts.map +1 -1
- package/dist/presentation/dataflow.js +47 -38
- package/dist/presentation/dataflow.js.map +1 -1
- package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -1
- package/dist/presentation/diff-impact-mermaid.js +60 -51
- package/dist/presentation/diff-impact-mermaid.js.map +1 -1
- package/dist/presentation/queries-cli/exports.d.ts.map +1 -1
- package/dist/presentation/queries-cli/exports.js +20 -14
- package/dist/presentation/queries-cli/exports.js.map +1 -1
- package/dist/presentation/queries-cli/impact.d.ts.map +1 -1
- package/dist/presentation/queries-cli/impact.js +15 -13
- package/dist/presentation/queries-cli/impact.js.map +1 -1
- package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
- package/dist/presentation/queries-cli/inspect.js +101 -79
- package/dist/presentation/queries-cli/inspect.js.map +1 -1
- package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
- package/dist/presentation/queries-cli/overview.js +25 -16
- package/dist/presentation/queries-cli/overview.js.map +1 -1
- package/dist/presentation/queries-cli/path.js +26 -20
- package/dist/presentation/queries-cli/path.js.map +1 -1
- package/dist/presentation/result-formatter.d.ts +10 -0
- package/dist/presentation/result-formatter.d.ts.map +1 -1
- package/dist/presentation/result-formatter.js +16 -1
- package/dist/presentation/result-formatter.js.map +1 -1
- package/dist/presentation/viewer.d.ts.map +1 -1
- package/dist/presentation/viewer.js +18 -12
- package/dist/presentation/viewer.js.map +1 -1
- package/dist/shared/errors.d.ts +5 -0
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +5 -0
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/hierarchy.d.ts +8 -2
- package/dist/shared/hierarchy.d.ts.map +1 -1
- package/dist/shared/hierarchy.js +42 -1
- package/dist/shared/hierarchy.js.map +1 -1
- package/dist/shared/normalize.d.ts +6 -1
- package/dist/shared/normalize.d.ts.map +1 -1
- package/dist/shared/normalize.js +20 -12
- package/dist/shared/normalize.js.map +1 -1
- package/dist/shared/paginate.d.ts +0 -9
- package/dist/shared/paginate.d.ts.map +1 -1
- package/dist/shared/paginate.js +0 -15
- package/dist/shared/paginate.js.map +1 -1
- package/dist/types.d.ts +10 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/ast-analysis/engine.ts +126 -105
- package/src/ast-analysis/metrics.ts +33 -11
- package/src/ast-analysis/shared.ts +33 -24
- package/src/ast-analysis/visitor-utils.ts +52 -32
- package/src/ast-analysis/visitor.ts +132 -71
- package/src/ast-analysis/visitors/ast-store-visitor.ts +53 -50
- package/src/ast-analysis/visitors/complexity-visitor.ts +35 -40
- package/src/ast-analysis/visitors/dataflow-visitor.ts +87 -43
- package/src/cli/commands/watch.ts +16 -2
- package/src/db/connection.ts +29 -28
- package/src/db/query-builder.ts +15 -3
- package/src/db/repository/base.ts +20 -0
- package/src/db/repository/native-repository.ts +79 -1
- package/src/db/repository/nodes.ts +13 -8
- package/src/db/repository/sqlite-repository.ts +29 -0
- package/src/domain/analysis/brief.ts +15 -25
- package/src/domain/analysis/context.ts +17 -10
- package/src/domain/analysis/dependencies.ts +67 -76
- package/src/domain/analysis/fn-impact.ts +36 -43
- package/src/domain/analysis/implementations.ts +11 -17
- package/src/domain/analysis/module-map.ts +58 -92
- package/src/domain/analysis/query-helpers.ts +18 -1
- package/src/domain/graph/builder/pipeline.ts +286 -97
- package/src/domain/graph/builder/stages/build-edges.ts +22 -18
- package/src/domain/graph/builder/stages/detect-changes.ts +2 -2
- package/src/domain/graph/builder/stages/finalize.ts +2 -2
- package/src/domain/graph/builder/stages/insert-nodes.ts +59 -34
- package/src/domain/graph/builder/stages/resolve-imports.ts +122 -100
- package/src/domain/graph/cycles.ts +110 -23
- package/src/domain/graph/resolve.ts +1 -1
- package/src/domain/graph/watcher.ts +202 -96
- package/src/domain/parser.ts +14 -26
- package/src/domain/search/generator.ts +1 -1
- package/src/domain/search/models.ts +17 -4
- package/src/domain/search/search/hybrid.ts +69 -51
- package/src/extractors/go.ts +43 -33
- package/src/extractors/helpers.ts +37 -23
- package/src/extractors/java.ts +66 -47
- package/src/extractors/javascript.ts +45 -46
- package/src/extractors/kotlin.ts +84 -77
- package/src/extractors/python.ts +31 -25
- package/src/extractors/rust.ts +37 -29
- package/src/extractors/solidity.ts +57 -61
- package/src/extractors/swift.ts +81 -80
- package/src/extractors/zig.ts +58 -61
- package/src/features/ast.ts +130 -110
- package/src/features/audit.ts +8 -6
- package/src/features/branch-compare.ts +105 -79
- package/src/features/communities.ts +25 -10
- package/src/features/complexity.ts +171 -134
- package/src/features/dataflow.ts +165 -175
- package/src/features/flow.ts +129 -92
- package/src/features/structure-query.ts +79 -64
- package/src/graph/algorithms/leiden/optimiser.ts +99 -55
- package/src/graph/algorithms/leiden/partition.ts +359 -294
- package/src/graph/model.ts +6 -1
- package/src/infrastructure/config.ts +6 -4
- package/src/infrastructure/suppress.ts +47 -0
- package/src/mcp/server.ts +53 -37
- package/src/presentation/dataflow.ts +50 -44
- package/src/presentation/diff-impact-mermaid.ts +104 -62
- package/src/presentation/queries-cli/exports.ts +21 -13
- package/src/presentation/queries-cli/impact.ts +15 -13
- package/src/presentation/queries-cli/inspect.ts +100 -81
- package/src/presentation/queries-cli/overview.ts +26 -16
- package/src/presentation/queries-cli/path.ts +33 -25
- package/src/presentation/result-formatter.ts +19 -1
- package/src/presentation/viewer.ts +42 -14
- package/src/shared/errors.ts +6 -0
- package/src/shared/hierarchy.ts +50 -2
- package/src/shared/normalize.ts +31 -12
- package/src/shared/paginate.ts +0 -17
- package/src/types.ts +24 -4
package/src/extractors/python.ts
CHANGED
|
@@ -245,35 +245,41 @@ function extractPythonParameters(fnNode: TreeSitterNode): SubDeclaration[] {
|
|
|
245
245
|
for (let i = 0; i < paramsNode.childCount; i++) {
|
|
246
246
|
const child = paramsNode.child(i);
|
|
247
247
|
if (!child) continue;
|
|
248
|
-
const
|
|
249
|
-
if (
|
|
250
|
-
params.push({ name: child.text, kind: 'parameter', line: child.startPosition.row + 1 });
|
|
251
|
-
} else if (
|
|
252
|
-
t === 'typed_parameter' ||
|
|
253
|
-
t === 'default_parameter' ||
|
|
254
|
-
t === 'typed_default_parameter'
|
|
255
|
-
) {
|
|
256
|
-
const nameNode = child.childForFieldName('name') || child.child(0);
|
|
257
|
-
if (nameNode && nameNode.type === 'identifier') {
|
|
258
|
-
params.push({
|
|
259
|
-
name: nameNode.text,
|
|
260
|
-
kind: 'parameter',
|
|
261
|
-
line: child.startPosition.row + 1,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
} else if (t === 'list_splat_pattern' || t === 'dictionary_splat_pattern') {
|
|
265
|
-
for (let j = 0; j < child.childCount; j++) {
|
|
266
|
-
const inner = child.child(j);
|
|
267
|
-
if (inner && inner.type === 'identifier') {
|
|
268
|
-
params.push({ name: inner.text, kind: 'parameter', line: child.startPosition.row + 1 });
|
|
269
|
-
break;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
248
|
+
const param = extractSinglePyParam(child);
|
|
249
|
+
if (param) params.push(param);
|
|
273
250
|
}
|
|
274
251
|
return params;
|
|
275
252
|
}
|
|
276
253
|
|
|
254
|
+
/** Extract a single parameter declaration from a parameter node. */
|
|
255
|
+
function extractSinglePyParam(child: TreeSitterNode): SubDeclaration | null {
|
|
256
|
+
const t = child.type;
|
|
257
|
+
if (t === 'identifier') {
|
|
258
|
+
return { name: child.text, kind: 'parameter', line: child.startPosition.row + 1 };
|
|
259
|
+
}
|
|
260
|
+
if (t === 'typed_parameter' || t === 'default_parameter' || t === 'typed_default_parameter') {
|
|
261
|
+
const nameNode = child.childForFieldName('name') || child.child(0);
|
|
262
|
+
if (nameNode && nameNode.type === 'identifier') {
|
|
263
|
+
return { name: nameNode.text, kind: 'parameter', line: child.startPosition.row + 1 };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (t === 'list_splat_pattern' || t === 'dictionary_splat_pattern') {
|
|
267
|
+
return extractSplatParam(child);
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Extract the identifier name from a *args or **kwargs splat pattern. */
|
|
273
|
+
function extractSplatParam(node: TreeSitterNode): SubDeclaration | null {
|
|
274
|
+
for (let j = 0; j < node.childCount; j++) {
|
|
275
|
+
const inner = node.child(j);
|
|
276
|
+
if (inner && inner.type === 'identifier') {
|
|
277
|
+
return { name: inner.text, kind: 'parameter', line: node.startPosition.row + 1 };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
|
|
277
283
|
/** Extract class-level assignment properties from expression statements. */
|
|
278
284
|
function extractClassAssignment(
|
|
279
285
|
child: TreeSitterNode,
|
package/src/extractors/rust.ts
CHANGED
|
@@ -138,19 +138,22 @@ function handleRustTraitItem(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
138
138
|
endLine: nodeEndLine(node),
|
|
139
139
|
});
|
|
140
140
|
const body = node.childForFieldName('body');
|
|
141
|
-
if (body)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
141
|
+
if (body) extractTraitMethods(body, nameNode.text, ctx);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Extract method signatures/definitions from a trait body. */
|
|
145
|
+
function extractTraitMethods(body: TreeSitterNode, traitName: string, ctx: ExtractorOutput): void {
|
|
146
|
+
for (let i = 0; i < body.childCount; i++) {
|
|
147
|
+
const child = body.child(i);
|
|
148
|
+
if (child && (child.type === 'function_signature_item' || child.type === 'function_item')) {
|
|
149
|
+
const methName = child.childForFieldName('name');
|
|
150
|
+
if (methName) {
|
|
151
|
+
ctx.definitions.push({
|
|
152
|
+
name: `${traitName}.${methName.text}`,
|
|
153
|
+
kind: 'method',
|
|
154
|
+
line: child.startPosition.row + 1,
|
|
155
|
+
endLine: child.endPosition.row + 1,
|
|
156
|
+
});
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
}
|
|
@@ -185,25 +188,30 @@ function handleRustUseDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
185
188
|
function handleRustCallExpr(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
186
189
|
const fn = node.childForFieldName('function');
|
|
187
190
|
if (!fn) return;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
+
const call = extractRustCallInfo(fn, node.startPosition.row + 1);
|
|
192
|
+
if (call) ctx.calls.push(call);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Extract call info from a Rust call function node. */
|
|
196
|
+
function extractRustCallInfo(fn: TreeSitterNode, line: number): Call | null {
|
|
197
|
+
if (fn.type === 'identifier') return { name: fn.text, line };
|
|
198
|
+
if (fn.type === 'field_expression') {
|
|
191
199
|
const field = fn.childForFieldName('field');
|
|
192
|
-
if (field)
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
200
|
+
if (!field) return null;
|
|
201
|
+
const value = fn.childForFieldName('value');
|
|
202
|
+
const call: Call = { name: field.text, line };
|
|
203
|
+
if (value) call.receiver = value.text;
|
|
204
|
+
return call;
|
|
205
|
+
}
|
|
206
|
+
if (fn.type === 'scoped_identifier') {
|
|
199
207
|
const name = fn.childForFieldName('name');
|
|
200
|
-
if (name)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
208
|
+
if (!name) return null;
|
|
209
|
+
const path = fn.childForFieldName('path');
|
|
210
|
+
const call: Call = { name: name.text, line };
|
|
211
|
+
if (path) call.receiver = path.text;
|
|
212
|
+
return call;
|
|
206
213
|
}
|
|
214
|
+
return null;
|
|
207
215
|
}
|
|
208
216
|
|
|
209
217
|
function handleRustMacroInvocation(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
@@ -97,60 +97,8 @@ function handleContractDecl(
|
|
|
97
97
|
if (!nameNode) return;
|
|
98
98
|
const name = nameNode.text;
|
|
99
99
|
|
|
100
|
-
const members: SubDeclaration[] = [];
|
|
101
100
|
const body = node.childForFieldName('body') || findChild(node, 'contract_body');
|
|
102
|
-
|
|
103
|
-
for (let i = 0; i < body.childCount; i++) {
|
|
104
|
-
const child = body.child(i);
|
|
105
|
-
if (!child) continue;
|
|
106
|
-
if (child.type === 'function_definition') {
|
|
107
|
-
const fnName = child.childForFieldName('name');
|
|
108
|
-
if (fnName) {
|
|
109
|
-
members.push({ name: fnName.text, kind: 'method', line: child.startPosition.row + 1 });
|
|
110
|
-
}
|
|
111
|
-
} else if (child.type === 'state_variable_declaration') {
|
|
112
|
-
const varName = child.childForFieldName('name');
|
|
113
|
-
if (varName) {
|
|
114
|
-
members.push({
|
|
115
|
-
name: varName.text,
|
|
116
|
-
kind: 'property',
|
|
117
|
-
line: child.startPosition.row + 1,
|
|
118
|
-
visibility: extractSolVisibility(child),
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
} else if (child.type === 'event_definition') {
|
|
122
|
-
const evName = child.childForFieldName('name');
|
|
123
|
-
if (evName) {
|
|
124
|
-
members.push({
|
|
125
|
-
name: evName.text,
|
|
126
|
-
kind: 'property',
|
|
127
|
-
decorators: ['event'],
|
|
128
|
-
line: child.startPosition.row + 1,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
} else if (child.type === 'error_declaration') {
|
|
132
|
-
const errName = child.childForFieldName('name');
|
|
133
|
-
if (errName) {
|
|
134
|
-
members.push({
|
|
135
|
-
name: errName.text,
|
|
136
|
-
kind: 'property',
|
|
137
|
-
decorators: ['error'],
|
|
138
|
-
line: child.startPosition.row + 1,
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
} else if (child.type === 'modifier_definition') {
|
|
142
|
-
const modName = child.childForFieldName('name');
|
|
143
|
-
if (modName) {
|
|
144
|
-
members.push({
|
|
145
|
-
name: modName.text,
|
|
146
|
-
kind: 'method',
|
|
147
|
-
decorators: ['modifier'],
|
|
148
|
-
line: child.startPosition.row + 1,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
101
|
+
const members = body ? extractContractMembers(body) : [];
|
|
154
102
|
|
|
155
103
|
ctx.definitions.push({
|
|
156
104
|
name,
|
|
@@ -160,15 +108,63 @@ function handleContractDecl(
|
|
|
160
108
|
children: members.length > 0 ? members : undefined,
|
|
161
109
|
});
|
|
162
110
|
|
|
163
|
-
|
|
111
|
+
extractInheritance(node, name, ctx);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Extract member declarations from a contract body node. */
|
|
115
|
+
function extractContractMembers(body: TreeSitterNode): SubDeclaration[] {
|
|
116
|
+
const members: SubDeclaration[] = [];
|
|
117
|
+
for (let i = 0; i < body.childCount; i++) {
|
|
118
|
+
const child = body.child(i);
|
|
119
|
+
if (!child) continue;
|
|
120
|
+
const member = extractContractMember(child);
|
|
121
|
+
if (member) members.push(member);
|
|
122
|
+
}
|
|
123
|
+
return members;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Map a single contract body child to a SubDeclaration, or null if not a recognized member. */
|
|
127
|
+
function extractContractMember(child: TreeSitterNode): SubDeclaration | null {
|
|
128
|
+
const line = child.startPosition.row + 1;
|
|
129
|
+
switch (child.type) {
|
|
130
|
+
case 'function_definition': {
|
|
131
|
+
const fnName = child.childForFieldName('name');
|
|
132
|
+
return fnName ? { name: fnName.text, kind: 'method', line } : null;
|
|
133
|
+
}
|
|
134
|
+
case 'state_variable_declaration': {
|
|
135
|
+
const varName = child.childForFieldName('name');
|
|
136
|
+
return varName
|
|
137
|
+
? { name: varName.text, kind: 'property', line, visibility: extractSolVisibility(child) }
|
|
138
|
+
: null;
|
|
139
|
+
}
|
|
140
|
+
case 'event_definition': {
|
|
141
|
+
const evName = child.childForFieldName('name');
|
|
142
|
+
return evName ? { name: evName.text, kind: 'property', decorators: ['event'], line } : null;
|
|
143
|
+
}
|
|
144
|
+
case 'error_declaration': {
|
|
145
|
+
const errName = child.childForFieldName('name');
|
|
146
|
+
return errName ? { name: errName.text, kind: 'property', decorators: ['error'], line } : null;
|
|
147
|
+
}
|
|
148
|
+
case 'modifier_definition': {
|
|
149
|
+
const modName = child.childForFieldName('name');
|
|
150
|
+
return modName
|
|
151
|
+
? { name: modName.text, kind: 'method', decorators: ['modifier'], line }
|
|
152
|
+
: null;
|
|
153
|
+
}
|
|
154
|
+
default:
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Extract inheritance (extends) relationships from a contract node. */
|
|
160
|
+
function extractInheritance(node: TreeSitterNode, name: string, ctx: ExtractorOutput): void {
|
|
164
161
|
const inheritance = findChild(node, 'inheritance_specifier');
|
|
165
|
-
if (inheritance)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
162
|
+
if (!inheritance) return;
|
|
163
|
+
for (let i = 0; i < inheritance.childCount; i++) {
|
|
164
|
+
const child = inheritance.child(i);
|
|
165
|
+
if (!child) continue;
|
|
166
|
+
if (child.type === 'user_defined_type' || child.type === 'identifier') {
|
|
167
|
+
ctx.classes.push({ name, extends: child.text, line: node.startPosition.row + 1 });
|
|
172
168
|
}
|
|
173
169
|
}
|
|
174
170
|
}
|
package/src/extractors/swift.ts
CHANGED
|
@@ -73,49 +73,7 @@ function handleSwiftClassDecl(node: TreeSitterNode, ctx: ExtractorOutput): void
|
|
|
73
73
|
|
|
74
74
|
const kind = isEnum ? 'enum' : isStruct ? 'struct' : 'class';
|
|
75
75
|
|
|
76
|
-
const children
|
|
77
|
-
|
|
78
|
-
if (isEnum) {
|
|
79
|
-
// Enum cases: enum_entry > simple_identifier, inside enum_class_body
|
|
80
|
-
const body = findChild(node, 'enum_class_body');
|
|
81
|
-
if (body) {
|
|
82
|
-
for (let i = 0; i < body.childCount; i++) {
|
|
83
|
-
const child = body.child(i);
|
|
84
|
-
if (child && child.type === 'enum_entry') {
|
|
85
|
-
const entryName = findChild(child, 'simple_identifier');
|
|
86
|
-
if (entryName) {
|
|
87
|
-
children.push({
|
|
88
|
-
name: entryName.text,
|
|
89
|
-
kind: 'constant',
|
|
90
|
-
line: child.startPosition.row + 1,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
} else {
|
|
97
|
-
// Extract properties from class_body
|
|
98
|
-
const body = findChild(node, 'class_body');
|
|
99
|
-
if (body) {
|
|
100
|
-
for (let i = 0; i < body.childCount; i++) {
|
|
101
|
-
const child = body.child(i);
|
|
102
|
-
if (child && child.type === 'property_declaration') {
|
|
103
|
-
const pattern = findChild(child, 'pattern');
|
|
104
|
-
if (pattern) {
|
|
105
|
-
const propName = findChild(pattern, 'simple_identifier');
|
|
106
|
-
if (propName) {
|
|
107
|
-
children.push({
|
|
108
|
-
name: propName.text,
|
|
109
|
-
kind: 'property',
|
|
110
|
-
line: child.startPosition.row + 1,
|
|
111
|
-
visibility: extractModifierVisibility(child),
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
76
|
+
const children = isEnum ? collectSwiftEnumEntries(node) : collectSwiftProperties(node);
|
|
119
77
|
|
|
120
78
|
ctx.definitions.push({
|
|
121
79
|
name,
|
|
@@ -125,52 +83,95 @@ function handleSwiftClassDecl(node: TreeSitterNode, ctx: ExtractorOutput): void
|
|
|
125
83
|
children: children.length > 0 ? children : undefined,
|
|
126
84
|
});
|
|
127
85
|
|
|
128
|
-
|
|
86
|
+
collectSwiftMethods(node, name, ctx);
|
|
87
|
+
collectSwiftInheritance(node, name, ctx);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Collect enum constant entries from an enum_class_body. */
|
|
91
|
+
function collectSwiftEnumEntries(node: TreeSitterNode): SubDeclaration[] {
|
|
92
|
+
const entries: SubDeclaration[] = [];
|
|
93
|
+
const body = findChild(node, 'enum_class_body');
|
|
94
|
+
if (!body) return entries;
|
|
95
|
+
for (let i = 0; i < body.childCount; i++) {
|
|
96
|
+
const child = body.child(i);
|
|
97
|
+
if (!child || child.type !== 'enum_entry') continue;
|
|
98
|
+
const entryName = findChild(child, 'simple_identifier');
|
|
99
|
+
if (entryName) {
|
|
100
|
+
entries.push({
|
|
101
|
+
name: entryName.text,
|
|
102
|
+
kind: 'constant',
|
|
103
|
+
line: child.startPosition.row + 1,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return entries;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Collect property declarations from a class_body. */
|
|
111
|
+
function collectSwiftProperties(node: TreeSitterNode): SubDeclaration[] {
|
|
112
|
+
const props: SubDeclaration[] = [];
|
|
113
|
+
const body = findChild(node, 'class_body');
|
|
114
|
+
if (!body) return props;
|
|
115
|
+
for (let i = 0; i < body.childCount; i++) {
|
|
116
|
+
const child = body.child(i);
|
|
117
|
+
if (!child || child.type !== 'property_declaration') continue;
|
|
118
|
+
const pattern = findChild(child, 'pattern');
|
|
119
|
+
if (!pattern) continue;
|
|
120
|
+
const propName = findChild(pattern, 'simple_identifier');
|
|
121
|
+
if (propName) {
|
|
122
|
+
props.push({
|
|
123
|
+
name: propName.text,
|
|
124
|
+
kind: 'property',
|
|
125
|
+
line: child.startPosition.row + 1,
|
|
126
|
+
visibility: extractModifierVisibility(child),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return props;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Collect method declarations from class_body or enum_class_body. */
|
|
134
|
+
function collectSwiftMethods(node: TreeSitterNode, className: string, ctx: ExtractorOutput): void {
|
|
129
135
|
const body = findChild(node, 'class_body') || findChild(node, 'enum_class_body');
|
|
130
|
-
if (body)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
}
|
|
136
|
+
if (!body) return;
|
|
137
|
+
for (let i = 0; i < body.childCount; i++) {
|
|
138
|
+
const child = body.child(i);
|
|
139
|
+
if (!child || child.type !== 'function_declaration') continue;
|
|
140
|
+
const methName = findChild(child, 'simple_identifier');
|
|
141
|
+
if (methName) {
|
|
142
|
+
ctx.definitions.push({
|
|
143
|
+
name: `${className}.${methName.text}`,
|
|
144
|
+
kind: 'method',
|
|
145
|
+
line: child.startPosition.row + 1,
|
|
146
|
+
endLine: child.endPosition.row + 1,
|
|
147
|
+
visibility: extractModifierVisibility(child),
|
|
148
|
+
});
|
|
145
149
|
}
|
|
146
150
|
}
|
|
151
|
+
}
|
|
147
152
|
|
|
148
|
-
|
|
149
|
-
|
|
153
|
+
/** Collect inheritance from inheritance_specifier children. First = extends, rest = implements. */
|
|
154
|
+
function collectSwiftInheritance(
|
|
155
|
+
node: TreeSitterNode,
|
|
156
|
+
className: string,
|
|
157
|
+
ctx: ExtractorOutput,
|
|
158
|
+
): void {
|
|
150
159
|
let first = true;
|
|
151
160
|
for (let i = 0; i < node.childCount; i++) {
|
|
152
161
|
const child = node.child(i);
|
|
153
162
|
if (!child || child.type !== 'inheritance_specifier') continue;
|
|
154
|
-
// inheritance_specifier > user_type > type_identifier
|
|
155
163
|
const userType = findChild(child, 'user_type');
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
ctx.classes.push({
|
|
168
|
-
name,
|
|
169
|
-
implements: typeId.text,
|
|
170
|
-
line: node.startPosition.row + 1,
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
164
|
+
const typeId = userType ? findChild(userType, 'type_identifier') : null;
|
|
165
|
+
if (!typeId) continue;
|
|
166
|
+
if (first) {
|
|
167
|
+
ctx.classes.push({ name: className, extends: typeId.text, line: node.startPosition.row + 1 });
|
|
168
|
+
first = false;
|
|
169
|
+
} else {
|
|
170
|
+
ctx.classes.push({
|
|
171
|
+
name: className,
|
|
172
|
+
implements: typeId.text,
|
|
173
|
+
line: node.startPosition.row + 1,
|
|
174
|
+
});
|
|
174
175
|
}
|
|
175
176
|
}
|
|
176
177
|
}
|
package/src/extractors/zig.ts
CHANGED
|
@@ -100,78 +100,75 @@ function handleZigVariable(node: TreeSitterNode, ctx: ExtractorOutput): void {
|
|
|
100
100
|
if (!nameNode) return;
|
|
101
101
|
const name = nameNode.text;
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
if (tryHandleZigContainerDecl(node, name, ctx)) return;
|
|
104
|
+
if (tryHandleZigImportDecl(node, name, ctx)) return;
|
|
105
|
+
|
|
106
|
+
// Regular constant/variable
|
|
107
|
+
const isConst = hasChildText(node, 'const');
|
|
108
|
+
ctx.definitions.push({
|
|
109
|
+
name,
|
|
110
|
+
kind: isConst ? 'constant' : 'variable',
|
|
111
|
+
line: node.startPosition.row + 1,
|
|
112
|
+
endLine: nodeEndLine(node),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Try to handle a variable_declaration as a struct/enum/union. Returns true if handled. */
|
|
117
|
+
function tryHandleZigContainerDecl(
|
|
118
|
+
node: TreeSitterNode,
|
|
119
|
+
name: string,
|
|
120
|
+
ctx: ExtractorOutput,
|
|
121
|
+
): boolean {
|
|
104
122
|
for (let i = 0; i < node.childCount; i++) {
|
|
105
123
|
const child = node.child(i);
|
|
106
124
|
if (!child) continue;
|
|
125
|
+
const containerKind = zigContainerKind(child.type);
|
|
126
|
+
if (!containerKind) continue;
|
|
107
127
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
if (child.type === 'enum_declaration') {
|
|
122
|
-
ctx.definitions.push({
|
|
123
|
-
name,
|
|
124
|
-
kind: 'enum',
|
|
125
|
-
line: node.startPosition.row + 1,
|
|
126
|
-
endLine: nodeEndLine(node),
|
|
127
|
-
visibility: isZigPub(node) ? 'public' : undefined,
|
|
128
|
-
});
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (child.type === 'union_declaration') {
|
|
132
|
-
ctx.definitions.push({
|
|
133
|
-
name,
|
|
134
|
-
kind: 'struct',
|
|
135
|
-
line: node.startPosition.row + 1,
|
|
136
|
-
endLine: nodeEndLine(node),
|
|
137
|
-
visibility: isZigPub(node) ? 'public' : undefined,
|
|
138
|
-
});
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
128
|
+
const members = child.type === 'struct_declaration' ? extractZigContainerFields(child) : [];
|
|
129
|
+
ctx.definitions.push({
|
|
130
|
+
name,
|
|
131
|
+
kind: containerKind,
|
|
132
|
+
line: node.startPosition.row + 1,
|
|
133
|
+
endLine: nodeEndLine(node),
|
|
134
|
+
children: members.length > 0 ? members : undefined,
|
|
135
|
+
visibility: isZigPub(node) ? 'public' : undefined,
|
|
136
|
+
});
|
|
137
|
+
if (child.type === 'struct_declaration') extractZigContainerMethods(child, name, ctx);
|
|
138
|
+
return true;
|
|
141
139
|
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
/** Map a Zig container node type to a definition kind, or undefined if not a container. */
|
|
144
|
+
function zigContainerKind(nodeType: string): 'struct' | 'enum' | undefined {
|
|
145
|
+
if (nodeType === 'struct_declaration' || nodeType === 'union_declaration') return 'struct';
|
|
146
|
+
if (nodeType === 'enum_declaration') return 'enum';
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Try to handle a variable_declaration as an @import. Returns true if handled. */
|
|
151
|
+
function tryHandleZigImportDecl(node: TreeSitterNode, name: string, ctx: ExtractorOutput): boolean {
|
|
144
152
|
for (let i = 0; i < node.childCount; i++) {
|
|
145
153
|
const child = node.child(i);
|
|
146
|
-
if (!child) continue;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (args) {
|
|
152
|
-
const strArg = findChild(args, 'string_literal') || findChild(args, 'string');
|
|
153
|
-
if (strArg) {
|
|
154
|
-
const source = strArg.text.replace(/^"|"$/g, '');
|
|
155
|
-
ctx.imports.push({
|
|
156
|
-
source,
|
|
157
|
-
names: [name],
|
|
158
|
-
line: node.startPosition.row + 1,
|
|
159
|
-
});
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
154
|
+
if (!child || child.type !== 'builtin_function') continue;
|
|
155
|
+
const source = extractZigImportSource(child);
|
|
156
|
+
if (source) {
|
|
157
|
+
ctx.imports.push({ source, names: [name], line: node.startPosition.row + 1 });
|
|
158
|
+
return true;
|
|
164
159
|
}
|
|
165
160
|
}
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
166
163
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
164
|
+
/** Extract the import source path from a builtin_function node if it is @import. */
|
|
165
|
+
function extractZigImportSource(builtinNode: TreeSitterNode): string | null {
|
|
166
|
+
const builtinId = findChild(builtinNode, 'builtin_identifier');
|
|
167
|
+
if (builtinId?.text !== '@import') return null;
|
|
168
|
+
const args = findChild(builtinNode, 'arguments');
|
|
169
|
+
if (!args) return null;
|
|
170
|
+
const strArg = findChild(args, 'string_literal') || findChild(args, 'string');
|
|
171
|
+
return strArg ? strArg.text.replace(/^"|"$/g, '') : null;
|
|
175
172
|
}
|
|
176
173
|
|
|
177
174
|
function extractZigContainerFields(container: TreeSitterNode): SubDeclaration[] {
|