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
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure graph sub-stages for the reaching-definitions solvers (#2201 review R4).
|
|
3
|
+
*
|
|
4
|
+
* Extracted from reaching-defs.ts to keep that module focused on the
|
|
5
|
+
* orchestrator, the dense oracle, the statement sweep, and the dispatcher.
|
|
6
|
+
* Everything here is a pure function of plain arrays — no CFG, no harvest, no
|
|
7
|
+
* solver state — so this module has NO dependency on reaching-defs.ts (a strict
|
|
8
|
+
* one-way import) and each stage is independently testable. The SSA pipeline
|
|
9
|
+
* (dominators → dominance frontiers → Tarjan SCC → reach-set condensation)
|
|
10
|
+
* implements Cooper-Harvey-Kennedy + Cytron + Tarjan; reverse-post-order, the
|
|
11
|
+
* loop-reachability check, and the def-set/lattice primitives are shared with
|
|
12
|
+
* the dense GEN/KILL solver and the dispatcher.
|
|
13
|
+
*
|
|
14
|
+
* These are held byte-identical to their former inline form by the differential
|
|
15
|
+
* equivalence fuzz (test/unit/cfg/reaching-defs-equivalence.test.ts) — any diff
|
|
16
|
+
* after extraction is an extraction bug, never the oracle.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* RPO over blocks reachable from `entry`; unreachable blocks appended by index.
|
|
20
|
+
* Returns the order AND the reachability bitmap the DFS already computed, so a
|
|
21
|
+
* caller needing "is every block reachable?" reuses this pass instead of a
|
|
22
|
+
* separate BFS (#2201 review R8 — the SSA path's reachability gate).
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export function reversePostOrder(entry, succs, n) {
|
|
27
|
+
const visited = new Array(n).fill(false);
|
|
28
|
+
const post = [];
|
|
29
|
+
// Iterative DFS with an explicit phase stack (children pushed in reverse so
|
|
30
|
+
// they pop in sorted order — determinism).
|
|
31
|
+
const stack = [{ node: entry, childIdx: 0 }];
|
|
32
|
+
visited[entry] = true;
|
|
33
|
+
while (stack.length) {
|
|
34
|
+
const top = stack[stack.length - 1];
|
|
35
|
+
const children = succs[top.node];
|
|
36
|
+
if (top.childIdx < children.length) {
|
|
37
|
+
const next = children[top.childIdx];
|
|
38
|
+
top.childIdx += 1;
|
|
39
|
+
if (!visited[next]) {
|
|
40
|
+
visited[next] = true;
|
|
41
|
+
stack.push({ node: next, childIdx: 0 });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
post.push(top.node);
|
|
46
|
+
stack.pop();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const order = post.reverse();
|
|
50
|
+
for (let b = 0; b < n; b++)
|
|
51
|
+
if (!visited[b])
|
|
52
|
+
order.push(b);
|
|
53
|
+
return { order, visited };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Immediate dominators (Cooper-Harvey-Kennedy; correct on irreducible CFGs).
|
|
57
|
+
* `rpo` is the reverse-post-order rooted at the synthetic start `S`, `dPredsX`
|
|
58
|
+
* the dominator-graph predecessors (incl. S→entry). Returns idom[b] for every
|
|
59
|
+
* node in [0, nx); idom[S] === S.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export function buildDominators(rpo, dPredsX, S, nx) {
|
|
64
|
+
const rpoIdx = new Array(nx);
|
|
65
|
+
rpo.forEach((b, i) => (rpoIdx[b] = i));
|
|
66
|
+
const idom = new Array(nx).fill(-1);
|
|
67
|
+
idom[S] = S;
|
|
68
|
+
const intersect = (a, b) => {
|
|
69
|
+
while (a !== b) {
|
|
70
|
+
while (rpoIdx[a] > rpoIdx[b])
|
|
71
|
+
a = idom[a];
|
|
72
|
+
while (rpoIdx[b] > rpoIdx[a])
|
|
73
|
+
b = idom[b];
|
|
74
|
+
}
|
|
75
|
+
return a;
|
|
76
|
+
};
|
|
77
|
+
for (let changed = true; changed;) {
|
|
78
|
+
changed = false;
|
|
79
|
+
for (const b of rpo) {
|
|
80
|
+
if (b === S)
|
|
81
|
+
continue;
|
|
82
|
+
let nd = -1;
|
|
83
|
+
for (const p of dPredsX[b])
|
|
84
|
+
if (idom[p] !== -1)
|
|
85
|
+
nd = nd === -1 ? p : intersect(nd, p);
|
|
86
|
+
if (nd !== -1 && idom[b] !== nd) {
|
|
87
|
+
idom[b] = nd;
|
|
88
|
+
changed = true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return idom;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Dominance frontiers (Cytron). df[b] is the set of nodes where b's dominance
|
|
96
|
+
* ends — the φ-placement targets for any binding defined in b.
|
|
97
|
+
*
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
export function buildDominanceFrontiers(dPredsX, idom, nx) {
|
|
101
|
+
const df = Array.from({ length: nx }, () => new Set());
|
|
102
|
+
for (let b = 0; b < nx; b++) {
|
|
103
|
+
const dp = dPredsX[b];
|
|
104
|
+
if (dp.length < 2)
|
|
105
|
+
continue;
|
|
106
|
+
for (const p of dp) {
|
|
107
|
+
let runner = p;
|
|
108
|
+
while (runner !== idom[b] && runner !== -1) {
|
|
109
|
+
df[runner].add(b);
|
|
110
|
+
runner = idom[runner];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return df;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Tarjan strongly-connected components over the value-graph operand edges
|
|
118
|
+
* (`nodeOps[node]` = operand node ids). Iterative (explicit work stack — the
|
|
119
|
+
* graph can be deep). SCCs are emitted in REVERSE topological order, so an
|
|
120
|
+
* SCC's operand SCCs are numbered before it — the property
|
|
121
|
+
* {@link condenseReachingSets} relies on for its single forward pass.
|
|
122
|
+
*
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
export function tarjanScc(nodeOps) {
|
|
126
|
+
const N = nodeOps.length;
|
|
127
|
+
const sccOf = new Array(N).fill(-1);
|
|
128
|
+
const sccMembers = [];
|
|
129
|
+
const index = new Array(N).fill(-1);
|
|
130
|
+
const low = new Array(N).fill(0);
|
|
131
|
+
const onStk = new Array(N).fill(false);
|
|
132
|
+
const tarjanStk = [];
|
|
133
|
+
let counter = 0;
|
|
134
|
+
for (let start = 0; start < N; start++) {
|
|
135
|
+
if (index[start] !== -1)
|
|
136
|
+
continue;
|
|
137
|
+
const work = [{ node: start, oi: 0 }];
|
|
138
|
+
index[start] = low[start] = counter++;
|
|
139
|
+
tarjanStk.push(start);
|
|
140
|
+
onStk[start] = true;
|
|
141
|
+
while (work.length) {
|
|
142
|
+
const top = work[work.length - 1];
|
|
143
|
+
const ops = nodeOps[top.node];
|
|
144
|
+
if (top.oi < ops.length) {
|
|
145
|
+
const w = ops[top.oi++];
|
|
146
|
+
if (index[w] === -1) {
|
|
147
|
+
index[w] = low[w] = counter++;
|
|
148
|
+
tarjanStk.push(w);
|
|
149
|
+
onStk[w] = true;
|
|
150
|
+
work.push({ node: w, oi: 0 });
|
|
151
|
+
}
|
|
152
|
+
else if (onStk[w] && index[w] < low[top.node]) {
|
|
153
|
+
low[top.node] = index[w];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
if (low[top.node] === index[top.node]) {
|
|
158
|
+
const members = [];
|
|
159
|
+
let w;
|
|
160
|
+
do {
|
|
161
|
+
w = tarjanStk.pop();
|
|
162
|
+
onStk[w] = false;
|
|
163
|
+
sccOf[w] = sccMembers.length;
|
|
164
|
+
members.push(w);
|
|
165
|
+
} while (w !== top.node);
|
|
166
|
+
sccMembers.push(members);
|
|
167
|
+
}
|
|
168
|
+
work.pop();
|
|
169
|
+
if (work.length) {
|
|
170
|
+
const par = work[work.length - 1].node;
|
|
171
|
+
if (low[top.node] < low[par])
|
|
172
|
+
low[par] = low[top.node];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { sccOf, sccMembers };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Reaching def-key set per SCC via condensation (cycle-safe union). Tarjan emits
|
|
181
|
+
* SCCs in reverse topological order, so a single forward pass over SCCs resolves
|
|
182
|
+
* every union: an SCC's reaching set is its members' own leaf keys plus the
|
|
183
|
+
* already-computed reaching sets of its cross-SCC operands.
|
|
184
|
+
*
|
|
185
|
+
* Alias fast path (#2201 review R2): an SCC with NO own leaf keys whose cross-SCC
|
|
186
|
+
* operands all resolve to a SINGLE source SCC has exactly that source's reaching
|
|
187
|
+
* set — share it BY REFERENCE instead of copying element-by-element (the O(defs²)
|
|
188
|
+
* cost at wide-fan-in φ merges). Safe: the returned sets are read-only after this
|
|
189
|
+
* pass, and contents are identical (set iteration order is irrelevant — the
|
|
190
|
+
* sweep sorts each use's keys before emission, KTD6).
|
|
191
|
+
*
|
|
192
|
+
* @internal
|
|
193
|
+
*/
|
|
194
|
+
export function condenseReachingSets(sccMembers, sccOf, nodeKeys, nodeOps) {
|
|
195
|
+
const reachByScc = new Array(sccMembers.length);
|
|
196
|
+
for (let s = 0; s < sccMembers.length; s++) {
|
|
197
|
+
const members = sccMembers[s];
|
|
198
|
+
let aliasTarget = -1; // the unique cross-SCC source SCC, or -1 if none/many
|
|
199
|
+
let hasOwnKeys = false;
|
|
200
|
+
let multiSource = false;
|
|
201
|
+
for (const node of members) {
|
|
202
|
+
if (nodeKeys[node]) {
|
|
203
|
+
hasOwnKeys = true;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
for (const w of nodeOps[node]) {
|
|
207
|
+
const ws = sccOf[w];
|
|
208
|
+
if (ws === s)
|
|
209
|
+
continue; // intra-SCC operand: same set being built, adds nothing
|
|
210
|
+
if (aliasTarget === -1)
|
|
211
|
+
aliasTarget = ws;
|
|
212
|
+
else if (aliasTarget !== ws) {
|
|
213
|
+
multiSource = true;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (multiSource)
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
if (!hasOwnKeys && !multiSource && aliasTarget !== -1) {
|
|
221
|
+
reachByScc[s] = reachByScc[aliasTarget]; // zero-copy share
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
// General case: union own leaf keys + every distinct cross-SCC operand set.
|
|
225
|
+
const set = new Set();
|
|
226
|
+
for (const node of members) {
|
|
227
|
+
const keys = nodeKeys[node];
|
|
228
|
+
if (keys)
|
|
229
|
+
for (const k of keys)
|
|
230
|
+
set.add(k);
|
|
231
|
+
for (const w of nodeOps[node]) {
|
|
232
|
+
const ws = sccOf[w];
|
|
233
|
+
if (ws !== s)
|
|
234
|
+
for (const k of reachByScc[ws])
|
|
235
|
+
set.add(k);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
reachByScc[s] = set;
|
|
239
|
+
}
|
|
240
|
+
return reachByScc;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* True iff a cycle is reachable from `entry` (the CFG has a loop). Iterative DFS
|
|
244
|
+
* with a gray/black coloring; a gray successor is a back-edge. O(V+E). Used by
|
|
245
|
+
* the production dispatcher to decide SSA-vs-dense.
|
|
246
|
+
*
|
|
247
|
+
* @internal
|
|
248
|
+
*/
|
|
249
|
+
export function hasReachableLoop(entry, succs, n) {
|
|
250
|
+
const color = new Uint8Array(n); // 0 white, 1 gray, 2 black
|
|
251
|
+
const stack = [{ node: entry, i: 0 }];
|
|
252
|
+
color[entry] = 1;
|
|
253
|
+
while (stack.length) {
|
|
254
|
+
const top = stack[stack.length - 1];
|
|
255
|
+
const ss = succs[top.node];
|
|
256
|
+
if (top.i < ss.length) {
|
|
257
|
+
const next = ss[top.i++];
|
|
258
|
+
if (color[next] === 1)
|
|
259
|
+
return true;
|
|
260
|
+
if (color[next] === 0) {
|
|
261
|
+
color[next] = 1;
|
|
262
|
+
stack.push({ node: next, i: 0 });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
color[top.node] = 2;
|
|
267
|
+
stack.pop();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Order-stable union of two def-sets (shares `a` when `b` adds nothing).
|
|
274
|
+
*
|
|
275
|
+
* @internal
|
|
276
|
+
*/
|
|
277
|
+
export function unionSets(a, b) {
|
|
278
|
+
let target = a;
|
|
279
|
+
let copied = false;
|
|
280
|
+
for (const key of b) {
|
|
281
|
+
if (!target.has(key)) {
|
|
282
|
+
if (!copied) {
|
|
283
|
+
target = new Set(a);
|
|
284
|
+
copied = true;
|
|
285
|
+
}
|
|
286
|
+
target.add(key);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return target;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Per-binding lattice equality with a reference fast path (sets only ever grow).
|
|
293
|
+
*
|
|
294
|
+
* @internal
|
|
295
|
+
*/
|
|
296
|
+
export function latticeEquals(a, b) {
|
|
297
|
+
if (a === b)
|
|
298
|
+
return true;
|
|
299
|
+
if (a.size !== b.size)
|
|
300
|
+
return false;
|
|
301
|
+
for (const [k, bSet] of b) {
|
|
302
|
+
const aSet = a.get(k);
|
|
303
|
+
if (aSet === bSet)
|
|
304
|
+
continue;
|
|
305
|
+
if (!aSet || aSet.size !== bSet.size)
|
|
306
|
+
return false;
|
|
307
|
+
for (const v of bSet)
|
|
308
|
+
if (!aSet.has(v))
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reaching definitions (#2082 M2 U3, SSA-sparse rewrite #2201) — per-function
|
|
3
|
+
* intraprocedural may-reaching-definitions, plus the canonical intra-block
|
|
4
|
+
* statement sweep that recovers statement-granular def→use facts from M1's
|
|
5
|
+
* coalesced blocks WITHOUT re-splitting the CFG.
|
|
6
|
+
*
|
|
7
|
+
* ARCHITECTURE (#2201): the analysis is split into solver-INDEPENDENT stages
|
|
8
|
+
* (shared by every path, so the byte-identical surface is maximal) and a
|
|
9
|
+
* swappable IN-set computation:
|
|
10
|
+
* - {@link harvestStatementFacts} — per-block GEN/allDefs + def/use telemetry.
|
|
11
|
+
* - {@link buildAdjacency} — throw-aware predecessor/successor adjacency.
|
|
12
|
+
* - the IN-set computer — answers block-entry reaching-set queries. Two
|
|
13
|
+
* implementations: {@link computeInSetsSparse} (SSA — CHK dominators →
|
|
14
|
+
* Cytron dominance frontiers + φ-placement → stack renaming over a
|
|
15
|
+
* synthetic entry, walked SCC-condensed) and {@link computeInSetsDense}
|
|
16
|
+
* (the original GEN/KILL worklist). Production runs {@link
|
|
17
|
+
* computeInSetsAuto}, which picks the SSA solver for looping functions large
|
|
18
|
+
* enough to amortize construction (where it is asymptotically faster and
|
|
19
|
+
* never hits the dense ceiling) and the dense worklist everywhere else; the
|
|
20
|
+
* dense path also serves the throw-edge / unreachable-block cases the SSA
|
|
21
|
+
* path does not model. The two are held byte-identical by the equivalence
|
|
22
|
+
* fuzz — only set CONTENTS must match (the sweep sorts each use's keys
|
|
23
|
+
* before the maxFacts cutoff, so iteration order is irrelevant).
|
|
24
|
+
* - {@link sweepFacts} — statement sweep + sort + maxFacts truncation.
|
|
25
|
+
*
|
|
26
|
+
* PURE AND DETERMINISTIC (load-bearing contract):
|
|
27
|
+
* - Pure function of its inputs — no graph, no logger (warnings are the
|
|
28
|
+
* caller's job), importable outside the worker. The M3 taint engine calls
|
|
29
|
+
* this same function in-phase (facts are recomputed on demand, never
|
|
30
|
+
* retained run-wide — the persisted REACHING_DEF edges are a bounded
|
|
31
|
+
* projection, never the taint substrate).
|
|
32
|
+
* - Deterministic — predecessors merge in sorted block-index order,
|
|
33
|
+
* insertion-ordered Maps/Sets throughout, and the output fact array is
|
|
34
|
+
* explicitly sorted. Snapshot tests and content-derived edge ids rely on it.
|
|
35
|
+
*
|
|
36
|
+
* COMPLEXITY DISCIPLINE: def-sets are SHARED BY REFERENCE, never deep-copied —
|
|
37
|
+
* a MUST def's kill is total per binding, so a transfer either aliases the
|
|
38
|
+
* incoming set or replaces it; a MAY def (conditional context — see
|
|
39
|
+
* StatementFacts.mayDefs) unions WITHOUT killing via a copy-on-extend.
|
|
40
|
+
*
|
|
41
|
+
* `limits.maxFacts` bounds materialization: facts are O(defs×uses) BY SPEC in
|
|
42
|
+
* merge-heavy code (N branch-arm defs × N later uses = N² facts), and a
|
|
43
|
+
* 2000-line function can spike 100k+ fact objects on the main thread. The
|
|
44
|
+
* emit path passes DEFAULT_PDG_MAX_REACHING_DEF_FACTS_PER_FUNCTION (emit.ts);
|
|
45
|
+
* M3 passes its own large-but-finite limit and treats `status: 'truncated'`
|
|
46
|
+
* as a per-function taint-coverage gap.
|
|
47
|
+
*/
|
|
48
|
+
import type { BindingEntry, FunctionCfg } from './types.js';
|
|
49
|
+
/** A statement-granular program point within one function's CFG. */
|
|
50
|
+
export interface ProgramPoint {
|
|
51
|
+
readonly blockIndex: number;
|
|
52
|
+
/** Statement index within the block's `statements` array. */
|
|
53
|
+
readonly stmtIndex: number;
|
|
54
|
+
readonly line: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Canonical `block:stmt` string key for a program point. Colon-separated to
|
|
58
|
+
* match the codebase's `blockIndex:stmtIndex` id conventions. Shared by the
|
|
59
|
+
* taint propagation engine (dedup/state keys) and the taint emit path
|
|
60
|
+
* (persisted edge-id material) so the two never drift.
|
|
61
|
+
*/
|
|
62
|
+
export declare function pointKey(p: ProgramPoint): string;
|
|
63
|
+
/** One def→use fact: the definition at `def` reaches the use at `use`. */
|
|
64
|
+
export interface DefUseFact {
|
|
65
|
+
/** Index into {@link FunctionDefUse.bindings}. */
|
|
66
|
+
readonly bindingIdx: number;
|
|
67
|
+
readonly def: ProgramPoint;
|
|
68
|
+
readonly use: ProgramPoint;
|
|
69
|
+
}
|
|
70
|
+
export interface ReachingDefsLimits {
|
|
71
|
+
/**
|
|
72
|
+
* Maximum number of facts to materialize; the sweep stops early and reports
|
|
73
|
+
* `status: 'truncated'`. `undefined`/0 ⇒ unlimited.
|
|
74
|
+
*/
|
|
75
|
+
readonly maxFacts?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Adversarial-only safety bound on the DENSE worklist's iteration.
|
|
78
|
+
*
|
|
79
|
+
* The dense GEN/KILL solver reads this as a ceiling on total block dequeues:
|
|
80
|
+
* iterative reaching-defs on a reducible CFG converges in O(loop-nesting-depth)
|
|
81
|
+
* passes, but a pathologically deep loop nest drives the visit total — and thus
|
|
82
|
+
* the solver — to O(blocks²), seconds + GB of heap (`maxFacts` does not help:
|
|
83
|
+
* fact count stays linear). Exceeding the budget means the fixpoint has NOT
|
|
84
|
+
* converged, so any facts would be unsound — the dense solver bails to a sound
|
|
85
|
+
* empty `status: 'truncated'` (like the `overflow` guard).
|
|
86
|
+
*
|
|
87
|
+
* The SSA solver (#2201) has NO fixpoint iteration — it answers reaching
|
|
88
|
+
* queries from the def-use graph in one pass — so it always converges and this
|
|
89
|
+
* budget never trips it. The production dispatcher ({@link computeInSetsAuto})
|
|
90
|
+
* routes the deep nests that would breach the dense ceiling to the SSA solver,
|
|
91
|
+
* which computes their full facts: the ceiling that fired on the dense worklist
|
|
92
|
+
* effectively never fires on real code (#2201 acceptance). The budget is still
|
|
93
|
+
* honored on the dense fallback path (small / loop-free functions, and the
|
|
94
|
+
* throw-edge / unreachable-block cases the SSA path does not model).
|
|
95
|
+
*
|
|
96
|
+
* `undefined`/0 ⇒ unlimited (the default for direct callers; the emit path sets
|
|
97
|
+
* a per-function budget).
|
|
98
|
+
*/
|
|
99
|
+
readonly maxBlockVisits?: number;
|
|
100
|
+
/**
|
|
101
|
+
* Memory bound on the SSA-sparse solver's value-graph construction (#2201
|
|
102
|
+
* review R1). `maxFacts` bounds fact MATERIALIZATION (sweepFacts) but nothing
|
|
103
|
+
* bounds the φ/value-graph the sparse path builds first; a high-binding-density
|
|
104
|
+
* deep loop routed to SSA (≥ SSA_MIN_BLOCKS blocks + a reachable loop) builds an
|
|
105
|
+
* O(blocks×bindings) graph the dense path would have truncated at the
|
|
106
|
+
* `maxBlockVisits` ceiling (~1.5 GB measured on a 3000-block × 300-binding
|
|
107
|
+
* function). When the projected node count would exceed this, the sparse solver
|
|
108
|
+
* falls back to the dense oracle (byte-identical, and bounded — dense honors
|
|
109
|
+
* `maxBlockVisits`). Honored ONLY by the sparse path; the dense solver ignores
|
|
110
|
+
* it. `undefined`/0 ⇒ {@link DEFAULT_MAX_SSA_VALUE_GRAPH_NODES}.
|
|
111
|
+
*/
|
|
112
|
+
readonly maxSsaValueGraphNodes?: number;
|
|
113
|
+
}
|
|
114
|
+
export interface FunctionDefUse {
|
|
115
|
+
/**
|
|
116
|
+
* `computed` — full facts.
|
|
117
|
+
* `no-facts` — the CFG carries no statement facts (hand-built or pre-M2
|
|
118
|
+
* side channel); empty facts, NOT an error.
|
|
119
|
+
* `truncated` — `limits.maxFacts` hit; `facts` is a deterministic prefix.
|
|
120
|
+
* `overflow` — a block's statement count breaches the def-key stride; no
|
|
121
|
+
* facts at all (computing any would risk key aliasing —
|
|
122
|
+
* wrong-block facts are strictly worse than none). Distinct
|
|
123
|
+
* from `truncated` so the caller's diagnostic doesn't
|
|
124
|
+
* misname it as the fact-materialization limit.
|
|
125
|
+
*/
|
|
126
|
+
readonly status: 'computed' | 'no-facts' | 'truncated' | 'overflow';
|
|
127
|
+
/** Pass-through of the CFG's binding table (empty for `no-facts`). */
|
|
128
|
+
readonly bindings: readonly BindingEntry[];
|
|
129
|
+
/** Sorted by (def block, def stmt, use block, use stmt, binding). */
|
|
130
|
+
readonly facts: readonly DefUseFact[];
|
|
131
|
+
/** Total def / use sites seen (telemetry; independent of truncation). */
|
|
132
|
+
readonly defCount: number;
|
|
133
|
+
readonly useCount: number;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Compute reaching definitions for one function. See the module doc for the
|
|
137
|
+
* purity/determinism/sharing contract.
|
|
138
|
+
*
|
|
139
|
+
* This is the production entry point. As of #2201 it auto-dispatches via
|
|
140
|
+
* {@link computeInSetsAuto} — the SSA-sparse solver ({@link computeInSetsSparse})
|
|
141
|
+
* for looping functions large enough to amortize construction, the dense
|
|
142
|
+
* GEN/KILL worklist ({@link computeInSetsDense}) everywhere else (and for the
|
|
143
|
+
* throw-edge / unreachable-block functions the SSA path does not model). The two
|
|
144
|
+
* solvers are held byte-identical by the equivalence fuzz (status, bindings,
|
|
145
|
+
* sorted facts, def/use telemetry), so the dispatch is a pure performance
|
|
146
|
+
* heuristic; the dense solver doubles as that differential oracle.
|
|
147
|
+
*/
|
|
148
|
+
export declare function computeReachingDefs(cfg: FunctionCfg, limits?: ReachingDefsLimits): FunctionDefUse;
|
|
149
|
+
/** A reaching-defs solver — {@link computeReachingDefs} or a memoized wrapper. */
|
|
150
|
+
export type ReachingDefsSolver = (cfg: FunctionCfg, limits?: ReachingDefsLimits) => FunctionDefUse;
|
|
151
|
+
/**
|
|
152
|
+
* Per-file memoized reaching-defs solver (#2227 tri-review, U12). Under `--pdg`
|
|
153
|
+
* the SAME per-function RD fixpoint was solved 3–4× per analyze (RD emit +
|
|
154
|
+
* call-summary harvest + taint + summary harvest). Cache by (cfg identity,
|
|
155
|
+
* limits) so each DISTINCT solve runs once: the RD-emit bucket (passes
|
|
156
|
+
* `maxBlockVisits`) and the harvest/taint bucket (does not) stay byte-identical
|
|
157
|
+
* to their inline solves because the limits are part of the key. Lazy — solves
|
|
158
|
+
* on first request, so the taint zero-match fast path still skips its solve.
|
|
159
|
+
* Create one per FILE and drop it after the file to bound the per-function
|
|
160
|
+
* `facts` arrays (100k+ objects on a huge function) from going whole-repo.
|
|
161
|
+
*/
|
|
162
|
+
export declare function createMemoizedReachingDefs(): ReachingDefsSolver;
|