optave-codegraph 3.13.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/LICENSE +190 -0
- package/README.md +984 -0
- package/dist/ast-analysis/engine.d.ts +19 -0
- package/dist/ast-analysis/engine.d.ts.map +1 -0
- package/dist/ast-analysis/engine.js +660 -0
- package/dist/ast-analysis/engine.js.map +1 -0
- package/dist/ast-analysis/metrics.d.ts +34 -0
- package/dist/ast-analysis/metrics.d.ts.map +1 -0
- package/dist/ast-analysis/metrics.js +123 -0
- package/dist/ast-analysis/metrics.js.map +1 -0
- package/dist/ast-analysis/rules/b2.d.ts +7 -0
- package/dist/ast-analysis/rules/b2.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b2.js +240 -0
- package/dist/ast-analysis/rules/b2.js.map +1 -0
- package/dist/ast-analysis/rules/b3.d.ts +6 -0
- package/dist/ast-analysis/rules/b3.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b3.js +105 -0
- package/dist/ast-analysis/rules/b3.js.map +1 -0
- package/dist/ast-analysis/rules/b4.d.ts +9 -0
- package/dist/ast-analysis/rules/b4.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b4.js +361 -0
- package/dist/ast-analysis/rules/b4.js.map +1 -0
- package/dist/ast-analysis/rules/b5.d.ts +4 -0
- package/dist/ast-analysis/rules/b5.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b5.js +52 -0
- package/dist/ast-analysis/rules/b5.js.map +1 -0
- package/dist/ast-analysis/rules/c.d.ts +4 -0
- package/dist/ast-analysis/rules/c.d.ts.map +1 -0
- package/dist/ast-analysis/rules/c.js +143 -0
- package/dist/ast-analysis/rules/c.js.map +1 -0
- package/dist/ast-analysis/rules/csharp.d.ts +7 -0
- package/dist/ast-analysis/rules/csharp.d.ts.map +1 -0
- package/dist/ast-analysis/rules/csharp.js +196 -0
- package/dist/ast-analysis/rules/csharp.js.map +1 -0
- package/dist/ast-analysis/rules/go.d.ts +7 -0
- package/dist/ast-analysis/rules/go.d.ts.map +1 -0
- package/dist/ast-analysis/rules/go.js +173 -0
- package/dist/ast-analysis/rules/go.js.map +1 -0
- package/dist/ast-analysis/rules/index.d.ts +13 -0
- package/dist/ast-analysis/rules/index.d.ts.map +1 -0
- package/dist/ast-analysis/rules/index.js +325 -0
- package/dist/ast-analysis/rules/index.js.map +1 -0
- package/dist/ast-analysis/rules/java.d.ts +7 -0
- package/dist/ast-analysis/rules/java.d.ts.map +1 -0
- package/dist/ast-analysis/rules/java.js +167 -0
- package/dist/ast-analysis/rules/java.js.map +1 -0
- package/dist/ast-analysis/rules/javascript.d.ts +7 -0
- package/dist/ast-analysis/rules/javascript.d.ts.map +1 -0
- package/dist/ast-analysis/rules/javascript.js +233 -0
- package/dist/ast-analysis/rules/javascript.js.map +1 -0
- package/dist/ast-analysis/rules/php.d.ts +7 -0
- package/dist/ast-analysis/rules/php.d.ts.map +1 -0
- package/dist/ast-analysis/rules/php.js +212 -0
- package/dist/ast-analysis/rules/php.js.map +1 -0
- package/dist/ast-analysis/rules/python.d.ts +7 -0
- package/dist/ast-analysis/rules/python.d.ts.map +1 -0
- package/dist/ast-analysis/rules/python.js +189 -0
- package/dist/ast-analysis/rules/python.js.map +1 -0
- package/dist/ast-analysis/rules/ruby.d.ts +7 -0
- package/dist/ast-analysis/rules/ruby.d.ts.map +1 -0
- package/dist/ast-analysis/rules/ruby.js +193 -0
- package/dist/ast-analysis/rules/ruby.js.map +1 -0
- package/dist/ast-analysis/rules/rust.d.ts +7 -0
- package/dist/ast-analysis/rules/rust.d.ts.map +1 -0
- package/dist/ast-analysis/rules/rust.js +166 -0
- package/dist/ast-analysis/rules/rust.js.map +1 -0
- package/dist/ast-analysis/shared.d.ts +12 -0
- package/dist/ast-analysis/shared.d.ts.map +1 -0
- package/dist/ast-analysis/shared.js +166 -0
- package/dist/ast-analysis/shared.js.map +1 -0
- package/dist/ast-analysis/visitor-utils.d.ts +70 -0
- package/dist/ast-analysis/visitor-utils.d.ts.map +1 -0
- package/dist/ast-analysis/visitor-utils.js +235 -0
- package/dist/ast-analysis/visitor-utils.js.map +1 -0
- package/dist/ast-analysis/visitor.d.ts +27 -0
- package/dist/ast-analysis/visitor.d.ts.map +1 -0
- package/dist/ast-analysis/visitor.js +178 -0
- package/dist/ast-analysis/visitor.js.map +1 -0
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts +4 -0
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/ast-store-visitor.js +288 -0
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.d.ts +5 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.js +166 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-loops.d.ts +7 -0
- package/dist/ast-analysis/visitors/cfg-loops.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-loops.js +73 -0
- package/dist/ast-analysis/visitors/cfg-loops.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-shared.d.ts +56 -0
- package/dist/ast-analysis/visitors/cfg-shared.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-shared.js +107 -0
- package/dist/ast-analysis/visitors/cfg-shared.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.d.ts +4 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.js +100 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts +5 -0
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-visitor.js +231 -0
- package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -0
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts +8 -0
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/complexity-visitor.js +233 -0
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -0
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts +5 -0
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/dataflow-visitor.js +378 -0
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -0
- package/dist/cli/commands/ast.d.ts +3 -0
- package/dist/cli/commands/ast.d.ts.map +1 -0
- package/dist/cli/commands/ast.js +23 -0
- package/dist/cli/commands/ast.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +3 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +47 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/batch.d.ts +3 -0
- package/dist/cli/commands/batch.d.ts.map +1 -0
- package/dist/cli/commands/batch.js +66 -0
- package/dist/cli/commands/batch.js.map +1 -0
- package/dist/cli/commands/branch-compare.d.ts +3 -0
- package/dist/cli/commands/branch-compare.d.ts.map +1 -0
- package/dist/cli/commands/branch-compare.js +26 -0
- package/dist/cli/commands/branch-compare.js.map +1 -0
- package/dist/cli/commands/brief.d.ts +3 -0
- package/dist/cli/commands/brief.d.ts.map +1 -0
- package/dist/cli/commands/brief.js +12 -0
- package/dist/cli/commands/brief.js.map +1 -0
- package/dist/cli/commands/build.d.ts +3 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +33 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/cfg.d.ts +3 -0
- package/dist/cli/commands/cfg.d.ts.map +1 -0
- package/dist/cli/commands/cfg.js +27 -0
- package/dist/cli/commands/cfg.js.map +1 -0
- package/dist/cli/commands/check.d.ts +3 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +65 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/children.d.ts +3 -0
- package/dist/cli/commands/children.d.ts.map +1 -0
- package/dist/cli/commands/children.js +33 -0
- package/dist/cli/commands/children.js.map +1 -0
- package/dist/cli/commands/co-change.d.ts +3 -0
- package/dist/cli/commands/co-change.d.ts.map +1 -0
- package/dist/cli/commands/co-change.js +66 -0
- package/dist/cli/commands/co-change.js.map +1 -0
- package/dist/cli/commands/communities.d.ts +3 -0
- package/dist/cli/commands/communities.d.ts.map +1 -0
- package/dist/cli/commands/communities.js +20 -0
- package/dist/cli/commands/communities.js.map +1 -0
- package/dist/cli/commands/complexity.d.ts +3 -0
- package/dist/cli/commands/complexity.d.ts.map +1 -0
- package/dist/cli/commands/complexity.js +47 -0
- package/dist/cli/commands/complexity.js.map +1 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +275 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/context.d.ts +3 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +35 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/cycles.d.ts +3 -0
- package/dist/cli/commands/cycles.d.ts.map +1 -0
- package/dist/cli/commands/cycles.js +33 -0
- package/dist/cli/commands/cycles.js.map +1 -0
- package/dist/cli/commands/dataflow.d.ts +3 -0
- package/dist/cli/commands/dataflow.d.ts.map +1 -0
- package/dist/cli/commands/dataflow.js +29 -0
- package/dist/cli/commands/dataflow.js.map +1 -0
- package/dist/cli/commands/deps.d.ts +3 -0
- package/dist/cli/commands/deps.d.ts.map +1 -0
- package/dist/cli/commands/deps.js +18 -0
- package/dist/cli/commands/deps.js.map +1 -0
- package/dist/cli/commands/diff-impact.d.ts +3 -0
- package/dist/cli/commands/diff-impact.d.ts.map +1 -0
- package/dist/cli/commands/diff-impact.js +29 -0
- package/dist/cli/commands/diff-impact.js.map +1 -0
- package/dist/cli/commands/embed.d.ts +3 -0
- package/dist/cli/commands/embed.d.ts.map +1 -0
- package/dist/cli/commands/embed.js +75 -0
- package/dist/cli/commands/embed.js.map +1 -0
- package/dist/cli/commands/export.d.ts +3 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +72 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/exports.d.ts +3 -0
- package/dist/cli/commands/exports.d.ts.map +1 -0
- package/dist/cli/commands/exports.js +14 -0
- package/dist/cli/commands/exports.js.map +1 -0
- package/dist/cli/commands/flow.d.ts +3 -0
- package/dist/cli/commands/flow.d.ts.map +1 -0
- package/dist/cli/commands/flow.js +32 -0
- package/dist/cli/commands/flow.js.map +1 -0
- package/dist/cli/commands/fn-impact.d.ts +3 -0
- package/dist/cli/commands/fn-impact.d.ts.map +1 -0
- package/dist/cli/commands/fn-impact.js +33 -0
- package/dist/cli/commands/fn-impact.js.map +1 -0
- package/dist/cli/commands/impact.d.ts +3 -0
- package/dist/cli/commands/impact.d.ts.map +1 -0
- package/dist/cli/commands/impact.js +12 -0
- package/dist/cli/commands/impact.js.map +1 -0
- package/dist/cli/commands/implementations.d.ts +3 -0
- package/dist/cli/commands/implementations.d.ts.map +1 -0
- package/dist/cli/commands/implementations.js +29 -0
- package/dist/cli/commands/implementations.js.map +1 -0
- package/dist/cli/commands/info.d.ts +3 -0
- package/dist/cli/commands/info.d.ts.map +1 -0
- package/dist/cli/commands/info.js +67 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/interfaces.d.ts +3 -0
- package/dist/cli/commands/interfaces.d.ts.map +1 -0
- package/dist/cli/commands/interfaces.js +29 -0
- package/dist/cli/commands/interfaces.js.map +1 -0
- package/dist/cli/commands/map.d.ts +3 -0
- package/dist/cli/commands/map.d.ts.map +1 -0
- package/dist/cli/commands/map.js +19 -0
- package/dist/cli/commands/map.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +3 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +18 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/models.d.ts +3 -0
- package/dist/cli/commands/models.d.ts.map +1 -0
- package/dist/cli/commands/models.js +19 -0
- package/dist/cli/commands/models.js.map +1 -0
- package/dist/cli/commands/owners.d.ts +3 -0
- package/dist/cli/commands/owners.d.ts.map +1 -0
- package/dist/cli/commands/owners.js +27 -0
- package/dist/cli/commands/owners.js.map +1 -0
- package/dist/cli/commands/path.d.ts +3 -0
- package/dist/cli/commands/path.d.ts.map +1 -0
- package/dist/cli/commands/path.js +41 -0
- package/dist/cli/commands/path.js.map +1 -0
- package/dist/cli/commands/plot.d.ts +3 -0
- package/dist/cli/commands/plot.d.ts.map +1 -0
- package/dist/cli/commands/plot.js +96 -0
- package/dist/cli/commands/plot.js.map +1 -0
- package/dist/cli/commands/query.d.ts +3 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +51 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/registry.d.ts +3 -0
- package/dist/cli/commands/registry.d.ts.map +1 -0
- package/dist/cli/commands/registry.js +95 -0
- package/dist/cli/commands/registry.js.map +1 -0
- package/dist/cli/commands/roles.d.ts +3 -0
- package/dist/cli/commands/roles.d.ts.map +1 -0
- package/dist/cli/commands/roles.js +36 -0
- package/dist/cli/commands/roles.js.map +1 -0
- package/dist/cli/commands/search.d.ts +3 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +43 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/sequence.d.ts +3 -0
- package/dist/cli/commands/sequence.d.ts.map +1 -0
- package/dist/cli/commands/sequence.js +29 -0
- package/dist/cli/commands/sequence.js.map +1 -0
- package/dist/cli/commands/snapshot.d.ts +3 -0
- package/dist/cli/commands/snapshot.d.ts.map +1 -0
- package/dist/cli/commands/snapshot.js +61 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +3 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +15 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/structure.d.ts +3 -0
- package/dist/cli/commands/structure.d.ts.map +1 -0
- package/dist/cli/commands/structure.js +50 -0
- package/dist/cli/commands/structure.js.map +1 -0
- package/dist/cli/commands/triage.d.ts +3 -0
- package/dist/cli/commands/triage.d.ts.map +1 -0
- package/dist/cli/commands/triage.js +89 -0
- package/dist/cli/commands/triage.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +3 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +28 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/commands/where.d.ts +3 -0
- package/dist/cli/commands/where.d.ts.map +1 -0
- package/dist/cli/commands/where.js +20 -0
- package/dist/cli/commands/where.js.map +1 -0
- package/dist/cli/index.d.ts +22 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +139 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/shared/open-graph.d.ts +11 -0
- package/dist/cli/shared/open-graph.d.ts.map +1 -0
- package/dist/cli/shared/open-graph.js +9 -0
- package/dist/cli/shared/open-graph.js.map +1 -0
- package/dist/cli/shared/options.d.ts +25 -0
- package/dist/cli/shared/options.d.ts.map +1 -0
- package/dist/cli/shared/options.js +66 -0
- package/dist/cli/shared/options.js.map +1 -0
- package/dist/cli/shared/output.d.ts +2 -0
- package/dist/cli/shared/output.d.ts.map +1 -0
- package/dist/cli/shared/output.js +2 -0
- package/dist/cli/shared/output.js.map +1 -0
- package/dist/cli/types.d.ts +32 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +38 -0
- package/dist/cli.js.map +1 -0
- package/dist/db/better-sqlite3.d.ts +4 -0
- package/dist/db/better-sqlite3.d.ts.map +1 -0
- package/dist/db/better-sqlite3.js +19 -0
- package/dist/db/better-sqlite3.js.map +1 -0
- package/dist/db/connection.d.ts +82 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +444 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/index.d.ts +6 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +6 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +11 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +416 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/query-builder.d.ts +88 -0
- package/dist/db/query-builder.d.ts.map +1 -0
- package/dist/db/query-builder.js +321 -0
- package/dist/db/query-builder.js.map +1 -0
- package/dist/db/repository/base.d.ts +103 -0
- package/dist/db/repository/base.d.ts.map +1 -0
- package/dist/db/repository/base.js +172 -0
- package/dist/db/repository/base.js.map +1 -0
- package/dist/db/repository/build-stmts.d.ts +16 -0
- package/dist/db/repository/build-stmts.d.ts.map +1 -0
- package/dist/db/repository/build-stmts.js +76 -0
- package/dist/db/repository/build-stmts.js.map +1 -0
- package/dist/db/repository/cached-stmt.d.ts +9 -0
- package/dist/db/repository/cached-stmt.d.ts.map +1 -0
- package/dist/db/repository/cached-stmt.js +15 -0
- package/dist/db/repository/cached-stmt.js.map +1 -0
- package/dist/db/repository/cfg.d.ts +34 -0
- package/dist/db/repository/cfg.d.ts.map +1 -0
- package/dist/db/repository/cfg.js +46 -0
- package/dist/db/repository/cfg.js.map +1 -0
- package/dist/db/repository/cochange.d.ts +14 -0
- package/dist/db/repository/cochange.d.ts.map +1 -0
- package/dist/db/repository/cochange.js +38 -0
- package/dist/db/repository/cochange.js.map +1 -0
- package/dist/db/repository/complexity.d.ts +7 -0
- package/dist/db/repository/complexity.d.ts.map +1 -0
- package/dist/db/repository/complexity.js +12 -0
- package/dist/db/repository/complexity.js.map +1 -0
- package/dist/db/repository/dataflow.d.ts +11 -0
- package/dist/db/repository/dataflow.d.ts.map +1 -0
- package/dist/db/repository/dataflow.js +30 -0
- package/dist/db/repository/dataflow.js.map +1 -0
- package/dist/db/repository/edges.d.ts +66 -0
- package/dist/db/repository/edges.d.ts.map +1 -0
- package/dist/db/repository/edges.js +175 -0
- package/dist/db/repository/edges.js.map +1 -0
- package/dist/db/repository/embeddings.d.ts +14 -0
- package/dist/db/repository/embeddings.d.ts.map +1 -0
- package/dist/db/repository/embeddings.js +40 -0
- package/dist/db/repository/embeddings.js.map +1 -0
- package/dist/db/repository/graph-read.d.ts +18 -0
- package/dist/db/repository/graph-read.d.ts.map +1 -0
- package/dist/db/repository/graph-read.js +33 -0
- package/dist/db/repository/graph-read.js.map +1 -0
- package/dist/db/repository/in-memory-repository.d.ts +88 -0
- package/dist/db/repository/in-memory-repository.d.ts.map +1 -0
- package/dist/db/repository/in-memory-repository.js +541 -0
- package/dist/db/repository/in-memory-repository.js.map +1 -0
- package/dist/db/repository/index.d.ts +16 -0
- package/dist/db/repository/index.d.ts.map +1 -0
- package/dist/db/repository/index.js +16 -0
- package/dist/db/repository/index.js.map +1 -0
- package/dist/db/repository/native-repository.d.ts +70 -0
- package/dist/db/repository/native-repository.d.ts.map +1 -0
- package/dist/db/repository/native-repository.js +418 -0
- package/dist/db/repository/native-repository.js.map +1 -0
- package/dist/db/repository/nodes.d.ts +86 -0
- package/dist/db/repository/nodes.d.ts.map +1 -0
- package/dist/db/repository/nodes.js +203 -0
- package/dist/db/repository/nodes.js.map +1 -0
- package/dist/db/repository/sqlite-repository.d.ts +59 -0
- package/dist/db/repository/sqlite-repository.d.ts.map +1 -0
- package/dist/db/repository/sqlite-repository.js +199 -0
- package/dist/db/repository/sqlite-repository.js.map +1 -0
- package/dist/domain/analysis/brief.d.ts +25 -0
- package/dist/domain/analysis/brief.d.ts.map +1 -0
- package/dist/domain/analysis/brief.js +136 -0
- package/dist/domain/analysis/brief.js.map +1 -0
- package/dist/domain/analysis/context.d.ts +241 -0
- package/dist/domain/analysis/context.d.ts.map +1 -0
- package/dist/domain/analysis/context.js +361 -0
- package/dist/domain/analysis/context.js.map +1 -0
- package/dist/domain/analysis/dependencies.d.ts +158 -0
- package/dist/domain/analysis/dependencies.d.ts.map +1 -0
- package/dist/domain/analysis/dependencies.js +522 -0
- package/dist/domain/analysis/dependencies.js.map +1 -0
- package/dist/domain/analysis/diff-impact.d.ts +90 -0
- package/dist/domain/analysis/diff-impact.d.ts.map +1 -0
- package/dist/domain/analysis/diff-impact.js +301 -0
- package/dist/domain/analysis/diff-impact.js.map +1 -0
- package/dist/domain/analysis/exports.d.ts +8 -0
- package/dist/domain/analysis/exports.d.ts.map +1 -0
- package/dist/domain/analysis/exports.js +178 -0
- package/dist/domain/analysis/exports.js.map +1 -0
- package/dist/domain/analysis/fn-impact.d.ts +61 -0
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -0
- package/dist/domain/analysis/fn-impact.js +190 -0
- package/dist/domain/analysis/fn-impact.js.map +1 -0
- package/dist/domain/analysis/impact.d.ts +11 -0
- package/dist/domain/analysis/impact.d.ts.map +1 -0
- package/dist/domain/analysis/impact.js +11 -0
- package/dist/domain/analysis/impact.js.map +1 -0
- package/dist/domain/analysis/implementations.d.ts +59 -0
- package/dist/domain/analysis/implementations.d.ts.map +1 -0
- package/dist/domain/analysis/implementations.js +65 -0
- package/dist/domain/analysis/implementations.js.map +1 -0
- package/dist/domain/analysis/module-map.d.ts +86 -0
- package/dist/domain/analysis/module-map.d.ts.map +1 -0
- package/dist/domain/analysis/module-map.js +468 -0
- package/dist/domain/analysis/module-map.js.map +1 -0
- package/dist/domain/analysis/query-helpers.d.ts +27 -0
- package/dist/domain/analysis/query-helpers.d.ts.map +1 -0
- package/dist/domain/analysis/query-helpers.js +41 -0
- package/dist/domain/analysis/query-helpers.js.map +1 -0
- package/dist/domain/analysis/roles.d.ts +20 -0
- package/dist/domain/analysis/roles.d.ts.map +1 -0
- package/dist/domain/analysis/roles.js +74 -0
- package/dist/domain/analysis/roles.js.map +1 -0
- package/dist/domain/analysis/symbol-lookup.d.ts +125 -0
- package/dist/domain/analysis/symbol-lookup.d.ts.map +1 -0
- package/dist/domain/analysis/symbol-lookup.js +206 -0
- package/dist/domain/analysis/symbol-lookup.js.map +1 -0
- package/dist/domain/graph/builder/call-resolver.d.ts +89 -0
- package/dist/domain/graph/builder/call-resolver.d.ts.map +1 -0
- package/dist/domain/graph/builder/call-resolver.js +212 -0
- package/dist/domain/graph/builder/call-resolver.js.map +1 -0
- package/dist/domain/graph/builder/cha.d.ts +69 -0
- package/dist/domain/graph/builder/cha.d.ts.map +1 -0
- package/dist/domain/graph/builder/cha.js +158 -0
- package/dist/domain/graph/builder/cha.js.map +1 -0
- package/dist/domain/graph/builder/context.d.ts +91 -0
- package/dist/domain/graph/builder/context.d.ts.map +1 -0
- package/dist/domain/graph/builder/context.js +66 -0
- package/dist/domain/graph/builder/context.js.map +1 -0
- package/dist/domain/graph/builder/helpers.d.ts +97 -0
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -0
- package/dist/domain/graph/builder/helpers.js +558 -0
- package/dist/domain/graph/builder/helpers.js.map +1 -0
- package/dist/domain/graph/builder/incremental.d.ts +53 -0
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -0
- package/dist/domain/graph/builder/incremental.js +647 -0
- package/dist/domain/graph/builder/incremental.js.map +1 -0
- package/dist/domain/graph/builder/native-db-proxy.d.ts +24 -0
- package/dist/domain/graph/builder/native-db-proxy.d.ts.map +1 -0
- package/dist/domain/graph/builder/native-db-proxy.js +91 -0
- package/dist/domain/graph/builder/native-db-proxy.js.map +1 -0
- package/dist/domain/graph/builder/pipeline.d.ts +9 -0
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -0
- package/dist/domain/graph/builder/pipeline.js +448 -0
- package/dist/domain/graph/builder/pipeline.js.map +1 -0
- package/dist/domain/graph/builder/stages/build-edges.d.ts +3 -0
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/build-edges.js +1425 -0
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -0
- package/dist/domain/graph/builder/stages/build-structure.d.ts +3 -0
- package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/build-structure.js +250 -0
- package/dist/domain/graph/builder/stages/build-structure.js.map +1 -0
- package/dist/domain/graph/builder/stages/collect-files.d.ts +3 -0
- package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/collect-files.js +161 -0
- package/dist/domain/graph/builder/stages/collect-files.js.map +1 -0
- package/dist/domain/graph/builder/stages/detect-changes.d.ts +27 -0
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/detect-changes.js +593 -0
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -0
- package/dist/domain/graph/builder/stages/finalize.d.ts +3 -0
- package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/finalize.js +274 -0
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -0
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts +35 -0
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/insert-nodes.js +351 -0
- package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -0
- 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 +1763 -0
- package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -0
- package/dist/domain/graph/builder/stages/parse-files.d.ts +3 -0
- package/dist/domain/graph/builder/stages/parse-files.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/parse-files.js +22 -0
- package/dist/domain/graph/builder/stages/parse-files.js.map +1 -0
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts +7 -0
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/resolve-imports.js +231 -0
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -0
- package/dist/domain/graph/builder/stages/run-analyses.d.ts +3 -0
- package/dist/domain/graph/builder/stages/run-analyses.d.ts.map +1 -0
- package/dist/domain/graph/builder/stages/run-analyses.js +23 -0
- package/dist/domain/graph/builder/stages/run-analyses.js.map +1 -0
- package/dist/domain/graph/builder.d.ts +4 -0
- package/dist/domain/graph/builder.d.ts.map +1 -0
- package/dist/domain/graph/builder.js +6 -0
- package/dist/domain/graph/builder.js.map +1 -0
- package/dist/domain/graph/change-journal.d.ts +50 -0
- package/dist/domain/graph/change-journal.d.ts.map +1 -0
- package/dist/domain/graph/change-journal.js +97 -0
- package/dist/domain/graph/change-journal.js.map +1 -0
- package/dist/domain/graph/cycles.d.ts +19 -0
- package/dist/domain/graph/cycles.d.ts.map +1 -0
- package/dist/domain/graph/cycles.js +142 -0
- package/dist/domain/graph/cycles.js.map +1 -0
- package/dist/domain/graph/journal.d.ts +30 -0
- package/dist/domain/graph/journal.d.ts.map +1 -0
- package/dist/domain/graph/journal.js +360 -0
- package/dist/domain/graph/journal.js.map +1 -0
- package/dist/domain/graph/resolve.d.ts +67 -0
- package/dist/domain/graph/resolve.d.ts.map +1 -0
- package/dist/domain/graph/resolve.js +521 -0
- package/dist/domain/graph/resolve.js.map +1 -0
- package/dist/domain/graph/resolver/points-to.d.ts +53 -0
- package/dist/domain/graph/resolver/points-to.d.ts.map +1 -0
- package/dist/domain/graph/resolver/points-to.js +261 -0
- package/dist/domain/graph/resolver/points-to.js.map +1 -0
- package/dist/domain/graph/resolver/strategy.d.ts +61 -0
- package/dist/domain/graph/resolver/strategy.d.ts.map +1 -0
- package/dist/domain/graph/resolver/strategy.js +222 -0
- package/dist/domain/graph/resolver/strategy.js.map +1 -0
- package/dist/domain/graph/resolver/ts-resolver.d.ts +9 -0
- package/dist/domain/graph/resolver/ts-resolver.d.ts.map +1 -0
- package/dist/domain/graph/resolver/ts-resolver.js +476 -0
- package/dist/domain/graph/resolver/ts-resolver.js.map +1 -0
- package/dist/domain/graph/watcher.d.ts +23 -0
- package/dist/domain/graph/watcher.d.ts.map +1 -0
- package/dist/domain/graph/watcher.js +272 -0
- package/dist/domain/graph/watcher.js.map +1 -0
- package/dist/domain/parser.d.ts +128 -0
- package/dist/domain/parser.d.ts.map +1 -0
- package/dist/domain/parser.js +1246 -0
- package/dist/domain/parser.js.map +1 -0
- package/dist/domain/queries.d.ts +22 -0
- package/dist/domain/queries.d.ts.map +1 -0
- package/dist/domain/queries.js +26 -0
- package/dist/domain/queries.js.map +1 -0
- package/dist/domain/search/generator.d.ts +16 -0
- package/dist/domain/search/generator.d.ts.map +1 -0
- package/dist/domain/search/generator.js +181 -0
- package/dist/domain/search/generator.js.map +1 -0
- package/dist/domain/search/index.d.ts +15 -0
- package/dist/domain/search/index.d.ts.map +1 -0
- package/dist/domain/search/index.js +13 -0
- package/dist/domain/search/index.js.map +1 -0
- package/dist/domain/search/models.d.ts +63 -0
- package/dist/domain/search/models.d.ts.map +1 -0
- package/dist/domain/search/models.js +303 -0
- package/dist/domain/search/models.js.map +1 -0
- package/dist/domain/search/search/cli-formatter.d.ts +10 -0
- package/dist/domain/search/search/cli-formatter.d.ts.map +1 -0
- package/dist/domain/search/search/cli-formatter.js +134 -0
- package/dist/domain/search/search/cli-formatter.js.map +1 -0
- package/dist/domain/search/search/filters.d.ts +9 -0
- package/dist/domain/search/search/filters.d.ts.map +1 -0
- package/dist/domain/search/search/filters.js +31 -0
- package/dist/domain/search/search/filters.js.map +1 -0
- package/dist/domain/search/search/hybrid.d.ts +21 -0
- package/dist/domain/search/search/hybrid.d.ts.map +1 -0
- package/dist/domain/search/search/hybrid.js +122 -0
- package/dist/domain/search/search/hybrid.js.map +1 -0
- package/dist/domain/search/search/keyword.d.ts +18 -0
- package/dist/domain/search/search/keyword.d.ts.map +1 -0
- package/dist/domain/search/search/keyword.js +58 -0
- package/dist/domain/search/search/keyword.js.map +1 -0
- package/dist/domain/search/search/prepare.d.ts +25 -0
- package/dist/domain/search/search/prepare.d.ts.map +1 -0
- package/dist/domain/search/search/prepare.js +63 -0
- package/dist/domain/search/search/prepare.js.map +1 -0
- package/dist/domain/search/search/semantic.d.ts +41 -0
- package/dist/domain/search/search/semantic.d.ts.map +1 -0
- package/dist/domain/search/search/semantic.js +135 -0
- package/dist/domain/search/search/semantic.js.map +1 -0
- package/dist/domain/search/stores/fts5.d.ts +10 -0
- package/dist/domain/search/stores/fts5.d.ts.map +1 -0
- package/dist/domain/search/stores/fts5.js +27 -0
- package/dist/domain/search/stores/fts5.js.map +1 -0
- package/dist/domain/search/stores/sqlite-blob.d.ts +5 -0
- package/dist/domain/search/stores/sqlite-blob.d.ts.map +1 -0
- package/dist/domain/search/stores/sqlite-blob.js +16 -0
- package/dist/domain/search/stores/sqlite-blob.js.map +1 -0
- package/dist/domain/search/strategies/source.d.ts +6 -0
- package/dist/domain/search/strategies/source.d.ts.map +1 -0
- package/dist/domain/search/strategies/source.js +14 -0
- package/dist/domain/search/strategies/source.js.map +1 -0
- package/dist/domain/search/strategies/structured.d.ts +10 -0
- package/dist/domain/search/strategies/structured.d.ts.map +1 -0
- package/dist/domain/search/strategies/structured.js +35 -0
- package/dist/domain/search/strategies/structured.js.map +1 -0
- package/dist/domain/search/strategies/text-utils.d.ts +9 -0
- package/dist/domain/search/strategies/text-utils.d.ts.map +1 -0
- package/dist/domain/search/strategies/text-utils.js +45 -0
- package/dist/domain/search/strategies/text-utils.js.map +1 -0
- package/dist/domain/wasm-worker-entry.d.ts +24 -0
- package/dist/domain/wasm-worker-entry.d.ts.map +1 -0
- package/dist/domain/wasm-worker-entry.js +749 -0
- package/dist/domain/wasm-worker-entry.js.map +1 -0
- package/dist/domain/wasm-worker-pool.d.ts +59 -0
- package/dist/domain/wasm-worker-pool.d.ts.map +1 -0
- package/dist/domain/wasm-worker-pool.js +363 -0
- package/dist/domain/wasm-worker-pool.js.map +1 -0
- package/dist/domain/wasm-worker-protocol.d.ts +81 -0
- package/dist/domain/wasm-worker-protocol.d.ts.map +1 -0
- package/dist/domain/wasm-worker-protocol.js +13 -0
- package/dist/domain/wasm-worker-protocol.js.map +1 -0
- package/dist/extractors/bash.d.ts +6 -0
- package/dist/extractors/bash.d.ts.map +1 -0
- package/dist/extractors/bash.js +91 -0
- package/dist/extractors/bash.js.map +1 -0
- package/dist/extractors/c.d.ts +6 -0
- package/dist/extractors/c.d.ts.map +1 -0
- package/dist/extractors/c.js +223 -0
- package/dist/extractors/c.js.map +1 -0
- package/dist/extractors/clojure.d.ts +12 -0
- package/dist/extractors/clojure.d.ts.map +1 -0
- package/dist/extractors/clojure.js +245 -0
- package/dist/extractors/clojure.js.map +1 -0
- package/dist/extractors/cpp.d.ts +6 -0
- package/dist/extractors/cpp.d.ts.map +1 -0
- package/dist/extractors/cpp.js +365 -0
- package/dist/extractors/cpp.js.map +1 -0
- package/dist/extractors/csharp.d.ts +6 -0
- package/dist/extractors/csharp.d.ts.map +1 -0
- package/dist/extractors/csharp.js +430 -0
- package/dist/extractors/csharp.js.map +1 -0
- package/dist/extractors/cuda.d.ts +11 -0
- package/dist/extractors/cuda.d.ts.map +1 -0
- package/dist/extractors/cuda.js +419 -0
- package/dist/extractors/cuda.js.map +1 -0
- package/dist/extractors/dart.d.ts +6 -0
- package/dist/extractors/dart.d.ts.map +1 -0
- package/dist/extractors/dart.js +277 -0
- package/dist/extractors/dart.js.map +1 -0
- package/dist/extractors/elixir.d.ts +9 -0
- package/dist/extractors/elixir.d.ts.map +1 -0
- package/dist/extractors/elixir.js +327 -0
- package/dist/extractors/elixir.js.map +1 -0
- package/dist/extractors/erlang.d.ts +14 -0
- package/dist/extractors/erlang.d.ts.map +1 -0
- package/dist/extractors/erlang.js +275 -0
- package/dist/extractors/erlang.js.map +1 -0
- package/dist/extractors/fsharp.d.ts +20 -0
- package/dist/extractors/fsharp.d.ts.map +1 -0
- package/dist/extractors/fsharp.js +312 -0
- package/dist/extractors/fsharp.js.map +1 -0
- package/dist/extractors/gleam.d.ts +14 -0
- package/dist/extractors/gleam.d.ts.map +1 -0
- package/dist/extractors/gleam.js +225 -0
- package/dist/extractors/gleam.js.map +1 -0
- package/dist/extractors/go.d.ts +6 -0
- package/dist/extractors/go.d.ts.map +1 -0
- package/dist/extractors/go.js +460 -0
- package/dist/extractors/go.js.map +1 -0
- package/dist/extractors/groovy.d.ts +10 -0
- package/dist/extractors/groovy.d.ts.map +1 -0
- package/dist/extractors/groovy.js +403 -0
- package/dist/extractors/groovy.js.map +1 -0
- package/dist/extractors/haskell.d.ts +8 -0
- package/dist/extractors/haskell.d.ts.map +1 -0
- package/dist/extractors/haskell.js +261 -0
- package/dist/extractors/haskell.js.map +1 -0
- package/dist/extractors/hcl.d.ts +6 -0
- package/dist/extractors/hcl.d.ts.map +1 -0
- package/dist/extractors/hcl.js +114 -0
- package/dist/extractors/hcl.js.map +1 -0
- package/dist/extractors/helpers.d.ts +144 -0
- package/dist/extractors/helpers.d.ts.map +1 -0
- package/dist/extractors/helpers.js +360 -0
- package/dist/extractors/helpers.js.map +1 -0
- package/dist/extractors/index.d.ts +33 -0
- package/dist/extractors/index.d.ts.map +1 -0
- package/dist/extractors/index.js +33 -0
- package/dist/extractors/index.js.map +1 -0
- package/dist/extractors/java.d.ts +6 -0
- package/dist/extractors/java.d.ts.map +1 -0
- package/dist/extractors/java.js +390 -0
- package/dist/extractors/java.js.map +1 -0
- package/dist/extractors/javascript.d.ts +10 -0
- package/dist/extractors/javascript.d.ts.map +1 -0
- package/dist/extractors/javascript.js +3618 -0
- package/dist/extractors/javascript.js.map +1 -0
- package/dist/extractors/julia.d.ts +16 -0
- package/dist/extractors/julia.d.ts.map +1 -0
- package/dist/extractors/julia.js +411 -0
- package/dist/extractors/julia.js.map +1 -0
- package/dist/extractors/kotlin.d.ts +6 -0
- package/dist/extractors/kotlin.d.ts.map +1 -0
- package/dist/extractors/kotlin.js +340 -0
- package/dist/extractors/kotlin.js.map +1 -0
- package/dist/extractors/lua.d.ts +6 -0
- package/dist/extractors/lua.d.ts.map +1 -0
- package/dist/extractors/lua.js +162 -0
- package/dist/extractors/lua.js.map +1 -0
- package/dist/extractors/objc.d.ts +9 -0
- package/dist/extractors/objc.d.ts.map +1 -0
- package/dist/extractors/objc.js +543 -0
- package/dist/extractors/objc.js.map +1 -0
- package/dist/extractors/ocaml.d.ts +6 -0
- package/dist/extractors/ocaml.d.ts.map +1 -0
- package/dist/extractors/ocaml.js +310 -0
- package/dist/extractors/ocaml.js.map +1 -0
- package/dist/extractors/php.d.ts +6 -0
- package/dist/extractors/php.d.ts.map +1 -0
- package/dist/extractors/php.js +381 -0
- package/dist/extractors/php.js.map +1 -0
- package/dist/extractors/python.d.ts +6 -0
- package/dist/extractors/python.d.ts.map +1 -0
- package/dist/extractors/python.js +428 -0
- package/dist/extractors/python.js.map +1 -0
- package/dist/extractors/r.d.ts +13 -0
- package/dist/extractors/r.d.ts.map +1 -0
- package/dist/extractors/r.js +267 -0
- package/dist/extractors/r.js.map +1 -0
- package/dist/extractors/ruby.d.ts +6 -0
- package/dist/extractors/ruby.d.ts.map +1 -0
- package/dist/extractors/ruby.js +281 -0
- package/dist/extractors/ruby.js.map +1 -0
- package/dist/extractors/rust.d.ts +6 -0
- package/dist/extractors/rust.d.ts.map +1 -0
- package/dist/extractors/rust.js +354 -0
- package/dist/extractors/rust.js.map +1 -0
- package/dist/extractors/scala.d.ts +6 -0
- package/dist/extractors/scala.d.ts.map +1 -0
- package/dist/extractors/scala.js +315 -0
- package/dist/extractors/scala.js.map +1 -0
- package/dist/extractors/solidity.d.ts +9 -0
- package/dist/extractors/solidity.d.ts.map +1 -0
- package/dist/extractors/solidity.js +351 -0
- package/dist/extractors/solidity.js.map +1 -0
- package/dist/extractors/swift.d.ts +6 -0
- package/dist/extractors/swift.d.ts.map +1 -0
- package/dist/extractors/swift.js +326 -0
- package/dist/extractors/swift.js.map +1 -0
- package/dist/extractors/verilog.d.ts +9 -0
- package/dist/extractors/verilog.d.ts.map +1 -0
- package/dist/extractors/verilog.js +351 -0
- package/dist/extractors/verilog.js.map +1 -0
- package/dist/extractors/zig.d.ts +9 -0
- package/dist/extractors/zig.d.ts.map +1 -0
- package/dist/extractors/zig.js +274 -0
- package/dist/extractors/zig.js.map +1 -0
- package/dist/features/ast.d.ts +78 -0
- package/dist/features/ast.d.ts.map +1 -0
- package/dist/features/ast.js +228 -0
- package/dist/features/ast.js.map +1 -0
- package/dist/features/audit.d.ts +15 -0
- package/dist/features/audit.d.ts.map +1 -0
- package/dist/features/audit.js +275 -0
- package/dist/features/audit.js.map +1 -0
- package/dist/features/batch.d.ts +54 -0
- package/dist/features/batch.d.ts.map +1 -0
- package/dist/features/batch.js +97 -0
- package/dist/features/batch.js.map +1 -0
- package/dist/features/boundaries.d.ts +51 -0
- package/dist/features/boundaries.d.ts.map +1 -0
- package/dist/features/boundaries.js +248 -0
- package/dist/features/boundaries.js.map +1 -0
- package/dist/features/branch-compare.d.ts +71 -0
- package/dist/features/branch-compare.d.ts.map +1 -0
- package/dist/features/branch-compare.js +444 -0
- package/dist/features/branch-compare.js.map +1 -0
- package/dist/features/cfg.d.ts +79 -0
- package/dist/features/cfg.d.ts.map +1 -0
- package/dist/features/cfg.js +483 -0
- package/dist/features/cfg.js.map +1 -0
- package/dist/features/check.d.ts +84 -0
- package/dist/features/check.d.ts.map +1 -0
- package/dist/features/check.js +290 -0
- package/dist/features/check.js.map +1 -0
- package/dist/features/cochange.d.ts +68 -0
- package/dist/features/cochange.d.ts.map +1 -0
- package/dist/features/cochange.js +384 -0
- package/dist/features/cochange.js.map +1 -0
- package/dist/features/communities.d.ts +26 -0
- package/dist/features/communities.d.ts.map +1 -0
- package/dist/features/communities.js +149 -0
- package/dist/features/communities.js.map +1 -0
- package/dist/features/complexity-query.d.ts +37 -0
- package/dist/features/complexity-query.d.ts.map +1 -0
- package/dist/features/complexity-query.js +268 -0
- package/dist/features/complexity-query.js.map +1 -0
- package/dist/features/complexity.d.ts +52 -0
- package/dist/features/complexity.d.ts.map +1 -0
- package/dist/features/complexity.js +490 -0
- package/dist/features/complexity.js.map +1 -0
- package/dist/features/dataflow.d.ts +129 -0
- package/dist/features/dataflow.d.ts.map +1 -0
- package/dist/features/dataflow.js +1079 -0
- package/dist/features/dataflow.js.map +1 -0
- package/dist/features/export.d.ts +35 -0
- package/dist/features/export.d.ts.map +1 -0
- package/dist/features/export.js +340 -0
- package/dist/features/export.js.map +1 -0
- package/dist/features/flow.d.ts +21 -0
- package/dist/features/flow.d.ts.map +1 -0
- package/dist/features/flow.js +195 -0
- package/dist/features/flow.js.map +1 -0
- package/dist/features/graph-enrichment.d.ts +44 -0
- package/dist/features/graph-enrichment.d.ts.map +1 -0
- package/dist/features/graph-enrichment.js +312 -0
- package/dist/features/graph-enrichment.js.map +1 -0
- package/dist/features/manifesto.d.ts +23 -0
- package/dist/features/manifesto.d.ts.map +1 -0
- package/dist/features/manifesto.js +382 -0
- package/dist/features/manifesto.js.map +1 -0
- package/dist/features/owners.d.ts +60 -0
- package/dist/features/owners.d.ts.map +1 -0
- package/dist/features/owners.js +248 -0
- package/dist/features/owners.js.map +1 -0
- package/dist/features/sequence.d.ts +42 -0
- package/dist/features/sequence.d.ts.map +1 -0
- package/dist/features/sequence.js +271 -0
- package/dist/features/sequence.js.map +1 -0
- package/dist/features/shared/find-nodes.d.ts +7 -0
- package/dist/features/shared/find-nodes.d.ts.map +1 -0
- package/dist/features/shared/find-nodes.js +18 -0
- package/dist/features/shared/find-nodes.js.map +1 -0
- package/dist/features/snapshot.d.ts +25 -0
- package/dist/features/snapshot.d.ts.map +1 -0
- package/dist/features/snapshot.js +188 -0
- package/dist/features/snapshot.js.map +1 -0
- package/dist/features/structure-query.d.ts +76 -0
- package/dist/features/structure-query.d.ts.map +1 -0
- package/dist/features/structure-query.js +274 -0
- package/dist/features/structure-query.js.map +1 -0
- package/dist/features/structure.d.ts +39 -0
- package/dist/features/structure.d.ts.map +1 -0
- package/dist/features/structure.js +796 -0
- package/dist/features/structure.js.map +1 -0
- package/dist/features/triage.d.ts +47 -0
- package/dist/features/triage.d.ts.map +1 -0
- package/dist/features/triage.js +123 -0
- package/dist/features/triage.js.map +1 -0
- package/dist/graph/algorithms/bfs.d.ts +14 -0
- package/dist/graph/algorithms/bfs.d.ts.map +1 -0
- package/dist/graph/algorithms/bfs.js +72 -0
- package/dist/graph/algorithms/bfs.js.map +1 -0
- package/dist/graph/algorithms/centrality.d.ts +12 -0
- package/dist/graph/algorithms/centrality.d.ts.map +1 -0
- package/dist/graph/algorithms/centrality.js +42 -0
- package/dist/graph/algorithms/centrality.js.map +1 -0
- package/dist/graph/algorithms/index.d.ts +7 -0
- package/dist/graph/algorithms/index.d.ts.map +1 -0
- package/dist/graph/algorithms/index.js +7 -0
- package/dist/graph/algorithms/index.js.map +1 -0
- package/dist/graph/algorithms/leiden/adapter.d.ts +37 -0
- package/dist/graph/algorithms/leiden/adapter.d.ts.map +1 -0
- package/dist/graph/algorithms/leiden/adapter.js +173 -0
- package/dist/graph/algorithms/leiden/adapter.js.map +1 -0
- package/dist/graph/algorithms/leiden/cpm.d.ts +28 -0
- package/dist/graph/algorithms/leiden/cpm.d.ts.map +1 -0
- package/dist/graph/algorithms/leiden/cpm.js +48 -0
- package/dist/graph/algorithms/leiden/cpm.js.map +1 -0
- package/dist/graph/algorithms/leiden/index.d.ts +37 -0
- package/dist/graph/algorithms/leiden/index.d.ts.map +1 -0
- package/dist/graph/algorithms/leiden/index.js +157 -0
- package/dist/graph/algorithms/leiden/index.js.map +1 -0
- package/dist/graph/algorithms/leiden/modularity.d.ts +33 -0
- package/dist/graph/algorithms/leiden/modularity.d.ts.map +1 -0
- package/dist/graph/algorithms/leiden/modularity.js +80 -0
- package/dist/graph/algorithms/leiden/modularity.js.map +1 -0
- package/dist/graph/algorithms/leiden/optimiser.d.ts +62 -0
- package/dist/graph/algorithms/leiden/optimiser.d.ts.map +1 -0
- package/dist/graph/algorithms/leiden/optimiser.js +530 -0
- package/dist/graph/algorithms/leiden/optimiser.js.map +1 -0
- package/dist/graph/algorithms/leiden/partition.d.ts +44 -0
- package/dist/graph/algorithms/leiden/partition.d.ts.map +1 -0
- package/dist/graph/algorithms/leiden/partition.js +438 -0
- package/dist/graph/algorithms/leiden/partition.js.map +1 -0
- package/dist/graph/algorithms/leiden/rng.d.ts +9 -0
- package/dist/graph/algorithms/leiden/rng.d.ts.map +1 -0
- package/dist/graph/algorithms/leiden/rng.js +17 -0
- package/dist/graph/algorithms/leiden/rng.js.map +1 -0
- package/dist/graph/algorithms/louvain.d.ts +20 -0
- package/dist/graph/algorithms/louvain.d.ts.map +1 -0
- package/dist/graph/algorithms/louvain.js +52 -0
- package/dist/graph/algorithms/louvain.js.map +1 -0
- package/dist/graph/algorithms/shortest-path.d.ts +10 -0
- package/dist/graph/algorithms/shortest-path.d.ts.map +1 -0
- package/dist/graph/algorithms/shortest-path.js +55 -0
- package/dist/graph/algorithms/shortest-path.js.map +1 -0
- package/dist/graph/algorithms/tarjan.d.ts +9 -0
- package/dist/graph/algorithms/tarjan.d.ts.map +1 -0
- package/dist/graph/algorithms/tarjan.js +52 -0
- package/dist/graph/algorithms/tarjan.js.map +1 -0
- package/dist/graph/builders/dependency.d.ts +18 -0
- package/dist/graph/builders/dependency.d.ts.map +1 -0
- package/dist/graph/builders/dependency.js +101 -0
- package/dist/graph/builders/dependency.js.map +1 -0
- package/dist/graph/builders/index.d.ts +4 -0
- package/dist/graph/builders/index.d.ts.map +1 -0
- package/dist/graph/builders/index.js +4 -0
- package/dist/graph/builders/index.js.map +1 -0
- package/dist/graph/builders/structure.d.ts +10 -0
- package/dist/graph/builders/structure.d.ts.map +1 -0
- package/dist/graph/builders/structure.js +33 -0
- package/dist/graph/builders/structure.js.map +1 -0
- package/dist/graph/builders/temporal.d.ts +13 -0
- package/dist/graph/builders/temporal.d.ts.map +1 -0
- package/dist/graph/builders/temporal.js +29 -0
- package/dist/graph/builders/temporal.js.map +1 -0
- package/dist/graph/classifiers/index.d.ts +3 -0
- package/dist/graph/classifiers/index.d.ts.map +1 -0
- package/dist/graph/classifiers/index.js +3 -0
- package/dist/graph/classifiers/index.js.map +1 -0
- package/dist/graph/classifiers/risk.d.ts +39 -0
- package/dist/graph/classifiers/risk.d.ts.map +1 -0
- package/dist/graph/classifiers/risk.js +78 -0
- package/dist/graph/classifiers/risk.js.map +1 -0
- package/dist/graph/classifiers/roles.d.ts +48 -0
- package/dist/graph/classifiers/roles.d.ts.map +1 -0
- package/dist/graph/classifiers/roles.js +180 -0
- package/dist/graph/classifiers/roles.js.map +1 -0
- package/dist/graph/index.d.ts +5 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +6 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/model.d.ts +57 -0
- package/dist/graph/model.d.ts.map +1 -0
- package/dist/graph/model.js +205 -0
- package/dist/graph/model.js.map +1 -0
- package/dist/index.cjs +16 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/config.d.ts +281 -0
- package/dist/infrastructure/config.d.ts.map +1 -0
- package/dist/infrastructure/config.js +857 -0
- package/dist/infrastructure/config.js.map +1 -0
- package/dist/infrastructure/logger.d.ts +7 -0
- package/dist/infrastructure/logger.d.ts.map +1 -0
- package/dist/infrastructure/logger.js +21 -0
- package/dist/infrastructure/logger.js.map +1 -0
- package/dist/infrastructure/native.d.ts +38 -0
- package/dist/infrastructure/native.d.ts.map +1 -0
- package/dist/infrastructure/native.js +182 -0
- package/dist/infrastructure/native.js.map +1 -0
- package/dist/infrastructure/registry.d.ts +81 -0
- package/dist/infrastructure/registry.d.ts.map +1 -0
- package/dist/infrastructure/registry.js +229 -0
- package/dist/infrastructure/registry.js.map +1 -0
- package/dist/infrastructure/result-formatter.d.ts +2 -0
- package/dist/infrastructure/result-formatter.d.ts.map +1 -0
- package/dist/infrastructure/result-formatter.js +3 -0
- package/dist/infrastructure/result-formatter.js.map +1 -0
- 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/infrastructure/test-filter.d.ts +5 -0
- package/dist/infrastructure/test-filter.d.ts.map +1 -0
- package/dist/infrastructure/test-filter.js +7 -0
- package/dist/infrastructure/test-filter.js.map +1 -0
- package/dist/infrastructure/update-check.d.ts +26 -0
- package/dist/infrastructure/update-check.d.ts.map +1 -0
- package/dist/infrastructure/update-check.js +164 -0
- package/dist/infrastructure/update-check.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/middleware.d.ts +26 -0
- package/dist/mcp/middleware.d.ts.map +1 -0
- package/dist/mcp/middleware.js +32 -0
- package/dist/mcp/middleware.js.map +1 -0
- package/dist/mcp/server.d.ts +14 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +193 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +21 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tool-registry.js +839 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/mcp/tools/ast-query.d.ts +14 -0
- package/dist/mcp/tools/ast-query.d.ts.map +1 -0
- package/dist/mcp/tools/ast-query.js +13 -0
- package/dist/mcp/tools/ast-query.js.map +1 -0
- package/dist/mcp/tools/audit.d.ts +15 -0
- package/dist/mcp/tools/audit.d.ts.map +1 -0
- package/dist/mcp/tools/audit.js +20 -0
- package/dist/mcp/tools/audit.js.map +1 -0
- package/dist/mcp/tools/batch-query.d.ts +13 -0
- package/dist/mcp/tools/batch-query.d.ts.map +1 -0
- package/dist/mcp/tools/batch-query.js +11 -0
- package/dist/mcp/tools/batch-query.js.map +1 -0
- package/dist/mcp/tools/branch-compare.d.ts +12 -0
- package/dist/mcp/tools/branch-compare.d.ts.map +1 -0
- package/dist/mcp/tools/branch-compare.js +10 -0
- package/dist/mcp/tools/branch-compare.js.map +1 -0
- package/dist/mcp/tools/brief.d.ts +9 -0
- package/dist/mcp/tools/brief.d.ts.map +1 -0
- package/dist/mcp/tools/brief.js +8 -0
- package/dist/mcp/tools/brief.js.map +1 -0
- package/dist/mcp/tools/cfg.d.ts +14 -0
- package/dist/mcp/tools/cfg.d.ts.map +1 -0
- package/dist/mcp/tools/cfg.js +20 -0
- package/dist/mcp/tools/cfg.js.map +1 -0
- package/dist/mcp/tools/check.d.ts +20 -0
- package/dist/mcp/tools/check.d.ts.map +1 -0
- package/dist/mcp/tools/check.js +39 -0
- package/dist/mcp/tools/check.js.map +1 -0
- package/dist/mcp/tools/co-changes.d.ts +12 -0
- package/dist/mcp/tools/co-changes.d.ts.map +1 -0
- package/dist/mcp/tools/co-changes.js +19 -0
- package/dist/mcp/tools/co-changes.js.map +1 -0
- package/dist/mcp/tools/code-owners.d.ts +12 -0
- package/dist/mcp/tools/code-owners.d.ts.map +1 -0
- package/dist/mcp/tools/code-owners.js +12 -0
- package/dist/mcp/tools/code-owners.js.map +1 -0
- package/dist/mcp/tools/communities.d.ts +13 -0
- package/dist/mcp/tools/communities.d.ts.map +1 -0
- package/dist/mcp/tools/communities.js +14 -0
- package/dist/mcp/tools/communities.js.map +1 -0
- package/dist/mcp/tools/complexity.d.ts +16 -0
- package/dist/mcp/tools/complexity.d.ts.map +1 -0
- package/dist/mcp/tools/complexity.js +16 -0
- package/dist/mcp/tools/complexity.js.map +1 -0
- package/dist/mcp/tools/context.d.ts +16 -0
- package/dist/mcp/tools/context.d.ts.map +1 -0
- package/dist/mcp/tools/context.js +16 -0
- package/dist/mcp/tools/context.js.map +1 -0
- package/dist/mcp/tools/dataflow.d.ts +15 -0
- package/dist/mcp/tools/dataflow.d.ts.map +1 -0
- package/dist/mcp/tools/dataflow.js +25 -0
- package/dist/mcp/tools/dataflow.js.map +1 -0
- package/dist/mcp/tools/diff-impact.d.ts +14 -0
- package/dist/mcp/tools/diff-impact.d.ts.map +1 -0
- package/dist/mcp/tools/diff-impact.js +23 -0
- package/dist/mcp/tools/diff-impact.js.map +1 -0
- package/dist/mcp/tools/execution-flow.d.ts +15 -0
- package/dist/mcp/tools/execution-flow.d.ts.map +1 -0
- package/dist/mcp/tools/execution-flow.js +25 -0
- package/dist/mcp/tools/execution-flow.js.map +1 -0
- package/dist/mcp/tools/export-graph.d.ts +11 -0
- package/dist/mcp/tools/export-graph.d.ts.map +1 -0
- package/dist/mcp/tools/export-graph.js +57 -0
- package/dist/mcp/tools/export-graph.js.map +1 -0
- package/dist/mcp/tools/file-deps.d.ts +11 -0
- package/dist/mcp/tools/file-deps.d.ts.map +1 -0
- package/dist/mcp/tools/file-deps.js +11 -0
- package/dist/mcp/tools/file-deps.js.map +1 -0
- package/dist/mcp/tools/file-exports.d.ts +12 -0
- package/dist/mcp/tools/file-exports.d.ts.map +1 -0
- package/dist/mcp/tools/file-exports.js +12 -0
- package/dist/mcp/tools/file-exports.js.map +1 -0
- package/dist/mcp/tools/find-cycles.d.ts +7 -0
- package/dist/mcp/tools/find-cycles.d.ts.map +1 -0
- package/dist/mcp/tools/find-cycles.js +15 -0
- package/dist/mcp/tools/find-cycles.js.map +1 -0
- package/dist/mcp/tools/fn-impact.d.ts +14 -0
- package/dist/mcp/tools/fn-impact.d.ts.map +1 -0
- package/dist/mcp/tools/fn-impact.js +14 -0
- package/dist/mcp/tools/fn-impact.js.map +1 -0
- package/dist/mcp/tools/impact-analysis.d.ts +9 -0
- package/dist/mcp/tools/impact-analysis.d.ts.map +1 -0
- package/dist/mcp/tools/impact-analysis.js +8 -0
- package/dist/mcp/tools/impact-analysis.js.map +1 -0
- package/dist/mcp/tools/implementations.d.ts +13 -0
- package/dist/mcp/tools/implementations.d.ts.map +1 -0
- package/dist/mcp/tools/implementations.js +13 -0
- package/dist/mcp/tools/implementations.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +7 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +76 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/interfaces.d.ts +13 -0
- package/dist/mcp/tools/interfaces.d.ts.map +1 -0
- package/dist/mcp/tools/interfaces.js +13 -0
- package/dist/mcp/tools/interfaces.js.map +1 -0
- package/dist/mcp/tools/list-functions.d.ts +12 -0
- package/dist/mcp/tools/list-functions.d.ts.map +1 -0
- package/dist/mcp/tools/list-functions.js +13 -0
- package/dist/mcp/tools/list-functions.js.map +1 -0
- package/dist/mcp/tools/list-repos.d.ts +8 -0
- package/dist/mcp/tools/list-repos.d.ts.map +1 -0
- package/dist/mcp/tools/list-repos.js +11 -0
- package/dist/mcp/tools/list-repos.js.map +1 -0
- package/dist/mcp/tools/module-map.d.ts +9 -0
- package/dist/mcp/tools/module-map.d.ts.map +1 -0
- package/dist/mcp/tools/module-map.js +6 -0
- package/dist/mcp/tools/module-map.js.map +1 -0
- package/dist/mcp/tools/node-roles.d.ts +12 -0
- package/dist/mcp/tools/node-roles.d.ts.map +1 -0
- package/dist/mcp/tools/node-roles.js +13 -0
- package/dist/mcp/tools/node-roles.js.map +1 -0
- package/dist/mcp/tools/path.d.ts +15 -0
- package/dist/mcp/tools/path.d.ts.map +1 -0
- package/dist/mcp/tools/path.js +21 -0
- package/dist/mcp/tools/path.js.map +1 -0
- package/dist/mcp/tools/query.d.ts +20 -0
- package/dist/mcp/tools/query.d.ts.map +1 -0
- package/dist/mcp/tools/query.js +29 -0
- package/dist/mcp/tools/query.js.map +1 -0
- package/dist/mcp/tools/semantic-search.d.ts +13 -0
- package/dist/mcp/tools/semantic-search.d.ts.map +1 -0
- package/dist/mcp/tools/semantic-search.js +62 -0
- package/dist/mcp/tools/semantic-search.js.map +1 -0
- package/dist/mcp/tools/sequence.d.ts +16 -0
- package/dist/mcp/tools/sequence.d.ts.map +1 -0
- package/dist/mcp/tools/sequence.js +16 -0
- package/dist/mcp/tools/sequence.js.map +1 -0
- package/dist/mcp/tools/structure.d.ts +13 -0
- package/dist/mcp/tools/structure.d.ts.map +1 -0
- package/dist/mcp/tools/structure.js +14 -0
- package/dist/mcp/tools/structure.js.map +1 -0
- package/dist/mcp/tools/symbol-children.d.ts +13 -0
- package/dist/mcp/tools/symbol-children.d.ts.map +1 -0
- package/dist/mcp/tools/symbol-children.js +13 -0
- package/dist/mcp/tools/symbol-children.js.map +1 -0
- package/dist/mcp/tools/triage.d.ts +17 -0
- package/dist/mcp/tools/triage.d.ts.map +1 -0
- package/dist/mcp/tools/triage.js +34 -0
- package/dist/mcp/tools/triage.js.map +1 -0
- package/dist/mcp/tools/where.d.ts +12 -0
- package/dist/mcp/tools/where.d.ts.map +1 -0
- package/dist/mcp/tools/where.js +12 -0
- package/dist/mcp/tools/where.js.map +1 -0
- package/dist/mcp/types.d.ts +19 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +6 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/presentation/audit.d.ts +15 -0
- package/dist/presentation/audit.d.ts.map +1 -0
- package/dist/presentation/audit.js +78 -0
- package/dist/presentation/audit.js.map +1 -0
- package/dist/presentation/batch.d.ts +20 -0
- package/dist/presentation/batch.d.ts.map +1 -0
- package/dist/presentation/batch.js +21 -0
- package/dist/presentation/batch.js.map +1 -0
- package/dist/presentation/branch-compare.d.ts +13 -0
- package/dist/presentation/branch-compare.d.ts.map +1 -0
- package/dist/presentation/branch-compare.js +91 -0
- package/dist/presentation/branch-compare.js.map +1 -0
- package/dist/presentation/brief.d.ts +9 -0
- package/dist/presentation/brief.d.ts.map +1 -0
- package/dist/presentation/brief.js +39 -0
- package/dist/presentation/brief.js.map +1 -0
- package/dist/presentation/cfg.d.ts +13 -0
- package/dist/presentation/cfg.d.ts.map +1 -0
- package/dist/presentation/cfg.js +62 -0
- package/dist/presentation/cfg.js.map +1 -0
- package/dist/presentation/check.d.ts +19 -0
- package/dist/presentation/check.d.ts.map +1 -0
- package/dist/presentation/check.js +74 -0
- package/dist/presentation/check.js.map +1 -0
- package/dist/presentation/cochange.d.ts +32 -0
- package/dist/presentation/cochange.d.ts.map +1 -0
- package/dist/presentation/cochange.js +33 -0
- package/dist/presentation/cochange.js.map +1 -0
- package/dist/presentation/colors.d.ts +12 -0
- package/dist/presentation/colors.d.ts.map +1 -0
- package/dist/presentation/colors.js +47 -0
- package/dist/presentation/colors.js.map +1 -0
- package/dist/presentation/communities.d.ts +11 -0
- package/dist/presentation/communities.d.ts.map +1 -0
- package/dist/presentation/communities.js +57 -0
- package/dist/presentation/communities.js.map +1 -0
- package/dist/presentation/complexity.d.ts +17 -0
- package/dist/presentation/complexity.d.ts.map +1 -0
- package/dist/presentation/complexity.js +59 -0
- package/dist/presentation/complexity.js.map +1 -0
- package/dist/presentation/dataflow.d.ts +14 -0
- package/dist/presentation/dataflow.d.ts.map +1 -0
- package/dist/presentation/dataflow.js +100 -0
- package/dist/presentation/dataflow.js.map +1 -0
- package/dist/presentation/diff-impact-mermaid.d.ts +11 -0
- package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -0
- package/dist/presentation/diff-impact-mermaid.js +114 -0
- package/dist/presentation/diff-impact-mermaid.js.map +1 -0
- package/dist/presentation/export.d.ts +130 -0
- package/dist/presentation/export.d.ts.map +1 -0
- package/dist/presentation/export.js +311 -0
- package/dist/presentation/export.js.map +1 -0
- package/dist/presentation/flow.d.ts +16 -0
- package/dist/presentation/flow.d.ts.map +1 -0
- package/dist/presentation/flow.js +85 -0
- package/dist/presentation/flow.js.map +1 -0
- package/dist/presentation/manifesto.d.ts +13 -0
- package/dist/presentation/manifesto.d.ts.map +1 -0
- package/dist/presentation/manifesto.js +51 -0
- package/dist/presentation/manifesto.js.map +1 -0
- package/dist/presentation/owners.d.ts +16 -0
- package/dist/presentation/owners.d.ts.map +1 -0
- package/dist/presentation/owners.js +42 -0
- package/dist/presentation/owners.js.map +1 -0
- package/dist/presentation/queries-cli/exports.d.ts +12 -0
- package/dist/presentation/queries-cli/exports.d.ts.map +1 -0
- package/dist/presentation/queries-cli/exports.js +100 -0
- package/dist/presentation/queries-cli/exports.js.map +1 -0
- package/dist/presentation/queries-cli/impact.d.ts +23 -0
- package/dist/presentation/queries-cli/impact.d.ts.map +1 -0
- package/dist/presentation/queries-cli/impact.js +208 -0
- package/dist/presentation/queries-cli/impact.js.map +1 -0
- package/dist/presentation/queries-cli/index.d.ts +6 -0
- package/dist/presentation/queries-cli/index.d.ts.map +1 -0
- package/dist/presentation/queries-cli/index.js +6 -0
- package/dist/presentation/queries-cli/index.js.map +1 -0
- package/dist/presentation/queries-cli/inspect.d.ts +23 -0
- package/dist/presentation/queries-cli/inspect.d.ts.map +1 -0
- package/dist/presentation/queries-cli/inspect.js +376 -0
- package/dist/presentation/queries-cli/inspect.js.map +1 -0
- package/dist/presentation/queries-cli/overview.d.ts +19 -0
- package/dist/presentation/queries-cli/overview.d.ts.map +1 -0
- package/dist/presentation/queries-cli/overview.js +196 -0
- package/dist/presentation/queries-cli/overview.js.map +1 -0
- package/dist/presentation/queries-cli/path.d.ts +15 -0
- package/dist/presentation/queries-cli/path.d.ts.map +1 -0
- package/dist/presentation/queries-cli/path.js +101 -0
- package/dist/presentation/queries-cli/path.js.map +1 -0
- package/dist/presentation/queries-cli.d.ts +12 -0
- package/dist/presentation/queries-cli.d.ts.map +1 -0
- package/dist/presentation/queries-cli.js +12 -0
- package/dist/presentation/queries-cli.js.map +1 -0
- package/dist/presentation/query.d.ts +2 -0
- package/dist/presentation/query.d.ts.map +1 -0
- package/dist/presentation/query.js +2 -0
- package/dist/presentation/query.js.map +1 -0
- package/dist/presentation/result-formatter.d.ts +23 -0
- package/dist/presentation/result-formatter.d.ts.map +1 -0
- package/dist/presentation/result-formatter.js +122 -0
- package/dist/presentation/result-formatter.js.map +1 -0
- package/dist/presentation/sequence-renderer.d.ts +19 -0
- package/dist/presentation/sequence-renderer.d.ts.map +1 -0
- package/dist/presentation/sequence-renderer.js +23 -0
- package/dist/presentation/sequence-renderer.js.map +1 -0
- package/dist/presentation/sequence.d.ts +15 -0
- package/dist/presentation/sequence.d.ts.map +1 -0
- package/dist/presentation/sequence.js +26 -0
- package/dist/presentation/sequence.js.map +1 -0
- package/dist/presentation/structure.d.ts +46 -0
- package/dist/presentation/structure.d.ts.map +1 -0
- package/dist/presentation/structure.js +50 -0
- package/dist/presentation/structure.js.map +1 -0
- package/dist/presentation/table.d.ts +24 -0
- package/dist/presentation/table.d.ts.map +1 -0
- package/dist/presentation/table.js +33 -0
- package/dist/presentation/table.js.map +1 -0
- package/dist/presentation/triage.d.ts +19 -0
- package/dist/presentation/triage.d.ts.map +1 -0
- package/dist/presentation/triage.js +34 -0
- package/dist/presentation/triage.js.map +1 -0
- package/dist/presentation/viewer.d.ts +102 -0
- package/dist/presentation/viewer.d.ts.map +1 -0
- package/dist/presentation/viewer.js +618 -0
- package/dist/presentation/viewer.js.map +1 -0
- package/dist/shared/constants.d.ts +33 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +54 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/errors.d.ts +46 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +69 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/file-utils.d.ts +27 -0
- package/dist/shared/file-utils.d.ts.map +1 -0
- package/dist/shared/file-utils.js +186 -0
- package/dist/shared/file-utils.js.map +1 -0
- package/dist/shared/generators.d.ts +57 -0
- package/dist/shared/generators.d.ts.map +1 -0
- package/dist/shared/generators.js +106 -0
- package/dist/shared/generators.js.map +1 -0
- package/dist/shared/globs.d.ts +40 -0
- package/dist/shared/globs.d.ts.map +1 -0
- package/dist/shared/globs.js +126 -0
- package/dist/shared/globs.js.map +1 -0
- package/dist/shared/hierarchy.d.ts +9 -0
- package/dist/shared/hierarchy.d.ts.map +1 -0
- package/dist/shared/hierarchy.js +68 -0
- package/dist/shared/hierarchy.js.map +1 -0
- package/dist/shared/kinds.d.ts +12 -0
- package/dist/shared/kinds.d.ts.map +1 -0
- package/dist/shared/kinds.js +67 -0
- package/dist/shared/kinds.js.map +1 -0
- package/dist/shared/normalize.d.ts +49 -0
- package/dist/shared/normalize.d.ts.map +1 -0
- package/dist/shared/normalize.js +57 -0
- package/dist/shared/normalize.js.map +1 -0
- package/dist/shared/paginate.d.ts +32 -0
- package/dist/shared/paginate.d.ts.map +1 -0
- package/dist/shared/paginate.js +82 -0
- package/dist/shared/paginate.js.map +1 -0
- package/dist/shared/version.d.ts +2 -0
- package/dist/shared/version.d.ts.map +1 -0
- package/dist/shared/version.js +5 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/types.d.ts +2468 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/grammars/tree-sitter-bash.wasm +0 -0
- package/grammars/tree-sitter-c.wasm +0 -0
- package/grammars/tree-sitter-c_sharp.wasm +0 -0
- package/grammars/tree-sitter-clojure.wasm +0 -0
- package/grammars/tree-sitter-cpp.wasm +0 -0
- package/grammars/tree-sitter-cuda.wasm +0 -0
- package/grammars/tree-sitter-dart.wasm +0 -0
- package/grammars/tree-sitter-elixir.wasm +0 -0
- 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/grammars/tree-sitter-go.wasm +0 -0
- package/grammars/tree-sitter-groovy.wasm +0 -0
- package/grammars/tree-sitter-haskell.wasm +0 -0
- package/grammars/tree-sitter-hcl.wasm +0 -0
- package/grammars/tree-sitter-java.wasm +0 -0
- package/grammars/tree-sitter-javascript.wasm +0 -0
- package/grammars/tree-sitter-julia.wasm +0 -0
- package/grammars/tree-sitter-kotlin.wasm +0 -0
- package/grammars/tree-sitter-lua.wasm +0 -0
- package/grammars/tree-sitter-objc.wasm +0 -0
- package/grammars/tree-sitter-ocaml.wasm +0 -0
- package/grammars/tree-sitter-ocaml_interface.wasm +0 -0
- package/grammars/tree-sitter-php.wasm +0 -0
- package/grammars/tree-sitter-python.wasm +0 -0
- package/grammars/tree-sitter-r.wasm +0 -0
- package/grammars/tree-sitter-ruby.wasm +0 -0
- package/grammars/tree-sitter-rust.wasm +0 -0
- package/grammars/tree-sitter-scala.wasm +0 -0
- package/grammars/tree-sitter-solidity.wasm +0 -0
- package/grammars/tree-sitter-swift.wasm +0 -0
- package/grammars/tree-sitter-tsx.wasm +0 -0
- package/grammars/tree-sitter-typescript.wasm +0 -0
- package/grammars/tree-sitter-verilog.wasm +0 -0
- package/grammars/tree-sitter-zig.wasm +0 -0
- package/package.json +188 -0
- package/src/ast-analysis/engine.ts +926 -0
- package/src/ast-analysis/metrics.ts +150 -0
- package/src/ast-analysis/rules/b2.ts +263 -0
- package/src/ast-analysis/rules/b3.ts +127 -0
- package/src/ast-analysis/rules/b4.ts +378 -0
- package/src/ast-analysis/rules/b5.ts +65 -0
- package/src/ast-analysis/rules/c.ts +157 -0
- package/src/ast-analysis/rules/csharp.ts +210 -0
- package/src/ast-analysis/rules/go.ts +187 -0
- package/src/ast-analysis/rules/index.ts +380 -0
- package/src/ast-analysis/rules/java.ts +181 -0
- package/src/ast-analysis/rules/javascript.ts +249 -0
- package/src/ast-analysis/rules/php.ts +226 -0
- package/src/ast-analysis/rules/python.ts +202 -0
- package/src/ast-analysis/rules/ruby.ts +209 -0
- package/src/ast-analysis/rules/rust.ts +179 -0
- package/src/ast-analysis/shared.ts +223 -0
- package/src/ast-analysis/visitor-utils.ts +278 -0
- package/src/ast-analysis/visitor.ts +266 -0
- package/src/ast-analysis/visitors/ast-store-visitor.ts +334 -0
- package/src/ast-analysis/visitors/cfg-conditionals.ts +227 -0
- package/src/ast-analysis/visitors/cfg-loops.ts +136 -0
- package/src/ast-analysis/visitors/cfg-shared.ts +196 -0
- package/src/ast-analysis/visitors/cfg-try-catch.ts +142 -0
- package/src/ast-analysis/visitors/cfg-visitor.ts +367 -0
- package/src/ast-analysis/visitors/complexity-visitor.ts +328 -0
- package/src/ast-analysis/visitors/dataflow-visitor.ts +571 -0
- package/src/cli/commands/ast.ts +24 -0
- package/src/cli/commands/audit.ts +48 -0
- package/src/cli/commands/batch.ts +66 -0
- package/src/cli/commands/branch-compare.ts +27 -0
- package/src/cli/commands/brief.ts +13 -0
- package/src/cli/commands/build.ts +35 -0
- package/src/cli/commands/cfg.ts +28 -0
- package/src/cli/commands/check.ts +72 -0
- package/src/cli/commands/children.ts +34 -0
- package/src/cli/commands/co-change.ts +72 -0
- package/src/cli/commands/communities.ts +21 -0
- package/src/cli/commands/complexity.ts +48 -0
- package/src/cli/commands/config.ts +353 -0
- package/src/cli/commands/context.ts +36 -0
- package/src/cli/commands/cycles.ts +33 -0
- package/src/cli/commands/dataflow.ts +30 -0
- package/src/cli/commands/deps.ts +18 -0
- package/src/cli/commands/diff-impact.ts +30 -0
- package/src/cli/commands/embed.ts +82 -0
- package/src/cli/commands/export.ts +79 -0
- package/src/cli/commands/exports.ts +15 -0
- package/src/cli/commands/flow.ts +34 -0
- package/src/cli/commands/fn-impact.ts +34 -0
- package/src/cli/commands/impact.ts +13 -0
- package/src/cli/commands/implementations.ts +30 -0
- package/src/cli/commands/info.ts +79 -0
- package/src/cli/commands/interfaces.ts +30 -0
- package/src/cli/commands/map.ts +20 -0
- package/src/cli/commands/mcp.ts +19 -0
- package/src/cli/commands/models.ts +29 -0
- package/src/cli/commands/owners.ts +28 -0
- package/src/cli/commands/path.ts +42 -0
- package/src/cli/commands/plot.ts +110 -0
- package/src/cli/commands/query.ts +51 -0
- package/src/cli/commands/registry.ts +106 -0
- package/src/cli/commands/roles.ts +38 -0
- package/src/cli/commands/search.ts +45 -0
- package/src/cli/commands/sequence.ts +30 -0
- package/src/cli/commands/snapshot.ts +67 -0
- package/src/cli/commands/stats.ts +16 -0
- package/src/cli/commands/structure.ts +55 -0
- package/src/cli/commands/triage.ts +93 -0
- package/src/cli/commands/watch.ts +29 -0
- package/src/cli/commands/where.ts +21 -0
- package/src/cli/index.ts +159 -0
- package/src/cli/shared/open-graph.ts +13 -0
- package/src/cli/shared/options.ts +69 -0
- package/src/cli/shared/output.ts +1 -0
- package/src/cli/types.ts +35 -0
- package/src/cli.ts +37 -0
- package/src/db/better-sqlite3.ts +21 -0
- package/src/db/connection.ts +478 -0
- package/src/db/index.ts +84 -0
- package/src/db/migrations.ts +440 -0
- package/src/db/query-builder.ts +371 -0
- package/src/db/repository/base.ts +269 -0
- package/src/db/repository/build-stmts.ts +126 -0
- package/src/db/repository/cached-stmt.ts +20 -0
- package/src/db/repository/cfg.ts +81 -0
- package/src/db/repository/cochange.ts +48 -0
- package/src/db/repository/complexity.ts +21 -0
- package/src/db/repository/dataflow.ts +35 -0
- package/src/db/repository/edges.ts +281 -0
- package/src/db/repository/embeddings.ts +47 -0
- package/src/db/repository/graph-read.ts +62 -0
- package/src/db/repository/in-memory-repository.ts +657 -0
- package/src/db/repository/index.ts +53 -0
- package/src/db/repository/native-repository.ts +546 -0
- package/src/db/repository/nodes.ts +322 -0
- package/src/db/repository/sqlite-repository.ts +303 -0
- package/src/domain/analysis/brief.ts +165 -0
- package/src/domain/analysis/context.ts +537 -0
- package/src/domain/analysis/dependencies.ts +738 -0
- package/src/domain/analysis/diff-impact.ts +381 -0
- package/src/domain/analysis/exports.ts +262 -0
- package/src/domain/analysis/fn-impact.ts +311 -0
- package/src/domain/analysis/impact.ts +11 -0
- package/src/domain/analysis/implementations.ts +81 -0
- package/src/domain/analysis/module-map.ts +576 -0
- package/src/domain/analysis/query-helpers.ts +52 -0
- package/src/domain/analysis/roles.ts +95 -0
- package/src/domain/analysis/symbol-lookup.ts +284 -0
- package/src/domain/graph/builder/call-resolver.ts +289 -0
- package/src/domain/graph/builder/cha.ts +192 -0
- package/src/domain/graph/builder/context.ts +120 -0
- package/src/domain/graph/builder/helpers.ts +665 -0
- package/src/domain/graph/builder/incremental.ts +987 -0
- package/src/domain/graph/builder/native-db-proxy.ts +104 -0
- package/src/domain/graph/builder/pipeline.ts +517 -0
- package/src/domain/graph/builder/stages/build-edges.ts +1986 -0
- package/src/domain/graph/builder/stages/build-structure.ts +330 -0
- package/src/domain/graph/builder/stages/collect-files.ts +175 -0
- package/src/domain/graph/builder/stages/detect-changes.ts +751 -0
- package/src/domain/graph/builder/stages/finalize.ts +321 -0
- package/src/domain/graph/builder/stages/insert-nodes.ts +489 -0
- package/src/domain/graph/builder/stages/native-db-lifecycle.ts +74 -0
- package/src/domain/graph/builder/stages/native-orchestrator.ts +2241 -0
- package/src/domain/graph/builder/stages/parse-files.ts +26 -0
- package/src/domain/graph/builder/stages/resolve-imports.ts +285 -0
- package/src/domain/graph/builder/stages/run-analyses.ts +26 -0
- package/src/domain/graph/builder.ts +11 -0
- package/src/domain/graph/change-journal.ts +141 -0
- package/src/domain/graph/cycles.ts +155 -0
- package/src/domain/graph/journal.ts +377 -0
- package/src/domain/graph/resolve.ts +579 -0
- package/src/domain/graph/resolver/points-to.ts +377 -0
- package/src/domain/graph/resolver/strategy.ts +265 -0
- package/src/domain/graph/resolver/ts-resolver.ts +536 -0
- package/src/domain/graph/watcher.ts +339 -0
- package/src/domain/parser.ts +1437 -0
- package/src/domain/queries.ts +50 -0
- package/src/domain/search/generator.ts +260 -0
- package/src/domain/search/index.ts +15 -0
- package/src/domain/search/models.ts +356 -0
- package/src/domain/search/search/cli-formatter.ts +179 -0
- package/src/domain/search/search/filters.ts +38 -0
- package/src/domain/search/search/hybrid.ts +197 -0
- package/src/domain/search/search/keyword.ts +101 -0
- package/src/domain/search/search/prepare.ts +95 -0
- package/src/domain/search/search/semantic.ts +226 -0
- package/src/domain/search/stores/fts5.ts +27 -0
- package/src/domain/search/stores/sqlite-blob.ts +15 -0
- package/src/domain/search/strategies/source.ts +19 -0
- package/src/domain/search/strategies/structured.ts +48 -0
- package/src/domain/search/strategies/text-utils.ts +41 -0
- package/src/domain/wasm-worker-entry.ts +921 -0
- package/src/domain/wasm-worker-pool.ts +375 -0
- package/src/domain/wasm-worker-protocol.ts +98 -0
- package/src/extractors/bash.ts +97 -0
- package/src/extractors/c.ts +231 -0
- package/src/extractors/clojure.ts +273 -0
- package/src/extractors/cpp.ts +383 -0
- package/src/extractors/csharp.ts +448 -0
- package/src/extractors/cuda.ts +433 -0
- package/src/extractors/dart.ts +304 -0
- package/src/extractors/elixir.ts +350 -0
- package/src/extractors/erlang.ts +295 -0
- package/src/extractors/fsharp.ts +357 -0
- package/src/extractors/gleam.ts +247 -0
- package/src/extractors/go.ts +512 -0
- package/src/extractors/groovy.ts +436 -0
- package/src/extractors/haskell.ts +276 -0
- package/src/extractors/hcl.ts +136 -0
- package/src/extractors/helpers.ts +449 -0
- package/src/extractors/index.ts +32 -0
- package/src/extractors/java.ts +439 -0
- package/src/extractors/javascript.ts +3844 -0
- package/src/extractors/julia.ts +432 -0
- package/src/extractors/kotlin.ts +358 -0
- package/src/extractors/lua.ts +169 -0
- package/src/extractors/objc.ts +555 -0
- package/src/extractors/ocaml.ts +337 -0
- package/src/extractors/php.ts +399 -0
- package/src/extractors/python.ts +439 -0
- package/src/extractors/r.ts +275 -0
- package/src/extractors/ruby.ts +292 -0
- package/src/extractors/rust.ts +371 -0
- package/src/extractors/scala.ts +335 -0
- package/src/extractors/solidity.ts +375 -0
- package/src/extractors/swift.ts +337 -0
- package/src/extractors/verilog.ts +383 -0
- package/src/extractors/zig.ts +291 -0
- package/src/features/ast.ts +405 -0
- package/src/features/audit.ts +446 -0
- package/src/features/batch.ts +182 -0
- package/src/features/boundaries.ts +345 -0
- package/src/features/branch-compare.ts +618 -0
- package/src/features/cfg.ts +750 -0
- package/src/features/check.ts +454 -0
- package/src/features/cochange.ts +506 -0
- package/src/features/communities.ts +232 -0
- package/src/features/complexity-query.ts +388 -0
- package/src/features/complexity.ts +753 -0
- package/src/features/dataflow.ts +1654 -0
- package/src/features/export.ts +486 -0
- package/src/features/flow.ts +307 -0
- package/src/features/graph-enrichment.ts +493 -0
- package/src/features/manifesto.ts +508 -0
- package/src/features/owners.ts +360 -0
- package/src/features/sequence.ts +410 -0
- package/src/features/shared/find-nodes.ts +28 -0
- package/src/features/snapshot.ts +221 -0
- package/src/features/structure-query.ts +456 -0
- package/src/features/structure.ts +1100 -0
- package/src/features/triage.ts +199 -0
- package/src/graph/algorithms/bfs.ts +92 -0
- package/src/graph/algorithms/centrality.ts +50 -0
- package/src/graph/algorithms/index.ts +6 -0
- package/src/graph/algorithms/leiden/LICENSE +24 -0
- package/src/graph/algorithms/leiden/adapter.ts +252 -0
- package/src/graph/algorithms/leiden/cpm.ts +77 -0
- package/src/graph/algorithms/leiden/index.ts +224 -0
- package/src/graph/algorithms/leiden/modularity.ts +122 -0
- package/src/graph/algorithms/leiden/optimiser.ts +706 -0
- package/src/graph/algorithms/leiden/partition.ts +577 -0
- package/src/graph/algorithms/leiden/rng.ts +20 -0
- package/src/graph/algorithms/louvain.ts +75 -0
- package/src/graph/algorithms/shortest-path.ts +59 -0
- package/src/graph/algorithms/tarjan.ts +55 -0
- package/src/graph/builders/dependency.ts +148 -0
- package/src/graph/builders/index.ts +3 -0
- package/src/graph/builders/structure.ts +58 -0
- package/src/graph/builders/temporal.ts +51 -0
- package/src/graph/classifiers/index.ts +2 -0
- package/src/graph/classifiers/risk.ts +123 -0
- package/src/graph/classifiers/roles.ts +226 -0
- package/src/graph/index.ts +13 -0
- package/src/graph/model.ts +238 -0
- package/src/index.cjs +16 -0
- package/src/index.ts +72 -0
- package/src/infrastructure/config.ts +954 -0
- package/src/infrastructure/logger.ts +24 -0
- package/src/infrastructure/native.ts +199 -0
- package/src/infrastructure/registry.ts +313 -0
- package/src/infrastructure/result-formatter.ts +2 -0
- package/src/infrastructure/suppress.ts +47 -0
- package/src/infrastructure/test-filter.ts +7 -0
- package/src/infrastructure/update-check.ts +196 -0
- package/src/mcp/index.ts +2 -0
- package/src/mcp/middleware.ts +38 -0
- package/src/mcp/server.ts +259 -0
- package/src/mcp/tool-registry.ts +890 -0
- package/src/mcp/tools/ast-query.ts +25 -0
- package/src/mcp/tools/audit.ts +33 -0
- package/src/mcp/tools/batch-query.ts +22 -0
- package/src/mcp/tools/branch-compare.ts +22 -0
- package/src/mcp/tools/brief.ts +15 -0
- package/src/mcp/tools/cfg.ts +32 -0
- package/src/mcp/tools/check.ts +60 -0
- package/src/mcp/tools/co-changes.ts +29 -0
- package/src/mcp/tools/code-owners.ts +22 -0
- package/src/mcp/tools/communities.ts +25 -0
- package/src/mcp/tools/complexity.ts +30 -0
- package/src/mcp/tools/context.ts +30 -0
- package/src/mcp/tools/dataflow.ts +38 -0
- package/src/mcp/tools/diff-impact.ts +35 -0
- package/src/mcp/tools/execution-flow.ts +38 -0
- package/src/mcp/tools/export-graph.ts +67 -0
- package/src/mcp/tools/file-deps.ts +20 -0
- package/src/mcp/tools/file-exports.ts +22 -0
- package/src/mcp/tools/find-cycles.ts +19 -0
- package/src/mcp/tools/fn-impact.ts +26 -0
- package/src/mcp/tools/impact-analysis.ts +15 -0
- package/src/mcp/tools/implementations.ts +24 -0
- package/src/mcp/tools/index.ts +81 -0
- package/src/mcp/tools/interfaces.ts +24 -0
- package/src/mcp/tools/list-functions.ts +23 -0
- package/src/mcp/tools/list-repos.ts +17 -0
- package/src/mcp/tools/module-map.ts +13 -0
- package/src/mcp/tools/node-roles.ts +23 -0
- package/src/mcp/tools/path.ts +34 -0
- package/src/mcp/tools/query.ts +47 -0
- package/src/mcp/tools/semantic-search.ts +76 -0
- package/src/mcp/tools/sequence.ts +30 -0
- package/src/mcp/tools/structure.ts +25 -0
- package/src/mcp/tools/symbol-children.ts +24 -0
- package/src/mcp/tools/triage.ts +50 -0
- package/src/mcp/tools/where.ts +22 -0
- package/src/mcp/types.ts +21 -0
- package/src/presentation/audit.ts +109 -0
- package/src/presentation/batch.ts +50 -0
- package/src/presentation/branch-compare.ts +148 -0
- package/src/presentation/brief.ts +63 -0
- package/src/presentation/cfg.ts +103 -0
- package/src/presentation/check.ts +138 -0
- package/src/presentation/cochange.ts +57 -0
- package/src/presentation/colors.ts +51 -0
- package/src/presentation/communities.ts +114 -0
- package/src/presentation/complexity.ts +127 -0
- package/src/presentation/dataflow.ts +179 -0
- package/src/presentation/diff-impact-mermaid.ts +169 -0
- package/src/presentation/export.ts +509 -0
- package/src/presentation/flow.ts +147 -0
- package/src/presentation/manifesto.ts +92 -0
- package/src/presentation/owners.ts +89 -0
- package/src/presentation/queries-cli/exports.ts +152 -0
- package/src/presentation/queries-cli/impact.ts +340 -0
- package/src/presentation/queries-cli/index.ts +13 -0
- package/src/presentation/queries-cli/inspect.ts +594 -0
- package/src/presentation/queries-cli/overview.ts +375 -0
- package/src/presentation/queries-cli/path.ts +187 -0
- package/src/presentation/queries-cli.ts +30 -0
- package/src/presentation/query.ts +17 -0
- package/src/presentation/result-formatter.ts +161 -0
- package/src/presentation/sequence-renderer.ts +46 -0
- package/src/presentation/sequence.ts +43 -0
- package/src/presentation/structure.ts +109 -0
- package/src/presentation/table.ts +45 -0
- package/src/presentation/triage.ts +84 -0
- package/src/presentation/viewer.ts +715 -0
- package/src/shared/constants.ts +70 -0
- package/src/shared/errors.ts +85 -0
- package/src/shared/file-utils.ts +233 -0
- package/src/shared/generators.ts +176 -0
- package/src/shared/globs.ts +121 -0
- package/src/shared/hierarchy.ts +81 -0
- package/src/shared/kinds.ts +85 -0
- package/src/shared/normalize.ts +106 -0
- package/src/shared/paginate.ts +93 -0
- package/src/shared/version.ts +10 -0
- package/src/types.ts +2871 -0
|
@@ -0,0 +1,1986 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage: buildEdges
|
|
3
|
+
*
|
|
4
|
+
* Builds import, call, receiver, extends, and implements edges.
|
|
5
|
+
* Uses pre-loaded node lookup maps (N+1 optimization).
|
|
6
|
+
*/
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { performance } from 'node:perf_hooks';
|
|
9
|
+
import { getNodeId } from '../../../../db/index.js';
|
|
10
|
+
import { setTypeMapEntry } from '../../../../extractors/helpers.js';
|
|
11
|
+
import { PROPAGATION_HOP_PENALTY } from '../../../../extractors/javascript.js';
|
|
12
|
+
import { debug } from '../../../../infrastructure/logger.js';
|
|
13
|
+
import { loadNative } from '../../../../infrastructure/native.js';
|
|
14
|
+
import { TS_NATIVE_CONFIDENCE_FLOOR } from '../../../../shared/constants.js';
|
|
15
|
+
import type {
|
|
16
|
+
ArrayCallbackBinding,
|
|
17
|
+
ArrayElemBinding,
|
|
18
|
+
BetterSqlite3Database,
|
|
19
|
+
Call,
|
|
20
|
+
ClassRelation,
|
|
21
|
+
Definition,
|
|
22
|
+
DynamicKind,
|
|
23
|
+
ExtractorOutput,
|
|
24
|
+
FnRefBinding,
|
|
25
|
+
ForOfBinding,
|
|
26
|
+
Import,
|
|
27
|
+
NativeAddon,
|
|
28
|
+
NodeRow,
|
|
29
|
+
ObjectPropBinding,
|
|
30
|
+
ObjectRestParamBinding,
|
|
31
|
+
ParamBinding,
|
|
32
|
+
SpreadArgBinding,
|
|
33
|
+
ThisCallBinding,
|
|
34
|
+
TypeMapEntry,
|
|
35
|
+
} from '../../../../types.js';
|
|
36
|
+
import { computeConfidence } from '../../resolve.js';
|
|
37
|
+
import type { PointsToMap } from '../../resolver/points-to.js';
|
|
38
|
+
import { buildPointsToMap, resolveViaPointsTo } from '../../resolver/points-to.js';
|
|
39
|
+
import { enrichTypeMapWithTsc } from '../../resolver/ts-resolver.js';
|
|
40
|
+
import {
|
|
41
|
+
type CallNodeLookup,
|
|
42
|
+
findCaller,
|
|
43
|
+
isModuleScopedLanguage,
|
|
44
|
+
resolveCallTargets,
|
|
45
|
+
resolveReceiverEdge,
|
|
46
|
+
} from '../call-resolver.js';
|
|
47
|
+
import type { ChaContext } from '../cha.js';
|
|
48
|
+
import { buildChaContext, resolveChaTargets, resolveThisDispatch } from '../cha.js';
|
|
49
|
+
import type { PipelineContext } from '../context.js';
|
|
50
|
+
import {
|
|
51
|
+
BUILTIN_RECEIVERS,
|
|
52
|
+
batchInsertEdges,
|
|
53
|
+
CHA_DISPATCH_PENALTY,
|
|
54
|
+
CHA_TYPED_DISPATCH_CONFIDENCE,
|
|
55
|
+
runChaPostPass,
|
|
56
|
+
} from '../helpers.js';
|
|
57
|
+
import { getResolved, isBarrelFile, resolveBarrelExportCached } from './resolve-imports.js';
|
|
58
|
+
|
|
59
|
+
// ── Local types ──────────────────────────────────────────────────────────
|
|
60
|
+
|
|
61
|
+
type EdgeRowTuple = [number, number, string, number, number, string | null, string | null];
|
|
62
|
+
// src tgt kind conf dyn technique dynamic_kind
|
|
63
|
+
|
|
64
|
+
interface NodeIdStmt {
|
|
65
|
+
get(name: string, kind: string, file: string, line: number): { id: number } | undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Minimal node shape returned by the SELECT query. */
|
|
69
|
+
interface QueryNodeRow {
|
|
70
|
+
id: number;
|
|
71
|
+
name: string;
|
|
72
|
+
kind: string;
|
|
73
|
+
file: string;
|
|
74
|
+
line: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Shape fed to the native buildCallEdges FFI. */
|
|
78
|
+
interface NativeFileEntry {
|
|
79
|
+
file: string;
|
|
80
|
+
fileNodeId: number;
|
|
81
|
+
definitions: Array<{
|
|
82
|
+
name: string;
|
|
83
|
+
kind: string;
|
|
84
|
+
line: number;
|
|
85
|
+
endLine: number | null;
|
|
86
|
+
params?: string[];
|
|
87
|
+
}>;
|
|
88
|
+
calls: Call[];
|
|
89
|
+
importedNames: Array<{ name: string; file: string }>;
|
|
90
|
+
classes: ClassRelation[];
|
|
91
|
+
typeMap: Array<{ name: string; typeName: string; confidence: number }>;
|
|
92
|
+
/** Phase 8.3: function-reference bindings for pts analysis. */
|
|
93
|
+
fnRefBindings?: Array<{ lhs: string; rhs: string; rhsReceiver?: string }>;
|
|
94
|
+
paramBindings?: ParamBinding[];
|
|
95
|
+
thisCallBindings?: ThisCallBinding[];
|
|
96
|
+
arrayElemBindings?: ArrayElemBinding[];
|
|
97
|
+
spreadArgBindings?: SpreadArgBinding[];
|
|
98
|
+
forOfBindings?: ForOfBinding[];
|
|
99
|
+
arrayCallbackBindings?: ArrayCallbackBinding[];
|
|
100
|
+
objectRestParamBindings?: ObjectRestParamBinding[];
|
|
101
|
+
objectPropBindings?: ObjectPropBinding[];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Shape returned by native buildCallEdges. */
|
|
105
|
+
interface NativeEdge {
|
|
106
|
+
sourceId: number;
|
|
107
|
+
targetId: number;
|
|
108
|
+
kind: string;
|
|
109
|
+
confidence: number;
|
|
110
|
+
dynamic: number;
|
|
111
|
+
dynamic_kind?: string | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ── Node lookup setup ───────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
function makeGetNodeIdStmt(db: BetterSqlite3Database): NodeIdStmt {
|
|
117
|
+
return {
|
|
118
|
+
get: (name: string, kind: string, file: string, line: number) => {
|
|
119
|
+
const id = getNodeId(db, name, kind, file, line);
|
|
120
|
+
return id != null ? { id } : undefined;
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function setupNodeLookups(ctx: PipelineContext, allNodes: QueryNodeRow[]): void {
|
|
126
|
+
ctx.nodesByName = new Map();
|
|
127
|
+
for (const node of allNodes) {
|
|
128
|
+
if (!ctx.nodesByName.has(node.name)) ctx.nodesByName.set(node.name, []);
|
|
129
|
+
ctx.nodesByName.get(node.name)!.push(node as unknown as NodeRow);
|
|
130
|
+
}
|
|
131
|
+
ctx.nodesByNameAndFile = new Map();
|
|
132
|
+
for (const node of allNodes) {
|
|
133
|
+
const key = `${node.name}|${node.file}`;
|
|
134
|
+
if (!ctx.nodesByNameAndFile.has(key)) ctx.nodesByNameAndFile.set(key, []);
|
|
135
|
+
ctx.nodesByNameAndFile.get(key)!.push(node as unknown as NodeRow);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ── Import edges ────────────────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
/** Pick the edge kind for an import statement based on its modifiers. */
|
|
142
|
+
function importEdgeKind(imp: Import): string {
|
|
143
|
+
if (imp.reexport) return 'reexports';
|
|
144
|
+
if (imp.typeOnly) return 'imports-type';
|
|
145
|
+
if (imp.dynamicImport) return 'dynamic-imports';
|
|
146
|
+
return 'imports';
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* For a `import type` statement, emit symbol-level `imports-type` edges so
|
|
151
|
+
* the target symbols get fan-in credit and aren't classified as dead code.
|
|
152
|
+
*/
|
|
153
|
+
function emitTypeOnlySymbolEdges(
|
|
154
|
+
ctx: PipelineContext,
|
|
155
|
+
imp: Import,
|
|
156
|
+
resolvedPath: string,
|
|
157
|
+
fileNodeId: number,
|
|
158
|
+
allEdgeRows: EdgeRowTuple[],
|
|
159
|
+
): void {
|
|
160
|
+
if (!ctx.nodesByNameAndFile) return;
|
|
161
|
+
for (const name of imp.names) {
|
|
162
|
+
const cleanName = name.replace(/^\*\s+as\s+/, '');
|
|
163
|
+
let targetFile = resolvedPath;
|
|
164
|
+
if (isBarrelFile(ctx, resolvedPath)) {
|
|
165
|
+
const actual = resolveBarrelExportCached(ctx, resolvedPath, cleanName);
|
|
166
|
+
if (actual) targetFile = actual;
|
|
167
|
+
}
|
|
168
|
+
const candidates = ctx.nodesByNameAndFile.get(`${cleanName}|${targetFile}`);
|
|
169
|
+
if (candidates && candidates.length > 0) {
|
|
170
|
+
allEdgeRows.push([fileNodeId, candidates[0]!.id, 'imports-type', 1.0, 0, null, null]);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Process a single import statement and emit all resulting edges (file→file,
|
|
177
|
+
* type-only symbol-level, and barrel re-export targets).
|
|
178
|
+
*/
|
|
179
|
+
function emitEdgesForImport(
|
|
180
|
+
ctx: PipelineContext,
|
|
181
|
+
imp: Import,
|
|
182
|
+
fileNodeId: number,
|
|
183
|
+
relPath: string,
|
|
184
|
+
getNodeIdStmt: NodeIdStmt,
|
|
185
|
+
allEdgeRows: EdgeRowTuple[],
|
|
186
|
+
): void {
|
|
187
|
+
const resolvedPath = getResolved(ctx, path.join(ctx.rootDir, relPath), imp.source);
|
|
188
|
+
const targetRow = getNodeIdStmt.get(resolvedPath, 'file', resolvedPath, 0);
|
|
189
|
+
if (!targetRow) return;
|
|
190
|
+
|
|
191
|
+
const edgeKind = importEdgeKind(imp);
|
|
192
|
+
allEdgeRows.push([fileNodeId, targetRow.id, edgeKind, 1.0, 0, null, null]);
|
|
193
|
+
|
|
194
|
+
if (imp.typeOnly) {
|
|
195
|
+
emitTypeOnlySymbolEdges(ctx, imp, resolvedPath, fileNodeId, allEdgeRows);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (!imp.reexport && isBarrelFile(ctx, resolvedPath)) {
|
|
199
|
+
buildBarrelEdges(ctx, imp, resolvedPath, fileNodeId, edgeKind, getNodeIdStmt, allEdgeRows);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function buildImportEdges(
|
|
204
|
+
ctx: PipelineContext,
|
|
205
|
+
getNodeIdStmt: NodeIdStmt,
|
|
206
|
+
allEdgeRows: EdgeRowTuple[],
|
|
207
|
+
): void {
|
|
208
|
+
const { fileSymbols, barrelOnlyFiles } = ctx;
|
|
209
|
+
|
|
210
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
211
|
+
const isBarrelOnly = barrelOnlyFiles.has(relPath);
|
|
212
|
+
const fileNodeRow = getNodeIdStmt.get(relPath, 'file', relPath, 0);
|
|
213
|
+
if (!fileNodeRow) continue;
|
|
214
|
+
const fileNodeId = fileNodeRow.id;
|
|
215
|
+
|
|
216
|
+
for (const imp of symbols.imports) {
|
|
217
|
+
// Barrel-only files: only emit reexport edges, skip regular imports
|
|
218
|
+
if (isBarrelOnly && !imp.reexport) continue;
|
|
219
|
+
emitEdgesForImport(ctx, imp, fileNodeId, relPath, getNodeIdStmt, allEdgeRows);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function buildBarrelEdges(
|
|
225
|
+
ctx: PipelineContext,
|
|
226
|
+
imp: Import,
|
|
227
|
+
resolvedPath: string,
|
|
228
|
+
fileNodeId: number,
|
|
229
|
+
edgeKind: string,
|
|
230
|
+
getNodeIdStmt: NodeIdStmt,
|
|
231
|
+
edgeRows: EdgeRowTuple[],
|
|
232
|
+
): void {
|
|
233
|
+
const resolvedSources = new Set<string>();
|
|
234
|
+
for (const name of imp.names) {
|
|
235
|
+
const cleanName = name.replace(/^\*\s+as\s+/, '');
|
|
236
|
+
const actualSource = resolveBarrelExportCached(ctx, resolvedPath, cleanName);
|
|
237
|
+
if (actualSource && actualSource !== resolvedPath && !resolvedSources.has(actualSource)) {
|
|
238
|
+
resolvedSources.add(actualSource);
|
|
239
|
+
const actualRow = getNodeIdStmt.get(actualSource, 'file', actualSource, 0);
|
|
240
|
+
if (actualRow) {
|
|
241
|
+
const kind =
|
|
242
|
+
edgeKind === 'imports-type'
|
|
243
|
+
? 'imports-type'
|
|
244
|
+
: edgeKind === 'dynamic-imports'
|
|
245
|
+
? 'dynamic-imports'
|
|
246
|
+
: 'imports';
|
|
247
|
+
edgeRows.push([fileNodeId, actualRow.id, kind, 0.9, 0, null, null]);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ── Import edges (native engine) ────────────────────────────────────────
|
|
254
|
+
|
|
255
|
+
/** Native FFI input shape for a single import statement. */
|
|
256
|
+
interface NativeImportInfo {
|
|
257
|
+
source: string;
|
|
258
|
+
names: string[];
|
|
259
|
+
reexport: boolean;
|
|
260
|
+
typeOnly: boolean;
|
|
261
|
+
dynamicImport: boolean;
|
|
262
|
+
wildcardReexport: boolean;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** Native FFI input shape for a single file. */
|
|
266
|
+
interface NativeFileInput {
|
|
267
|
+
file: string;
|
|
268
|
+
fileNodeId: number;
|
|
269
|
+
isBarrelOnly: boolean;
|
|
270
|
+
imports: NativeImportInfo[];
|
|
271
|
+
definitionNames: string[];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Native FFI input shape for re-exports of a single file. */
|
|
275
|
+
interface NativeReexportInput {
|
|
276
|
+
file: string;
|
|
277
|
+
reexports: Array<{ source: string; names: string[]; wildcardReexport: boolean }>;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Lazily-resolving cache of file-node rows for the native input arrays. */
|
|
281
|
+
interface FileNodeIdRegistry {
|
|
282
|
+
ids: Array<{ file: string; nodeId: number }>;
|
|
283
|
+
add(relPath: string): { id: number } | undefined;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function createFileNodeIdRegistry(getNodeIdStmt: NodeIdStmt): FileNodeIdRegistry {
|
|
287
|
+
const ids: Array<{ file: string; nodeId: number }> = [];
|
|
288
|
+
const seen = new Set<string>();
|
|
289
|
+
const cache = new Map<string, { id: number }>();
|
|
290
|
+
return {
|
|
291
|
+
ids,
|
|
292
|
+
add(relPath: string) {
|
|
293
|
+
if (seen.has(relPath)) return cache.get(relPath);
|
|
294
|
+
const row = getNodeIdStmt.get(relPath, 'file', relPath, 0);
|
|
295
|
+
if (row) {
|
|
296
|
+
seen.add(relPath);
|
|
297
|
+
ids.push({ file: relPath, nodeId: row.id });
|
|
298
|
+
cache.set(relPath, row);
|
|
299
|
+
}
|
|
300
|
+
return row;
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function toNativeImportInfo(imp: Import): NativeImportInfo {
|
|
306
|
+
return {
|
|
307
|
+
source: imp.source,
|
|
308
|
+
names: imp.names,
|
|
309
|
+
reexport: !!imp.reexport,
|
|
310
|
+
typeOnly: !!imp.typeOnly,
|
|
311
|
+
dynamicImport: !!imp.dynamicImport,
|
|
312
|
+
wildcardReexport: !!imp.wildcardReexport,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Pre-resolve every import for the given files, registering each resolved
|
|
318
|
+
* target with the registry so the native side has full node-id coverage.
|
|
319
|
+
*
|
|
320
|
+
* Resolved-import keys use forward-slash-normalized rootDir + "/" + relPath to
|
|
321
|
+
* match the Rust lookup format. On Windows, rootDir has backslashes but Rust
|
|
322
|
+
* normalizes them — the JS side must do the same or every key lookup misses
|
|
323
|
+
* (#750).
|
|
324
|
+
*/
|
|
325
|
+
function buildNativeFileInputs(
|
|
326
|
+
ctx: PipelineContext,
|
|
327
|
+
registry: FileNodeIdRegistry,
|
|
328
|
+
): {
|
|
329
|
+
files: NativeFileInput[];
|
|
330
|
+
resolvedImports: Array<{ key: string; resolvedPath: string }>;
|
|
331
|
+
} {
|
|
332
|
+
const { fileSymbols, barrelOnlyFiles, rootDir } = ctx;
|
|
333
|
+
const fwdRootDir = rootDir.replace(/\\/g, '/');
|
|
334
|
+
const files: NativeFileInput[] = [];
|
|
335
|
+
const resolvedImports: Array<{ key: string; resolvedPath: string }> = [];
|
|
336
|
+
|
|
337
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
338
|
+
const fileNodeRow = registry.add(relPath);
|
|
339
|
+
if (!fileNodeRow) continue;
|
|
340
|
+
|
|
341
|
+
const importInfos: NativeImportInfo[] = [];
|
|
342
|
+
for (const imp of symbols.imports) {
|
|
343
|
+
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
344
|
+
registry.add(resolvedPath);
|
|
345
|
+
resolvedImports.push({ key: `${fwdRootDir}/${relPath}|${imp.source}`, resolvedPath });
|
|
346
|
+
importInfos.push(toNativeImportInfo(imp));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
files.push({
|
|
350
|
+
file: relPath,
|
|
351
|
+
fileNodeId: fileNodeRow.id,
|
|
352
|
+
isBarrelOnly: barrelOnlyFiles.has(relPath),
|
|
353
|
+
imports: importInfos,
|
|
354
|
+
definitionNames: symbols.definitions.map((d) => d.name),
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return { files, resolvedImports };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/** Flatten `ctx.reexportMap` into the array shape the native side expects. */
|
|
361
|
+
function buildNativeReexports(
|
|
362
|
+
ctx: PipelineContext,
|
|
363
|
+
registry: FileNodeIdRegistry,
|
|
364
|
+
): NativeReexportInput[] {
|
|
365
|
+
const fileReexports: NativeReexportInput[] = [];
|
|
366
|
+
if (!ctx.reexportMap) return fileReexports;
|
|
367
|
+
|
|
368
|
+
for (const [file, entries] of ctx.reexportMap) {
|
|
369
|
+
const reexports = (
|
|
370
|
+
entries as Array<{ source: string; names: string[]; wildcardReexport: boolean }>
|
|
371
|
+
).map((re) => ({
|
|
372
|
+
source: re.source,
|
|
373
|
+
names: re.names,
|
|
374
|
+
wildcardReexport: !!re.wildcardReexport,
|
|
375
|
+
}));
|
|
376
|
+
fileReexports.push({ file, reexports });
|
|
377
|
+
|
|
378
|
+
for (const re of reexports) {
|
|
379
|
+
registry.add(re.source);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return fileReexports;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function collectBarrelFiles(ctx: PipelineContext): string[] {
|
|
386
|
+
const barrelFiles: string[] = [];
|
|
387
|
+
for (const [relPath] of ctx.fileSymbols) {
|
|
388
|
+
if (isBarrelFile(ctx, relPath)) barrelFiles.push(relPath);
|
|
389
|
+
}
|
|
390
|
+
return barrelFiles;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function collectSymbolNodes(
|
|
394
|
+
ctx: PipelineContext,
|
|
395
|
+
): Array<{ name: string; file: string; nodeId: number }> {
|
|
396
|
+
const symbolNodes: Array<{ name: string; file: string; nodeId: number }> = [];
|
|
397
|
+
if (!ctx.nodesByNameAndFile) return symbolNodes;
|
|
398
|
+
for (const [key, nodes] of ctx.nodesByNameAndFile) {
|
|
399
|
+
if (nodes.length === 0) continue;
|
|
400
|
+
const [name, file] = key.split('|');
|
|
401
|
+
symbolNodes.push({ name: name!, file: file!, nodeId: nodes[0]!.id });
|
|
402
|
+
}
|
|
403
|
+
return symbolNodes;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function buildImportEdgesNative(
|
|
407
|
+
ctx: PipelineContext,
|
|
408
|
+
getNodeIdStmt: NodeIdStmt,
|
|
409
|
+
allEdgeRows: EdgeRowTuple[],
|
|
410
|
+
native: NativeAddon,
|
|
411
|
+
): void {
|
|
412
|
+
const registry = createFileNodeIdRegistry(getNodeIdStmt);
|
|
413
|
+
|
|
414
|
+
const { files, resolvedImports } = buildNativeFileInputs(ctx, registry);
|
|
415
|
+
const fileReexports = buildNativeReexports(ctx, registry);
|
|
416
|
+
const barrelFiles = collectBarrelFiles(ctx);
|
|
417
|
+
const symbolNodes = collectSymbolNodes(ctx);
|
|
418
|
+
|
|
419
|
+
const nativeEdges = native.buildImportEdges!(
|
|
420
|
+
files,
|
|
421
|
+
resolvedImports,
|
|
422
|
+
fileReexports,
|
|
423
|
+
registry.ids,
|
|
424
|
+
barrelFiles,
|
|
425
|
+
ctx.rootDir,
|
|
426
|
+
symbolNodes,
|
|
427
|
+
) as NativeEdge[];
|
|
428
|
+
|
|
429
|
+
for (const e of nativeEdges) {
|
|
430
|
+
allEdgeRows.push([e.sourceId, e.targetId, e.kind, e.confidence, e.dynamic, null, null]);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// ── Phase 8.2: Cross-file return-type propagation ───────────────────────
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Augment each file's typeMap with return types from imported functions.
|
|
438
|
+
*
|
|
439
|
+
* The per-file extractor already resolves same-file call assignments (intra-file
|
|
440
|
+
* propagation). This function handles the cross-file case: when a file imports a
|
|
441
|
+
* function from another file and assigns its return value to a variable, we look up
|
|
442
|
+
* the callee's return type in the source file's returnTypeMap and inject it.
|
|
443
|
+
*
|
|
444
|
+
* Called once before call-edge building so both the native and JS paths benefit.
|
|
445
|
+
*/
|
|
446
|
+
function propagateReturnTypesAcrossFiles(
|
|
447
|
+
fileSymbols: Map<string, ExtractorOutput>,
|
|
448
|
+
ctx: PipelineContext,
|
|
449
|
+
rootDir: string,
|
|
450
|
+
): void {
|
|
451
|
+
// Index: filePath → per-file return-type map
|
|
452
|
+
const returnTypeIndex = new Map<string, Map<string, TypeMapEntry>>();
|
|
453
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
454
|
+
if (symbols.returnTypeMap?.size) returnTypeIndex.set(relPath, symbols.returnTypeMap);
|
|
455
|
+
}
|
|
456
|
+
if (returnTypeIndex.size === 0) return;
|
|
457
|
+
|
|
458
|
+
// Flat global map for qualified method lookups (TypeName.methodName → entry).
|
|
459
|
+
// Conflicts resolved by keeping the highest-confidence entry.
|
|
460
|
+
const globalReturnTypeMap = new Map<string, TypeMapEntry>();
|
|
461
|
+
for (const rtm of returnTypeIndex.values()) {
|
|
462
|
+
for (const [name, entry] of rtm) {
|
|
463
|
+
const existing = globalReturnTypeMap.get(name);
|
|
464
|
+
if (!existing || entry.confidence > existing.confidence) globalReturnTypeMap.set(name, entry);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
469
|
+
if (!symbols.callAssignments?.length) continue;
|
|
470
|
+
// Phase 8.4 side-effect: buildImportedNamesMap now traces through barrel
|
|
471
|
+
// files (traceBarrel), so `importedFrom` resolves to the leaf definition
|
|
472
|
+
// file rather than the barrel. This means returnTypeIndex.get(importedFrom)
|
|
473
|
+
// now finds entries it previously missed, improving cross-file return-type
|
|
474
|
+
// propagation through re-export chains (Phase 8.2 improvement).
|
|
475
|
+
const importedNamesMap = buildImportedNamesMap(ctx, relPath, symbols, rootDir);
|
|
476
|
+
|
|
477
|
+
for (const ca of symbols.callAssignments) {
|
|
478
|
+
if (symbols.typeMap.has(ca.varName)) continue; // already resolved locally
|
|
479
|
+
|
|
480
|
+
let returnEntry: TypeMapEntry | undefined;
|
|
481
|
+
if (ca.receiverTypeName) {
|
|
482
|
+
returnEntry = globalReturnTypeMap.get(`${ca.receiverTypeName}.${ca.calleeName}`);
|
|
483
|
+
} else {
|
|
484
|
+
const importedFrom = importedNamesMap.get(ca.calleeName);
|
|
485
|
+
if (importedFrom) returnEntry = returnTypeIndex.get(importedFrom)?.get(ca.calleeName);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (returnEntry) {
|
|
489
|
+
const propagatedConf = returnEntry.confidence - PROPAGATION_HOP_PENALTY;
|
|
490
|
+
if (propagatedConf > 0)
|
|
491
|
+
setTypeMapEntry(symbols.typeMap, ca.varName, returnEntry.type, propagatedConf);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// ── Call edges (native engine) ──────────────────────────────────────────
|
|
498
|
+
|
|
499
|
+
function buildCallEdgesNative(
|
|
500
|
+
ctx: PipelineContext,
|
|
501
|
+
getNodeIdStmt: NodeIdStmt,
|
|
502
|
+
allEdgeRows: EdgeRowTuple[],
|
|
503
|
+
allNodes: QueryNodeRow[],
|
|
504
|
+
native: NativeAddon,
|
|
505
|
+
): void {
|
|
506
|
+
const { fileSymbols, barrelOnlyFiles, rootDir } = ctx;
|
|
507
|
+
const nativeFiles: NativeFileEntry[] = [];
|
|
508
|
+
|
|
509
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
510
|
+
if (barrelOnlyFiles.has(relPath)) continue;
|
|
511
|
+
const fileNodeRow = getNodeIdStmt.get(relPath, 'file', relPath, 0);
|
|
512
|
+
if (!fileNodeRow) continue;
|
|
513
|
+
|
|
514
|
+
const importedNames = buildImportedNamesForNative(ctx, relPath, symbols, rootDir);
|
|
515
|
+
const typeMapRaw: Array<{ name: string; typeName: string; confidence: number }> =
|
|
516
|
+
symbols.typeMap instanceof Map
|
|
517
|
+
? [...symbols.typeMap.entries()].map(([name, entry]) => ({
|
|
518
|
+
name,
|
|
519
|
+
typeName: typeof entry === 'string' ? entry : entry.type,
|
|
520
|
+
confidence: typeof entry === 'object' ? entry.confidence : 0.9,
|
|
521
|
+
}))
|
|
522
|
+
: Array.isArray(symbols.typeMap)
|
|
523
|
+
? (symbols.typeMap as Array<{ name: string; typeName: string; confidence: number }>)
|
|
524
|
+
: [];
|
|
525
|
+
// Deduplicate: keep highest-confidence entry per name (first-wins on tie),
|
|
526
|
+
// matching JS setTypeMapEntry semantics. The Map branch is already
|
|
527
|
+
// deduped by setTypeMapEntry — this loop is only needed for the Array
|
|
528
|
+
// branch (pre-rebuilt native addon) but runs unconditionally as
|
|
529
|
+
// belt-and-suspenders since it's a cheap O(n) pass.
|
|
530
|
+
const typeMapDedup = new Map<string, { name: string; typeName: string; confidence: number }>();
|
|
531
|
+
for (const entry of typeMapRaw) {
|
|
532
|
+
const existing = typeMapDedup.get(entry.name);
|
|
533
|
+
if (!existing || entry.confidence > existing.confidence) {
|
|
534
|
+
typeMapDedup.set(entry.name, entry);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
const typeMap = [...typeMapDedup.values()];
|
|
538
|
+
nativeFiles.push({
|
|
539
|
+
file: relPath,
|
|
540
|
+
fileNodeId: fileNodeRow.id,
|
|
541
|
+
definitions: symbols.definitions.map((d) => {
|
|
542
|
+
const params = d.children?.filter((c) => c.kind === 'parameter').map((c) => c.name);
|
|
543
|
+
return {
|
|
544
|
+
name: d.name,
|
|
545
|
+
kind: d.kind,
|
|
546
|
+
line: d.line,
|
|
547
|
+
endLine: d.endLine ?? null,
|
|
548
|
+
params: params?.length ? params : undefined,
|
|
549
|
+
};
|
|
550
|
+
}),
|
|
551
|
+
calls: symbols.calls,
|
|
552
|
+
importedNames,
|
|
553
|
+
classes: symbols.classes,
|
|
554
|
+
typeMap,
|
|
555
|
+
fnRefBindings: symbols.fnRefBindings?.length ? symbols.fnRefBindings : undefined,
|
|
556
|
+
paramBindings: symbols.paramBindings?.length ? symbols.paramBindings : undefined,
|
|
557
|
+
thisCallBindings: symbols.thisCallBindings?.length ? symbols.thisCallBindings : undefined,
|
|
558
|
+
arrayElemBindings: symbols.arrayElemBindings?.length ? symbols.arrayElemBindings : undefined,
|
|
559
|
+
spreadArgBindings: symbols.spreadArgBindings?.length ? symbols.spreadArgBindings : undefined,
|
|
560
|
+
forOfBindings: symbols.forOfBindings?.length ? symbols.forOfBindings : undefined,
|
|
561
|
+
arrayCallbackBindings: symbols.arrayCallbackBindings?.length
|
|
562
|
+
? symbols.arrayCallbackBindings
|
|
563
|
+
: undefined,
|
|
564
|
+
objectRestParamBindings: symbols.objectRestParamBindings?.length
|
|
565
|
+
? symbols.objectRestParamBindings
|
|
566
|
+
: undefined,
|
|
567
|
+
objectPropBindings: symbols.objectPropBindings?.length
|
|
568
|
+
? symbols.objectPropBindings
|
|
569
|
+
: undefined,
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
const nativeEdges = native.buildCallEdges(nativeFiles, allNodes, [
|
|
574
|
+
...BUILTIN_RECEIVERS,
|
|
575
|
+
]) as NativeEdge[];
|
|
576
|
+
for (const e of nativeEdges) {
|
|
577
|
+
allEdgeRows.push([
|
|
578
|
+
e.sourceId,
|
|
579
|
+
e.targetId,
|
|
580
|
+
e.kind,
|
|
581
|
+
e.confidence,
|
|
582
|
+
e.dynamic,
|
|
583
|
+
e.kind === 'calls' ? 'ts-native' : null,
|
|
584
|
+
e.dynamic_kind ?? null,
|
|
585
|
+
]);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Object.defineProperty accessor post-pass for the native call-edge path.
|
|
591
|
+
*
|
|
592
|
+
* When a function is registered as a getter/setter via
|
|
593
|
+
* `Object.defineProperty(obj, "bar", { get: getter })`, calls to `this.X()`
|
|
594
|
+
* inside `getter` need to resolve against `obj` (because `this === obj` when
|
|
595
|
+
* the accessor is invoked). The native Rust engine has no knowledge of
|
|
596
|
+
* `definePropertyReceivers`, so this JS post-pass adds the missing edges.
|
|
597
|
+
*/
|
|
598
|
+
function buildDefinePropertyPostPass(
|
|
599
|
+
ctx: PipelineContext,
|
|
600
|
+
getNodeIdStmt: NodeIdStmt,
|
|
601
|
+
allEdgeRows: EdgeRowTuple[],
|
|
602
|
+
sharedLookup?: CallNodeLookup,
|
|
603
|
+
): void {
|
|
604
|
+
const filesWithReceivers = [...ctx.fileSymbols].filter(
|
|
605
|
+
([, symbols]) => symbols.definePropertyReceivers && symbols.definePropertyReceivers.size > 0,
|
|
606
|
+
);
|
|
607
|
+
if (filesWithReceivers.length === 0) return;
|
|
608
|
+
|
|
609
|
+
const seenByPair = new Set<string>();
|
|
610
|
+
for (const [srcId, tgtId] of allEdgeRows) {
|
|
611
|
+
seenByPair.add(`${srcId}|${tgtId}`);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
const { barrelOnlyFiles, rootDir } = ctx;
|
|
615
|
+
const lookup = sharedLookup ?? makeContextLookup(ctx, getNodeIdStmt);
|
|
616
|
+
|
|
617
|
+
for (const [relPath, symbols] of filesWithReceivers) {
|
|
618
|
+
if (barrelOnlyFiles.has(relPath)) continue;
|
|
619
|
+
const fileNodeRow = getNodeIdStmt.get(relPath, 'file', relPath, 0);
|
|
620
|
+
if (!fileNodeRow) continue;
|
|
621
|
+
|
|
622
|
+
const importedNames = buildImportedNamesMap(ctx, relPath, symbols, rootDir);
|
|
623
|
+
const typeMap: Map<string, TypeMapEntry | string> = symbols.typeMap || new Map();
|
|
624
|
+
const definePropertyReceivers = symbols.definePropertyReceivers!;
|
|
625
|
+
|
|
626
|
+
for (const call of symbols.calls) {
|
|
627
|
+
if (call.receiver !== 'this') continue;
|
|
628
|
+
|
|
629
|
+
const caller = findCaller(lookup, call, symbols.definitions, relPath, fileNodeRow);
|
|
630
|
+
if (!caller.callerName) continue;
|
|
631
|
+
|
|
632
|
+
const receiverVarName = definePropertyReceivers.get(caller.callerName);
|
|
633
|
+
if (!receiverVarName) continue;
|
|
634
|
+
|
|
635
|
+
// Only add edges the native engine missed (no direct target already).
|
|
636
|
+
const { targets: directTargets } = resolveCallTargets(
|
|
637
|
+
lookup,
|
|
638
|
+
call,
|
|
639
|
+
relPath,
|
|
640
|
+
importedNames,
|
|
641
|
+
typeMap as Map<string, unknown>,
|
|
642
|
+
caller.callerName,
|
|
643
|
+
);
|
|
644
|
+
if (directTargets.length > 0) continue;
|
|
645
|
+
|
|
646
|
+
// Resolve via receiver type
|
|
647
|
+
let targets: ReadonlyArray<{ id: number; file: string }> = [];
|
|
648
|
+
const typeEntry = typeMap.get(receiverVarName);
|
|
649
|
+
const typeName = typeEntry
|
|
650
|
+
? typeof typeEntry === 'string'
|
|
651
|
+
? typeEntry
|
|
652
|
+
: (typeEntry as { type?: string }).type
|
|
653
|
+
: null;
|
|
654
|
+
if (typeName) {
|
|
655
|
+
const qualifiedName = `${typeName}.${call.name}`;
|
|
656
|
+
targets = lookup.byNameAndFile(qualifiedName, relPath);
|
|
657
|
+
}
|
|
658
|
+
// Same-file fallback for plain object-literal methods
|
|
659
|
+
if (targets.length === 0) {
|
|
660
|
+
targets = lookup.byNameAndFile(call.name, relPath);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
for (const t of targets) {
|
|
664
|
+
const edgeKey = `${caller.id}|${t.id}`;
|
|
665
|
+
if (t.id !== caller.id && !seenByPair.has(edgeKey)) {
|
|
666
|
+
const conf = computeConfidence(relPath, t.file, null);
|
|
667
|
+
if (conf > 0) {
|
|
668
|
+
seenByPair.add(edgeKey);
|
|
669
|
+
allEdgeRows.push([caller.id, t.id, 'calls', conf, 0, 'ts-native', null]);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Phase 8.5: CHA + RTA post-pass for the native call-edge path.
|
|
679
|
+
*
|
|
680
|
+
* The native Rust engine has no knowledge of the CHA context, so `this.method()`
|
|
681
|
+
* calls and interface method dispatches are not expanded to their concrete
|
|
682
|
+
* implementations. This JS post-pass runs after the native edges and adds only
|
|
683
|
+
* the CHA-resolved edges that the native engine missed.
|
|
684
|
+
*
|
|
685
|
+
* Seeds seenByPair from the current allEdgeRows snapshot to avoid duplicating
|
|
686
|
+
* edges the native engine already produced.
|
|
687
|
+
*/
|
|
688
|
+
function buildChaPostPass(
|
|
689
|
+
ctx: PipelineContext,
|
|
690
|
+
getNodeIdStmt: NodeIdStmt,
|
|
691
|
+
allEdgeRows: EdgeRowTuple[],
|
|
692
|
+
chaCtx: ChaContext,
|
|
693
|
+
): void {
|
|
694
|
+
// Fast-exit when the CHA context is empty (no class hierarchy in the project)
|
|
695
|
+
if (chaCtx.implementors.size === 0 && chaCtx.parents.size === 0) return;
|
|
696
|
+
|
|
697
|
+
// Seed only from 'calls' edges — import/extends/implements edges share (src,tgt) pairs
|
|
698
|
+
// with real call edges at the file-node level and would cause false dedup if included.
|
|
699
|
+
const seenByPair = new Set<string>();
|
|
700
|
+
for (const row of allEdgeRows) {
|
|
701
|
+
if (row[2] === 'calls') seenByPair.add(`${row[0]}|${row[1]}`);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
const { fileSymbols, barrelOnlyFiles } = ctx;
|
|
705
|
+
const lookup = makeContextLookup(ctx, getNodeIdStmt);
|
|
706
|
+
|
|
707
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
708
|
+
if (barrelOnlyFiles.has(relPath)) continue;
|
|
709
|
+
const fileNodeRow = getNodeIdStmt.get(relPath, 'file', relPath, 0);
|
|
710
|
+
if (!fileNodeRow) continue;
|
|
711
|
+
|
|
712
|
+
const typeMap: Map<string, TypeMapEntry | string> = symbols.typeMap || new Map();
|
|
713
|
+
|
|
714
|
+
for (const call of symbols.calls) {
|
|
715
|
+
if (!call.receiver) continue;
|
|
716
|
+
if (BUILTIN_RECEIVERS.has(call.receiver)) continue;
|
|
717
|
+
|
|
718
|
+
const caller = findCaller(lookup, call, symbols.definitions, relPath, fileNodeRow);
|
|
719
|
+
let chaTargets: ReadonlyArray<{ id: number; file: string }> = [];
|
|
720
|
+
let isTypedReceiverDispatch = false;
|
|
721
|
+
|
|
722
|
+
if (call.receiver === 'this' || call.receiver === 'self' || call.receiver === 'super') {
|
|
723
|
+
chaTargets = resolveThisDispatch(
|
|
724
|
+
call.name,
|
|
725
|
+
caller.callerName,
|
|
726
|
+
call.receiver,
|
|
727
|
+
chaCtx,
|
|
728
|
+
lookup,
|
|
729
|
+
relPath,
|
|
730
|
+
);
|
|
731
|
+
} else {
|
|
732
|
+
const typeEntry = typeMap.get(call.receiver);
|
|
733
|
+
const typeName = typeEntry
|
|
734
|
+
? typeof typeEntry === 'string'
|
|
735
|
+
? typeEntry
|
|
736
|
+
: (typeEntry as { type?: string }).type
|
|
737
|
+
: null;
|
|
738
|
+
if (typeName) {
|
|
739
|
+
chaTargets = resolveChaTargets(typeName, call.name, chaCtx, lookup);
|
|
740
|
+
isTypedReceiverDispatch = true;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
for (const t of chaTargets) {
|
|
745
|
+
const edgeKey = `${caller.id}|${t.id}`;
|
|
746
|
+
if (t.id !== caller.id && !seenByPair.has(edgeKey)) {
|
|
747
|
+
// Typed-receiver (interface/CHA) dispatch: use CHA_TYPED_DISPATCH_CONFIDENCE
|
|
748
|
+
// — file proximity is not meaningful for virtual dispatch confidence.
|
|
749
|
+
// this/super dispatch keeps computeConfidence-based proximity scoring to
|
|
750
|
+
// match runPostNativeThisDispatch (native-orchestrator.ts).
|
|
751
|
+
const conf = isTypedReceiverDispatch
|
|
752
|
+
? CHA_TYPED_DISPATCH_CONFIDENCE
|
|
753
|
+
: computeConfidence(relPath, t.file, null) - CHA_DISPATCH_PENALTY;
|
|
754
|
+
if (conf > 0) {
|
|
755
|
+
seenByPair.add(edgeKey);
|
|
756
|
+
// Tag super-dispatch edges distinctly so runChaPostPass can exclude them
|
|
757
|
+
// from further CHA expansion (super calls are not virtual dispatch).
|
|
758
|
+
const technique = call.receiver === 'super' ? 'super-dispatch' : 'cha';
|
|
759
|
+
allEdgeRows.push([caller.id, t.id, 'calls', conf, 0, technique, null]);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
function buildImportedNamesForNative(
|
|
768
|
+
ctx: PipelineContext,
|
|
769
|
+
relPath: string,
|
|
770
|
+
symbols: ExtractorOutput,
|
|
771
|
+
rootDir: string,
|
|
772
|
+
): Array<{ name: string; file: string }> {
|
|
773
|
+
const importedNames: Array<{ name: string; file: string }> = [];
|
|
774
|
+
// Process dynamic imports first (lower priority), then static imports
|
|
775
|
+
// (higher priority). Rust HashMap::collect keeps the last entry per key,
|
|
776
|
+
// so static imports win when both contribute the same name.
|
|
777
|
+
const addImports = (imp: (typeof symbols.imports)[number]) => {
|
|
778
|
+
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
779
|
+
for (const name of imp.names) {
|
|
780
|
+
const cleanName = name.replace(/^\*\s+as\s+/, '');
|
|
781
|
+
let targetFile = resolvedPath;
|
|
782
|
+
if (isBarrelFile(ctx, resolvedPath)) {
|
|
783
|
+
const actual = resolveBarrelExportCached(ctx, resolvedPath, cleanName);
|
|
784
|
+
if (actual) targetFile = actual;
|
|
785
|
+
}
|
|
786
|
+
importedNames.push({ name: cleanName, file: targetFile });
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
for (const imp of symbols.imports) {
|
|
790
|
+
if (imp.dynamicImport) addImports(imp);
|
|
791
|
+
}
|
|
792
|
+
for (const imp of symbols.imports) {
|
|
793
|
+
if (!imp.dynamicImport) addImports(imp);
|
|
794
|
+
}
|
|
795
|
+
return importedNames;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// ── Call edges (JS fallback) ────────────────────────────────────────────
|
|
799
|
+
|
|
800
|
+
function buildCallEdgesJS(
|
|
801
|
+
ctx: PipelineContext,
|
|
802
|
+
getNodeIdStmt: NodeIdStmt,
|
|
803
|
+
allEdgeRows: EdgeRowTuple[],
|
|
804
|
+
chaCtx?: ChaContext,
|
|
805
|
+
): void {
|
|
806
|
+
const { fileSymbols, barrelOnlyFiles, rootDir } = ctx;
|
|
807
|
+
const lookup = makeContextLookup(ctx, getNodeIdStmt);
|
|
808
|
+
|
|
809
|
+
for (const [relPath, symbols] of fileSymbols) {
|
|
810
|
+
if (barrelOnlyFiles.has(relPath)) continue;
|
|
811
|
+
const fileNodeRow = getNodeIdStmt.get(relPath, 'file', relPath, 0);
|
|
812
|
+
if (!fileNodeRow) continue;
|
|
813
|
+
|
|
814
|
+
const importedNames = buildImportedNamesMap(ctx, relPath, symbols, rootDir);
|
|
815
|
+
const typeMap: Map<string, TypeMapEntry | string> = new Map(
|
|
816
|
+
symbols.typeMap instanceof Map ? symbols.typeMap : [],
|
|
817
|
+
);
|
|
818
|
+
|
|
819
|
+
// Phase 8.3f: seed typeMap[callee::restName] = { type: argName } for each
|
|
820
|
+
// object-destructuring rest parameter binding × call-site argument binding.
|
|
821
|
+
// Keys are scoped so two functions with the same rest-param name in the same
|
|
822
|
+
// file don't collide (#1358). When only one callee uses a given rest name,
|
|
823
|
+
// also seed the unscoped key as a null-callerName fallback.
|
|
824
|
+
if (symbols.objectRestParamBindings?.length && symbols.paramBindings?.length) {
|
|
825
|
+
const restNameCallees = new Map<string, Set<string>>();
|
|
826
|
+
for (const orpb of symbols.objectRestParamBindings) {
|
|
827
|
+
if (!restNameCallees.has(orpb.restName)) restNameCallees.set(orpb.restName, new Set());
|
|
828
|
+
restNameCallees.get(orpb.restName)!.add(orpb.callee);
|
|
829
|
+
}
|
|
830
|
+
for (const orpb of symbols.objectRestParamBindings) {
|
|
831
|
+
for (const pb of symbols.paramBindings) {
|
|
832
|
+
if (pb.callee === orpb.callee && pb.argIndex === orpb.argIndex) {
|
|
833
|
+
const scopedKey = `${orpb.callee}::${orpb.restName}`;
|
|
834
|
+
if (!typeMap.has(scopedKey)) {
|
|
835
|
+
typeMap.set(scopedKey, { type: pb.argName, confidence: 0.65 });
|
|
836
|
+
if (restNameCallees.get(orpb.restName)!.size === 1 && !typeMap.has(orpb.restName)) {
|
|
837
|
+
typeMap.set(orpb.restName, { type: pb.argName, confidence: 0.65 });
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
const seenCallEdges = new Set<string>();
|
|
846
|
+
const ptsMap = buildPointsToMapForFile(symbols, importedNames);
|
|
847
|
+
|
|
848
|
+
buildFileCallEdges(
|
|
849
|
+
relPath,
|
|
850
|
+
symbols,
|
|
851
|
+
fileNodeRow,
|
|
852
|
+
importedNames,
|
|
853
|
+
seenCallEdges,
|
|
854
|
+
lookup,
|
|
855
|
+
allEdgeRows,
|
|
856
|
+
typeMap,
|
|
857
|
+
ptsMap,
|
|
858
|
+
chaCtx,
|
|
859
|
+
);
|
|
860
|
+
buildClassHierarchyEdges(ctx, relPath, symbols, allEdgeRows);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
function buildImportedNamesMap(
|
|
865
|
+
ctx: PipelineContext,
|
|
866
|
+
relPath: string,
|
|
867
|
+
symbols: ExtractorOutput,
|
|
868
|
+
rootDir: string,
|
|
869
|
+
): Map<string, string> {
|
|
870
|
+
const importedNames = new Map<string, string>();
|
|
871
|
+
// Process dynamic imports first (lower priority), then static imports
|
|
872
|
+
// (higher priority). Static imports represent direct bindings while dynamic
|
|
873
|
+
// imports often use aliased destructuring (`{ foo: bar } = await import(…)`).
|
|
874
|
+
// When both contribute the same name, the static binding is authoritative.
|
|
875
|
+
//
|
|
876
|
+
// Phase 8.4: trace through barrel files so that symbol names map to their
|
|
877
|
+
// actual definition file, not the re-exporting barrel. Mirrors the tracing
|
|
878
|
+
// already done in buildImportedNamesForNative (the native path).
|
|
879
|
+
const traceBarrel = (resolvedPath: string, cleanName: string): string => {
|
|
880
|
+
if (!isBarrelFile(ctx, resolvedPath)) return resolvedPath;
|
|
881
|
+
const actual = resolveBarrelExportCached(ctx, resolvedPath, cleanName);
|
|
882
|
+
return actual ?? resolvedPath;
|
|
883
|
+
};
|
|
884
|
+
for (const imp of symbols.imports) {
|
|
885
|
+
if (!imp.dynamicImport) continue;
|
|
886
|
+
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
887
|
+
for (const name of imp.names) {
|
|
888
|
+
const cleanName = name.replace(/^\*\s+as\s+/, '');
|
|
889
|
+
importedNames.set(cleanName, traceBarrel(resolvedPath, cleanName));
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
for (const imp of symbols.imports) {
|
|
893
|
+
if (imp.dynamicImport) continue;
|
|
894
|
+
const resolvedPath = getResolved(ctx, path.join(rootDir, relPath), imp.source);
|
|
895
|
+
for (const name of imp.names) {
|
|
896
|
+
const cleanName = name.replace(/^\*\s+as\s+/, '');
|
|
897
|
+
importedNames.set(cleanName, traceBarrel(resolvedPath, cleanName));
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
return importedNames;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
function makeContextLookup(ctx: PipelineContext, getNodeIdStmt: NodeIdStmt): CallNodeLookup {
|
|
904
|
+
return {
|
|
905
|
+
byNameAndFile: (name, file) => ctx.nodesByNameAndFile.get(`${name}|${file}`) ?? [],
|
|
906
|
+
byName: (name) => ctx.nodesByName.get(name) ?? [],
|
|
907
|
+
isBarrel: (file) => isBarrelFile(ctx, file),
|
|
908
|
+
resolveBarrel: (barrelFile, symbolName) =>
|
|
909
|
+
resolveBarrelExportCached(ctx, barrelFile, symbolName),
|
|
910
|
+
nodeId: (name, kind, file, line) => getNodeIdStmt.get(name, kind, file, line),
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* Build a per-file points-to map for Phase 8.3 alias resolution.
|
|
916
|
+
* Returns null fast when the file has no function-reference bindings.
|
|
917
|
+
*
|
|
918
|
+
* Only callable definitions (function/method) are seeded as concrete targets.
|
|
919
|
+
* Class and interface names are intentionally excluded — aliasing a constructor
|
|
920
|
+
* (`const Svc = MyService`) is an uncommon pattern that would require tracking
|
|
921
|
+
* `new`-expression flows separately from the alias chain. That is left to Phase
|
|
922
|
+
* 8.2 call-assignment propagation, which already handles constructor assignments.
|
|
923
|
+
*/
|
|
924
|
+
function buildPointsToMapForFile(
|
|
925
|
+
symbols: ExtractorOutput,
|
|
926
|
+
importedNames: Map<string, string>,
|
|
927
|
+
): PointsToMap | null {
|
|
928
|
+
const hasThisCallBindings = !!symbols.thisCallBindings?.length;
|
|
929
|
+
if (
|
|
930
|
+
!symbols.fnRefBindings?.length &&
|
|
931
|
+
!symbols.paramBindings?.length &&
|
|
932
|
+
!symbols.arrayElemBindings?.length &&
|
|
933
|
+
!symbols.spreadArgBindings?.length &&
|
|
934
|
+
!symbols.forOfBindings?.length &&
|
|
935
|
+
!symbols.arrayCallbackBindings?.length &&
|
|
936
|
+
!symbols.objectRestParamBindings?.length &&
|
|
937
|
+
!symbols.objectPropBindings?.length &&
|
|
938
|
+
!hasThisCallBindings
|
|
939
|
+
)
|
|
940
|
+
return null;
|
|
941
|
+
const defNames = new Set(
|
|
942
|
+
symbols.definitions
|
|
943
|
+
.filter((d) => d.kind === 'function' || d.kind === 'method')
|
|
944
|
+
.map((d) => d.name),
|
|
945
|
+
);
|
|
946
|
+
const definitionParams = buildDefinitionParamsMap(symbols.definitions);
|
|
947
|
+
|
|
948
|
+
// Convert thisCallBindings into scoped fnRefBindings: `fn::this → namedCtx`.
|
|
949
|
+
// The scoped key `fn::this` is looked up when `this()` calls are resolved inside
|
|
950
|
+
// function `fn` — caller.callerName='fn', call.name='this' → scopedPtsKey='fn::this'.
|
|
951
|
+
let allFnRefBindings: readonly FnRefBinding[] = symbols.fnRefBindings ?? [];
|
|
952
|
+
if (hasThisCallBindings) {
|
|
953
|
+
const extra: FnRefBinding[] = (symbols.thisCallBindings ?? []).map((b) => ({
|
|
954
|
+
lhs: `${b.callee}::this`,
|
|
955
|
+
rhs: b.thisArg,
|
|
956
|
+
}));
|
|
957
|
+
allFnRefBindings = [...allFnRefBindings, ...extra];
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
return buildPointsToMap(
|
|
961
|
+
allFnRefBindings,
|
|
962
|
+
defNames,
|
|
963
|
+
importedNames,
|
|
964
|
+
symbols.paramBindings,
|
|
965
|
+
definitionParams,
|
|
966
|
+
symbols.arrayElemBindings,
|
|
967
|
+
symbols.spreadArgBindings,
|
|
968
|
+
symbols.forOfBindings,
|
|
969
|
+
symbols.arrayCallbackBindings,
|
|
970
|
+
symbols.objectRestParamBindings,
|
|
971
|
+
symbols.objectPropBindings,
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
function buildDefinitionParamsMap(
|
|
976
|
+
definitions: readonly Definition[],
|
|
977
|
+
): Map<string, readonly string[]> {
|
|
978
|
+
const map = new Map<string, readonly string[]>();
|
|
979
|
+
for (const def of definitions) {
|
|
980
|
+
if ((def.kind === 'function' || def.kind === 'method') && def.children) {
|
|
981
|
+
const params = def.children.filter((c) => c.kind === 'parameter').map((c) => c.name);
|
|
982
|
+
if (params.length > 0) {
|
|
983
|
+
if (map.has(def.name)) {
|
|
984
|
+
// Two definitions share the same name (e.g. overloads, same-named method and
|
|
985
|
+
// function, or conditional redeclaration). Keep the first entry — using the
|
|
986
|
+
// wrong parameter list would map argIndex to the wrong parameter name.
|
|
987
|
+
debug(
|
|
988
|
+
`buildDefinitionParamsMap: duplicate def name "${def.name}" (kind=${def.kind}, line=${def.line}) — skipping; first entry kept`,
|
|
989
|
+
);
|
|
990
|
+
} else {
|
|
991
|
+
map.set(def.name, params);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return map;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// ── Per-call resolution helpers ─────────────────────────────────────────
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* Resolve targets for a single call site with all JS-path fallbacks applied.
|
|
1003
|
+
*
|
|
1004
|
+
* Runs in order:
|
|
1005
|
+
* 1. Primary resolution via `resolveCallTargets` (importedNames + typeMap).
|
|
1006
|
+
* 2. Same-class `this.method()` fallback (non-super receivers only).
|
|
1007
|
+
* 3. Same-class bare-call fallback for non-JS/TS class-scoped languages.
|
|
1008
|
+
* 4. Object.defineProperty accessor fallback (this-calls inside getter/setter).
|
|
1009
|
+
*
|
|
1010
|
+
* Returns the resolved targets array and the importedFrom hint for confidence scoring.
|
|
1011
|
+
*/
|
|
1012
|
+
function resolveFallbackTargets(
|
|
1013
|
+
call: Call,
|
|
1014
|
+
caller: { id: number; callerName: string | null },
|
|
1015
|
+
relPath: string,
|
|
1016
|
+
importedNames: Map<string, string>,
|
|
1017
|
+
lookup: CallNodeLookup,
|
|
1018
|
+
typeMap: Map<string, TypeMapEntry | string>,
|
|
1019
|
+
definePropertyReceivers: Map<string, string> | undefined,
|
|
1020
|
+
): {
|
|
1021
|
+
targets: ReadonlyArray<{ id: number; file: string; kind?: string }>;
|
|
1022
|
+
importedFrom: string | null | undefined;
|
|
1023
|
+
} {
|
|
1024
|
+
let { targets, importedFrom } = resolveCallTargets(
|
|
1025
|
+
lookup,
|
|
1026
|
+
call,
|
|
1027
|
+
relPath,
|
|
1028
|
+
importedNames,
|
|
1029
|
+
typeMap as Map<string, unknown>,
|
|
1030
|
+
caller.callerName,
|
|
1031
|
+
);
|
|
1032
|
+
|
|
1033
|
+
// Same-class `this.method()` fallback: when the call receiver is `this` and
|
|
1034
|
+
// resolveCallTargets found nothing, derive the enclosing class name from the
|
|
1035
|
+
// caller (e.g. `Logger.info` → class prefix `Logger`) and retry with the
|
|
1036
|
+
// qualified method name `Logger._write`. This mirrors what the native Rust
|
|
1037
|
+
// engine does implicitly via its class-scoped symbol table.
|
|
1038
|
+
// NOTE: restricted to `this` only — `super.method()` targets a parent class,
|
|
1039
|
+
// not the enclosing class, so qualifying with the child class name would
|
|
1040
|
+
// produce a false edge when the child also defines a same-named method.
|
|
1041
|
+
if (targets.length === 0 && call.receiver === 'this' && caller.callerName != null) {
|
|
1042
|
+
const lastDot = caller.callerName.lastIndexOf('.');
|
|
1043
|
+
if (lastDot > 0) {
|
|
1044
|
+
const prevDot = caller.callerName.lastIndexOf('.', lastDot - 1);
|
|
1045
|
+
const className = caller.callerName.slice(prevDot + 1, lastDot);
|
|
1046
|
+
const qualified = lookup
|
|
1047
|
+
.byNameAndFile(`${className}.${call.name}`, relPath)
|
|
1048
|
+
.filter((n) => n.kind === 'method');
|
|
1049
|
+
if (qualified.length > 0) targets = qualified;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// Same-class bare-call fallback: when a no-receiver call can't be resolved
|
|
1054
|
+
// globally, try the caller's own class as a qualifier. Handles C# static
|
|
1055
|
+
// sibling calls: `IsValidEmail()` inside `Validators.ValidateUser` resolves
|
|
1056
|
+
// to `Validators.IsValidEmail`. Skipped for JS/TS where bare calls are
|
|
1057
|
+
// module-scoped, not class-scoped.
|
|
1058
|
+
if (
|
|
1059
|
+
targets.length === 0 &&
|
|
1060
|
+
!call.receiver &&
|
|
1061
|
+
caller.callerName != null &&
|
|
1062
|
+
!isModuleScopedLanguage(relPath)
|
|
1063
|
+
) {
|
|
1064
|
+
const lastDot = caller.callerName.lastIndexOf('.');
|
|
1065
|
+
if (lastDot > 0) {
|
|
1066
|
+
const prevDot = caller.callerName.lastIndexOf('.', lastDot - 1);
|
|
1067
|
+
const className = caller.callerName.slice(prevDot + 1, lastDot);
|
|
1068
|
+
const qualified = lookup
|
|
1069
|
+
.byNameAndFile(`${className}.${call.name}`, relPath)
|
|
1070
|
+
.filter((n) => n.kind === 'method');
|
|
1071
|
+
if (qualified.length > 0) targets = qualified;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// Object.defineProperty accessor fallback: when a function is registered as
|
|
1076
|
+
// a getter/setter via `Object.defineProperty(obj, "bar", { get: getter })`,
|
|
1077
|
+
// calls to `this.X()` inside `getter` resolve against `obj` (this === obj
|
|
1078
|
+
// when the accessor is invoked). If the same-class fallback above found
|
|
1079
|
+
// nothing, try treating `obj` as the receiver and look up `obj.X` in the
|
|
1080
|
+
// typeMap, or fall back to a same-file lookup of any definition named X
|
|
1081
|
+
// that belongs to the object literal or its type.
|
|
1082
|
+
if (
|
|
1083
|
+
targets.length === 0 &&
|
|
1084
|
+
call.receiver === 'this' &&
|
|
1085
|
+
caller.callerName != null &&
|
|
1086
|
+
definePropertyReceivers
|
|
1087
|
+
) {
|
|
1088
|
+
const receiverVarName = definePropertyReceivers.get(caller.callerName);
|
|
1089
|
+
if (receiverVarName) {
|
|
1090
|
+
const typeEntry = typeMap.get(receiverVarName);
|
|
1091
|
+
const typeName = typeEntry
|
|
1092
|
+
? typeof typeEntry === 'string'
|
|
1093
|
+
? typeEntry
|
|
1094
|
+
: (typeEntry as { type?: string }).type
|
|
1095
|
+
: null;
|
|
1096
|
+
if (typeName) {
|
|
1097
|
+
const qualified = lookup.byNameAndFile(`${typeName}.${call.name}`, relPath);
|
|
1098
|
+
if (qualified.length > 0) targets = [...qualified];
|
|
1099
|
+
}
|
|
1100
|
+
// If still no targets, search for any definition named `call.name` in
|
|
1101
|
+
// the same file — handles plain object literals where the method isn't
|
|
1102
|
+
// qualified (e.g. `const obj = { baz() {} }` defines `baz` directly).
|
|
1103
|
+
// Note: this is intentionally broad — it matches any same-file definition
|
|
1104
|
+
// with the called name, not just members of the receiver object. This is
|
|
1105
|
+
// the same behaviour used by the native post-pass path (buildDefinePropertyPostPass).
|
|
1106
|
+
if (targets.length === 0) {
|
|
1107
|
+
const sameFile = lookup.byNameAndFile(call.name, relPath);
|
|
1108
|
+
if (sameFile.length > 0) targets = [...sameFile];
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
return { targets, importedFrom };
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
/**
|
|
1117
|
+
* Emit direct-call edges for the resolved targets of a single call site.
|
|
1118
|
+
*
|
|
1119
|
+
* Sorts targets by confidence descending first, then for each target:
|
|
1120
|
+
* - Skips self-edges and already-seen edges.
|
|
1121
|
+
* - If a pts edge already exists for this pair, upgrades it in-place to
|
|
1122
|
+
* direct-call confidence and promotes to seenCallEdges.
|
|
1123
|
+
* - Otherwise records a new `calls` edge with `ts-native` technique.
|
|
1124
|
+
*/
|
|
1125
|
+
function emitDirectCallEdgesForCall(
|
|
1126
|
+
caller: { id: number },
|
|
1127
|
+
targets: ReadonlyArray<{ id: number; file: string }>,
|
|
1128
|
+
importedFrom: string | null | undefined,
|
|
1129
|
+
isDynamic: number,
|
|
1130
|
+
relPath: string,
|
|
1131
|
+
seenCallEdges: Set<string>,
|
|
1132
|
+
ptsEdgeRows: Map<string, number>,
|
|
1133
|
+
allEdgeRows: EdgeRowTuple[],
|
|
1134
|
+
): void {
|
|
1135
|
+
// Sort targets by confidence descending before emitting edges.
|
|
1136
|
+
// For multi-target calls with duplicate (source_id, target_id) pairs the
|
|
1137
|
+
// stored confidence depends on which duplicate is processed last — sorting
|
|
1138
|
+
// here guarantees the highest-confidence target wins on dedup, matching the
|
|
1139
|
+
// native engine's sort_targets_by_confidence call in build_edges.rs.
|
|
1140
|
+
const sorted =
|
|
1141
|
+
targets.length > 1
|
|
1142
|
+
? [...targets].sort(
|
|
1143
|
+
(a, b) =>
|
|
1144
|
+
computeConfidence(relPath, b.file, importedFrom ?? null) -
|
|
1145
|
+
computeConfidence(relPath, a.file, importedFrom ?? null),
|
|
1146
|
+
)
|
|
1147
|
+
: targets;
|
|
1148
|
+
|
|
1149
|
+
for (const t of sorted) {
|
|
1150
|
+
const edgeKey = `${caller.id}|${t.id}`;
|
|
1151
|
+
if (t.id === caller.id) continue;
|
|
1152
|
+
const confidence = computeConfidence(relPath, t.file, importedFrom ?? null);
|
|
1153
|
+
if (seenCallEdges.has(edgeKey)) continue;
|
|
1154
|
+
const ptsIdx = ptsEdgeRows.get(edgeKey);
|
|
1155
|
+
if (ptsIdx !== undefined) {
|
|
1156
|
+
// A pts-resolved edge already exists for this caller→target pair with a
|
|
1157
|
+
// penalised confidence. Upgrade it to the direct-call confidence in-place,
|
|
1158
|
+
// then promote to seenCallEdges so no further processing is needed.
|
|
1159
|
+
const ptsRow = allEdgeRows[ptsIdx];
|
|
1160
|
+
if (ptsRow) {
|
|
1161
|
+
ptsRow[3] = confidence;
|
|
1162
|
+
ptsRow[4] = isDynamic; // upgrade is_dynamic: direct call overrides the pts-alias dynamic flag
|
|
1163
|
+
ptsRow[5] = 'ts-native'; // promoted from pts to direct-call resolution
|
|
1164
|
+
}
|
|
1165
|
+
ptsEdgeRows.delete(edgeKey);
|
|
1166
|
+
seenCallEdges.add(edgeKey);
|
|
1167
|
+
} else {
|
|
1168
|
+
seenCallEdges.add(edgeKey);
|
|
1169
|
+
allEdgeRows.push([caller.id, t.id, 'calls', confidence, isDynamic, 'ts-native', null]);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
/**
|
|
1175
|
+
* Phase 8.3 / 8.3c / bind: emit pts-resolved edges for unresolved no-receiver calls.
|
|
1176
|
+
*
|
|
1177
|
+
* Fires for three cases:
|
|
1178
|
+
* (a) dynamic=true: alias calls emitted by extractCallbackReferenceCalls.
|
|
1179
|
+
* Looks up `call.name` directly (alias entries are flat-keyed).
|
|
1180
|
+
* (b) non-dynamic: parameter variable calls (fn() where fn is a param).
|
|
1181
|
+
* Looks up the scoped key `callerName::call.name` to avoid spurious
|
|
1182
|
+
* edges from same-named parameters across different functions.
|
|
1183
|
+
* (c) non-dynamic: module-level alias bindings — `f = fn.bind(ctx)` or
|
|
1184
|
+
* `const f = handler` — where pts('f') was seeded by fnRefBindings.
|
|
1185
|
+
* Checked against fnRefBindingLhs so case (c) only fires for genuine
|
|
1186
|
+
* bind/alias entries and never for self-seeded local definitions.
|
|
1187
|
+
*
|
|
1188
|
+
* Pts edges are added to ptsEdgeRows (not seenCallEdges) so that a later
|
|
1189
|
+
* direct call to the same target can upgrade confidence rather than being
|
|
1190
|
+
* silently dropped by the dedup guard.
|
|
1191
|
+
*/
|
|
1192
|
+
function emitPtsNoReceiverEdges(
|
|
1193
|
+
call: Call,
|
|
1194
|
+
caller: { id: number; callerName: string | null },
|
|
1195
|
+
isDynamic: number,
|
|
1196
|
+
relPath: string,
|
|
1197
|
+
importedNames: Map<string, string>,
|
|
1198
|
+
lookup: CallNodeLookup,
|
|
1199
|
+
typeMap: Map<string, TypeMapEntry | string>,
|
|
1200
|
+
ptsMap: PointsToMap,
|
|
1201
|
+
fnRefBindingLhs: Set<string>,
|
|
1202
|
+
seenCallEdges: Set<string>,
|
|
1203
|
+
ptsEdgeRows: Map<string, number>,
|
|
1204
|
+
allEdgeRows: EdgeRowTuple[],
|
|
1205
|
+
): void {
|
|
1206
|
+
const scopedPtsKey = caller.callerName != null ? `${caller.callerName}::${call.name}` : null;
|
|
1207
|
+
// Module-level calls (callerName === null) use the '<module>' sentinel emitted by
|
|
1208
|
+
// extractSpreadForOfWalk for top-level for-of loops. Look it up as a fallback so
|
|
1209
|
+
// that `for (const f of arr) { f(); }` at module scope resolves correctly.
|
|
1210
|
+
const modulePtsKey =
|
|
1211
|
+
caller.callerName === null && ptsMap.has(`<module>::${call.name}`)
|
|
1212
|
+
? `<module>::${call.name}`
|
|
1213
|
+
: null;
|
|
1214
|
+
const flatPtsKey =
|
|
1215
|
+
!call.dynamic && fnRefBindingLhs.has(call.name) && ptsMap.has(call.name) ? call.name : null;
|
|
1216
|
+
|
|
1217
|
+
if (
|
|
1218
|
+
!(
|
|
1219
|
+
call.dynamic ||
|
|
1220
|
+
(scopedPtsKey != null && ptsMap.has(scopedPtsKey)) ||
|
|
1221
|
+
modulePtsKey != null ||
|
|
1222
|
+
flatPtsKey != null
|
|
1223
|
+
)
|
|
1224
|
+
)
|
|
1225
|
+
return;
|
|
1226
|
+
|
|
1227
|
+
const ptsLookupName = call.dynamic
|
|
1228
|
+
? call.name
|
|
1229
|
+
: scopedPtsKey != null && ptsMap.has(scopedPtsKey)
|
|
1230
|
+
? scopedPtsKey
|
|
1231
|
+
: modulePtsKey != null
|
|
1232
|
+
? modulePtsKey
|
|
1233
|
+
: // flatPtsKey != null is guaranteed: if neither call.dynamic nor scopedPtsKey
|
|
1234
|
+
// nor modulePtsKey matched, flatPtsKey must be non-null.
|
|
1235
|
+
flatPtsKey!;
|
|
1236
|
+
|
|
1237
|
+
for (const alias of resolveViaPointsTo(ptsLookupName, ptsMap)) {
|
|
1238
|
+
// Resolve the concrete alias target. Only `name` is needed here — receiver
|
|
1239
|
+
// and line are not relevant for alias resolution (we are looking up the
|
|
1240
|
+
// aliased function by name, not dispatching a method call).
|
|
1241
|
+
const { targets: aliasTargets, importedFrom: aliasFrom } = resolveCallTargets(
|
|
1242
|
+
lookup,
|
|
1243
|
+
{ name: alias },
|
|
1244
|
+
relPath,
|
|
1245
|
+
importedNames,
|
|
1246
|
+
typeMap as Map<string, unknown>,
|
|
1247
|
+
);
|
|
1248
|
+
const sortedAliasTargets =
|
|
1249
|
+
aliasTargets.length > 1
|
|
1250
|
+
? [...aliasTargets].sort(
|
|
1251
|
+
(a, b) =>
|
|
1252
|
+
computeConfidence(relPath, b.file, aliasFrom ?? null) -
|
|
1253
|
+
computeConfidence(relPath, a.file, aliasFrom ?? null),
|
|
1254
|
+
)
|
|
1255
|
+
: aliasTargets;
|
|
1256
|
+
for (const t of sortedAliasTargets) {
|
|
1257
|
+
const edgeKey = `${caller.id}|${t.id}`;
|
|
1258
|
+
if (t.id !== caller.id && !seenCallEdges.has(edgeKey) && !ptsEdgeRows.has(edgeKey)) {
|
|
1259
|
+
const conf =
|
|
1260
|
+
computeConfidence(relPath, t.file, aliasFrom ?? null) - PROPAGATION_HOP_PENALTY;
|
|
1261
|
+
if (conf > 0) {
|
|
1262
|
+
ptsEdgeRows.set(edgeKey, allEdgeRows.length);
|
|
1263
|
+
allEdgeRows.push([caller.id, t.id, 'calls', conf, isDynamic, 'points-to', null]);
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* Phase 8.3f: emit pts-resolved edges for unresolved receiver calls via
|
|
1272
|
+
* object-rest param bindings.
|
|
1273
|
+
*
|
|
1274
|
+
* Fires when `rest.prop()` is encountered and `rest` was seeded as
|
|
1275
|
+
* `pts["rest.prop"]` by the object-rest dispatch chain
|
|
1276
|
+
* (ObjectRestParamBinding + paramBinding + ObjectPropBinding).
|
|
1277
|
+
*/
|
|
1278
|
+
function emitPtsReceiverEdges(
|
|
1279
|
+
call: Call,
|
|
1280
|
+
caller: { id: number; callerName: string | null },
|
|
1281
|
+
isDynamic: number,
|
|
1282
|
+
relPath: string,
|
|
1283
|
+
importedNames: Map<string, string>,
|
|
1284
|
+
lookup: CallNodeLookup,
|
|
1285
|
+
typeMap: Map<string, TypeMapEntry | string>,
|
|
1286
|
+
ptsMap: PointsToMap,
|
|
1287
|
+
seenCallEdges: Set<string>,
|
|
1288
|
+
ptsEdgeRows: Map<string, number>,
|
|
1289
|
+
allEdgeRows: EdgeRowTuple[],
|
|
1290
|
+
): void {
|
|
1291
|
+
const receiverKey = `${call.receiver}.${call.name}`;
|
|
1292
|
+
if (!ptsMap.has(receiverKey)) return;
|
|
1293
|
+
|
|
1294
|
+
for (const alias of resolveViaPointsTo(receiverKey, ptsMap)) {
|
|
1295
|
+
const { targets: aliasTargets, importedFrom: aliasFrom } = resolveCallTargets(
|
|
1296
|
+
lookup,
|
|
1297
|
+
{ name: alias },
|
|
1298
|
+
relPath,
|
|
1299
|
+
importedNames,
|
|
1300
|
+
typeMap as Map<string, unknown>,
|
|
1301
|
+
);
|
|
1302
|
+
const sortedAliasTargets =
|
|
1303
|
+
aliasTargets.length > 1
|
|
1304
|
+
? [...aliasTargets].sort(
|
|
1305
|
+
(a, b) =>
|
|
1306
|
+
computeConfidence(relPath, b.file, aliasFrom ?? null) -
|
|
1307
|
+
computeConfidence(relPath, a.file, aliasFrom ?? null),
|
|
1308
|
+
)
|
|
1309
|
+
: aliasTargets;
|
|
1310
|
+
for (const t of sortedAliasTargets) {
|
|
1311
|
+
const edgeKey = `${caller.id}|${t.id}`;
|
|
1312
|
+
if (t.id !== caller.id && !seenCallEdges.has(edgeKey) && !ptsEdgeRows.has(edgeKey)) {
|
|
1313
|
+
const conf =
|
|
1314
|
+
computeConfidence(relPath, t.file, aliasFrom ?? null) - PROPAGATION_HOP_PENALTY;
|
|
1315
|
+
if (conf > 0) {
|
|
1316
|
+
ptsEdgeRows.set(edgeKey, allEdgeRows.length);
|
|
1317
|
+
allEdgeRows.push([caller.id, t.id, 'calls', conf, isDynamic, 'points-to', null]);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
/**
|
|
1325
|
+
* Phase 8.5: emit CHA + RTA dispatch edges for a single call site.
|
|
1326
|
+
*
|
|
1327
|
+
* For `this`/`self`/`super` calls: resolve through the class hierarchy.
|
|
1328
|
+
* For typed receiver calls: expand to all instantiated concrete implementations.
|
|
1329
|
+
*/
|
|
1330
|
+
function emitChaCallEdgesForCall(
|
|
1331
|
+
call: Call,
|
|
1332
|
+
caller: { id: number; callerName: string | null },
|
|
1333
|
+
relPath: string,
|
|
1334
|
+
typeMap: Map<string, TypeMapEntry | string>,
|
|
1335
|
+
lookup: CallNodeLookup,
|
|
1336
|
+
chaCtx: ChaContext,
|
|
1337
|
+
seenCallEdges: Set<string>,
|
|
1338
|
+
ptsEdgeRows: Map<string, number>,
|
|
1339
|
+
allEdgeRows: EdgeRowTuple[],
|
|
1340
|
+
): void {
|
|
1341
|
+
let chaTargets: ReadonlyArray<{ id: number; file: string }> = [];
|
|
1342
|
+
let isTypedReceiverDispatch = false;
|
|
1343
|
+
|
|
1344
|
+
if (call.receiver === 'this' || call.receiver === 'self' || call.receiver === 'super') {
|
|
1345
|
+
chaTargets = resolveThisDispatch(
|
|
1346
|
+
call.name,
|
|
1347
|
+
caller.callerName,
|
|
1348
|
+
call.receiver,
|
|
1349
|
+
chaCtx,
|
|
1350
|
+
lookup,
|
|
1351
|
+
relPath,
|
|
1352
|
+
);
|
|
1353
|
+
} else if (!BUILTIN_RECEIVERS.has(call.receiver!)) {
|
|
1354
|
+
const typeEntry = typeMap.get(call.receiver!);
|
|
1355
|
+
const typeName = typeEntry
|
|
1356
|
+
? typeof typeEntry === 'string'
|
|
1357
|
+
? typeEntry
|
|
1358
|
+
: (typeEntry as { type?: string }).type
|
|
1359
|
+
: null;
|
|
1360
|
+
if (typeName) {
|
|
1361
|
+
chaTargets = resolveChaTargets(typeName, call.name, chaCtx, lookup);
|
|
1362
|
+
isTypedReceiverDispatch = true;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
for (const t of chaTargets) {
|
|
1367
|
+
const edgeKey = `${caller.id}|${t.id}`;
|
|
1368
|
+
if (t.id !== caller.id && !seenCallEdges.has(edgeKey) && !ptsEdgeRows.has(edgeKey)) {
|
|
1369
|
+
// Typed-receiver (interface/CHA) dispatch: use CHA_TYPED_DISPATCH_CONFIDENCE
|
|
1370
|
+
// — file proximity is not meaningful for virtual dispatch confidence.
|
|
1371
|
+
// this/super dispatch keeps computeConfidence-based proximity scoring to
|
|
1372
|
+
// match runPostNativeThisDispatch (native-orchestrator.ts).
|
|
1373
|
+
const conf = isTypedReceiverDispatch
|
|
1374
|
+
? CHA_TYPED_DISPATCH_CONFIDENCE
|
|
1375
|
+
: computeConfidence(relPath, t.file, null) - CHA_DISPATCH_PENALTY;
|
|
1376
|
+
if (conf > 0) {
|
|
1377
|
+
seenCallEdges.add(edgeKey);
|
|
1378
|
+
allEdgeRows.push([caller.id, t.id, 'calls', conf, 0, 'cha', null]);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
/**
|
|
1385
|
+
* Dynamic kinds that can never be resolved statically — emit a sink edge to the
|
|
1386
|
+
* file node instead of silently dropping the call site. confidence=0.0 keeps
|
|
1387
|
+
* these below DEFAULT_MIN_CONFIDENCE so they never appear in normal query results.
|
|
1388
|
+
*/
|
|
1389
|
+
const FLAG_ONLY_KINDS: ReadonlySet<DynamicKind> = new Set([
|
|
1390
|
+
'eval',
|
|
1391
|
+
'computed-key',
|
|
1392
|
+
'unresolved-dynamic',
|
|
1393
|
+
]);
|
|
1394
|
+
|
|
1395
|
+
/**
|
|
1396
|
+
* Build call edges for all calls in a single file (WASM/JS engine path).
|
|
1397
|
+
*
|
|
1398
|
+
* Iterates over `symbols.calls` and dispatches each call through the full
|
|
1399
|
+
* JS resolution cascade:
|
|
1400
|
+
* 1. `resolveFallbackTargets` — primary + class-fallback + defineProperty fallback
|
|
1401
|
+
* 2. `emitDirectCallEdgesForCall` — emit direct-call edges (upgrading any pts pair)
|
|
1402
|
+
* 3. `emitPtsNoReceiverEdges` — Phase 8.3/8.3c pts fallback for no-receiver calls
|
|
1403
|
+
* 4. `emitPtsReceiverEdges` — Phase 8.3f pts fallback for rest-param receiver calls
|
|
1404
|
+
* 5. Inline `resolveReceiverEdge` — emit `receiver` edge for external receivers
|
|
1405
|
+
* 6. `emitChaCallEdgesForCall` — Phase 8.5 CHA + RTA dispatch expansion
|
|
1406
|
+
* 7. Sink edge for flag-only dynamic kinds (eval, computed-key, unresolved-dynamic)
|
|
1407
|
+
*/
|
|
1408
|
+
function buildFileCallEdges(
|
|
1409
|
+
relPath: string,
|
|
1410
|
+
symbols: ExtractorOutput,
|
|
1411
|
+
fileNodeRow: { id: number },
|
|
1412
|
+
importedNames: Map<string, string>,
|
|
1413
|
+
seenCallEdges: Set<string>,
|
|
1414
|
+
lookup: CallNodeLookup,
|
|
1415
|
+
allEdgeRows: EdgeRowTuple[],
|
|
1416
|
+
typeMap: Map<string, TypeMapEntry | string>,
|
|
1417
|
+
ptsMap?: PointsToMap | null,
|
|
1418
|
+
chaCtx?: ChaContext,
|
|
1419
|
+
): void {
|
|
1420
|
+
// Tracks edges that were inserted by the pts fallback (edgeKey → allEdgeRows index).
|
|
1421
|
+
// Kept separate from seenCallEdges so that a subsequent direct-call edge for the same
|
|
1422
|
+
// caller→target pair can upgrade the confidence in-place rather than being silently
|
|
1423
|
+
// dropped by the dedup guard. Once upgraded, the key moves to seenCallEdges and is
|
|
1424
|
+
// no longer tracked here.
|
|
1425
|
+
const ptsEdgeRows = new Map<string, number>();
|
|
1426
|
+
|
|
1427
|
+
// Pre-compute the set of names that appear as lhs in fnRefBindings so that
|
|
1428
|
+
// case (c) of the pts gate below only fires for names that are genuine
|
|
1429
|
+
// bind/alias entries, not for every locally-defined function or import that
|
|
1430
|
+
// buildPointsToMap seeds with a self-pointing entry.
|
|
1431
|
+
const fnRefBindingLhs = new Set(symbols.fnRefBindings?.map((b) => b.lhs) ?? []);
|
|
1432
|
+
|
|
1433
|
+
for (const call of symbols.calls) {
|
|
1434
|
+
if (call.receiver && BUILTIN_RECEIVERS.has(call.receiver)) continue;
|
|
1435
|
+
|
|
1436
|
+
const caller = findCaller(lookup, call, symbols.definitions, relPath, fileNodeRow);
|
|
1437
|
+
const isDynamic: number = call.dynamic ? 1 : 0;
|
|
1438
|
+
|
|
1439
|
+
// Step 1: Resolve targets with all JS-path fallbacks.
|
|
1440
|
+
const { targets, importedFrom } = resolveFallbackTargets(
|
|
1441
|
+
call,
|
|
1442
|
+
caller,
|
|
1443
|
+
relPath,
|
|
1444
|
+
importedNames,
|
|
1445
|
+
lookup,
|
|
1446
|
+
typeMap,
|
|
1447
|
+
symbols.definePropertyReceivers,
|
|
1448
|
+
);
|
|
1449
|
+
|
|
1450
|
+
// Step 2: Emit direct-call edges (upgrades any pending pts edge in-place).
|
|
1451
|
+
emitDirectCallEdgesForCall(
|
|
1452
|
+
caller,
|
|
1453
|
+
targets,
|
|
1454
|
+
importedFrom,
|
|
1455
|
+
isDynamic,
|
|
1456
|
+
relPath,
|
|
1457
|
+
seenCallEdges,
|
|
1458
|
+
ptsEdgeRows,
|
|
1459
|
+
allEdgeRows,
|
|
1460
|
+
);
|
|
1461
|
+
|
|
1462
|
+
// Step 3: Phase 8.3/8.3c pts fallback for unresolved no-receiver calls.
|
|
1463
|
+
if (targets.length === 0 && !call.receiver && ptsMap) {
|
|
1464
|
+
emitPtsNoReceiverEdges(
|
|
1465
|
+
call,
|
|
1466
|
+
caller,
|
|
1467
|
+
isDynamic,
|
|
1468
|
+
relPath,
|
|
1469
|
+
importedNames,
|
|
1470
|
+
lookup,
|
|
1471
|
+
typeMap,
|
|
1472
|
+
ptsMap,
|
|
1473
|
+
fnRefBindingLhs,
|
|
1474
|
+
seenCallEdges,
|
|
1475
|
+
ptsEdgeRows,
|
|
1476
|
+
allEdgeRows,
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
// Step 4: Phase 8.3f pts fallback for unresolved receiver calls (rest params).
|
|
1481
|
+
if (
|
|
1482
|
+
targets.length === 0 &&
|
|
1483
|
+
call.receiver &&
|
|
1484
|
+
!BUILTIN_RECEIVERS.has(call.receiver) &&
|
|
1485
|
+
call.receiver !== 'this' &&
|
|
1486
|
+
call.receiver !== 'self' &&
|
|
1487
|
+
call.receiver !== 'super' &&
|
|
1488
|
+
ptsMap
|
|
1489
|
+
) {
|
|
1490
|
+
emitPtsReceiverEdges(
|
|
1491
|
+
call,
|
|
1492
|
+
caller,
|
|
1493
|
+
isDynamic,
|
|
1494
|
+
relPath,
|
|
1495
|
+
importedNames,
|
|
1496
|
+
lookup,
|
|
1497
|
+
typeMap,
|
|
1498
|
+
ptsMap,
|
|
1499
|
+
seenCallEdges,
|
|
1500
|
+
ptsEdgeRows,
|
|
1501
|
+
allEdgeRows,
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
// Step 5: Emit receiver edge for external (non-this/self/super) receivers.
|
|
1506
|
+
if (
|
|
1507
|
+
call.receiver &&
|
|
1508
|
+
!BUILTIN_RECEIVERS.has(call.receiver) &&
|
|
1509
|
+
call.receiver !== 'this' &&
|
|
1510
|
+
call.receiver !== 'self' &&
|
|
1511
|
+
call.receiver !== 'super'
|
|
1512
|
+
) {
|
|
1513
|
+
const recv = resolveReceiverEdge(
|
|
1514
|
+
lookup,
|
|
1515
|
+
{ name: call.name, receiver: call.receiver },
|
|
1516
|
+
caller,
|
|
1517
|
+
relPath,
|
|
1518
|
+
typeMap as Map<string, unknown>,
|
|
1519
|
+
seenCallEdges,
|
|
1520
|
+
importedNames,
|
|
1521
|
+
);
|
|
1522
|
+
if (recv) {
|
|
1523
|
+
allEdgeRows.push([
|
|
1524
|
+
recv.callerId,
|
|
1525
|
+
recv.receiverId,
|
|
1526
|
+
'receiver',
|
|
1527
|
+
recv.confidence,
|
|
1528
|
+
0,
|
|
1529
|
+
null,
|
|
1530
|
+
null,
|
|
1531
|
+
]);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
// Step 6: Phase 8.5 CHA + RTA dispatch expansion.
|
|
1536
|
+
if (chaCtx && call.receiver) {
|
|
1537
|
+
emitChaCallEdgesForCall(
|
|
1538
|
+
call,
|
|
1539
|
+
caller,
|
|
1540
|
+
relPath,
|
|
1541
|
+
typeMap,
|
|
1542
|
+
lookup,
|
|
1543
|
+
chaCtx,
|
|
1544
|
+
seenCallEdges,
|
|
1545
|
+
ptsEdgeRows,
|
|
1546
|
+
allEdgeRows,
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
// Step 7: Flag-only dynamic kinds with no resolved target → sink edge to the
|
|
1551
|
+
// file node. confidence=0.0 keeps it below DEFAULT_MIN_CONFIDENCE so it never
|
|
1552
|
+
// appears in normal query results, but is queryable via `codegraph roles --dynamic`.
|
|
1553
|
+
if (targets.length === 0 && call.dynamicKind && FLAG_ONLY_KINDS.has(call.dynamicKind)) {
|
|
1554
|
+
// Key per (caller, file, kind) so each kind gets at most one sink edge per caller.
|
|
1555
|
+
const sinkKey = `${caller.id}:${fileNodeRow.id}:${call.dynamicKind}`;
|
|
1556
|
+
if (!seenCallEdges.has(sinkKey)) {
|
|
1557
|
+
seenCallEdges.add(sinkKey);
|
|
1558
|
+
allEdgeRows.push([caller.id, fileNodeRow.id, 'calls', 0.0, 1, null, call.dynamicKind]);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// ── Class hierarchy edges ───────────────────────────────────────────────
|
|
1565
|
+
|
|
1566
|
+
const HIERARCHY_SOURCE_KINDS = new Set(['class', 'struct', 'record', 'enum']);
|
|
1567
|
+
const EXTENDS_TARGET_KINDS = new Set(['class', 'struct', 'trait', 'record']);
|
|
1568
|
+
const IMPLEMENTS_TARGET_KINDS = new Set(['interface', 'trait', 'class']);
|
|
1569
|
+
|
|
1570
|
+
function buildClassHierarchyEdges(
|
|
1571
|
+
ctx: PipelineContext,
|
|
1572
|
+
relPath: string,
|
|
1573
|
+
symbols: ExtractorOutput,
|
|
1574
|
+
allEdgeRows: EdgeRowTuple[],
|
|
1575
|
+
): void {
|
|
1576
|
+
for (const cls of symbols.classes) {
|
|
1577
|
+
if (cls.extends) {
|
|
1578
|
+
const sourceRow = (ctx.nodesByNameAndFile.get(`${cls.name}|${relPath}`) || []).find((n) =>
|
|
1579
|
+
HIERARCHY_SOURCE_KINDS.has(n.kind),
|
|
1580
|
+
);
|
|
1581
|
+
const targetRows = (ctx.nodesByName.get(cls.extends) || []).filter((n) =>
|
|
1582
|
+
EXTENDS_TARGET_KINDS.has(n.kind),
|
|
1583
|
+
);
|
|
1584
|
+
if (sourceRow) {
|
|
1585
|
+
for (const t of targetRows) {
|
|
1586
|
+
allEdgeRows.push([sourceRow.id, t.id, 'extends', 1.0, 0, null, null]);
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
if (cls.implements) {
|
|
1592
|
+
const sourceRow = (ctx.nodesByNameAndFile.get(`${cls.name}|${relPath}`) || []).find((n) =>
|
|
1593
|
+
HIERARCHY_SOURCE_KINDS.has(n.kind),
|
|
1594
|
+
);
|
|
1595
|
+
const targetRows = (ctx.nodesByName.get(cls.implements) || []).filter((n) =>
|
|
1596
|
+
IMPLEMENTS_TARGET_KINDS.has(n.kind),
|
|
1597
|
+
);
|
|
1598
|
+
if (sourceRow) {
|
|
1599
|
+
for (const t of targetRows) {
|
|
1600
|
+
allEdgeRows.push([sourceRow.id, t.id, 'implements', 1.0, 0, null, null]);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// ── Native bulk-insert technique back-fill ──────────────────────────────
|
|
1608
|
+
|
|
1609
|
+
/**
|
|
1610
|
+
* After native bulkInsertEdges (which does not write the technique column),
|
|
1611
|
+
* apply technique values from the in-memory row array back to the DB, and lift
|
|
1612
|
+
* any resolved ts-native edge below TS_NATIVE_CONFIDENCE_FLOOR to that floor.
|
|
1613
|
+
*
|
|
1614
|
+
* Rows with an explicit technique get a targeted UPDATE by (source_id, target_id).
|
|
1615
|
+
* The catch-all 'ts-native' tag is scoped to only the source_ids present in this
|
|
1616
|
+
* batch — this prevents mis-tagging pre-migration NULL-technique edges from
|
|
1617
|
+
* unchanged files that were never purged and re-inserted.
|
|
1618
|
+
*/
|
|
1619
|
+
function applyEdgeTechniquesAfterNativeInsert(
|
|
1620
|
+
db: BetterSqlite3Database,
|
|
1621
|
+
rows: EdgeRowTuple[],
|
|
1622
|
+
): void {
|
|
1623
|
+
const callRows = rows.filter((r) => r[2] === 'calls');
|
|
1624
|
+
if (callRows.length === 0) return;
|
|
1625
|
+
|
|
1626
|
+
const taggedRows = callRows.filter((r) => r[5] != null);
|
|
1627
|
+
// Collect distinct source IDs for this batch so the catch-all UPDATE is scoped
|
|
1628
|
+
// to edges inserted in the current run, not the entire table.
|
|
1629
|
+
const sourceIds = [...new Set(callRows.map((r) => r[0]))];
|
|
1630
|
+
// Chunk to stay within SQLite's SQLITE_LIMIT_VARIABLE_NUMBER (999 on older builds).
|
|
1631
|
+
const CHUNK_SIZE = 500;
|
|
1632
|
+
|
|
1633
|
+
// Rows that carry an explicit dynamic_kind (sink edges for flagged dynamic calls).
|
|
1634
|
+
const dynamicKindRows = callRows.filter((r) => r[6] != null);
|
|
1635
|
+
|
|
1636
|
+
const tx = db.transaction(() => {
|
|
1637
|
+
if (taggedRows.length > 0) {
|
|
1638
|
+
const stmt = db.prepare(
|
|
1639
|
+
"UPDATE edges SET technique = ? WHERE kind = 'calls' AND source_id = ? AND target_id = ? AND technique IS NULL",
|
|
1640
|
+
);
|
|
1641
|
+
for (const r of taggedRows) stmt.run(r[5], r[0], r[1]);
|
|
1642
|
+
}
|
|
1643
|
+
for (let i = 0; i < sourceIds.length; i += CHUNK_SIZE) {
|
|
1644
|
+
const chunk = sourceIds.slice(i, i + CHUNK_SIZE);
|
|
1645
|
+
const placeholders = chunk.map(() => '?').join(',');
|
|
1646
|
+
db.prepare(
|
|
1647
|
+
`UPDATE edges SET technique = 'ts-native' WHERE kind = 'calls' AND technique IS NULL AND source_id IN (${placeholders})`,
|
|
1648
|
+
).run(...chunk);
|
|
1649
|
+
// Lift resolved ts-native edges below the confidence floor for this chunk.
|
|
1650
|
+
db.prepare(
|
|
1651
|
+
`UPDATE edges SET confidence = ?
|
|
1652
|
+
WHERE kind = 'calls' AND technique = 'ts-native'
|
|
1653
|
+
AND confidence > 0 AND confidence < ?
|
|
1654
|
+
AND source_id IN (${placeholders})`,
|
|
1655
|
+
).run(TS_NATIVE_CONFIDENCE_FLOOR, TS_NATIVE_CONFIDENCE_FLOOR, ...chunk);
|
|
1656
|
+
}
|
|
1657
|
+
// Back-fill dynamic_kind for flagged sink edges emitted by the native engine.
|
|
1658
|
+
// Native bulkInsertEdges uses INSERT OR IGNORE and does not write dynamic_kind, so
|
|
1659
|
+
// this UPDATE is the only way to set it for natively-inserted sink edges.
|
|
1660
|
+
//
|
|
1661
|
+
// Scope to confidence=0.0 AND dynamic=1 so we only touch sink edges (never normal
|
|
1662
|
+
// call edges that happen to share the same (source_id, target_id) pair).
|
|
1663
|
+
// Include dynamic_kind in the WHERE so two sink edges from the same caller to the
|
|
1664
|
+
// same file with different kinds don't clobber each other across incremental runs.
|
|
1665
|
+
if (dynamicKindRows.length > 0) {
|
|
1666
|
+
const stmt = db.prepare(
|
|
1667
|
+
"UPDATE edges SET dynamic_kind = ? WHERE kind = 'calls' AND source_id = ? AND target_id = ? AND confidence = 0.0 AND dynamic = 1 AND (dynamic_kind IS NULL OR dynamic_kind = ?)",
|
|
1668
|
+
);
|
|
1669
|
+
for (const r of dynamicKindRows) stmt.run(r[6], r[0], r[1], r[6]);
|
|
1670
|
+
}
|
|
1671
|
+
});
|
|
1672
|
+
tx();
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
// ── Reverse-dep edge reconnection (#932, #933) ─────────────────────────
|
|
1676
|
+
|
|
1677
|
+
/**
|
|
1678
|
+
* Reconnect edges that were saved before changed-file purge.
|
|
1679
|
+
*
|
|
1680
|
+
* Each saved edge records: sourceId (still valid — reverse-dep nodes were not
|
|
1681
|
+
* purged) and target attributes (name, kind, file, line). The target node was
|
|
1682
|
+
* deleted and re-inserted with a new ID by insertNodes. We look up the new ID
|
|
1683
|
+
* by (name, kind, file) and re-create the edge.
|
|
1684
|
+
*/
|
|
1685
|
+
function reconnectReverseDepEdges(ctx: PipelineContext): void {
|
|
1686
|
+
const { db } = ctx;
|
|
1687
|
+
const findNodeStmt = db.prepare(
|
|
1688
|
+
'SELECT id FROM nodes WHERE name = ? AND kind = ? AND file = ? ORDER BY ABS(line - ?) LIMIT 1',
|
|
1689
|
+
);
|
|
1690
|
+
const reconnectedRows: EdgeRowTuple[] = [];
|
|
1691
|
+
let dropped = 0;
|
|
1692
|
+
|
|
1693
|
+
for (const saved of ctx.savedReverseDepEdges) {
|
|
1694
|
+
const newTarget = findNodeStmt.get(
|
|
1695
|
+
saved.tgtName,
|
|
1696
|
+
saved.tgtKind,
|
|
1697
|
+
saved.tgtFile,
|
|
1698
|
+
saved.tgtLine,
|
|
1699
|
+
) as { id: number } | undefined;
|
|
1700
|
+
if (newTarget) {
|
|
1701
|
+
reconnectedRows.push([
|
|
1702
|
+
saved.sourceId,
|
|
1703
|
+
newTarget.id,
|
|
1704
|
+
saved.edgeKind,
|
|
1705
|
+
saved.confidence,
|
|
1706
|
+
saved.dynamic,
|
|
1707
|
+
saved.technique,
|
|
1708
|
+
saved.dynamicKind ?? null,
|
|
1709
|
+
]);
|
|
1710
|
+
} else {
|
|
1711
|
+
// Target was removed or renamed in the changed file — edge is stale
|
|
1712
|
+
dropped++;
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
if (reconnectedRows.length > 0) {
|
|
1717
|
+
if (ctx.nativeDb?.bulkInsertEdges) {
|
|
1718
|
+
const nativeEdges = reconnectedRows.map((r) => ({
|
|
1719
|
+
sourceId: r[0],
|
|
1720
|
+
targetId: r[1],
|
|
1721
|
+
kind: r[2],
|
|
1722
|
+
confidence: r[3],
|
|
1723
|
+
dynamic: r[4],
|
|
1724
|
+
}));
|
|
1725
|
+
const ok = ctx.nativeDb.bulkInsertEdges(nativeEdges);
|
|
1726
|
+
if (!ok) {
|
|
1727
|
+
batchInsertEdges(db, reconnectedRows);
|
|
1728
|
+
} else {
|
|
1729
|
+
applyEdgeTechniquesAfterNativeInsert(db, reconnectedRows);
|
|
1730
|
+
}
|
|
1731
|
+
} else {
|
|
1732
|
+
batchInsertEdges(db, reconnectedRows);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
debug(
|
|
1737
|
+
`Reconnected ${reconnectedRows.length} reverse-dep edges` +
|
|
1738
|
+
(dropped > 0 ? ` (${dropped} dropped — targets removed/renamed)` : ''),
|
|
1739
|
+
);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// ── Main entry point ────────────────────────────────────────────────────
|
|
1743
|
+
|
|
1744
|
+
/**
|
|
1745
|
+
* For small incremental builds (≤5 changed files on a large codebase), scope
|
|
1746
|
+
* the node loading query to only files that are relevant: changed files +
|
|
1747
|
+
* their import targets. Falls back to loading ALL nodes for full builds or
|
|
1748
|
+
* larger incremental changes.
|
|
1749
|
+
*/
|
|
1750
|
+
const NODE_KIND_FILTER_SQL = `kind IN ('function','method','class','interface','struct','type','module','enum','trait','record','constant','variable')`;
|
|
1751
|
+
|
|
1752
|
+
function loadNodes(ctx: PipelineContext): { rows: QueryNodeRow[]; scoped: boolean } {
|
|
1753
|
+
const { db, fileSymbols, isFullBuild, batchResolved } = ctx;
|
|
1754
|
+
const nodeKindFilter = NODE_KIND_FILTER_SQL;
|
|
1755
|
+
|
|
1756
|
+
// Gate: only scope for small incremental on large codebases
|
|
1757
|
+
if (!isFullBuild && fileSymbols.size <= ctx.config.build.smallFilesThreshold) {
|
|
1758
|
+
const existingFileCount = (
|
|
1759
|
+
db.prepare("SELECT COUNT(*) as c FROM nodes WHERE kind = 'file'").get() as { c: number }
|
|
1760
|
+
).c;
|
|
1761
|
+
if (existingFileCount > 20) {
|
|
1762
|
+
// Collect relevant files: changed files + their import targets
|
|
1763
|
+
const relevantFiles = new Set<string>(fileSymbols.keys());
|
|
1764
|
+
if (batchResolved) {
|
|
1765
|
+
for (const resolvedPath of batchResolved.values()) {
|
|
1766
|
+
relevantFiles.add(resolvedPath);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
// Also add barrel-only files
|
|
1770
|
+
for (const barrelPath of ctx.barrelOnlyFiles) {
|
|
1771
|
+
relevantFiles.add(barrelPath);
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
const placeholders = [...relevantFiles].map(() => '?').join(',');
|
|
1775
|
+
const rows = db
|
|
1776
|
+
.prepare(
|
|
1777
|
+
`SELECT id, name, kind, file, line FROM nodes WHERE ${nodeKindFilter} AND file IN (${placeholders})`,
|
|
1778
|
+
)
|
|
1779
|
+
.all(...relevantFiles) as QueryNodeRow[];
|
|
1780
|
+
return { rows, scoped: true };
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
const rows = db
|
|
1785
|
+
.prepare(`SELECT id, name, kind, file, line FROM nodes WHERE ${nodeKindFilter}`)
|
|
1786
|
+
.all() as QueryNodeRow[];
|
|
1787
|
+
return { rows, scoped: false };
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
/**
|
|
1791
|
+
* For scoped node loading, patch nodesByName.get with a lazy SQL fallback
|
|
1792
|
+
* so global name-only lookups (resolveByMethodOrGlobal)
|
|
1793
|
+
* can still find nodes outside the scoped set.
|
|
1794
|
+
*/
|
|
1795
|
+
function addLazyFallback(ctx: PipelineContext, scopedLoad: boolean): void {
|
|
1796
|
+
if (!scopedLoad) return;
|
|
1797
|
+
const { db } = ctx;
|
|
1798
|
+
// Match the upfront kind filter exactly. Using `kind != 'file'` here lets
|
|
1799
|
+
// parameters, properties, and other non-definition kinds leak into call
|
|
1800
|
+
// resolution, producing bogus call edges like `parser.ts → <a parameter
|
|
1801
|
+
// with the same name>` (#1174 follow-up). Calls only ever target the
|
|
1802
|
+
// definition kinds, so the fallback's filter must agree with `loadNodes`.
|
|
1803
|
+
const fallbackStmt = db.prepare(
|
|
1804
|
+
`SELECT id, name, kind, file, line FROM nodes WHERE name = ? AND ${NODE_KIND_FILTER_SQL}`,
|
|
1805
|
+
);
|
|
1806
|
+
const originalGet = ctx.nodesByName.get.bind(ctx.nodesByName);
|
|
1807
|
+
ctx.nodesByName.get = (name: string) => {
|
|
1808
|
+
const result = originalGet(name);
|
|
1809
|
+
if (result !== undefined) return result;
|
|
1810
|
+
const rows = fallbackStmt.all(name) as unknown as NodeRow[];
|
|
1811
|
+
if (rows.length > 0) {
|
|
1812
|
+
ctx.nodesByName.set(name, rows);
|
|
1813
|
+
return rows;
|
|
1814
|
+
}
|
|
1815
|
+
return undefined;
|
|
1816
|
+
};
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
export async function buildEdges(ctx: PipelineContext): Promise<void> {
|
|
1820
|
+
const { db, engineName } = ctx;
|
|
1821
|
+
|
|
1822
|
+
const getNodeIdStmt = makeGetNodeIdStmt(db);
|
|
1823
|
+
|
|
1824
|
+
const { rows: allNodesBefore, scoped: scopedLoad } = loadNodes(ctx);
|
|
1825
|
+
setupNodeLookups(ctx, allNodesBefore);
|
|
1826
|
+
addLazyFallback(ctx, scopedLoad);
|
|
1827
|
+
|
|
1828
|
+
const t0 = performance.now();
|
|
1829
|
+
|
|
1830
|
+
// Enrich typeMap for .ts/.tsx files using the TypeScript compiler API.
|
|
1831
|
+
// Runs before call-edge construction so the accurate types are available
|
|
1832
|
+
// for method-call resolution. Gated on config so users can opt out.
|
|
1833
|
+
//
|
|
1834
|
+
// Skip for small incremental builds: TypeScript program creation requires
|
|
1835
|
+
// loading the entire tsconfig file list (~700ms startup on the codegraph
|
|
1836
|
+
// corpus), which dominates the 1-file rebuild time. Native engine bypasses
|
|
1837
|
+
// this entirely via the Rust orchestrator; WASM/JS engines need this gate
|
|
1838
|
+
// to match native's effective behaviour on tiny incremental changes.
|
|
1839
|
+
// Mirrors the smallFilesThreshold gates for nativeDb and native call-edges.
|
|
1840
|
+
const isSmallIncremental =
|
|
1841
|
+
!ctx.isFullBuild && ctx.fileSymbols.size <= ctx.config.build.smallFilesThreshold;
|
|
1842
|
+
if (ctx.config.build.typescriptResolver && !isSmallIncremental) {
|
|
1843
|
+
await enrichTypeMapWithTsc(ctx.rootDir, ctx.fileSymbols);
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
const native = engineName === 'native' ? loadNative() : null;
|
|
1847
|
+
|
|
1848
|
+
// Phase 8.2: Augment typeMaps with cross-file return-type propagation before
|
|
1849
|
+
// the transaction opens. This is pure in-memory mutation (no DB I/O) and must
|
|
1850
|
+
// run outside the transaction to avoid leaving ctx.fileSymbols in a partial
|
|
1851
|
+
// state if the transaction rolls back unexpectedly.
|
|
1852
|
+
propagateReturnTypesAcrossFiles(ctx.fileSymbols, ctx, ctx.rootDir);
|
|
1853
|
+
// Phase 8.5: Build CHA context after propagation so typeMap confidence values
|
|
1854
|
+
// (used for RTA seeding) reflect any cross-file propagated types.
|
|
1855
|
+
const chaCtx = buildChaContext(ctx.fileSymbols);
|
|
1856
|
+
|
|
1857
|
+
// Phase 1: Compute edges inside a better-sqlite3 transaction.
|
|
1858
|
+
// Barrel-edge deletion lives here so that the JS path (which also inserts
|
|
1859
|
+
// edges in this transaction) keeps deletion + insertion atomic.
|
|
1860
|
+
// When using the native rusqlite path, insertion happens in Phase 2 on a
|
|
1861
|
+
// separate connection — a crash between Phase 1 and Phase 2 would leave
|
|
1862
|
+
// barrel edges missing until the next incremental rebuild re-creates them.
|
|
1863
|
+
const allEdgeRows: EdgeRowTuple[] = [];
|
|
1864
|
+
const computeEdgesTx = db.transaction(() => {
|
|
1865
|
+
if (ctx.barrelOnlyFiles.size > 0) {
|
|
1866
|
+
const deleteOutgoingEdges = db.prepare(
|
|
1867
|
+
'DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?)',
|
|
1868
|
+
);
|
|
1869
|
+
for (const relPath of ctx.barrelOnlyFiles) {
|
|
1870
|
+
deleteOutgoingEdges.run(relPath);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
// Skip native import-edge path for small incremental builds: napi-rs
|
|
1875
|
+
// marshaling overhead (~13ms) exceeds Rust computation savings at this scale.
|
|
1876
|
+
const useNativeImportEdges =
|
|
1877
|
+
native?.buildImportEdges &&
|
|
1878
|
+
(ctx.isFullBuild || ctx.fileSymbols.size > ctx.config.build.smallFilesThreshold);
|
|
1879
|
+
if (useNativeImportEdges) {
|
|
1880
|
+
const beforeLen = allEdgeRows.length;
|
|
1881
|
+
buildImportEdgesNative(ctx, getNodeIdStmt, allEdgeRows, native!);
|
|
1882
|
+
// Fallback: if native produced 0 import edges but there are imports to
|
|
1883
|
+
// process, the native binary may have a key-format mismatch (e.g. Windows
|
|
1884
|
+
// path separators — #750). Retry with the JS implementation.
|
|
1885
|
+
// NOTE: This also fires for codebases where every import targets an
|
|
1886
|
+
// external package (npm deps) that the resolver intentionally skips.
|
|
1887
|
+
// In that case the JS path resolves zero edges too, so the only cost
|
|
1888
|
+
// is the redundant JS traversal — no correctness impact.
|
|
1889
|
+
const hasImports = [...ctx.fileSymbols.values()].some((s) => s.imports.length > 0);
|
|
1890
|
+
if (allEdgeRows.length === beforeLen && hasImports) {
|
|
1891
|
+
debug('Native buildImportEdges produced 0 edges — falling back to JS');
|
|
1892
|
+
buildImportEdges(ctx, getNodeIdStmt, allEdgeRows);
|
|
1893
|
+
}
|
|
1894
|
+
} else {
|
|
1895
|
+
buildImportEdges(ctx, getNodeIdStmt, allEdgeRows);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
// Skip native call-edge path for small incremental builds: napi-rs
|
|
1899
|
+
// marshaling overhead for allNodes exceeds Rust computation savings.
|
|
1900
|
+
const useNativeCallEdges =
|
|
1901
|
+
native?.buildCallEdges &&
|
|
1902
|
+
(ctx.isFullBuild || ctx.fileSymbols.size > ctx.config.build.smallFilesThreshold);
|
|
1903
|
+
if (useNativeCallEdges) {
|
|
1904
|
+
buildCallEdgesNative(ctx, getNodeIdStmt, allEdgeRows, allNodesBefore, native!);
|
|
1905
|
+
// The native engine receives all pts bindings (paramBindings,
|
|
1906
|
+
// fnRefBindings, thisCallBindings, objectRestParamBindings, …) through
|
|
1907
|
+
// NativeFileEntry and runs the same points-to solver as the JS path, so
|
|
1908
|
+
// no pts post-passes are needed here. Only capabilities that remain
|
|
1909
|
+
// JS-only run as post-passes below.
|
|
1910
|
+
const sharedLookup = makeContextLookup(ctx, getNodeIdStmt);
|
|
1911
|
+
// Object.defineProperty accessor post-pass: resolve this-dispatch inside
|
|
1912
|
+
// getter/setter functions registered via Object.defineProperty.
|
|
1913
|
+
buildDefinePropertyPostPass(ctx, getNodeIdStmt, allEdgeRows, sharedLookup);
|
|
1914
|
+
// Phase 8.5 post-pass: augment native call edges with CHA-resolved dispatch.
|
|
1915
|
+
// The native Rust engine has no knowledge of the CHA context, so this/self
|
|
1916
|
+
// calls and interface dispatch are not expanded to concrete implementations.
|
|
1917
|
+
buildChaPostPass(ctx, getNodeIdStmt, allEdgeRows, chaCtx);
|
|
1918
|
+
} else {
|
|
1919
|
+
buildCallEdgesJS(ctx, getNodeIdStmt, allEdgeRows, chaCtx);
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
// Apply ts-native confidence floor to allEdgeRows in-memory. The proximity
|
|
1923
|
+
// heuristic returns 0.3 for cross-module calls with no import-path evidence,
|
|
1924
|
+
// but both WASM and native engines perform actual name-based symbol lookup,
|
|
1925
|
+
// which is stronger evidence than pure proximity. Clamping to
|
|
1926
|
+
// TS_NATIVE_CONFIDENCE_FLOOR (0.5) avoids unfairly dragging down the
|
|
1927
|
+
// call-confidence metric. Sink edges (confidence = 0.0) are excluded so
|
|
1928
|
+
// they remain below DEFAULT_MIN_CONFIDENCE.
|
|
1929
|
+
for (const r of allEdgeRows) {
|
|
1930
|
+
if (
|
|
1931
|
+
r[2] === 'calls' &&
|
|
1932
|
+
r[5] === 'ts-native' &&
|
|
1933
|
+
(r[3] as number) > 0 &&
|
|
1934
|
+
(r[3] as number) < TS_NATIVE_CONFIDENCE_FLOOR
|
|
1935
|
+
) {
|
|
1936
|
+
r[3] = TS_NATIVE_CONFIDENCE_FLOOR;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
// When using native edge insert, skip JS insert here — do it after tx commits.
|
|
1941
|
+
// Otherwise insert edges within this transaction for atomicity.
|
|
1942
|
+
const useNativeEdgeInsert = ctx.engineName === 'native' && !!ctx.nativeDb?.bulkInsertEdges;
|
|
1943
|
+
if (!useNativeEdgeInsert) {
|
|
1944
|
+
batchInsertEdges(db, allEdgeRows);
|
|
1945
|
+
}
|
|
1946
|
+
});
|
|
1947
|
+
computeEdgesTx();
|
|
1948
|
+
|
|
1949
|
+
// Phase 2: Native rusqlite bulk insert (outside better-sqlite3 transaction
|
|
1950
|
+
// to avoid SQLITE_BUSY contention). Uses NativeDatabase persistent connection.
|
|
1951
|
+
// Standalone napi functions were removed in 6.17.
|
|
1952
|
+
if (ctx.engineName === 'native' && ctx.nativeDb?.bulkInsertEdges && allEdgeRows.length > 0) {
|
|
1953
|
+
const nativeEdges = allEdgeRows.map((r) => ({
|
|
1954
|
+
sourceId: r[0],
|
|
1955
|
+
targetId: r[1],
|
|
1956
|
+
kind: r[2],
|
|
1957
|
+
confidence: r[3],
|
|
1958
|
+
dynamic: r[4],
|
|
1959
|
+
}));
|
|
1960
|
+
const ok = ctx.nativeDb.bulkInsertEdges(nativeEdges);
|
|
1961
|
+
if (!ok) {
|
|
1962
|
+
debug('Native bulkInsertEdges failed — falling back to JS batchInsertEdges');
|
|
1963
|
+
batchInsertEdges(ctx.db, allEdgeRows);
|
|
1964
|
+
} else {
|
|
1965
|
+
applyEdgeTechniquesAfterNativeInsert(ctx.db, allEdgeRows);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
// Phase 3: Reconnect saved reverse-dep edges (#932, #933).
|
|
1970
|
+
// When the WASM/JS path purged changed files, edges FROM reverse-dep files TO
|
|
1971
|
+
// those files were deleted (target-side). The reverse-dep files were NOT
|
|
1972
|
+
// reparsed — instead we saved the edge topology before purge and now reconnect
|
|
1973
|
+
// each edge to the new node IDs created by insertNodes.
|
|
1974
|
+
if (ctx.savedReverseDepEdges.length > 0) {
|
|
1975
|
+
reconnectReverseDepEdges(ctx);
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
// Phase 4: CHA post-pass — expand virtual-dispatch edges for class hierarchies
|
|
1979
|
+
// and interface implementations. Runs after all call + hierarchy edges are
|
|
1980
|
+
// committed so the DB is consistent.
|
|
1981
|
+
// Note: the native orchestrator success path runs this independently in
|
|
1982
|
+
// tryNativeOrchestrator; this phase covers the WASM and native-fallback paths.
|
|
1983
|
+
runChaPostPass(db);
|
|
1984
|
+
|
|
1985
|
+
ctx.timing.edgesMs = performance.now() - t0;
|
|
1986
|
+
}
|