@optave/codegraph 3.12.0 → 3.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -46
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +38 -40
- package/dist/ast-analysis/engine.js.map +1 -1
- 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/index.d.ts.map +1 -1
- package/dist/ast-analysis/rules/index.js +34 -0
- package/dist/ast-analysis/rules/index.js.map +1 -1
- package/dist/ast-analysis/rules/javascript.d.ts.map +1 -1
- package/dist/ast-analysis/rules/javascript.js +3 -0
- package/dist/ast-analysis/rules/javascript.js.map +1 -1
- package/dist/ast-analysis/shared.d.ts.map +1 -1
- package/dist/ast-analysis/shared.js +2 -0
- package/dist/ast-analysis/shared.js.map +1 -1
- package/dist/ast-analysis/visitor-utils.d.ts +1 -0
- package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
- package/dist/ast-analysis/visitor-utils.js +5 -0
- package/dist/ast-analysis/visitor-utils.js.map +1 -1
- package/dist/ast-analysis/visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitor.js +60 -47
- package/dist/ast-analysis/visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/cfg-visitor.js +126 -76
- package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js +27 -15
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.js +54 -21
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +2 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/batch.d.ts.map +1 -1
- package/dist/cli/commands/batch.js +1 -0
- package/dist/cli/commands/batch.js.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +6 -1
- package/dist/cli/commands/build.js.map +1 -1
- 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/roles.d.ts.map +1 -1
- package/dist/cli/commands/roles.js +6 -1
- package/dist/cli/commands/roles.js.map +1 -1
- package/dist/cli/commands/triage.js +1 -1
- package/dist/cli/commands/triage.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/shared/options.d.ts +2 -1
- package/dist/cli/shared/options.d.ts.map +1 -1
- package/dist/cli/shared/options.js +11 -1
- package/dist/cli/shared/options.js.map +1 -1
- package/dist/cli/types.d.ts +2 -0
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/db/better-sqlite3.d.ts +2 -1
- package/dist/db/better-sqlite3.d.ts.map +1 -1
- package/dist/db/better-sqlite3.js.map +1 -1
- package/dist/db/connection.d.ts +7 -1
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +20 -5
- package/dist/db/connection.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +69 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/repository/build-stmts.d.ts.map +1 -1
- package/dist/db/repository/build-stmts.js +18 -0
- package/dist/db/repository/build-stmts.js.map +1 -1
- package/dist/db/repository/dataflow.d.ts +5 -0
- package/dist/db/repository/dataflow.d.ts.map +1 -1
- package/dist/db/repository/dataflow.js +14 -0
- package/dist/db/repository/dataflow.js.map +1 -1
- package/dist/db/repository/index.d.ts +1 -1
- package/dist/db/repository/index.d.ts.map +1 -1
- package/dist/db/repository/index.js +1 -1
- package/dist/db/repository/index.js.map +1 -1
- package/dist/db/repository/native-repository.d.ts.map +1 -1
- package/dist/db/repository/native-repository.js +47 -34
- package/dist/db/repository/native-repository.js.map +1 -1
- package/dist/domain/analysis/context.d.ts +2 -2
- package/dist/domain/analysis/dependencies.d.ts +2 -2
- package/dist/domain/analysis/diff-impact.d.ts +2 -2
- package/dist/domain/analysis/fn-impact.d.ts +3 -1
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
- package/dist/domain/analysis/fn-impact.js +4 -0
- package/dist/domain/analysis/fn-impact.js.map +1 -1
- package/dist/domain/analysis/implementations.d.ts +2 -2
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +32 -5
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/analysis/roles.d.ts +7 -1
- package/dist/domain/analysis/roles.d.ts.map +1 -1
- package/dist/domain/analysis/roles.js +16 -0
- package/dist/domain/analysis/roles.js.map +1 -1
- package/dist/domain/analysis/symbol-lookup.d.ts +4 -4
- package/dist/domain/graph/builder/call-resolver.d.ts +29 -13
- package/dist/domain/graph/builder/call-resolver.d.ts.map +1 -1
- package/dist/domain/graph/builder/call-resolver.js +125 -205
- package/dist/domain/graph/builder/call-resolver.js.map +1 -1
- package/dist/domain/graph/builder/cha.d.ts +9 -1
- package/dist/domain/graph/builder/cha.d.ts.map +1 -1
- package/dist/domain/graph/builder/cha.js +17 -2
- package/dist/domain/graph/builder/cha.js.map +1 -1
- package/dist/domain/graph/builder/context.d.ts +1 -0
- package/dist/domain/graph/builder/context.d.ts.map +1 -1
- package/dist/domain/graph/builder/context.js.map +1 -1
- package/dist/domain/graph/builder/helpers.d.ts +24 -1
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
- package/dist/domain/graph/builder/helpers.js +174 -65
- package/dist/domain/graph/builder/helpers.js.map +1 -1
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
- package/dist/domain/graph/builder/incremental.js +166 -97
- package/dist/domain/graph/builder/incremental.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +46 -5
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.d.ts +0 -2
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.js +554 -538
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.js +10 -7
- package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +3 -2
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +4 -0
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/builder/stages/native-orchestrator.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/native-orchestrator.js +952 -343
- package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/resolver/points-to.d.ts.map +1 -1
- package/dist/domain/graph/resolver/points-to.js +105 -57
- package/dist/domain/graph/resolver/points-to.js.map +1 -1
- 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/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +16 -9
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +16 -5
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +58 -17
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/queries.d.ts +1 -1
- package/dist/domain/queries.d.ts.map +1 -1
- package/dist/domain/queries.js +1 -1
- package/dist/domain/queries.js.map +1 -1
- package/dist/domain/wasm-worker-entry.js +13 -2
- package/dist/domain/wasm-worker-entry.js.map +1 -1
- package/dist/domain/wasm-worker-pool.d.ts.map +1 -1
- package/dist/domain/wasm-worker-pool.js +26 -5
- package/dist/domain/wasm-worker-pool.js.map +1 -1
- package/dist/domain/wasm-worker-protocol.d.ts +8 -0
- package/dist/domain/wasm-worker-protocol.d.ts.map +1 -1
- package/dist/extractors/cpp.d.ts.map +1 -1
- package/dist/extractors/cpp.js +42 -1
- package/dist/extractors/cpp.js.map +1 -1
- package/dist/extractors/cuda.d.ts.map +1 -1
- package/dist/extractors/cuda.js +42 -1
- package/dist/extractors/cuda.js.map +1 -1
- package/dist/extractors/dart.js +48 -3
- package/dist/extractors/dart.js.map +1 -1
- package/dist/extractors/groovy.js +62 -3
- package/dist/extractors/groovy.js.map +1 -1
- package/dist/extractors/helpers.d.ts +15 -2
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +45 -1
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/java.d.ts.map +1 -1
- package/dist/extractors/java.js +85 -8
- package/dist/extractors/java.js.map +1 -1
- package/dist/extractors/javascript.d.ts.map +1 -1
- package/dist/extractors/javascript.js +686 -169
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/kotlin.js +58 -3
- package/dist/extractors/kotlin.js.map +1 -1
- package/dist/extractors/objc.js +25 -2
- package/dist/extractors/objc.js.map +1 -1
- package/dist/extractors/scala.js +62 -2
- package/dist/extractors/scala.js.map +1 -1
- package/dist/extractors/swift.js +52 -3
- package/dist/extractors/swift.js.map +1 -1
- package/dist/features/audit.js +26 -23
- package/dist/features/audit.js.map +1 -1
- package/dist/features/boundaries.d.ts.map +1 -1
- package/dist/features/boundaries.js +12 -9
- package/dist/features/boundaries.js.map +1 -1
- package/dist/features/cfg.d.ts.map +1 -1
- package/dist/features/cfg.js +25 -18
- package/dist/features/cfg.js.map +1 -1
- package/dist/features/check.d.ts.map +1 -1
- package/dist/features/check.js +18 -5
- package/dist/features/check.js.map +1 -1
- package/dist/features/communities.d.ts +4 -2
- package/dist/features/communities.d.ts.map +1 -1
- package/dist/features/communities.js +6 -4
- package/dist/features/communities.js.map +1 -1
- package/dist/features/dataflow.d.ts +60 -0
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +530 -6
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/manifesto.d.ts.map +1 -1
- package/dist/features/manifesto.js +59 -72
- package/dist/features/manifesto.js.map +1 -1
- package/dist/features/sequence.d.ts.map +1 -1
- package/dist/features/sequence.js +27 -22
- package/dist/features/sequence.js.map +1 -1
- package/dist/features/snapshot.d.ts.map +1 -1
- package/dist/features/snapshot.js +36 -28
- package/dist/features/snapshot.js.map +1 -1
- package/dist/features/structure-query.d.ts +1 -1
- package/dist/features/structure-query.d.ts.map +1 -1
- package/dist/features/structure-query.js +6 -6
- package/dist/features/structure-query.js.map +1 -1
- package/dist/features/structure.d.ts.map +1 -1
- package/dist/features/structure.js +150 -62
- package/dist/features/structure.js.map +1 -1
- package/dist/features/triage.d.ts.map +1 -1
- package/dist/features/triage.js +18 -11
- package/dist/features/triage.js.map +1 -1
- package/dist/graph/algorithms/bfs.d.ts +1 -1
- package/dist/graph/algorithms/bfs.d.ts.map +1 -1
- package/dist/graph/algorithms/bfs.js +14 -13
- package/dist/graph/algorithms/bfs.js.map +1 -1
- package/dist/graph/algorithms/tarjan.d.ts.map +1 -1
- package/dist/graph/algorithms/tarjan.js +5 -0
- package/dist/graph/algorithms/tarjan.js.map +1 -1
- package/dist/graph/builders/dependency.js +28 -22
- package/dist/graph/builders/dependency.js.map +1 -1
- package/dist/graph/classifiers/roles.d.ts +10 -1
- package/dist/graph/classifiers/roles.d.ts.map +1 -1
- package/dist/graph/classifiers/roles.js +60 -6
- package/dist/graph/classifiers/roles.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/config.d.ts +87 -4
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +424 -22
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/registry.d.ts +27 -7
- package/dist/infrastructure/registry.d.ts.map +1 -1
- package/dist/infrastructure/registry.js +79 -5
- package/dist/infrastructure/registry.js.map +1 -1
- package/dist/infrastructure/update-check.d.ts.map +1 -1
- package/dist/infrastructure/update-check.js +49 -31
- package/dist/infrastructure/update-check.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -10
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/ast-query.d.ts +1 -1
- package/dist/mcp/tools/ast-query.d.ts.map +1 -1
- package/dist/mcp/tools/audit.d.ts +1 -1
- package/dist/mcp/tools/audit.d.ts.map +1 -1
- package/dist/mcp/tools/batch-query.d.ts +1 -1
- package/dist/mcp/tools/batch-query.d.ts.map +1 -1
- package/dist/mcp/tools/branch-compare.d.ts +1 -1
- package/dist/mcp/tools/branch-compare.d.ts.map +1 -1
- package/dist/mcp/tools/brief.d.ts +1 -1
- package/dist/mcp/tools/brief.d.ts.map +1 -1
- package/dist/mcp/tools/cfg.d.ts +1 -1
- package/dist/mcp/tools/cfg.d.ts.map +1 -1
- package/dist/mcp/tools/check.d.ts +1 -1
- package/dist/mcp/tools/check.d.ts.map +1 -1
- package/dist/mcp/tools/co-changes.d.ts +1 -1
- package/dist/mcp/tools/co-changes.d.ts.map +1 -1
- package/dist/mcp/tools/code-owners.d.ts +1 -1
- package/dist/mcp/tools/code-owners.d.ts.map +1 -1
- package/dist/mcp/tools/communities.d.ts +1 -1
- package/dist/mcp/tools/communities.d.ts.map +1 -1
- package/dist/mcp/tools/complexity.d.ts +1 -1
- package/dist/mcp/tools/complexity.d.ts.map +1 -1
- package/dist/mcp/tools/context.d.ts +1 -1
- package/dist/mcp/tools/context.d.ts.map +1 -1
- package/dist/mcp/tools/dataflow.d.ts +1 -1
- package/dist/mcp/tools/dataflow.d.ts.map +1 -1
- package/dist/mcp/tools/diff-impact.d.ts +1 -1
- package/dist/mcp/tools/diff-impact.d.ts.map +1 -1
- package/dist/mcp/tools/execution-flow.d.ts +1 -1
- package/dist/mcp/tools/execution-flow.d.ts.map +1 -1
- package/dist/mcp/tools/export-graph.d.ts +1 -1
- package/dist/mcp/tools/export-graph.d.ts.map +1 -1
- package/dist/mcp/tools/file-deps.d.ts +1 -1
- package/dist/mcp/tools/file-deps.d.ts.map +1 -1
- package/dist/mcp/tools/file-exports.d.ts +1 -1
- package/dist/mcp/tools/file-exports.d.ts.map +1 -1
- package/dist/mcp/tools/find-cycles.d.ts +1 -1
- package/dist/mcp/tools/find-cycles.d.ts.map +1 -1
- package/dist/mcp/tools/fn-impact.d.ts +1 -1
- package/dist/mcp/tools/fn-impact.d.ts.map +1 -1
- package/dist/mcp/tools/impact-analysis.d.ts +1 -1
- package/dist/mcp/tools/impact-analysis.d.ts.map +1 -1
- package/dist/mcp/tools/implementations.d.ts +1 -1
- package/dist/mcp/tools/implementations.d.ts.map +1 -1
- package/dist/mcp/tools/index.d.ts +2 -5
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/interfaces.d.ts +1 -1
- package/dist/mcp/tools/interfaces.d.ts.map +1 -1
- package/dist/mcp/tools/list-functions.d.ts +1 -1
- package/dist/mcp/tools/list-functions.d.ts.map +1 -1
- package/dist/mcp/tools/list-repos.d.ts +1 -1
- package/dist/mcp/tools/list-repos.d.ts.map +1 -1
- package/dist/mcp/tools/module-map.d.ts +1 -1
- package/dist/mcp/tools/module-map.d.ts.map +1 -1
- package/dist/mcp/tools/node-roles.d.ts +1 -1
- package/dist/mcp/tools/node-roles.d.ts.map +1 -1
- package/dist/mcp/tools/path.d.ts +1 -1
- package/dist/mcp/tools/path.d.ts.map +1 -1
- package/dist/mcp/tools/query.d.ts +1 -1
- package/dist/mcp/tools/query.d.ts.map +1 -1
- package/dist/mcp/tools/semantic-search.d.ts +1 -1
- package/dist/mcp/tools/semantic-search.d.ts.map +1 -1
- package/dist/mcp/tools/sequence.d.ts +1 -1
- package/dist/mcp/tools/sequence.d.ts.map +1 -1
- package/dist/mcp/tools/structure.d.ts +1 -1
- package/dist/mcp/tools/structure.d.ts.map +1 -1
- package/dist/mcp/tools/symbol-children.d.ts +1 -1
- package/dist/mcp/tools/symbol-children.d.ts.map +1 -1
- package/dist/mcp/tools/triage.d.ts +1 -1
- package/dist/mcp/tools/triage.d.ts.map +1 -1
- package/dist/mcp/tools/where.d.ts +1 -1
- package/dist/mcp/tools/where.d.ts.map +1 -1
- 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/queries-cli/index.d.ts +1 -1
- package/dist/presentation/queries-cli/index.d.ts.map +1 -1
- package/dist/presentation/queries-cli/index.js +1 -1
- package/dist/presentation/queries-cli/index.js.map +1 -1
- package/dist/presentation/queries-cli/overview.d.ts +1 -0
- package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
- package/dist/presentation/queries-cli/overview.js +20 -1
- package/dist/presentation/queries-cli/overview.js.map +1 -1
- package/dist/presentation/queries-cli.d.ts +1 -1
- package/dist/presentation/queries-cli.d.ts.map +1 -1
- package/dist/presentation/queries-cli.js +1 -1
- package/dist/presentation/queries-cli.js.map +1 -1
- package/dist/presentation/structure.d.ts +1 -1
- package/dist/presentation/structure.d.ts.map +1 -1
- package/dist/presentation/structure.js +2 -2
- package/dist/presentation/structure.js.map +1 -1
- package/dist/presentation/viewer.d.ts.map +1 -1
- package/dist/presentation/viewer.js +45 -32
- package/dist/presentation/viewer.js.map +1 -1
- package/dist/shared/constants.d.ts +21 -0
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +25 -0
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/normalize.d.ts.map +1 -1
- package/dist/shared/normalize.js +12 -22
- package/dist/shared/normalize.js.map +1 -1
- package/dist/shared/paginate.d.ts +4 -17
- package/dist/shared/paginate.d.ts.map +1 -1
- package/dist/shared/paginate.js.map +1 -1
- package/dist/types.d.ts +113 -1
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-erlang.wasm +0 -0
- package/grammars/tree-sitter-gleam.wasm +0 -0
- package/package.json +7 -8
- package/src/ast-analysis/engine.ts +43 -63
- 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/index.ts +34 -0
- package/src/ast-analysis/rules/javascript.ts +3 -0
- package/src/ast-analysis/shared.ts +2 -0
- package/src/ast-analysis/visitor-utils.ts +5 -0
- package/src/ast-analysis/visitor.ts +82 -52
- package/src/ast-analysis/visitors/cfg-visitor.ts +198 -84
- package/src/ast-analysis/visitors/complexity-visitor.ts +44 -16
- package/src/ast-analysis/visitors/dataflow-visitor.ts +68 -29
- package/src/cli/commands/audit.ts +2 -1
- package/src/cli/commands/batch.ts +1 -0
- package/src/cli/commands/build.ts +6 -1
- package/src/cli/commands/config.ts +353 -0
- package/src/cli/commands/roles.ts +6 -1
- package/src/cli/commands/triage.ts +1 -1
- package/src/cli/index.ts +10 -0
- package/src/cli/shared/options.ts +11 -1
- package/src/cli/types.ts +2 -0
- package/src/db/better-sqlite3.ts +5 -4
- package/src/db/connection.ts +23 -5
- package/src/db/index.ts +1 -0
- package/src/db/migrations.ts +69 -1
- package/src/db/repository/build-stmts.ts +30 -0
- package/src/db/repository/dataflow.ts +16 -0
- package/src/db/repository/index.ts +1 -1
- package/src/db/repository/native-repository.ts +56 -40
- package/src/domain/analysis/fn-impact.ts +4 -0
- package/src/domain/analysis/module-map.ts +38 -6
- package/src/domain/analysis/roles.ts +23 -0
- package/src/domain/graph/builder/call-resolver.ts +156 -218
- package/src/domain/graph/builder/cha.ts +18 -1
- package/src/domain/graph/builder/context.ts +1 -0
- package/src/domain/graph/builder/helpers.ts +205 -67
- package/src/domain/graph/builder/incremental.ts +249 -119
- package/src/domain/graph/builder/pipeline.ts +59 -6
- package/src/domain/graph/builder/stages/build-edges.ts +783 -652
- package/src/domain/graph/builder/stages/collect-files.ts +12 -6
- package/src/domain/graph/builder/stages/detect-changes.ts +4 -2
- package/src/domain/graph/builder/stages/finalize.ts +4 -0
- package/src/domain/graph/builder/stages/native-orchestrator.ts +1214 -398
- package/src/domain/graph/builder/stages/resolve-imports.ts +1 -1
- package/src/domain/graph/resolver/points-to.ts +182 -59
- package/src/domain/graph/resolver/strategy.ts +265 -0
- package/src/domain/graph/watcher.ts +19 -9
- package/src/domain/parser.ts +57 -16
- package/src/domain/queries.ts +1 -1
- package/src/domain/wasm-worker-entry.ts +13 -2
- package/src/domain/wasm-worker-pool.ts +29 -4
- package/src/domain/wasm-worker-protocol.ts +5 -0
- package/src/extractors/cpp.ts +44 -1
- package/src/extractors/cuda.ts +44 -1
- package/src/extractors/dart.ts +48 -3
- package/src/extractors/groovy.ts +62 -2
- package/src/extractors/helpers.ts +48 -2
- package/src/extractors/java.ts +88 -8
- package/src/extractors/javascript.ts +693 -167
- package/src/extractors/kotlin.ts +57 -3
- package/src/extractors/objc.ts +25 -1
- package/src/extractors/scala.ts +63 -1
- package/src/extractors/swift.ts +46 -3
- package/src/features/audit.ts +43 -34
- package/src/features/boundaries.ts +17 -9
- package/src/features/cfg.ts +31 -22
- package/src/features/check.ts +21 -5
- package/src/features/communities.ts +28 -19
- package/src/features/dataflow.ts +755 -6
- package/src/features/manifesto.ts +76 -75
- package/src/features/sequence.ts +29 -23
- package/src/features/snapshot.ts +36 -25
- package/src/features/structure-query.ts +7 -7
- package/src/features/structure.ts +185 -55
- package/src/features/triage.ts +28 -15
- package/src/graph/algorithms/bfs.ts +13 -12
- package/src/graph/algorithms/tarjan.ts +5 -0
- package/src/graph/builders/dependency.ts +35 -23
- package/src/graph/classifiers/roles.ts +74 -7
- package/src/index.ts +5 -1
- package/src/infrastructure/config.ts +511 -23
- package/src/infrastructure/registry.ts +117 -12
- package/src/infrastructure/update-check.ts +55 -33
- package/src/mcp/server.ts +2 -8
- package/src/mcp/tools/ast-query.ts +1 -1
- package/src/mcp/tools/audit.ts +1 -1
- package/src/mcp/tools/batch-query.ts +1 -1
- package/src/mcp/tools/branch-compare.ts +1 -1
- package/src/mcp/tools/brief.ts +1 -1
- package/src/mcp/tools/cfg.ts +1 -1
- package/src/mcp/tools/check.ts +1 -1
- package/src/mcp/tools/co-changes.ts +1 -1
- package/src/mcp/tools/code-owners.ts +1 -1
- package/src/mcp/tools/communities.ts +1 -1
- package/src/mcp/tools/complexity.ts +1 -1
- package/src/mcp/tools/context.ts +1 -1
- package/src/mcp/tools/dataflow.ts +1 -1
- package/src/mcp/tools/diff-impact.ts +1 -1
- package/src/mcp/tools/execution-flow.ts +1 -1
- package/src/mcp/tools/export-graph.ts +1 -1
- package/src/mcp/tools/file-deps.ts +1 -1
- package/src/mcp/tools/file-exports.ts +1 -1
- package/src/mcp/tools/find-cycles.ts +1 -1
- package/src/mcp/tools/fn-impact.ts +1 -1
- package/src/mcp/tools/impact-analysis.ts +1 -1
- package/src/mcp/tools/implementations.ts +1 -1
- package/src/mcp/tools/index.ts +2 -5
- package/src/mcp/tools/interfaces.ts +1 -1
- package/src/mcp/tools/list-functions.ts +1 -1
- package/src/mcp/tools/list-repos.ts +1 -1
- package/src/mcp/tools/module-map.ts +1 -1
- package/src/mcp/tools/node-roles.ts +1 -1
- package/src/mcp/tools/path.ts +1 -1
- package/src/mcp/tools/query.ts +1 -1
- package/src/mcp/tools/semantic-search.ts +1 -1
- package/src/mcp/tools/sequence.ts +1 -1
- package/src/mcp/tools/structure.ts +1 -1
- package/src/mcp/tools/symbol-children.ts +1 -1
- package/src/mcp/tools/triage.ts +1 -1
- package/src/mcp/tools/where.ts +1 -1
- package/src/mcp/types.ts +21 -0
- package/src/presentation/queries-cli/index.ts +1 -1
- package/src/presentation/queries-cli/overview.ts +35 -1
- package/src/presentation/queries-cli.ts +1 -0
- package/src/presentation/structure.ts +3 -3
- package/src/presentation/viewer.ts +98 -87
- package/src/shared/constants.ts +26 -0
- package/src/shared/normalize.ts +13 -22
- package/src/shared/paginate.ts +4 -18
- package/src/types.ts +127 -1
|
@@ -135,7 +135,7 @@ async function reparseBarrelFiles(
|
|
|
135
135
|
// which only runs on the original (changed + reverse-dep) fileSymbols. Barrel
|
|
136
136
|
// candidates are merged here *after* insertNodes, so wiping those kinds
|
|
137
137
|
// would permanently drop them (mirrors the Rust orchestrator's Stage 6b
|
|
138
|
-
// delete in
|
|
138
|
+
// delete in domain/graph/builder/pipeline.rs).
|
|
139
139
|
const deleteOutgoingEdges = db.prepare(
|
|
140
140
|
`DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?)
|
|
141
141
|
AND kind NOT IN ('contains', 'parameter_of')`,
|
|
@@ -41,38 +41,17 @@ export type PointsToMap = Map<string, Set<string>>;
|
|
|
41
41
|
const MAX_SOLVER_ITERATIONS = 50;
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* Seeds concrete function names (locally-defined functions + imported names),
|
|
47
|
-
* then propagates assignments through fixed-point iteration until stable.
|
|
48
|
-
*
|
|
49
|
-
* Each "concrete target" in a pts set is a name that `resolveCallTargets` can
|
|
50
|
-
* look up — either a locally-defined function name (found via byNameAndFile) or
|
|
51
|
-
* an imported name (found via importedNames → byNameAndFile in the source file).
|
|
44
|
+
* Seed the pts map from locally-defined functions, imported names, and
|
|
45
|
+
* fnRefBindings (direct assignment aliases: `const fn = handler`).
|
|
52
46
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* @param importedNames - names imported into this file (name → resolved file)
|
|
56
|
-
* @param paramBindings - call-site arg→param bindings (Phase 8.3c)
|
|
57
|
-
* @param definitionParams - per-function ordered parameter names (Phase 8.3c)
|
|
58
|
-
* @param arrayElemBindings - array literal element bindings (Phase 8.3e)
|
|
59
|
-
* @param spreadArgBindings - spread-argument bindings (Phase 8.3e)
|
|
60
|
-
* @param forOfBindings - for-of iteration variable bindings (Phase 8.3e)
|
|
61
|
-
* @param arrayCallbackBindings - Array.from/callback bindings (Phase 8.3e)
|
|
47
|
+
* Returns the seeded pts map and the base constraint list built from
|
|
48
|
+
* fnRefBindings (member-expression aliases: `const fn = obj.method`).
|
|
62
49
|
*/
|
|
63
|
-
|
|
50
|
+
function buildThisAssignmentMap(
|
|
64
51
|
fnRefBindings: readonly FnRefBinding[],
|
|
65
52
|
definitionNames: ReadonlySet<string>,
|
|
66
53
|
importedNames: ReadonlyMap<string, string>,
|
|
67
|
-
|
|
68
|
-
definitionParams?: ReadonlyMap<string, readonly string[]>,
|
|
69
|
-
arrayElemBindings?: readonly ArrayElemBinding[],
|
|
70
|
-
spreadArgBindings?: readonly SpreadArgBinding[],
|
|
71
|
-
forOfBindings?: readonly ForOfBinding[],
|
|
72
|
-
arrayCallbackBindings?: readonly ArrayCallbackBinding[],
|
|
73
|
-
objectRestParamBindings?: readonly ObjectRestParamBinding[],
|
|
74
|
-
objectPropBindings?: readonly ObjectPropBinding[],
|
|
75
|
-
): PointsToMap {
|
|
54
|
+
): { pts: PointsToMap; constraints: Array<{ lhs: string; rhsKey: string }> } {
|
|
76
55
|
const pts: PointsToMap = new Map();
|
|
77
56
|
|
|
78
57
|
// Seed: each locally-defined function points to itself.
|
|
@@ -96,6 +75,24 @@ export function buildPointsToMap(
|
|
|
96
75
|
rhsKey: b.rhsReceiver ? `${b.rhsReceiver}.${b.rhs}` : b.rhs,
|
|
97
76
|
}));
|
|
98
77
|
|
|
78
|
+
return { pts, constraints };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Append parameter-flow and array/spread/forOf/callback constraints (Phases 8.3c and 8.3e).
|
|
83
|
+
*
|
|
84
|
+
* Mutates `pts` (seeds array-element entries) and appends to `constraints`.
|
|
85
|
+
*/
|
|
86
|
+
function buildParamAndArrayConstraints(
|
|
87
|
+
pts: PointsToMap,
|
|
88
|
+
constraints: Array<{ lhs: string; rhsKey: string }>,
|
|
89
|
+
paramBindings?: readonly ParamBinding[],
|
|
90
|
+
definitionParams?: ReadonlyMap<string, readonly string[]>,
|
|
91
|
+
arrayElemBindings?: readonly ArrayElemBinding[],
|
|
92
|
+
spreadArgBindings?: readonly SpreadArgBinding[],
|
|
93
|
+
forOfBindings?: readonly ForOfBinding[],
|
|
94
|
+
arrayCallbackBindings?: readonly ArrayCallbackBinding[],
|
|
95
|
+
): void {
|
|
99
96
|
// Phase 8.3c: parameter-flow constraints.
|
|
100
97
|
// For each call f(x) at argIndex i where f is locally defined, add
|
|
101
98
|
// constraint: pts(f::paramName_i) ⊇ pts(x). This makes the pts solver
|
|
@@ -180,46 +177,113 @@ export function buildPointsToMap(
|
|
|
180
177
|
constraints.push({ lhs: `${calleeName}::${params[0]}`, rhsKey: `${sourceName}[*]` });
|
|
181
178
|
}
|
|
182
179
|
}
|
|
180
|
+
}
|
|
183
181
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Seed pts entries for object-rest parameter dispatch (Phase 8.3f).
|
|
184
|
+
*
|
|
185
|
+
* `function f({ ...rest }) {}` + `f(obj)` + `const obj = { prop: fn }` →
|
|
186
|
+
* seeds pts["rest.prop"] = {"fn"} so that `rest.prop()` resolves to `fn`.
|
|
187
|
+
*
|
|
188
|
+
* Mutates `pts` in place.
|
|
189
|
+
*/
|
|
190
|
+
function buildObjectRestConstraints(
|
|
191
|
+
pts: PointsToMap,
|
|
192
|
+
definitionNames: ReadonlySet<string>,
|
|
193
|
+
importedNames: ReadonlyMap<string, string>,
|
|
194
|
+
paramBindings: readonly ParamBinding[],
|
|
195
|
+
objectRestParamBindings: readonly ObjectRestParamBinding[],
|
|
196
|
+
objectPropBindings: readonly ObjectPropBinding[],
|
|
197
|
+
): void {
|
|
198
|
+
// Index paramBindings: "callee::argIndex" → argName[] (O(|paramBindings|) build,
|
|
199
|
+
// O(1) lookup — avoids scanning paramBindings for each rest binding).
|
|
200
|
+
const paramByCalleeIdx = new Map<string, string[]>();
|
|
201
|
+
for (const { callee, argIndex, argName } of paramBindings) {
|
|
202
|
+
const k = `${callee}::${argIndex}`;
|
|
203
|
+
const list = paramByCalleeIdx.get(k);
|
|
204
|
+
if (list) list.push(argName);
|
|
205
|
+
else paramByCalleeIdx.set(k, [argName]);
|
|
206
|
+
}
|
|
197
207
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
208
|
+
// Index objectPropBindings: objectName → {propName, valueName}[]
|
|
209
|
+
const propsByObject = new Map<string, Array<{ propName: string; valueName: string }>>();
|
|
210
|
+
for (const { objectName, propName, valueName } of objectPropBindings) {
|
|
211
|
+
const list = propsByObject.get(objectName);
|
|
212
|
+
if (list) list.push({ propName, valueName });
|
|
213
|
+
else propsByObject.set(objectName, [{ propName, valueName }]);
|
|
214
|
+
}
|
|
205
215
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
+
for (const { callee, restName, argIndex } of objectRestParamBindings) {
|
|
217
|
+
const argNames = paramByCalleeIdx.get(`${callee}::${argIndex}`) ?? [];
|
|
218
|
+
for (const argName of argNames) {
|
|
219
|
+
const props = propsByObject.get(argName) ?? [];
|
|
220
|
+
for (const { propName, valueName } of props) {
|
|
221
|
+
if (!definitionNames.has(valueName) && !importedNames.has(valueName)) continue;
|
|
222
|
+
const key = `${restName}.${propName}`;
|
|
223
|
+
if (!pts.has(key)) pts.set(key, new Set());
|
|
224
|
+
pts.get(key)!.add(valueName);
|
|
216
225
|
}
|
|
217
226
|
}
|
|
218
227
|
}
|
|
228
|
+
}
|
|
219
229
|
|
|
220
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Append higher-order constraints to the constraint list based on how
|
|
232
|
+
* function values flow through call sites, arrays, for-of loops, callbacks,
|
|
233
|
+
* and object rest-param destructuring.
|
|
234
|
+
*
|
|
235
|
+
* Coordinates buildParamAndArrayConstraints (Phase 8.3c/e) and
|
|
236
|
+
* buildObjectRestConstraints (Phase 8.3f).
|
|
237
|
+
*
|
|
238
|
+
* Mutates `pts` (seeds array-element and object-rest entries) and appends to `constraints`.
|
|
239
|
+
*/
|
|
240
|
+
function appendAdvancedConstraints(
|
|
241
|
+
pts: PointsToMap,
|
|
242
|
+
constraints: Array<{ lhs: string; rhsKey: string }>,
|
|
243
|
+
definitionNames: ReadonlySet<string>,
|
|
244
|
+
importedNames: ReadonlyMap<string, string>,
|
|
245
|
+
paramBindings?: readonly ParamBinding[],
|
|
246
|
+
definitionParams?: ReadonlyMap<string, readonly string[]>,
|
|
247
|
+
arrayElemBindings?: readonly ArrayElemBinding[],
|
|
248
|
+
spreadArgBindings?: readonly SpreadArgBinding[],
|
|
249
|
+
forOfBindings?: readonly ForOfBinding[],
|
|
250
|
+
arrayCallbackBindings?: readonly ArrayCallbackBinding[],
|
|
251
|
+
objectRestParamBindings?: readonly ObjectRestParamBinding[],
|
|
252
|
+
objectPropBindings?: readonly ObjectPropBinding[],
|
|
253
|
+
): void {
|
|
254
|
+
buildParamAndArrayConstraints(
|
|
255
|
+
pts,
|
|
256
|
+
constraints,
|
|
257
|
+
paramBindings,
|
|
258
|
+
definitionParams,
|
|
259
|
+
arrayElemBindings,
|
|
260
|
+
spreadArgBindings,
|
|
261
|
+
forOfBindings,
|
|
262
|
+
arrayCallbackBindings,
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
if (objectRestParamBindings && objectPropBindings && paramBindings) {
|
|
266
|
+
buildObjectRestConstraints(
|
|
267
|
+
pts,
|
|
268
|
+
definitionNames,
|
|
269
|
+
importedNames,
|
|
270
|
+
paramBindings,
|
|
271
|
+
objectRestParamBindings,
|
|
272
|
+
objectPropBindings,
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
221
276
|
|
|
222
|
-
|
|
277
|
+
/**
|
|
278
|
+
* Run the fixed-point solver: propagate pts sets through constraints until
|
|
279
|
+
* no new information flows (or MAX_SOLVER_ITERATIONS is reached).
|
|
280
|
+
*
|
|
281
|
+
* Mutates `pts` in place.
|
|
282
|
+
*/
|
|
283
|
+
function buildCallSiteTypeMap(
|
|
284
|
+
pts: PointsToMap,
|
|
285
|
+
constraints: ReadonlyArray<{ lhs: string; rhsKey: string }>,
|
|
286
|
+
): void {
|
|
223
287
|
for (let iter = 0; iter < MAX_SOLVER_ITERATIONS; iter++) {
|
|
224
288
|
let changed = false;
|
|
225
289
|
for (const { lhs, rhsKey } of constraints) {
|
|
@@ -236,6 +300,65 @@ export function buildPointsToMap(
|
|
|
236
300
|
}
|
|
237
301
|
if (!changed) break;
|
|
238
302
|
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Build a points-to map for one file.
|
|
307
|
+
*
|
|
308
|
+
* Seeds concrete function names (locally-defined functions + imported names),
|
|
309
|
+
* then propagates assignments through fixed-point iteration until stable.
|
|
310
|
+
*
|
|
311
|
+
* Each "concrete target" in a pts set is a name that `resolveCallTargets` can
|
|
312
|
+
* look up — either a locally-defined function name (found via byNameAndFile) or
|
|
313
|
+
* an imported name (found via importedNames → byNameAndFile in the source file).
|
|
314
|
+
*
|
|
315
|
+
* @param fnRefBindings - identifier/member-expr bindings from the extractor
|
|
316
|
+
* @param definitionNames - locally-defined callable names in this file
|
|
317
|
+
* @param importedNames - names imported into this file (name → resolved file)
|
|
318
|
+
* @param paramBindings - call-site arg→param bindings (Phase 8.3c)
|
|
319
|
+
* @param definitionParams - per-function ordered parameter names (Phase 8.3c)
|
|
320
|
+
* @param arrayElemBindings - array literal element bindings (Phase 8.3e)
|
|
321
|
+
* @param spreadArgBindings - spread-argument bindings (Phase 8.3e)
|
|
322
|
+
* @param forOfBindings - for-of iteration variable bindings (Phase 8.3e)
|
|
323
|
+
* @param arrayCallbackBindings - Array.from/callback bindings (Phase 8.3e)
|
|
324
|
+
*/
|
|
325
|
+
export function buildPointsToMap(
|
|
326
|
+
fnRefBindings: readonly FnRefBinding[],
|
|
327
|
+
definitionNames: ReadonlySet<string>,
|
|
328
|
+
importedNames: ReadonlyMap<string, string>,
|
|
329
|
+
paramBindings?: readonly ParamBinding[],
|
|
330
|
+
definitionParams?: ReadonlyMap<string, readonly string[]>,
|
|
331
|
+
arrayElemBindings?: readonly ArrayElemBinding[],
|
|
332
|
+
spreadArgBindings?: readonly SpreadArgBinding[],
|
|
333
|
+
forOfBindings?: readonly ForOfBinding[],
|
|
334
|
+
arrayCallbackBindings?: readonly ArrayCallbackBinding[],
|
|
335
|
+
objectRestParamBindings?: readonly ObjectRestParamBinding[],
|
|
336
|
+
objectPropBindings?: readonly ObjectPropBinding[],
|
|
337
|
+
): PointsToMap {
|
|
338
|
+
const { pts, constraints } = buildThisAssignmentMap(
|
|
339
|
+
fnRefBindings,
|
|
340
|
+
definitionNames,
|
|
341
|
+
importedNames,
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
appendAdvancedConstraints(
|
|
345
|
+
pts,
|
|
346
|
+
constraints,
|
|
347
|
+
definitionNames,
|
|
348
|
+
importedNames,
|
|
349
|
+
paramBindings,
|
|
350
|
+
definitionParams,
|
|
351
|
+
arrayElemBindings,
|
|
352
|
+
spreadArgBindings,
|
|
353
|
+
forOfBindings,
|
|
354
|
+
arrayCallbackBindings,
|
|
355
|
+
objectRestParamBindings,
|
|
356
|
+
objectPropBindings,
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
if (constraints.length === 0) return pts;
|
|
360
|
+
|
|
361
|
+
buildCallSiteTypeMap(pts, constraints);
|
|
239
362
|
|
|
240
363
|
return pts;
|
|
241
364
|
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call resolution strategy helpers — extracted from call-resolver.ts.
|
|
3
|
+
*
|
|
4
|
+
* `resolveByMethodOrGlobal` in call-resolver.ts dispatches to two sub-strategies:
|
|
5
|
+
* - resolveByReceiver — receiver is a concrete object/class (not this/self/super)
|
|
6
|
+
* - resolveByGlobal — bare call or this/self/super receiver
|
|
7
|
+
*
|
|
8
|
+
* Splitting them here keeps each strategy unit-testable and reduces call-resolver.ts
|
|
9
|
+
* cognitive complexity from 107 to a thin dispatcher.
|
|
10
|
+
*
|
|
11
|
+
* This file intentionally does NOT import from ../builder/call-resolver.ts to avoid
|
|
12
|
+
* a circular dependency. The StrategyLookup interface mirrors CallNodeLookup structurally
|
|
13
|
+
* (TypeScript structural typing ensures compatibility without an explicit import).
|
|
14
|
+
*/
|
|
15
|
+
import { computeConfidence } from '../resolve.js';
|
|
16
|
+
|
|
17
|
+
// ── Lookup adapter (structural mirror of CallNodeLookup) ──────────────────────
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Structural mirror of `CallNodeLookup` from call-resolver.ts.
|
|
21
|
+
* Any `CallNodeLookup` instance satisfies this type without explicit declaration.
|
|
22
|
+
* Defined here to break the circular import that would arise from importing
|
|
23
|
+
* `CallNodeLookup` directly from call-resolver.ts.
|
|
24
|
+
*/
|
|
25
|
+
export interface StrategyLookup {
|
|
26
|
+
byNameAndFile(
|
|
27
|
+
name: string,
|
|
28
|
+
file: string,
|
|
29
|
+
): ReadonlyArray<{ id: number; file: string; kind?: string }>;
|
|
30
|
+
byName(name: string): ReadonlyArray<{ id: number; file: string; kind?: string }>;
|
|
31
|
+
isBarrel(file: string): boolean;
|
|
32
|
+
resolveBarrel(barrelFile: string, symbolName: string): string | null;
|
|
33
|
+
nodeId(name: string, kind: string, file: string, line: number): { id: number } | undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ── Module-scoped language detection ─────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Languages where bare `foo()` calls inside a class method are lexically scoped
|
|
40
|
+
* to the module, not the class — there is no implicit this/class binding.
|
|
41
|
+
* For these languages, the same-class fallback must not run for bare (no-receiver)
|
|
42
|
+
* calls that found no exact same-file match.
|
|
43
|
+
*/
|
|
44
|
+
const MODULE_SCOPED_BARE_CALL_EXTENSIONS = new Set([
|
|
45
|
+
'.js',
|
|
46
|
+
'.mjs',
|
|
47
|
+
'.cjs',
|
|
48
|
+
'.jsx',
|
|
49
|
+
'.ts',
|
|
50
|
+
'.tsx',
|
|
51
|
+
'.mts',
|
|
52
|
+
'.cts',
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
export function isModuleScopedLanguage(relPath: string): boolean {
|
|
56
|
+
const ext = relPath.slice(relPath.lastIndexOf('.'));
|
|
57
|
+
return MODULE_SCOPED_BARE_CALL_EXTENSIONS.has(ext);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ── resolveByReceiver ─────────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a call site whose receiver is a concrete object reference
|
|
64
|
+
* (i.e. `receiver` is present and is NOT `this`, `self`, or `super`).
|
|
65
|
+
*
|
|
66
|
+
* Resolution cascade:
|
|
67
|
+
* 1. typeMap class-scoped lookup (`ClassName.prop` key) for `this.prop` receivers.
|
|
68
|
+
* 2. typeMap bare key, full-receiver key, callee-scoped rest-param key.
|
|
69
|
+
* 3. Inline `new Ctor()` heuristic for un-normalised receiver text.
|
|
70
|
+
* 4. Typed method lookup via `TypeName.methodName` in symbol DB.
|
|
71
|
+
* 5. Prototype alias: `Foo.prototype.bar = identifier` via typeMap.
|
|
72
|
+
* 6. Direct qualified method lookup: `ClassName.staticMethod()`.
|
|
73
|
+
* 7. Composite pts key: `obj.prop` → callback target function.
|
|
74
|
+
*/
|
|
75
|
+
export function resolveByReceiver(
|
|
76
|
+
lookup: StrategyLookup,
|
|
77
|
+
call: { name: string; receiver: string },
|
|
78
|
+
relPath: string,
|
|
79
|
+
typeMap: Map<string, unknown>,
|
|
80
|
+
callerName?: string | null,
|
|
81
|
+
): ReadonlyArray<{ id: number; file: string }> {
|
|
82
|
+
// Strip "this." so `this.repo.method()` resolves via typeMap["repo"]
|
|
83
|
+
// (or the "this.repo" key seeded directly by the TSC property-declaration enricher).
|
|
84
|
+
const effectiveReceiver = call.receiver.startsWith('this.')
|
|
85
|
+
? call.receiver.slice('this.'.length)
|
|
86
|
+
: call.receiver;
|
|
87
|
+
|
|
88
|
+
// For this.prop receivers, prefer the class-scoped key (ClassName.prop) seeded by
|
|
89
|
+
// handlePropWriteTypeMap / handleFieldDefTypeMap — prevents false edges when multiple
|
|
90
|
+
// classes define the same property name (issues #1323, #1458).
|
|
91
|
+
// Class-scoped lookup runs first so bare fallback keys (confidence 0.6) don't shadow
|
|
92
|
+
// the correct per-class entry when callerName is available.
|
|
93
|
+
let typeEntry: unknown;
|
|
94
|
+
if (call.receiver.startsWith('this.') && callerName) {
|
|
95
|
+
const dotIdx = callerName.lastIndexOf('.');
|
|
96
|
+
if (dotIdx > -1) {
|
|
97
|
+
const callerClass = callerName.slice(0, dotIdx);
|
|
98
|
+
typeEntry = typeMap.get(`${callerClass}.${effectiveReceiver}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
typeEntry ??=
|
|
102
|
+
typeMap.get(effectiveReceiver) ??
|
|
103
|
+
typeMap.get(call.receiver) ??
|
|
104
|
+
// Phase 8.3f: callee-scoped rest-param key (`callee::restName`) to avoid
|
|
105
|
+
// same-name rest-binding collision across functions in the same file (#1358).
|
|
106
|
+
(callerName ? typeMap.get(`${callerName}::${effectiveReceiver}`) : undefined);
|
|
107
|
+
|
|
108
|
+
let typeName = typeEntry
|
|
109
|
+
? typeof typeEntry === 'string'
|
|
110
|
+
? typeEntry
|
|
111
|
+
: (typeEntry as { type?: string }).type
|
|
112
|
+
: null;
|
|
113
|
+
|
|
114
|
+
// Belt-and-suspenders fallback for inline new-expression receivers that
|
|
115
|
+
// extractReceiverName did not normalise (e.g. raw text leaked from an
|
|
116
|
+
// unhandled AST node type). extractReceiverName already handles the common
|
|
117
|
+
// `new_expression` / `parenthesized_expression(new_expression)` shapes by
|
|
118
|
+
// returning the constructor name directly, so this branch is exercised only
|
|
119
|
+
// by future node types or constructs that fall through to the raw-text path.
|
|
120
|
+
// The uppercase-initial restriction ([A-Z_$]) is a heuristic to distinguish
|
|
121
|
+
// constructors (PascalCase) from regular functions and avoids false positives
|
|
122
|
+
// on `(new xmlParser()).parse()` style calls.
|
|
123
|
+
if (!typeName && call.receiver) {
|
|
124
|
+
const m = /^\(?\s*new\s+([A-Z_$][A-Za-z0-9_$]*)/.exec(call.receiver);
|
|
125
|
+
if (m?.[1]) typeName = m[1];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (typeName) {
|
|
129
|
+
const typed = lookup
|
|
130
|
+
.byName(`${typeName}.${call.name}`)
|
|
131
|
+
.filter((n) => n.kind === 'method' && computeConfidence(relPath, n.file, null) >= 0.5);
|
|
132
|
+
if (typed.length > 0) return typed;
|
|
133
|
+
|
|
134
|
+
// Prototype alias: `Foo.prototype.bar = identifier` seeds typeMap['Foo.bar'] = { type: identifier }.
|
|
135
|
+
// Checked after the symbol-DB lookup so an actual method definition always wins.
|
|
136
|
+
const protoEntry = typeMap.get(`${typeName}.${call.name}`);
|
|
137
|
+
const protoTarget = protoEntry
|
|
138
|
+
? typeof protoEntry === 'string'
|
|
139
|
+
? protoEntry
|
|
140
|
+
: (protoEntry as { type?: string }).type
|
|
141
|
+
: null;
|
|
142
|
+
if (protoTarget) {
|
|
143
|
+
const resolved = lookup
|
|
144
|
+
.byName(protoTarget)
|
|
145
|
+
.filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
|
|
146
|
+
if (resolved.length > 0) return resolved;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Direct qualified method lookup: ClassName.staticMethod() or ClassName.instanceMethod()
|
|
151
|
+
// when the receiver is a class name with no typeMap entry. Handles static method calls
|
|
152
|
+
// like `C6.staticMethod()` or `D.d()` where the receiver IS the class.
|
|
153
|
+
// Matches both 'method' and 'function' kinds to cover field-initializer synthetic defs.
|
|
154
|
+
if (!typeName) {
|
|
155
|
+
const qualifiedName = `${effectiveReceiver}.${call.name}`;
|
|
156
|
+
const direct = lookup
|
|
157
|
+
.byName(qualifiedName)
|
|
158
|
+
.filter(
|
|
159
|
+
(n) =>
|
|
160
|
+
(n.kind === 'method' || n.kind === 'function') &&
|
|
161
|
+
computeConfidence(relPath, n.file, null) >= 0.5,
|
|
162
|
+
);
|
|
163
|
+
if (direct.length > 0) return direct;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Phase 8.3d: composite pts key — `obj.prop = fn` seeds typeMap['obj.prop'] = { type: 'fn' }.
|
|
167
|
+
// When a call site references `obj.prop` as a callback, resolve directly to the target fn.
|
|
168
|
+
const compositeEntry = typeMap.get(`${call.receiver}.${call.name}`);
|
|
169
|
+
const ptsTarget = compositeEntry
|
|
170
|
+
? typeof compositeEntry === 'string'
|
|
171
|
+
? compositeEntry
|
|
172
|
+
: (compositeEntry as { type?: string }).type
|
|
173
|
+
: null;
|
|
174
|
+
if (ptsTarget) {
|
|
175
|
+
const resolved = lookup
|
|
176
|
+
.byName(ptsTarget)
|
|
177
|
+
.filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
|
|
178
|
+
if (resolved.length > 0) return resolved;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ── resolveByGlobal ───────────────────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Resolve a call site with no receiver, or whose receiver is `this`, `self`,
|
|
188
|
+
* or `super`.
|
|
189
|
+
*
|
|
190
|
+
* Resolution cascade:
|
|
191
|
+
* 1. Accessor this-dispatch via Object.defineProperty (Phase 8.3f).
|
|
192
|
+
* 2. Exact global name lookup with confidence filter.
|
|
193
|
+
* 3. Same-class sibling method fallback (C#/Java static siblings, this.method()).
|
|
194
|
+
*/
|
|
195
|
+
export function resolveByGlobal(
|
|
196
|
+
lookup: StrategyLookup,
|
|
197
|
+
call: { name: string; receiver?: string | null },
|
|
198
|
+
relPath: string,
|
|
199
|
+
typeMap: Map<string, unknown>,
|
|
200
|
+
callerName?: string | null,
|
|
201
|
+
): ReadonlyArray<{ id: number; file: string }> {
|
|
202
|
+
// Phase 8.3f: accessor this-dispatch via Object.defineProperty.
|
|
203
|
+
// When a plain function (no class prefix) is registered as a get/set accessor for `obj`
|
|
204
|
+
// via Object.defineProperty, typeMap seeds 'callerName:this' = 'obj'.
|
|
205
|
+
// We then resolve this.method() → typeMap['obj.method'] → the concrete definition.
|
|
206
|
+
// This runs before the broad exact-name lookup to avoid false positives from
|
|
207
|
+
// unrelated same-file definitions.
|
|
208
|
+
if (call.receiver === 'this' && callerName && !callerName.includes('.')) {
|
|
209
|
+
const accessorThisEntry = typeMap.get(`${callerName}:this`);
|
|
210
|
+
const objName = accessorThisEntry
|
|
211
|
+
? typeof accessorThisEntry === 'string'
|
|
212
|
+
? accessorThisEntry
|
|
213
|
+
: (accessorThisEntry as { type?: string }).type
|
|
214
|
+
: null;
|
|
215
|
+
if (objName) {
|
|
216
|
+
const objMethodEntry = typeMap.get(`${objName}.${call.name}`);
|
|
217
|
+
const targetFn = objMethodEntry
|
|
218
|
+
? typeof objMethodEntry === 'string'
|
|
219
|
+
? objMethodEntry
|
|
220
|
+
: (objMethodEntry as { type?: string }).type
|
|
221
|
+
: null;
|
|
222
|
+
if (targetFn) {
|
|
223
|
+
const resolved = lookup
|
|
224
|
+
.byName(targetFn)
|
|
225
|
+
.filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
|
|
226
|
+
if (resolved.length > 0) return resolved;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const exact = lookup
|
|
232
|
+
.byName(call.name)
|
|
233
|
+
.filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
|
|
234
|
+
if (exact.length > 0) return exact;
|
|
235
|
+
|
|
236
|
+
// Try same-class method lookup via callerName.
|
|
237
|
+
// e.g. `this.area()` inside `Shape.describe` → try `Shape.area`.
|
|
238
|
+
// Also covers no-receiver calls inside class methods, e.g. `IsValidEmail(x)` inside
|
|
239
|
+
// `Validators.ValidateUser` → try `Validators.IsValidEmail` (C#/Java static siblings).
|
|
240
|
+
// This seeds the initial edge that runChaPostPass later expands to subclass overrides.
|
|
241
|
+
//
|
|
242
|
+
// For JS/TS, bare (no-receiver) calls are module-scoped — there is no implicit class
|
|
243
|
+
// binding. Skip the same-class fallback for bare calls in those languages to prevent
|
|
244
|
+
// false positives (e.g. `flush()` inside `Processor.run` must not resolve to
|
|
245
|
+
// `Processor.flush`). this.method() calls are unaffected: they still reach the fallback
|
|
246
|
+
// because `call.receiver === 'this'` is truthy, not a bare call.
|
|
247
|
+
const isBareCall = !call.receiver;
|
|
248
|
+
if (callerName && !(isBareCall && isModuleScopedLanguage(relPath))) {
|
|
249
|
+
const dotIdx = callerName.lastIndexOf('.');
|
|
250
|
+
if (dotIdx > -1) {
|
|
251
|
+
// Extract only the segment immediately before the method name so that
|
|
252
|
+
// 'Namespace.ClassName.method' yields 'ClassName', not 'Namespace.ClassName'.
|
|
253
|
+
// Symbols are stored under their bare class name, not their qualified path.
|
|
254
|
+
const prevDot = callerName.lastIndexOf('.', dotIdx - 1);
|
|
255
|
+
const callerClass = callerName.slice(prevDot + 1, dotIdx);
|
|
256
|
+
const qualifiedName = `${callerClass}.${call.name}`;
|
|
257
|
+
const sameClass = lookup
|
|
258
|
+
.byName(qualifiedName)
|
|
259
|
+
.filter((t) => t.kind === 'method' && computeConfidence(relPath, t.file, null) >= 0.5);
|
|
260
|
+
if (sameClass.length > 0) return sameClass;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return exact; // empty
|
|
265
|
+
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { closeDb, getNodeId as getNodeIdQuery, initSchema, openDb } from '../../db/index.js';
|
|
4
|
+
import { loadConfig } from '../../infrastructure/config.js';
|
|
4
5
|
import { debug, info, warn } from '../../infrastructure/logger.js';
|
|
5
|
-
import { isSupportedFile, normalizePath
|
|
6
|
+
import { buildIgnoreSet, isSupportedFile, normalizePath } from '../../shared/constants.js';
|
|
6
7
|
import { DbError } from '../../shared/errors.js';
|
|
7
8
|
import { createParseTreeCache, getActiveEngine } from '../parser.js';
|
|
8
9
|
import { type IncrementalStmts, rebuildFile } from './builder/incremental.js';
|
|
9
10
|
import { appendChangeEvents, buildChangeEvent, diffSymbols } from './change-journal.js';
|
|
10
11
|
import { appendJournalEntriesAndStampHeader } from './journal.js';
|
|
11
12
|
|
|
12
|
-
function shouldIgnorePath(filePath: string): boolean {
|
|
13
|
+
function shouldIgnorePath(filePath: string, ignoreSet: ReadonlySet<string>): boolean {
|
|
13
14
|
const parts = filePath.split(path.sep);
|
|
14
|
-
return parts.some((p) =>
|
|
15
|
+
return parts.some((p) => ignoreSet.has(p) || p.startsWith('.'));
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
/** Prepare all SQL statements needed by the watcher's incremental rebuild. */
|
|
@@ -139,7 +140,7 @@ function logRebuildResults(updates: RebuildResult[]): void {
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
/** Recursively collect tracked source files for stat-based polling. */
|
|
142
|
-
function collectTrackedFiles(dir: string, result: string[]): void {
|
|
143
|
+
function collectTrackedFiles(dir: string, result: string[], ignoreSet: ReadonlySet<string>): void {
|
|
143
144
|
let entries: fs.Dirent[];
|
|
144
145
|
try {
|
|
145
146
|
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
@@ -148,10 +149,10 @@ function collectTrackedFiles(dir: string, result: string[]): void {
|
|
|
148
149
|
return;
|
|
149
150
|
}
|
|
150
151
|
for (const entry of entries) {
|
|
151
|
-
if (
|
|
152
|
+
if (ignoreSet.has(entry.name) || entry.name.startsWith('.')) continue;
|
|
152
153
|
const full = path.join(dir, entry.name);
|
|
153
154
|
if (entry.isDirectory()) {
|
|
154
|
-
collectTrackedFiles(full, result);
|
|
155
|
+
collectTrackedFiles(full, result, ignoreSet);
|
|
155
156
|
} else if (isSupportedFile(entry.name)) {
|
|
156
157
|
result.push(full);
|
|
157
158
|
}
|
|
@@ -168,6 +169,8 @@ interface WatcherContext {
|
|
|
168
169
|
pending: Set<string>;
|
|
169
170
|
timer: ReturnType<typeof setTimeout> | null;
|
|
170
171
|
debounceMs: number;
|
|
172
|
+
/** Merged ignore set from IGNORE_DIRS + config.ignoreDirs + config.ignoreAdditionalDirs. */
|
|
173
|
+
ignoreSet: ReadonlySet<string>;
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
/** Initialize DB, engine, cache, and statements for watch mode. */
|
|
@@ -177,6 +180,12 @@ function setupWatcher(rootDir: string, opts: { engine?: string; dbPath?: string
|
|
|
177
180
|
throw new DbError('No graph.db found. Run `codegraph build` first.', { file: dbPath });
|
|
178
181
|
}
|
|
179
182
|
|
|
183
|
+
// Load repo config so ignoreDirs and ignoreAdditionalDirs are respected by
|
|
184
|
+
// the watcher the same way they are by collectFiles in the batch build path.
|
|
185
|
+
const config = loadConfig(rootDir);
|
|
186
|
+
const extraDirs = [...(config.ignoreDirs ?? []), ...(config.ignoreAdditionalDirs ?? [])];
|
|
187
|
+
const ignoreSet = buildIgnoreSet(extraDirs.length ? extraDirs : undefined);
|
|
188
|
+
|
|
180
189
|
const db = openDb(dbPath);
|
|
181
190
|
initSchema(db);
|
|
182
191
|
const engineOpts: import('../../types.js').EngineOpts = {
|
|
@@ -205,6 +214,7 @@ function setupWatcher(rootDir: string, opts: { engine?: string; dbPath?: string
|
|
|
205
214
|
pending: new Set<string>(),
|
|
206
215
|
timer: null,
|
|
207
216
|
debounceMs: 300,
|
|
217
|
+
ignoreSet,
|
|
208
218
|
};
|
|
209
219
|
}
|
|
210
220
|
|
|
@@ -223,7 +233,7 @@ function startPollingWatcher(ctx: WatcherContext, pollIntervalMs: number): () =>
|
|
|
223
233
|
const mtimeMap = new Map<string, number>();
|
|
224
234
|
|
|
225
235
|
const initial: string[] = [];
|
|
226
|
-
collectTrackedFiles(ctx.rootDir, initial);
|
|
236
|
+
collectTrackedFiles(ctx.rootDir, initial, ctx.ignoreSet);
|
|
227
237
|
for (const f of initial) {
|
|
228
238
|
try {
|
|
229
239
|
mtimeMap.set(f, fs.statSync(f).mtimeMs);
|
|
@@ -235,7 +245,7 @@ function startPollingWatcher(ctx: WatcherContext, pollIntervalMs: number): () =>
|
|
|
235
245
|
|
|
236
246
|
const pollTimer = setInterval(() => {
|
|
237
247
|
const current: string[] = [];
|
|
238
|
-
collectTrackedFiles(ctx.rootDir, current);
|
|
248
|
+
collectTrackedFiles(ctx.rootDir, current, ctx.ignoreSet);
|
|
239
249
|
const currentSet = new Set(current);
|
|
240
250
|
|
|
241
251
|
for (const f of current) {
|
|
@@ -270,7 +280,7 @@ function startPollingWatcher(ctx: WatcherContext, pollIntervalMs: number): () =>
|
|
|
270
280
|
function startNativeWatcher(ctx: WatcherContext): () => void {
|
|
271
281
|
const watcher = fs.watch(ctx.rootDir, { recursive: true }, (_eventType, filename) => {
|
|
272
282
|
if (!filename) return;
|
|
273
|
-
if (shouldIgnorePath(filename)) return;
|
|
283
|
+
if (shouldIgnorePath(filename, ctx.ignoreSet)) return;
|
|
274
284
|
if (!isSupportedFile(filename)) return;
|
|
275
285
|
|
|
276
286
|
ctx.pending.add(path.join(ctx.rootDir, filename));
|