gitnexus 1.6.8-rc.9 → 1.6.8
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 +3 -3
- package/dist/_shared/graph/types.d.ts +31 -1
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +11 -1
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +6 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.d.ts +21 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +6 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +31 -1
- package/dist/cli/ai-context.js +18 -16
- package/dist/cli/analyze-config.js +11 -0
- package/dist/cli/analyze.d.ts +14 -0
- package/dist/cli/analyze.js +98 -0
- package/dist/cli/embedding-dims.d.ts +33 -0
- package/dist/cli/embedding-dims.js +39 -0
- package/dist/cli/eval-server.d.ts +8 -0
- package/dist/cli/eval-server.js +242 -2
- package/dist/cli/help-i18n.js +19 -0
- package/dist/cli/i18n/en.d.ts +15 -1
- package/dist/cli/i18n/en.js +15 -1
- package/dist/cli/i18n/resources.d.ts +29 -1
- package/dist/cli/i18n/zh-CN.d.ts +14 -0
- package/dist/cli/i18n/zh-CN.js +15 -1
- package/dist/cli/index.js +89 -1
- package/dist/cli/mcp.d.ts +6 -1
- package/dist/cli/mcp.js +26 -1
- package/dist/cli/optional-grammars.d.ts +6 -8
- package/dist/cli/optional-grammars.js +8 -11
- package/dist/cli/setup.d.ts +3 -1
- package/dist/cli/setup.js +67 -17
- package/dist/cli/skill-gen.js +2 -1
- package/dist/cli/tool.d.ts +19 -1
- package/dist/cli/tool.js +96 -3
- package/dist/core/embeddings/hf-env.d.ts +0 -66
- package/dist/core/embeddings/http-client.d.ts +7 -0
- package/dist/core/embeddings/http-client.js +5 -3
- package/dist/core/embeddings/server-mapping.d.ts +1 -1
- package/dist/core/embeddings/server-mapping.js +7 -3
- package/dist/core/graph/import-cycles.d.ts +10 -0
- package/dist/core/graph/import-cycles.js +103 -0
- package/dist/core/group/cross-impact.d.ts +2 -1
- package/dist/core/group/cross-impact.js +5 -1
- package/dist/core/group/extractors/grpc-patterns/proto.js +10 -6
- package/dist/core/group/extractors/http-patterns/kotlin.js +7 -7
- package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
- package/dist/core/group/extractors/http-route-extractor.js +22 -4
- package/dist/core/group/extractors/include-extractor.js +22 -13
- package/dist/core/group/sync.d.ts +27 -1
- package/dist/core/group/sync.js +0 -0
- package/dist/core/incremental/subgraph-extract.js +18 -1
- package/dist/core/ingestion/cfg/cfg-builder.d.ts +114 -0
- package/dist/core/ingestion/cfg/cfg-builder.js +196 -0
- package/dist/core/ingestion/cfg/collect.d.ts +51 -0
- package/dist/core/ingestion/cfg/collect.js +77 -0
- package/dist/core/ingestion/cfg/control-dependence.d.ts +58 -0
- package/dist/core/ingestion/cfg/control-dependence.js +182 -0
- package/dist/core/ingestion/cfg/control-flow-context.d.ts +106 -0
- package/dist/core/ingestion/cfg/control-flow-context.js +124 -0
- package/dist/core/ingestion/cfg/emit.d.ts +293 -0
- package/dist/core/ingestion/cfg/emit.js +646 -0
- package/dist/core/ingestion/cfg/post-dominators.d.ts +79 -0
- package/dist/core/ingestion/cfg/post-dominators.js +176 -0
- package/dist/core/ingestion/cfg/reaching-def-reason-codec.d.ts +106 -0
- package/dist/core/ingestion/cfg/reaching-def-reason-codec.js +133 -0
- package/dist/core/ingestion/cfg/reaching-defs-graph.d.ts +18 -0
- package/dist/core/ingestion/cfg/reaching-defs-graph.js +312 -0
- package/dist/core/ingestion/cfg/reaching-defs.d.ts +162 -0
- package/dist/core/ingestion/cfg/reaching-defs.js +785 -0
- package/dist/core/ingestion/cfg/synthetic-escape.d.ts +124 -0
- package/dist/core/ingestion/cfg/synthetic-escape.js +300 -0
- package/dist/core/ingestion/cfg/traversal-result.d.ts +20 -0
- package/dist/core/ingestion/cfg/traversal-result.js +2 -0
- package/dist/core/ingestion/cfg/types.d.ts +274 -0
- package/dist/core/ingestion/cfg/types.js +13 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.d.ts +111 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.js +541 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp.d.ts +74 -0
- package/dist/core/ingestion/cfg/visitors/c-cpp.js +584 -0
- package/dist/core/ingestion/cfg/visitors/call-site-harvest.d.ts +195 -0
- package/dist/core/ingestion/cfg/visitors/call-site-harvest.js +350 -0
- package/dist/core/ingestion/cfg/visitors/csharp-harvest.d.ts +124 -0
- package/dist/core/ingestion/cfg/visitors/csharp-harvest.js +589 -0
- package/dist/core/ingestion/cfg/visitors/csharp.d.ts +87 -0
- package/dist/core/ingestion/cfg/visitors/csharp.js +867 -0
- package/dist/core/ingestion/cfg/visitors/dart-harvest.d.ts +278 -0
- package/dist/core/ingestion/cfg/visitors/dart-harvest.js +870 -0
- package/dist/core/ingestion/cfg/visitors/dart.d.ts +119 -0
- package/dist/core/ingestion/cfg/visitors/dart.js +836 -0
- package/dist/core/ingestion/cfg/visitors/go-harvest.d.ts +160 -0
- package/dist/core/ingestion/cfg/visitors/go-harvest.js +621 -0
- package/dist/core/ingestion/cfg/visitors/go.d.ts +108 -0
- package/dist/core/ingestion/cfg/visitors/go.js +638 -0
- package/dist/core/ingestion/cfg/visitors/java-harvest.d.ts +108 -0
- package/dist/core/ingestion/cfg/visitors/java-harvest.js +513 -0
- package/dist/core/ingestion/cfg/visitors/java.d.ts +101 -0
- package/dist/core/ingestion/cfg/visitors/java.js +812 -0
- package/dist/core/ingestion/cfg/visitors/kotlin-harvest.d.ts +253 -0
- package/dist/core/ingestion/cfg/visitors/kotlin-harvest.js +719 -0
- package/dist/core/ingestion/cfg/visitors/kotlin.d.ts +121 -0
- package/dist/core/ingestion/cfg/visitors/kotlin.js +809 -0
- package/dist/core/ingestion/cfg/visitors/php-harvest.d.ts +172 -0
- package/dist/core/ingestion/cfg/visitors/php-harvest.js +626 -0
- package/dist/core/ingestion/cfg/visitors/php.d.ts +96 -0
- package/dist/core/ingestion/cfg/visitors/php.js +721 -0
- package/dist/core/ingestion/cfg/visitors/python-harvest.d.ts +212 -0
- package/dist/core/ingestion/cfg/visitors/python-harvest.js +739 -0
- package/dist/core/ingestion/cfg/visitors/python.d.ts +103 -0
- package/dist/core/ingestion/cfg/visitors/python.js +558 -0
- package/dist/core/ingestion/cfg/visitors/ruby-harvest.d.ts +223 -0
- package/dist/core/ingestion/cfg/visitors/ruby-harvest.js +587 -0
- package/dist/core/ingestion/cfg/visitors/ruby.d.ts +112 -0
- package/dist/core/ingestion/cfg/visitors/ruby.js +756 -0
- package/dist/core/ingestion/cfg/visitors/rust-harvest.d.ts +324 -0
- package/dist/core/ingestion/cfg/visitors/rust-harvest.js +873 -0
- package/dist/core/ingestion/cfg/visitors/rust.d.ts +95 -0
- package/dist/core/ingestion/cfg/visitors/rust.js +558 -0
- package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.d.ts +87 -0
- package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.js +116 -0
- package/dist/core/ingestion/cfg/visitors/swift-harvest.d.ts +255 -0
- package/dist/core/ingestion/cfg/visitors/swift-harvest.js +679 -0
- package/dist/core/ingestion/cfg/visitors/swift.d.ts +116 -0
- package/dist/core/ingestion/cfg/visitors/swift.js +787 -0
- package/dist/core/ingestion/cfg/visitors/typescript-harvest.d.ts +149 -0
- package/dist/core/ingestion/cfg/visitors/typescript-harvest.js +1056 -0
- package/dist/core/ingestion/cfg/visitors/typescript.d.ts +66 -0
- package/dist/core/ingestion/cfg/visitors/typescript.js +583 -0
- package/dist/core/ingestion/import-resolvers/utils.js +2 -0
- package/dist/core/ingestion/language-provider.d.ts +11 -0
- package/dist/core/ingestion/languages/c-cpp.js +6 -1
- package/dist/core/ingestion/languages/cobol.js +4 -0
- package/dist/core/ingestion/languages/cpp/arity-metadata.js +41 -2
- package/dist/core/ingestion/languages/cpp/captures.js +50 -1
- package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +2 -0
- package/dist/core/ingestion/languages/cpp/conversion-rank.js +89 -0
- package/dist/core/ingestion/languages/cpp/header-scan.d.ts +1 -1
- package/dist/core/ingestion/languages/cpp/header-scan.js +2 -2
- package/dist/core/ingestion/languages/cpp/inline-namespaces.js +7 -2
- package/dist/core/ingestion/languages/cpp/member-lookup.js +2 -1
- package/dist/core/ingestion/languages/cpp/query.js +23 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +2 -1
- package/dist/core/ingestion/languages/csharp.js +2 -0
- package/dist/core/ingestion/languages/dart.js +2 -0
- package/dist/core/ingestion/languages/go.js +2 -0
- package/dist/core/ingestion/languages/java.js +3 -0
- package/dist/core/ingestion/languages/kotlin/query.js +3 -2
- package/dist/core/ingestion/languages/kotlin.js +3 -0
- package/dist/core/ingestion/languages/php.js +2 -0
- package/dist/core/ingestion/languages/python.js +2 -0
- package/dist/core/ingestion/languages/ruby.js +2 -0
- package/dist/core/ingestion/languages/rust.js +2 -0
- package/dist/core/ingestion/languages/swift.js +2 -0
- package/dist/core/ingestion/languages/typescript.js +5 -0
- package/dist/core/ingestion/languages/vue.js +6 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.js +6 -13
- package/dist/core/ingestion/method-extractors/generic.js +1 -0
- package/dist/core/ingestion/method-types.d.ts +2 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
- package/dist/core/ingestion/model/symbol-table.js +1 -0
- package/dist/core/ingestion/mro-processor.js +109 -0
- package/dist/core/ingestion/parsing-processor.js +23 -0
- package/dist/core/ingestion/pipeline-phases/call-summaries.d.ts +26 -0
- package/dist/core/ingestion/pipeline-phases/call-summaries.js +46 -0
- package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/index.js +2 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +0 -21
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +18 -1
- package/dist/core/ingestion/pipeline-phases/routes.d.ts +10 -0
- package/dist/core/ingestion/pipeline-phases/routes.js +30 -1
- package/dist/core/ingestion/pipeline-phases/taint-summaries.d.ts +30 -0
- package/dist/core/ingestion/pipeline-phases/taint-summaries.js +81 -0
- package/dist/core/ingestion/pipeline.d.ts +92 -10
- package/dist/core/ingestion/pipeline.js +11 -2
- package/dist/core/ingestion/scope-extractor.js +12 -2
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +9 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +75 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +67 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +12 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +14 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +6 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +13 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +9 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +28 -2
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +4 -0
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +9 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +6 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +174 -40
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +24 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +276 -190
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +43 -3
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +75 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +349 -1
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
- package/dist/core/ingestion/taint/call-summary-codec.d.ts +75 -0
- package/dist/core/ingestion/taint/call-summary-codec.js +128 -0
- package/dist/core/ingestion/taint/call-summary-emit.d.ts +43 -0
- package/dist/core/ingestion/taint/call-summary-emit.js +70 -0
- package/dist/core/ingestion/taint/call-summary-harvest.d.ts +77 -0
- package/dist/core/ingestion/taint/call-summary-harvest.js +179 -0
- package/dist/core/ingestion/taint/call-summary-model.d.ts +47 -0
- package/dist/core/ingestion/taint/call-summary-model.js +25 -0
- package/dist/core/ingestion/taint/emit.d.ts +125 -0
- package/dist/core/ingestion/taint/emit.js +208 -0
- package/dist/core/ingestion/taint/interproc-emit.d.ts +50 -0
- package/dist/core/ingestion/taint/interproc-emit.js +88 -0
- package/dist/core/ingestion/taint/interproc-solver.d.ts +110 -0
- package/dist/core/ingestion/taint/interproc-solver.js +312 -0
- package/dist/core/ingestion/taint/match.d.ts +153 -0
- package/dist/core/ingestion/taint/match.js +278 -0
- package/dist/core/ingestion/taint/path-codec.d.ts +134 -0
- package/dist/core/ingestion/taint/path-codec.js +190 -0
- package/dist/core/ingestion/taint/propagate.d.ts +216 -0
- package/dist/core/ingestion/taint/propagate.js +659 -0
- package/dist/core/ingestion/taint/site-safety.d.ts +29 -0
- package/dist/core/ingestion/taint/site-safety.js +98 -0
- package/dist/core/ingestion/taint/source-sink-config.d.ts +107 -23
- package/dist/core/ingestion/taint/source-sink-config.js +35 -12
- package/dist/core/ingestion/taint/source-sink-registry.d.ts +6 -4
- package/dist/core/ingestion/taint/source-sink-registry.js +6 -4
- package/dist/core/ingestion/taint/summary-harvest-driver.d.ts +80 -0
- package/dist/core/ingestion/taint/summary-harvest-driver.js +179 -0
- package/dist/core/ingestion/taint/summary-harvest.d.ts +89 -0
- package/dist/core/ingestion/taint/summary-harvest.js +537 -0
- package/dist/core/ingestion/taint/summary-model.d.ts +200 -0
- package/dist/core/ingestion/taint/summary-model.js +86 -0
- package/dist/core/ingestion/taint/typescript-model.d.ts +38 -0
- package/dist/core/ingestion/taint/typescript-model.js +102 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +21 -0
- package/dist/core/ingestion/utils/env.d.ts +7 -0
- package/dist/core/ingestion/utils/env.js +12 -0
- package/dist/core/ingestion/utils/method-props.js +1 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +13 -0
- package/dist/core/ingestion/workers/parse-worker.js +76 -17
- package/dist/core/ingestion/workers/worker-pool.d.ts +9 -40
- package/dist/core/ingestion/workers/worker-pool.js +15 -2
- package/dist/core/lbug/csv-generator.d.ts +51 -3
- package/dist/core/lbug/csv-generator.js +369 -255
- package/dist/core/lbug/lbug-adapter.d.ts +58 -18
- package/dist/core/lbug/lbug-adapter.js +346 -84
- package/dist/core/lbug/lbug-config.d.ts +19 -0
- package/dist/core/lbug/lbug-config.js +29 -0
- package/dist/core/lbug/pdg-emit-sink.d.ts +127 -0
- package/dist/core/lbug/pdg-emit-sink.js +358 -0
- package/dist/core/lbug/pool-adapter.d.ts +35 -0
- package/dist/core/lbug/pool-adapter.js +90 -1
- package/dist/core/lbug/rel-pair-routing.d.ts +54 -0
- package/dist/core/lbug/rel-pair-routing.js +140 -0
- package/dist/core/lbug/schema.d.ts +2 -2
- package/dist/core/lbug/schema.js +3 -0
- package/dist/core/logger.d.ts +0 -5
- package/dist/core/run-analyze.d.ts +96 -0
- package/dist/core/run-analyze.js +207 -3
- package/dist/core/tree-sitter/parser-loader.js +5 -4
- package/dist/core/tree-sitter/safe-parse.d.ts +0 -5
- package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
- package/dist/core/tree-sitter/vendored-grammars.js +57 -0
- package/dist/core/wiki/generator.js +3 -1
- package/dist/core/wiki/graph-queries.d.ts +6 -0
- package/dist/core/wiki/graph-queries.js +9 -1
- package/dist/mcp/http-transport.d.ts +134 -0
- package/dist/mcp/http-transport.js +503 -0
- package/dist/mcp/local/local-backend.d.ts +110 -24
- package/dist/mcp/local/local-backend.js +1225 -19
- package/dist/mcp/local/pdg-impact.d.ts +384 -0
- package/dist/mcp/local/pdg-impact.js +1972 -0
- package/dist/mcp/resources.js +13 -1
- package/dist/mcp/tools.d.ts +12 -0
- package/dist/mcp/tools.js +214 -7
- package/dist/server/analyze-launch.d.ts +29 -0
- package/dist/server/analyze-launch.js +137 -0
- package/dist/server/analyze-upload.d.ts +33 -0
- package/dist/server/analyze-upload.js +123 -0
- package/dist/server/analyze-worker.d.ts +17 -1
- package/dist/server/api.d.ts +17 -0
- package/dist/server/api.js +132 -168
- package/dist/server/git-clone.d.ts +43 -2
- package/dist/server/git-clone.js +211 -16
- package/dist/server/mcp-http.d.ts +5 -6
- package/dist/server/mcp-http.js +9 -82
- package/dist/server/middleware.d.ts +40 -0
- package/dist/server/middleware.js +92 -0
- package/dist/server/private-ip.d.ts +1 -0
- package/dist/server/private-ip.js +15 -0
- package/dist/server/upload-ingest.d.ts +56 -0
- package/dist/server/upload-ingest.js +276 -0
- package/dist/server/upload-paths.d.ts +37 -0
- package/dist/server/upload-paths.js +57 -0
- package/dist/server/upload-sweep.d.ts +20 -0
- package/dist/server/upload-sweep.js +57 -0
- package/dist/storage/git.js +5 -8
- package/dist/storage/parse-cache.d.ts +22 -1
- package/dist/storage/parse-cache.js +41 -10
- package/dist/storage/repo-manager.d.ts +121 -10
- package/dist/storage/repo-manager.js +43 -5
- package/dist/types/pipeline.d.ts +9 -0
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +110 -10
- package/hooks/claude/gitnexus-hook.cjs +110 -13
- package/hooks/claude/hook-db-lock-probe.cjs +513 -26
- package/package.json +8 -2
- package/scripts/assert-publish-grammar-coverage.cjs +31 -0
- package/scripts/build-tree-sitter-grammars.cjs +16 -10
- package/scripts/cross-platform-tests.ts +1 -0
- package/skills/gitnexus-debugging.md +16 -4
- package/skills/gitnexus-exploring.md +3 -3
- package/skills/gitnexus-guide.md +33 -0
- package/skills/gitnexus-pdg-query.md +89 -0
- package/skills/gitnexus-refactoring.md +1 -1
- package/skills/gitnexus-taint-analysis.md +178 -0
- package/vendor/tree-sitter-c/package.json +1 -1
- package/vendor/tree-sitter-dart/package.json +1 -1
- package/vendor/tree-sitter-kotlin/package.json +1 -1
- package/vendor/tree-sitter-proto/package.json +1 -1
- package/vendor/tree-sitter-swift/package.json +1 -1
- package/web/assets/{agent-CKPMqImC.js → agent-D3Xd7zZE.js} +123 -123
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-ChH9xW-N.js +36 -0
- package/web/assets/{blockDiagram-7IZFK4PR-B4niSLvR.js → blockDiagram-7IZFK4PR-BkWhpzWB.js} +1 -1
- package/web/assets/{c4Diagram-Y2BXMSZH-DIzEXalR.js → c4Diagram-Y2BXMSZH-DtBvpzWD.js} +1 -1
- package/web/assets/{chunk-3SSMPTDK-BzGeeheI.js → chunk-3SSMPTDK-B4_etUhr.js} +2 -2
- package/web/assets/{chunk-5IMINLNL-CnTLsXIV.js → chunk-5IMINLNL-DOdTeQri.js} +1 -1
- package/web/assets/{chunk-5VCL7Z4A-w1BCx98Z.js → chunk-5VCL7Z4A-CQ-2dYWj.js} +1 -1
- package/web/assets/chunk-6764PJDD-DpIS7hxD.js +1 -0
- package/web/assets/{chunk-67TQ5CYL-CChC2cAv.js → chunk-67TQ5CYL-4sNPJU1q.js} +3 -3
- package/web/assets/{chunk-7W6UQGC5-CgFyfZ6k.js → chunk-7W6UQGC5-KyEG0HQg.js} +1 -1
- package/web/assets/{chunk-AZZRMDJM-5E9ARdDQ.js → chunk-AZZRMDJM-y-xJBuMz.js} +1 -1
- package/web/assets/{chunk-INKRHTLW-ELpfuk9h.js → chunk-INKRHTLW-Nu4ri9P-.js} +1 -1
- package/web/assets/{chunk-JQRUD6KW-Dcq_Qnyy.js → chunk-JQRUD6KW-Dbva2Z17.js} +1 -1
- package/web/assets/{chunk-KGFNY3KK-W-VR57xb.js → chunk-KGFNY3KK-JGMJvKCK.js} +1 -1
- package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +161 -0
- package/web/assets/{chunk-KNLZD3CH-BuZBOcso.js → chunk-KNLZD3CH-BGlP6X9R.js} +1 -1
- package/web/assets/{chunk-KRXBNO2N-DH2NPM7I.js → chunk-KRXBNO2N-BW5o0KUN.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-zoomRtWX.js} +1 -1
- package/web/assets/{chunk-LII3EMHJ-3X33tCpU.js → chunk-LII3EMHJ-D-jm-dLa.js} +1 -1
- package/web/assets/{chunk-QA3QBVWF-D5Ha3GgB.js → chunk-QA3QBVWF-BgRW3SXd.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-DD0B2N2B.js} +1 -1
- package/web/assets/{chunk-T2UQINTJ-kGYG7ppP.js → chunk-T2UQINTJ-DSBqkzH7.js} +1 -1
- package/web/assets/chunk-T5OCTHI4-DdZvN-9i.js +1 -0
- package/web/assets/{chunk-UY5QBCOK-Du-c56gs.js → chunk-UY5QBCOK-DyF0vyGd.js} +1 -1
- package/web/assets/{chunk-W44A43WB-lrCpuupA.js → chunk-W44A43WB-JqMLIpR0.js} +1 -1
- package/web/assets/{chunk-ZXARS5L4-CSZRiyOf.js → chunk-ZXARS5L4-CxN8oiwI.js} +1 -1
- package/web/assets/classDiagram-KGZ6W3CR-DJm9BgF-.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-DJm9BgF-.js +1 -0
- package/web/assets/{context-builder-_HS0v2ma.js → context-builder-BHiFUA8O.js} +10 -2
- package/web/assets/{cose-bilkent-UX7MHV2Q-BHv2bbtl.js → cose-bilkent-UX7MHV2Q-D71wNYRJ.js} +1 -1
- package/web/assets/dagre-ND4H6XIP-BIkxmhcu.js +4 -0
- package/web/assets/diagram-3NCE3AQN-BTa6iH0T.js +43 -0
- package/web/assets/diagram-GF46GFSD-DZDV0vBj.js +24 -0
- package/web/assets/{diagram-HNR7UZ2L-fUWreZzx.js → diagram-HNR7UZ2L-DFCfd5LI.js} +2 -2
- package/web/assets/diagram-QXG6HAR7-BzM--Jj0.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-DFFwz0k4.js +10 -0
- package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-CfHMJJqo.js} +1 -1
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +1 -0
- package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-Be805QiJ.js} +3 -3
- package/web/assets/{ganttDiagram-JCBTUEKG-BHQssTz6.js → ganttDiagram-JCBTUEKG-D3iL2Aet.js} +1 -1
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +106 -0
- package/web/assets/index-BvYev1UJ.js +635 -0
- package/web/assets/index-_lgn7hs5.css +2 -0
- package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-Y7BKSoke.js +2 -0
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CT4SHFuI.js} +1 -1
- package/web/assets/{journeyDiagram-M6C3CM3L-DNPYCpvq.js → journeyDiagram-M6C3CM3L-CvArszLo.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-C6yDxr7N.js} +3 -3
- package/web/assets/{katex-K3KEBU37-CrVLz8l7.js → katex-K3KEBU37-CTc5BslQ.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-BOc2WEne.js} +1 -1
- package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +1 -0
- package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-Cvc0f_Pd.js} +1 -1
- package/web/assets/{quadrantDiagram-VICAPDV7-bAm6Hi_5.js → quadrantDiagram-VICAPDV7-yXSZ2lLz.js} +1 -1
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +1 -0
- package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-BRcZvHs4.js} +1 -1
- package/web/assets/{sankeyDiagram-URQDO5SZ-LFJz53u5.js → sankeyDiagram-URQDO5SZ-1qEjlFIB.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-PcSCuvrB.js} +3 -3
- package/web/assets/stateDiagram-7D4R322I-D6qYSV1E.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-Bg-ImOSX.js +1 -0
- package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-QWkh01xw.js} +1 -1
- package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +1 -0
- package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-ak4DfwuM.js} +3 -3
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +1 -0
- package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-CTzR4Loq.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-DA1BEaQz.js} +1 -1
- package/web/index.html +13 -15
- package/scripts/materialize-vendor-grammars.cjs +0 -97
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-D1EXI0zA.js +0 -36
- package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +0 -4
- package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +0 -1
- package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +0 -159
- package/web/assets/chunk-6764PJDD-ChwMM2z4.js +0 -1
- package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +0 -10
- package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +0 -1
- package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +0 -1
- package/web/assets/chunk-CilyBKbf.js +0 -1
- package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +0 -1
- package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +0 -1
- package/web/assets/chunk-RERM46MO-DQNbXtfw.js +0 -1
- package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +0 -1
- package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +0 -1
- package/web/assets/chunk-T5OCTHI4--9wWpVws.js +0 -1
- package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +0 -1
- package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +0 -1
- package/web/assets/classDiagram-KGZ6W3CR-Bv93af_b.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-CLfEqHUa.js +0 -1
- package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +0 -4
- package/web/assets/diagram-3NCE3AQN-BqAtKUpW.js +0 -43
- package/web/assets/diagram-GF46GFSD-CaBG6n6o.js +0 -24
- package/web/assets/diagram-QXG6HAR7-CZ-O3rcV.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-P4lSL4GH.js +0 -10
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +0 -1
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +0 -106
- package/web/assets/index-BKWA-m7o.css +0 -2
- package/web/assets/index-CG6q8eTs.js +0 -626
- package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +0 -1
- package/web/assets/infoDiagram-3YFTVSEB-DmLICZx1.js +0 -2
- package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +0 -1
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +0 -1
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +0 -1
- package/web/assets/stateDiagram-7D4R322I-CB2nABwH.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-COBGd2RL.js +0 -1
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +0 -1
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +0 -1
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +0 -1
- /package/web/assets/{chunk-AQ6EADP3-CCFje6lL.js → chunk-AQ6EADP3-CZhslHi-.js} +0 -0
|
@@ -89,6 +89,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
89
89
|
if (fnDef === undefined) {
|
|
90
90
|
fnDef = pickImplicitThisOverload(site, scopes, workspaceIndex, model, {
|
|
91
91
|
conversionRankFn: options.conversionRankFn,
|
|
92
|
+
conversionOnlyArgTypePrefixes: options.conversionOnlyArgTypePrefixes,
|
|
92
93
|
constraintCompatibility: options.constraintCompatibility,
|
|
93
94
|
});
|
|
94
95
|
fnDefFromImplicitThis = fnDef !== undefined;
|
|
@@ -112,6 +113,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
112
113
|
const narrowed = narrowOverloadCandidates(allCallables, site.arity, site.argumentTypes, {
|
|
113
114
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
114
115
|
conversionRankFn: options.conversionRankFn,
|
|
116
|
+
conversionOnlyArgTypePrefixes: options.conversionOnlyArgTypePrefixes,
|
|
115
117
|
constraintCompatibility: options.constraintCompatibility,
|
|
116
118
|
});
|
|
117
119
|
if (narrowed.length === 1) {
|
|
@@ -190,6 +192,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
190
192
|
const narrowed = narrowOverloadCandidates(ordinary, site.arity, site.argumentTypes, {
|
|
191
193
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
192
194
|
conversionRankFn: options.conversionRankFn,
|
|
195
|
+
conversionOnlyArgTypePrefixes: options.conversionOnlyArgTypePrefixes,
|
|
193
196
|
constraintCompatibility: options.constraintCompatibility,
|
|
194
197
|
});
|
|
195
198
|
if (narrowed.length === 1) {
|
|
@@ -240,6 +243,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
240
243
|
const narrowed = narrowOverloadCandidates(merged, site.arity, site.argumentTypes, {
|
|
241
244
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
242
245
|
conversionRankFn: options.conversionRankFn,
|
|
246
|
+
conversionOnlyArgTypePrefixes: options.conversionOnlyArgTypePrefixes,
|
|
243
247
|
constraintCompatibility: options.constraintCompatibility,
|
|
244
248
|
});
|
|
245
249
|
if (narrowed.length === 1) {
|
|
@@ -285,10 +289,22 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
285
289
|
callerScope: site.inScope,
|
|
286
290
|
scopes,
|
|
287
291
|
})
|
|
288
|
-
: undefined, site.argumentTypes, site.argumentTypeClasses, options.conversionRankFn, scopeDefsCache);
|
|
292
|
+
: undefined, site.argumentTypes, site.argumentTypeClasses, options.conversionRankFn, scopeDefsCache, options.conversionOnlyArgTypePrefixes);
|
|
289
293
|
}
|
|
290
294
|
if (fnDef === undefined)
|
|
291
295
|
continue;
|
|
296
|
+
if (fnDef.isDeleted === true) {
|
|
297
|
+
recordSuppressedOutcome(options.recordResolutionOutcome, {
|
|
298
|
+
phase: 'free-call-fallback',
|
|
299
|
+
filePath: parsed.filePath,
|
|
300
|
+
name: site.name,
|
|
301
|
+
range: site.atRange,
|
|
302
|
+
reason: 'selected-callable-deleted',
|
|
303
|
+
candidates: [fnDef],
|
|
304
|
+
});
|
|
305
|
+
handledSites.add(siteKey(parsed.filePath, site));
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
292
308
|
if ((fnDefFromImplicitThis || fnDef.type === 'Method' || fnDef.type === 'Constructor') &&
|
|
293
309
|
options.isCallableVisibleFromCaller !== undefined &&
|
|
294
310
|
!options.isCallableVisibleFromCaller({
|
|
@@ -310,6 +326,13 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
310
326
|
// means we don't add a new edge — so `emit-references` skips its
|
|
311
327
|
// potentially-wrong fallback for the same site.
|
|
312
328
|
handledSites.add(siteKey(parsed.filePath, site));
|
|
329
|
+
// Resolved-callee-id capture (#2227 U2/KTD6/R8): record this CALLS site's
|
|
330
|
+
// resolved target BEFORE the collapsed `seen` dedup. The free-call dedup
|
|
331
|
+
// key drops the line (one edge per caller→target), so capturing after
|
|
332
|
+
// `seen.has` would lose every same-target call past the first — capture
|
|
333
|
+
// here, per site, keyed on `site.atRange` (byte-equal to U1's
|
|
334
|
+
// SiteRecord.at: 1-based line / 0-based col).
|
|
335
|
+
options.calleeIdSink?.add(parsed.filePath, site.atRange.startLine, site.atRange.startCol, tgtGraphId);
|
|
313
336
|
const relId = `rel:CALLS:${callerGraphId}->${tgtGraphId}`;
|
|
314
337
|
if (seen.has(relId))
|
|
315
338
|
continue;
|
|
@@ -430,7 +453,7 @@ export function buildGlobalClassIndex(scopes) {
|
|
|
430
453
|
* order. Exported for unit testing — the `scopeDefsCache` equivalence is
|
|
431
454
|
* exercised via synthetic stubs in `pick-unique-global-callable.test.ts`.
|
|
432
455
|
*/
|
|
433
|
-
export function pickUniqueGlobalCallable(name, model, globalCallablesBySimpleName, callerFilePath, isFileLocalDef, callArity, isCallerVisible, callArgTypes, callArgTypeClasses, conversionRankFn, scopeDefsCache) {
|
|
456
|
+
export function pickUniqueGlobalCallable(name, model, globalCallablesBySimpleName, callerFilePath, isFileLocalDef, callArity, isCallerVisible, callArgTypes, callArgTypeClasses, conversionRankFn, scopeDefsCache, conversionOnlyArgTypePrefixes) {
|
|
434
457
|
// The scope-index candidate list is a pure function of (name, callerFilePath):
|
|
435
458
|
// the same-name bucket is fixed for the pass, the file-local filter depends
|
|
436
459
|
// only on the candidate + callerFilePath, and the logical-key dedup is
|
|
@@ -492,6 +515,7 @@ export function pickUniqueGlobalCallable(name, model, globalCallablesBySimpleNam
|
|
|
492
515
|
const narrowed = narrowOverloadCandidates(scopeDefs, callArity, callArgTypes, {
|
|
493
516
|
argumentTypeClasses: callArgTypeClasses,
|
|
494
517
|
conversionRankFn,
|
|
518
|
+
conversionOnlyArgTypePrefixes,
|
|
495
519
|
});
|
|
496
520
|
if (narrowed.length === 1)
|
|
497
521
|
return narrowed[0];
|
|
@@ -533,6 +557,7 @@ export function pickUniqueGlobalCallable(name, model, globalCallablesBySimpleNam
|
|
|
533
557
|
const narrowed = narrowOverloadCandidates(defs, callArity, callArgTypes, {
|
|
534
558
|
argumentTypeClasses: callArgTypeClasses,
|
|
535
559
|
conversionRankFn,
|
|
560
|
+
conversionOnlyArgTypePrefixes,
|
|
536
561
|
});
|
|
537
562
|
if (narrowed.length === 1)
|
|
538
563
|
return narrowed[0];
|
|
@@ -675,6 +700,7 @@ export function pickImplicitThisOverload(site, scopes, workspaceIndex, model, ho
|
|
|
675
700
|
const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes, {
|
|
676
701
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
677
702
|
conversionRankFn: hookCtx?.conversionRankFn,
|
|
703
|
+
conversionOnlyArgTypePrefixes: hookCtx?.conversionOnlyArgTypePrefixes,
|
|
678
704
|
constraintCompatibility: hookCtx?.constraintCompatibility,
|
|
679
705
|
});
|
|
680
706
|
if (candidates.length !== 1)
|
|
@@ -69,6 +69,10 @@ export interface OverloadNarrowingHookCtx {
|
|
|
69
69
|
/** Conversion-rank scoring fallback (step 4b). Engages when the
|
|
70
70
|
* exact-type filter rejects every candidate. */
|
|
71
71
|
readonly conversionRankFn?: ConversionRankFn;
|
|
72
|
+
/** Per-language argument-type prefixes whose conversion-rank failures
|
|
73
|
+
* should suppress genuinely ambiguous multi-overload sets instead of
|
|
74
|
+
* falling back to arity-only candidates. */
|
|
75
|
+
readonly conversionOnlyArgTypePrefixes?: readonly string[];
|
|
72
76
|
/** Constraint filter (step 4c). Drops candidates whose template
|
|
73
77
|
* guards (SFINAE `enable_if_t`, C++20 `requires`, future Rust
|
|
74
78
|
* trait bounds, etc.) provably fail at the call site. Three-valued
|
|
@@ -106,6 +106,10 @@ export function narrowOverloadCandidates(overloads, argCount, argTypes, hookCtx)
|
|
|
106
106
|
const ranked = rankByConversion(candidates, argTypes, hookCtx.conversionRankFn, hookCtx.argumentTypeClasses);
|
|
107
107
|
if (ranked.length > 0)
|
|
108
108
|
result = ranked;
|
|
109
|
+
else if (candidates.length > 1 &&
|
|
110
|
+
hasConversionOnlyArgType(argTypes, hookCtx.conversionOnlyArgTypePrefixes)) {
|
|
111
|
+
result = [];
|
|
112
|
+
}
|
|
109
113
|
}
|
|
110
114
|
}
|
|
111
115
|
// Constraint filter (step 4c; Tier-A — SFINAE / `requires` clauses).
|
|
@@ -145,6 +149,11 @@ export function narrowOverloadCandidates(overloads, argCount, argTypes, hookCtx)
|
|
|
145
149
|
}
|
|
146
150
|
return result;
|
|
147
151
|
}
|
|
152
|
+
function hasConversionOnlyArgType(argTypes, prefixes) {
|
|
153
|
+
if (prefixes === undefined || prefixes.length === 0)
|
|
154
|
+
return false;
|
|
155
|
+
return argTypes.some((type) => prefixes.some((prefix) => type.startsWith(prefix)));
|
|
156
|
+
}
|
|
148
157
|
function exactTypeSlotMatches(argType, paramType, argTypeClass, paramTypeClass) {
|
|
149
158
|
if (argType !== paramType)
|
|
150
159
|
return false;
|
|
@@ -43,13 +43,18 @@ import type { SemanticModel } from '../../model/semantic-model.js';
|
|
|
43
43
|
import type { ScopeResolver } from '../contract/scope-resolver.js';
|
|
44
44
|
import type { GraphNodeLookup } from '../graph-bridge/node-lookup.js';
|
|
45
45
|
import type { WorkspaceResolutionIndex } from '../workspace-index.js';
|
|
46
|
+
import type { CalleeIdSink } from '../graph-bridge/callee-id-sink.js';
|
|
46
47
|
import type { ResolutionOutcomeRecorder } from '../resolution-outcome.js';
|
|
47
48
|
/** Subset of `ScopeResolver` consumed by this pass. Accepting the
|
|
48
49
|
* subset rather than the full provider keeps tests and partial
|
|
49
50
|
* refactors lighter — callers only need to populate what we read. */
|
|
50
|
-
type ReceiverBoundProviderSubset = Pick<ScopeResolver, 'isSuperReceiver' | 'isSuperReceiverInContext' | 'fieldFallbackOnMethodLookup' | 'collapseMemberCallsByCallerTarget' | 'unwrapCollectionAccessor' | 'hoistTypeBindingsToModule' | 'resolveQualifiedReceiverMember' | 'resolveReceiverMember' | 'resolveThisViaEnclosingClass' | 'conversionRankFn' | 'constraintCompatibility' | 'isStaticOnly'>;
|
|
51
|
+
type ReceiverBoundProviderSubset = Pick<ScopeResolver, 'isSuperReceiver' | 'isSuperReceiverInContext' | 'fieldFallbackOnMethodLookup' | 'collapseMemberCallsByCallerTarget' | 'unwrapCollectionAccessor' | 'hoistTypeBindingsToModule' | 'resolveQualifiedReceiverMember' | 'resolveReceiverMember' | 'resolveThisViaEnclosingClass' | 'conversionRankFn' | 'conversionOnlyArgTypePrefixes' | 'constraintCompatibility' | 'isStaticOnly'>;
|
|
51
52
|
export declare function emitReceiverBoundCalls(graph: KnowledgeGraph, scopes: ScopeResolutionIndexes, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup, handledSites: Set<string>, provider: ReceiverBoundProviderSubset, index: WorkspaceResolutionIndex, model: SemanticModel, options?: {
|
|
52
53
|
readonly recordResolutionOutcome?: ResolutionOutcomeRecorder;
|
|
54
|
+
/** Resolved-callee-id capture sink (#2227 U2). Threaded in only under
|
|
55
|
+
* `--pdg`; `undefined` ⇒ zero overhead, byte-identity (R4). Per-file
|
|
56
|
+
* capture contexts are built from this + `parsed.filePath` in the loop. */
|
|
57
|
+
readonly calleeIdSink?: CalleeIdSink;
|
|
53
58
|
}): number;
|
|
54
59
|
/**
|
|
55
60
|
* Sentinel returned by `pickOverload` when narrowing leaves >1 candidate
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
*/
|
|
39
39
|
import { collectNamespaceTargets } from '../scope/namespace-targets.js';
|
|
40
40
|
import { findClassBindingInScope, findEnclosingClassDef, findExportedDef, findOwnedMember, findReceiverTypeBinding, findValueBindingInScope, isClassLike, } from '../scope/walkers.js';
|
|
41
|
-
import { tryEmitEdge, tryEmitEdgeWithExplicitTargetId } from '../graph-bridge/edges.js';
|
|
41
|
+
import { tryEmitEdge, tryEmitEdgeWithExplicitTargetId, } from '../graph-bridge/edges.js';
|
|
42
42
|
import { resolveCompoundReceiverClass } from '../passes/compound-receiver.js';
|
|
43
43
|
import { resolveDefGraphId } from '../graph-bridge/ids.js';
|
|
44
44
|
import { narrowOverloadCandidates, isOverloadAmbiguousAfterNormalization, } from './overload-narrowing.js';
|
|
@@ -130,7 +130,7 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
130
130
|
* when the primary receiver-typed edge targeted an Interface's
|
|
131
131
|
* method. Each implementing class's same-named method gets a
|
|
132
132
|
* secondary edge (excluding the primary target itself). */
|
|
133
|
-
const emitInterfaceDispatchFor = (ownerDef, memberName, primaryMemberDef, site, confidence) => {
|
|
133
|
+
const emitInterfaceDispatchFor = (ownerDef, memberName, primaryMemberDef, site, confidence, calleeCapture) => {
|
|
134
134
|
if (ownerDef.type !== 'Interface')
|
|
135
135
|
return 0;
|
|
136
136
|
const impls = implementorsByInterfaceDefId.get(ownerDef.nodeId);
|
|
@@ -138,12 +138,15 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
138
138
|
return 0;
|
|
139
139
|
let n = 0;
|
|
140
140
|
for (const implDef of impls) {
|
|
141
|
-
const implMember =
|
|
142
|
-
if (implMember === undefined
|
|
141
|
+
const implMember = pickOverload(implDef.nodeId, memberName, site, model, provider);
|
|
142
|
+
if (implMember === undefined ||
|
|
143
|
+
implMember === OVERLOAD_AMBIGUOUS ||
|
|
144
|
+
implMember.isDeleted === true) {
|
|
143
145
|
continue;
|
|
146
|
+
}
|
|
144
147
|
if (implMember.nodeId === primaryMemberDef.nodeId)
|
|
145
148
|
continue;
|
|
146
|
-
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, implMember, 'interface-dispatch', seen, confidence, collapse);
|
|
149
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, implMember, 'interface-dispatch', seen, confidence, collapse, calleeCapture);
|
|
147
150
|
if (ok)
|
|
148
151
|
n++;
|
|
149
152
|
}
|
|
@@ -151,6 +154,12 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
151
154
|
};
|
|
152
155
|
for (const parsed of parsedFiles) {
|
|
153
156
|
const namespaceTargets = collectNamespaceTargets(parsed, scopes);
|
|
157
|
+
// Per-file resolved-callee-id capture context (#2227 U2). Built once per
|
|
158
|
+
// file; `undefined` when the sink is absent (pdg off) so the `tryEmitEdge`
|
|
159
|
+
// capture is a no-op and emission stays byte-identical (R4).
|
|
160
|
+
const calleeCapture = options.calleeIdSink !== undefined
|
|
161
|
+
? { sink: options.calleeIdSink, filePath: parsed.filePath }
|
|
162
|
+
: undefined;
|
|
154
163
|
for (const site of parsed.referenceSites) {
|
|
155
164
|
if (site.kind !== 'call' && site.kind !== 'read' && site.kind !== 'write')
|
|
156
165
|
continue;
|
|
@@ -179,12 +188,30 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
179
188
|
? extendsOnly(enclosingClass.nodeId)
|
|
180
189
|
: scopes.methodDispatch.mroFor(enclosingClass.nodeId);
|
|
181
190
|
let memberDef;
|
|
191
|
+
let ambiguousOwnerId;
|
|
182
192
|
for (const ownerId of ancestors) {
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
const picked = site.kind === 'call'
|
|
194
|
+
? pickOverload(ownerId, memberName, site, model, provider)
|
|
195
|
+
: findOwnedMember(ownerId, memberName, model);
|
|
196
|
+
if (picked === OVERLOAD_AMBIGUOUS) {
|
|
197
|
+
ambiguousOwnerId = ownerId;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
if (picked !== undefined) {
|
|
201
|
+
memberDef = picked;
|
|
185
202
|
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (ambiguousOwnerId !== undefined) {
|
|
206
|
+
recordReceiverOverloadSuppression(options.recordResolutionOutcome, parsed.filePath, site, ambiguousOwnerId, memberName, model, provider);
|
|
207
|
+
handledSites.add(siteKey);
|
|
208
|
+
continue;
|
|
186
209
|
}
|
|
187
210
|
if (memberDef !== undefined) {
|
|
211
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
212
|
+
handledSites.add(siteKey);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
188
215
|
// Super/base calls resolve through the MRO chain, not
|
|
189
216
|
// through imports — the ancestor method is found by
|
|
190
217
|
// walking `methodDispatch.mroFor(enclosingClass)`, which
|
|
@@ -201,7 +228,7 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
201
228
|
// superclass via its `import`/`from … import …` binding.
|
|
202
229
|
// Closing that gap requires realigning the legacy tier
|
|
203
230
|
// classifier and is tracked separately.
|
|
204
|
-
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, 'global', seen, 0.85, collapse);
|
|
231
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, 'global', seen, 0.85, collapse, calleeCapture);
|
|
205
232
|
if (ok)
|
|
206
233
|
emitted++;
|
|
207
234
|
// Always mark handled when the site was resolved, even
|
|
@@ -219,9 +246,9 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
219
246
|
if (currentClass !== undefined) {
|
|
220
247
|
const chain = [currentClass.nodeId, ...scopes.methodDispatch.mroFor(currentClass.nodeId)];
|
|
221
248
|
let memberDef;
|
|
249
|
+
let ambiguousOwnerId;
|
|
222
250
|
// Static-only filter (#1756 / U3): same shape as Case 4's
|
|
223
|
-
// chain walk (skip-and-walk-on)
|
|
224
|
-
// narrowing — Case 0 uses `findOwnedMember` directly. When
|
|
251
|
+
// overload-aware chain walk (skip-and-walk-on). When
|
|
225
252
|
// an owner's resolved candidate is static-only (Kotlin
|
|
226
253
|
// companion-promoted), continue to the next ancestor in
|
|
227
254
|
// the MRO chain so a legitimate instance member can bind.
|
|
@@ -233,18 +260,30 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
233
260
|
// shapes like `Logger.create("a")`), so there's no wrong
|
|
234
261
|
// target to suppress.
|
|
235
262
|
for (const ownerId of chain) {
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (
|
|
240
|
-
|
|
263
|
+
const picked = site.kind === 'call'
|
|
264
|
+
? pickFirstNonStaticOnly(ownerId, memberName, site, model, provider)
|
|
265
|
+
: findOwnedMember(ownerId, memberName, model);
|
|
266
|
+
if (picked === OVERLOAD_AMBIGUOUS) {
|
|
267
|
+
ambiguousOwnerId = ownerId;
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
if (picked === STATIC_ONLY_FILTERED || picked === undefined) {
|
|
241
271
|
continue;
|
|
242
272
|
}
|
|
243
|
-
memberDef =
|
|
273
|
+
memberDef = picked;
|
|
244
274
|
break;
|
|
245
275
|
}
|
|
276
|
+
if (ambiguousOwnerId !== undefined) {
|
|
277
|
+
recordReceiverOverloadSuppression(options.recordResolutionOutcome, parsed.filePath, site, ambiguousOwnerId, memberName, model, provider);
|
|
278
|
+
handledSites.add(siteKey);
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
246
281
|
if (memberDef !== undefined) {
|
|
247
|
-
|
|
282
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
283
|
+
handledSites.add(siteKey);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, memberDef.filePath !== parsed.filePath ? 'import-resolved' : 'global', seen, 0.85, collapse, calleeCapture);
|
|
248
287
|
if (ok)
|
|
249
288
|
emitted++;
|
|
250
289
|
// Always mark handled when the site was resolved, even
|
|
@@ -290,13 +329,17 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
290
329
|
}
|
|
291
330
|
if (languageResolution?.kind === 'resolved') {
|
|
292
331
|
const memberDef = languageResolution.definition;
|
|
332
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
333
|
+
handledSites.add(siteKey);
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
293
336
|
const reason = site.kind === 'write' || site.kind === 'read'
|
|
294
337
|
? site.kind
|
|
295
338
|
: memberDef.filePath !== parsed.filePath
|
|
296
339
|
? 'import-resolved'
|
|
297
340
|
: 'global';
|
|
298
341
|
const confidence = site.kind === 'write' || site.kind === 'read' ? 1.0 : 0.85;
|
|
299
|
-
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse);
|
|
342
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse, calleeCapture);
|
|
300
343
|
if (ok)
|
|
301
344
|
emitted++;
|
|
302
345
|
handledSites.add(siteKey);
|
|
@@ -315,6 +358,7 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
315
358
|
const narrowed = narrowOverloadCandidates(methodOverloads, site.arity, site.argumentTypes, {
|
|
316
359
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
317
360
|
conversionRankFn: provider.conversionRankFn,
|
|
361
|
+
conversionOnlyArgTypePrefixes: provider.conversionOnlyArgTypePrefixes,
|
|
318
362
|
constraintCompatibility: provider.constraintCompatibility,
|
|
319
363
|
});
|
|
320
364
|
if (isOverloadAmbiguousAfterNormalization(narrowed, site.arity)) {
|
|
@@ -357,13 +401,17 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
357
401
|
continue;
|
|
358
402
|
}
|
|
359
403
|
if (memberDef !== undefined) {
|
|
404
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
405
|
+
handledSites.add(siteKey);
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
360
408
|
const reason = site.kind === 'write' || site.kind === 'read'
|
|
361
409
|
? site.kind
|
|
362
410
|
: memberDef.filePath !== parsed.filePath
|
|
363
411
|
? 'import-resolved'
|
|
364
412
|
: 'global';
|
|
365
413
|
const confidence = site.kind === 'write' || site.kind === 'read' ? 1.0 : 0.85;
|
|
366
|
-
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse);
|
|
414
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse, calleeCapture);
|
|
367
415
|
if (ok)
|
|
368
416
|
emitted++;
|
|
369
417
|
handledSites.add(siteKey);
|
|
@@ -373,12 +421,17 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
373
421
|
}
|
|
374
422
|
// ── Case 1: namespace receiver ───────────────────────────────
|
|
375
423
|
const targetFiles = namespaceTargets.get(receiverName);
|
|
376
|
-
if (targetFiles !== undefined) {
|
|
424
|
+
if (targetFiles !== undefined && provider.resolveQualifiedReceiverMember === undefined) {
|
|
377
425
|
let found = false;
|
|
378
426
|
for (const targetFile of targetFiles) {
|
|
379
427
|
const memberDef = findExportedDef(targetFile, memberName, index);
|
|
380
428
|
if (memberDef !== undefined) {
|
|
381
|
-
|
|
429
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
430
|
+
handledSites.add(siteKey);
|
|
431
|
+
found = true;
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, memberDef.filePath !== parsed.filePath ? 'import-resolved' : 'global', seen, 0.85, collapse, calleeCapture);
|
|
382
435
|
if (ok)
|
|
383
436
|
emitted++;
|
|
384
437
|
handledSites.add(siteKey);
|
|
@@ -413,7 +466,11 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
413
466
|
continue;
|
|
414
467
|
}
|
|
415
468
|
if (memberDef !== undefined) {
|
|
416
|
-
|
|
469
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
470
|
+
handledSites.add(siteKey);
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, memberDef.filePath !== parsed.filePath ? 'import-resolved' : 'global', seen, 0.85, collapse, calleeCapture);
|
|
417
474
|
if (ok)
|
|
418
475
|
emitted++;
|
|
419
476
|
handledSites.add(siteKey);
|
|
@@ -425,9 +482,17 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
425
482
|
if (classDef !== undefined) {
|
|
426
483
|
const chain = [classDef.nodeId, ...scopes.methodDispatch.mroFor(classDef.nodeId)];
|
|
427
484
|
let memberDef;
|
|
485
|
+
let ambiguousOwnerId;
|
|
428
486
|
for (const ownerId of chain) {
|
|
429
|
-
|
|
430
|
-
|
|
487
|
+
const picked = site.kind === 'call'
|
|
488
|
+
? pickOverload(ownerId, memberName, site, model, provider)
|
|
489
|
+
: findOwnedMember(ownerId, memberName, model);
|
|
490
|
+
if (picked === OVERLOAD_AMBIGUOUS) {
|
|
491
|
+
ambiguousOwnerId = ownerId;
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
if (picked !== undefined) {
|
|
495
|
+
memberDef = picked;
|
|
431
496
|
// The MRO chain is most-derived-first ([classDef, ...ancestors]).
|
|
432
497
|
// If the most-derived definition is arity-incompatible with the
|
|
433
498
|
// call site, PHP throws ArgumentCountError at runtime — it does
|
|
@@ -441,14 +506,23 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
441
506
|
break;
|
|
442
507
|
}
|
|
443
508
|
}
|
|
509
|
+
if (ambiguousOwnerId !== undefined) {
|
|
510
|
+
recordReceiverOverloadSuppression(options.recordResolutionOutcome, parsed.filePath, site, ambiguousOwnerId, memberName, model, provider);
|
|
511
|
+
handledSites.add(siteKey);
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
444
514
|
if (memberDef !== undefined) {
|
|
515
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
516
|
+
handledSites.add(siteKey);
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
445
519
|
const reason = site.kind === 'write' || site.kind === 'read'
|
|
446
520
|
? site.kind
|
|
447
521
|
: memberDef.filePath !== parsed.filePath
|
|
448
522
|
? 'import-resolved'
|
|
449
523
|
: 'global';
|
|
450
524
|
const confidence = site.kind === 'write' || site.kind === 'read' ? 1.0 : 0.85;
|
|
451
|
-
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse);
|
|
525
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse, calleeCapture);
|
|
452
526
|
if (ok)
|
|
453
527
|
emitted++;
|
|
454
528
|
handledSites.add(siteKey);
|
|
@@ -466,9 +540,26 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
466
540
|
for (const targetFile3 of targetFiles3) {
|
|
467
541
|
const classDef3 = findExportedDef(targetFile3, className, index);
|
|
468
542
|
if (classDef3 !== undefined) {
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
543
|
+
const picked = site.kind === 'call'
|
|
544
|
+
? pickOverload(classDef3.nodeId, memberName, site, model, provider)
|
|
545
|
+
: findOwnedMember(classDef3.nodeId, memberName, model);
|
|
546
|
+
if (picked === OVERLOAD_AMBIGUOUS) {
|
|
547
|
+
recordReceiverOverloadSuppression(options.recordResolutionOutcome, parsed.filePath, site, classDef3.nodeId, memberName, model, provider);
|
|
548
|
+
handledSites.add(siteKey);
|
|
549
|
+
found3 = true;
|
|
550
|
+
break;
|
|
551
|
+
}
|
|
552
|
+
if (picked !== undefined) {
|
|
553
|
+
const memberDef = picked;
|
|
554
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
555
|
+
handledSites.add(siteKey);
|
|
556
|
+
found3 = true;
|
|
557
|
+
break;
|
|
558
|
+
}
|
|
559
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, memberDef.filePath !== parsed.filePath ? 'import-resolved' : 'global', seen,
|
|
560
|
+
// Explicit defaults so the trailing capture ctx (#2227 U2) can
|
|
561
|
+
// be threaded without changing dedup/confidence behavior.
|
|
562
|
+
0.85, false, calleeCapture);
|
|
472
563
|
if (ok) {
|
|
473
564
|
emitted++;
|
|
474
565
|
handledSites.add(siteKey);
|
|
@@ -504,8 +595,9 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
504
595
|
if (ownerDef !== undefined) {
|
|
505
596
|
const chain = [ownerDef.nodeId, ...scopes.methodDispatch.mroFor(ownerDef.nodeId)];
|
|
506
597
|
let memberDef;
|
|
507
|
-
|
|
508
|
-
//
|
|
598
|
+
let ambiguousOwnerId;
|
|
599
|
+
// Static-only filter (#1756 / U3): mirrors Case 0's
|
|
600
|
+
// overload-aware chain walk. When
|
|
509
601
|
// a static-only candidate is found at an ancestor, walk on
|
|
510
602
|
// so a legitimate instance member can bind. If the entire
|
|
511
603
|
// chain is static-only, no edge is emitted (Case 3b is fed
|
|
@@ -513,17 +605,30 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
513
605
|
// `emitReferencesViaLookup` for compound shapes, so no
|
|
514
606
|
// handled-site marker is needed for chain-only-static).
|
|
515
607
|
for (const ownerId of chain) {
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (
|
|
608
|
+
const picked = site.kind === 'call'
|
|
609
|
+
? pickFirstNonStaticOnly(ownerId, memberName, site, model, provider)
|
|
610
|
+
: findOwnedMember(ownerId, memberName, model);
|
|
611
|
+
if (picked === OVERLOAD_AMBIGUOUS) {
|
|
612
|
+
ambiguousOwnerId = ownerId;
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
615
|
+
if (picked === STATIC_ONLY_FILTERED || picked === undefined) {
|
|
520
616
|
continue;
|
|
521
617
|
}
|
|
522
|
-
memberDef =
|
|
618
|
+
memberDef = picked;
|
|
523
619
|
break;
|
|
524
620
|
}
|
|
621
|
+
if (ambiguousOwnerId !== undefined) {
|
|
622
|
+
recordReceiverOverloadSuppression(options.recordResolutionOutcome, parsed.filePath, site, ambiguousOwnerId, memberName, model, provider);
|
|
623
|
+
handledSites.add(siteKey);
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
525
626
|
if (memberDef !== undefined) {
|
|
526
|
-
|
|
627
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
628
|
+
handledSites.add(siteKey);
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, memberDef.filePath !== parsed.filePath ? 'import-resolved' : 'global', seen, 0.85, collapse, calleeCapture);
|
|
527
632
|
if (ok)
|
|
528
633
|
emitted++;
|
|
529
634
|
// Always mark handled when the site was resolved, even
|
|
@@ -574,13 +679,17 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
574
679
|
}
|
|
575
680
|
if (languageResolution?.kind === 'resolved') {
|
|
576
681
|
const memberDef = languageResolution.definition;
|
|
682
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
683
|
+
handledSites.add(siteKey);
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
577
686
|
const reason = site.kind === 'write' || site.kind === 'read'
|
|
578
687
|
? site.kind
|
|
579
688
|
: memberDef.filePath !== parsed.filePath
|
|
580
689
|
? 'import-resolved'
|
|
581
690
|
: 'global';
|
|
582
691
|
const confidence = site.kind === 'write' || site.kind === 'read' ? 1.0 : 0.85;
|
|
583
|
-
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse);
|
|
692
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse, calleeCapture);
|
|
584
693
|
if (ok)
|
|
585
694
|
emitted++;
|
|
586
695
|
handledSites.add(siteKey);
|
|
@@ -657,6 +766,10 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
657
766
|
continue;
|
|
658
767
|
}
|
|
659
768
|
if (memberDef !== undefined) {
|
|
769
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, memberDef)) {
|
|
770
|
+
handledSites.add(siteKey);
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
660
773
|
// For read/write ACCESSES, mirror the legacy DAG's reason
|
|
661
774
|
// convention so consumers asserting `reason === 'write'`
|
|
662
775
|
// keep working.
|
|
@@ -666,13 +779,13 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
666
779
|
? 'import-resolved'
|
|
667
780
|
: 'global';
|
|
668
781
|
const confidence = site.kind === 'write' || site.kind === 'read' ? 1.0 : 0.85;
|
|
669
|
-
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse);
|
|
782
|
+
const ok = tryEmitEdge(graph, scopes, nodeLookup, site, memberDef, reason, seen, confidence, collapse, calleeCapture);
|
|
670
783
|
if (ok)
|
|
671
784
|
emitted++;
|
|
672
785
|
// Interface dispatch: when the primary owner is an
|
|
673
786
|
// Interface, emit secondary CALLS edges to every
|
|
674
787
|
// implementing class's same-named method.
|
|
675
|
-
emitted += emitInterfaceDispatchFor(ownerDef, memberName, memberDef, site, confidence);
|
|
788
|
+
emitted += emitInterfaceDispatchFor(ownerDef, memberName, memberDef, site, confidence, calleeCapture);
|
|
676
789
|
// Always mark handled when the site was resolved, even
|
|
677
790
|
// if the edge was deduplicated (collapse mode), so
|
|
678
791
|
// `emitReferencesViaLookup` doesn't re-emit from the
|
|
@@ -713,6 +826,10 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
713
826
|
continue;
|
|
714
827
|
}
|
|
715
828
|
if (picked !== undefined) {
|
|
829
|
+
if (suppressDeletedCallTarget(options.recordResolutionOutcome, parsed.filePath, site, picked)) {
|
|
830
|
+
handledSites.add(siteKey);
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
716
833
|
// Static-only filter (#1756 / U3): unlike Case 4 there's no
|
|
717
834
|
// MRO chain to walk here — Case 5 dispatches on a single
|
|
718
835
|
// owner via `pickOverload`. When the picked candidate is
|
|
@@ -732,7 +849,7 @@ export function emitReceiverBoundCalls(graph, scopes, parsedFiles, nodeLookup, h
|
|
|
732
849
|
? 'import-resolved'
|
|
733
850
|
: 'global';
|
|
734
851
|
const confidence = site.kind === 'write' || site.kind === 'read' ? 1.0 : 0.85;
|
|
735
|
-
const ok = tryEmitEdgeWithExplicitTargetId(graph, scopes, nodeLookup, site, picked.nodeId, reason, seen, confidence, collapse);
|
|
852
|
+
const ok = tryEmitEdgeWithExplicitTargetId(graph, scopes, nodeLookup, site, picked.nodeId, reason, seen, confidence, collapse, calleeCapture);
|
|
736
853
|
if (ok)
|
|
737
854
|
emitted++;
|
|
738
855
|
handledSites.add(siteKey);
|
|
@@ -760,6 +877,7 @@ function pickOverload(ownerId, memberName, site, model, provider) {
|
|
|
760
877
|
const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes, {
|
|
761
878
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
762
879
|
conversionRankFn: provider.conversionRankFn,
|
|
880
|
+
conversionOnlyArgTypePrefixes: provider.conversionOnlyArgTypePrefixes,
|
|
763
881
|
constraintCompatibility: provider.constraintCompatibility,
|
|
764
882
|
});
|
|
765
883
|
// When narrowing leaves >1 candidate that share identical normalized
|
|
@@ -860,6 +978,7 @@ function pickFirstNonStaticOnly(ownerId, memberName, site, model, provider) {
|
|
|
860
978
|
const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes, {
|
|
861
979
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
862
980
|
conversionRankFn: provider.conversionRankFn,
|
|
981
|
+
conversionOnlyArgTypePrefixes: provider.conversionOnlyArgTypePrefixes,
|
|
863
982
|
constraintCompatibility: provider.constraintCompatibility,
|
|
864
983
|
});
|
|
865
984
|
// Same ambiguity handling as `pickOverload`: when normalization
|
|
@@ -873,6 +992,20 @@ function pickFirstNonStaticOnly(ownerId, memberName, site, model, provider) {
|
|
|
873
992
|
return OVERLOAD_AMBIGUOUS;
|
|
874
993
|
return candidates[0] ?? overloads[0];
|
|
875
994
|
}
|
|
995
|
+
function suppressDeletedCallTarget(record, filePath, site, target) {
|
|
996
|
+
if (site.kind !== 'call' || target.isDeleted !== true)
|
|
997
|
+
return false;
|
|
998
|
+
record?.({
|
|
999
|
+
kind: 'suppressed',
|
|
1000
|
+
phase: 'receiver-bound-calls',
|
|
1001
|
+
filePath,
|
|
1002
|
+
name: site.name,
|
|
1003
|
+
range: site.atRange,
|
|
1004
|
+
reason: 'selected-callable-deleted',
|
|
1005
|
+
candidateIds: [target.nodeId],
|
|
1006
|
+
});
|
|
1007
|
+
return true;
|
|
1008
|
+
}
|
|
876
1009
|
function recordReceiverOverloadSuppression(record, filePath, site, ownerId, memberName, model, provider) {
|
|
877
1010
|
if (record === undefined)
|
|
878
1011
|
return;
|
|
@@ -880,6 +1013,7 @@ function recordReceiverOverloadSuppression(record, filePath, site, ownerId, memb
|
|
|
880
1013
|
const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes, {
|
|
881
1014
|
argumentTypeClasses: site.argumentTypeClasses,
|
|
882
1015
|
conversionRankFn: provider.conversionRankFn,
|
|
1016
|
+
conversionOnlyArgTypePrefixes: provider.conversionOnlyArgTypePrefixes,
|
|
883
1017
|
constraintCompatibility: provider.constraintCompatibility,
|
|
884
1018
|
});
|
|
885
1019
|
const reason = isOverloadAmbiguousAfterNormalization(candidates, site.arity)
|