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,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared call-site taint substrate for the C-family CFG harvesters (#2195 U6,
|
|
3
|
+
* plan R7 / KTD2) — the language-agnostic mechanism the C/C++, C#, Java and Go
|
|
4
|
+
* harvesters layer their grammar-specific call/member walks on top of.
|
|
5
|
+
*
|
|
6
|
+
* This file is PURE MECHANISM: it contains no tree-sitter node-type or field
|
|
7
|
+
* literals (each harvester supplies those when it drives `openCallSite` /
|
|
8
|
+
* `addMemberRead` / `setFrameArg`), so it names no language and carries nothing
|
|
9
|
+
* the grammar-literal CI gate needs to validate. It is the C-family analogue of
|
|
10
|
+
* the `FactAccumulator` site machinery in
|
|
11
|
+
* {@link import('./typescript-harvest.js')} — extracted into one place because
|
|
12
|
+
* the four C-family harvesters already share an identical def/use accumulator,
|
|
13
|
+
* and the site layer is identical across them too (only the per-grammar node
|
|
14
|
+
* shapes differ, and those live in each harvester's `walkValue`/`visitCall`).
|
|
15
|
+
*
|
|
16
|
+
* Produces the same {@link SiteRecord} shape the (future, deferred) shared
|
|
17
|
+
* taint matcher consumes uniformly across all languages: callee path, receiver,
|
|
18
|
+
* per-argument occurrence entries (with sanitizer-interposition via-tags),
|
|
19
|
+
* result defs, spread/template markers, and member reads. INERT BY DESIGN — no
|
|
20
|
+
* C-family source/sink/sanitizer model is registered today (`getSourceSinkConfig`
|
|
21
|
+
* returns undefined for every C-family language), so a harvest with no model
|
|
22
|
+
* produces ZERO TAINTED edges; this only emits the substrate the deferred model
|
|
23
|
+
* work will match against.
|
|
24
|
+
*
|
|
25
|
+
* Sites are emitted on {@link StatementFacts.sites} only when non-empty, exactly
|
|
26
|
+
* like the TS harvester — flag-off runs never harvest, and most fact-bearing
|
|
27
|
+
* statements carry no calls.
|
|
28
|
+
*
|
|
29
|
+
* NOTE: nothing serialized here may carry a field named `nodeId` — the durable
|
|
30
|
+
* parsedfile-store reviver dedups objects keyed on that field name.
|
|
31
|
+
*/
|
|
32
|
+
import type { SyntaxNode } from '../../utils/ast-helpers.js';
|
|
33
|
+
import type { StatementFacts } from '../types.js';
|
|
34
|
+
/**
|
|
35
|
+
* Minimal ordered, deduplicating def/use collector for one statement record,
|
|
36
|
+
* with NO call-site machinery (#2195 U7). The Kotlin / Python / Ruby / Rust /
|
|
37
|
+
* Dart / Swift harvesters each carried a BYTE-IDENTICAL copy of this class:
|
|
38
|
+
* those units harvest NO call sites (the taint substrate is a later step), so a
|
|
39
|
+
* site-free accumulator keeps their emitted facts free of any `sites` key
|
|
40
|
+
* (matching the Python harvester) and byte-identical to one another. This is the
|
|
41
|
+
* no-site sibling of {@link CallSiteFactAccumulator}; `finish` omits `sites`
|
|
42
|
+
* entirely. `useCount` is live (Ruby's emit guard is `defCount() ||
|
|
43
|
+
* useCount()`).
|
|
44
|
+
*/
|
|
45
|
+
export declare class DefUseAccumulator {
|
|
46
|
+
private readonly line;
|
|
47
|
+
private readonly defs;
|
|
48
|
+
private readonly uses;
|
|
49
|
+
private readonly mayDefs;
|
|
50
|
+
private readonly defSeen;
|
|
51
|
+
private readonly useSeen;
|
|
52
|
+
private readonly mayDefSeen;
|
|
53
|
+
constructor(line: number);
|
|
54
|
+
addDef(idx: number): void;
|
|
55
|
+
/** A def that may not execute (conditional context) — gen without kill. */
|
|
56
|
+
addMayDef(idx: number): void;
|
|
57
|
+
addUse(idx: number): void;
|
|
58
|
+
defCount(): number;
|
|
59
|
+
useCount(): number;
|
|
60
|
+
finish(): StatementFacts;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Defensive per-statement cap on harvested taint `sites` (#2195 U11). A real
|
|
64
|
+
* statement carries a handful of call / member-read sites; this only bounds a
|
|
65
|
+
* pathological or machine-generated statement (e.g. hundreds of nested calls)
|
|
66
|
+
* from producing an unbounded site list. Mirrors the PDG edge/fact caps' style
|
|
67
|
+
* (a generous-but-finite limit, checked before each push). Overflow is silent
|
|
68
|
+
* but observable via {@link CallSiteFactAccumulator.sitesTruncated}; the first
|
|
69
|
+
* `DEFAULT_PDG_MAX_SITES_PER_STATEMENT` sites are kept fully intact (callee,
|
|
70
|
+
* args, parent), the over-cap tail is dropped.
|
|
71
|
+
*/
|
|
72
|
+
export declare const DEFAULT_PDG_MAX_SITES_PER_STATEMENT = 512;
|
|
73
|
+
/**
|
|
74
|
+
* Ordered, deduplicating def/use collector for one statement record, PLUS the
|
|
75
|
+
* call-site harvest machinery (#2195 U6). A drop-in superset of the simple
|
|
76
|
+
* def/use accumulator the C-family harvesters used before the substrate landed
|
|
77
|
+
* — `addDef`/`addMayDef`/`addUse`/`defCount`/`useCount`/`finish` are unchanged,
|
|
78
|
+
* so harvesters that never open a site emit byte-identical facts (no `sites`
|
|
79
|
+
* key, since `finish` omits it when empty).
|
|
80
|
+
*/
|
|
81
|
+
export declare class CallSiteFactAccumulator {
|
|
82
|
+
private readonly line;
|
|
83
|
+
private readonly defs;
|
|
84
|
+
private readonly uses;
|
|
85
|
+
private readonly mayDefs;
|
|
86
|
+
private readonly defSeen;
|
|
87
|
+
private readonly useSeen;
|
|
88
|
+
private readonly mayDefSeen;
|
|
89
|
+
/** Taint sites recorded for this statement. */
|
|
90
|
+
private readonly sites;
|
|
91
|
+
/** Composite (object|property|parent) keys of recorded member-read sites — O(1) dedup. */
|
|
92
|
+
private readonly memberReadKeys;
|
|
93
|
+
/** Stack of open call/new sites — the occurrence fan-out targets. */
|
|
94
|
+
private readonly frames;
|
|
95
|
+
/** Set once the per-statement site cap is hit; over-cap sites are dropped. */
|
|
96
|
+
private _sitesTruncated;
|
|
97
|
+
constructor(line: number);
|
|
98
|
+
/** True iff this statement hit {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}. */
|
|
99
|
+
get sitesTruncated(): boolean;
|
|
100
|
+
addDef(idx: number): void;
|
|
101
|
+
/** A def that may not execute (conditional context) — gen without kill. */
|
|
102
|
+
addMayDef(idx: number): void;
|
|
103
|
+
addUse(idx: number): void;
|
|
104
|
+
/**
|
|
105
|
+
* Statement-level use that is NOT a value occurrence in any open site
|
|
106
|
+
* argument — bare callee names only (see each harvester's `visitCall`).
|
|
107
|
+
*/
|
|
108
|
+
addUseWithoutOccurrence(idx: number): void;
|
|
109
|
+
defCount(): number;
|
|
110
|
+
useCount(): number;
|
|
111
|
+
/** `[defs.length, mayDefs.length]` marker for {@link defsSince}. */
|
|
112
|
+
defSnapshot(): readonly [number, number];
|
|
113
|
+
/** Binding indices def'd (must- OR may-) since the snapshot was taken. */
|
|
114
|
+
defsSince(snap: readonly [number, number]): number[];
|
|
115
|
+
/**
|
|
116
|
+
* Open a call/new site; parent = innermost enclosing argument position.
|
|
117
|
+
* Returns the new site index, or -1 when the per-statement site cap is hit
|
|
118
|
+
* (the caller threads -1 through `pushFrame`/`setSite*`, all of which no-op on
|
|
119
|
+
* a sentinel index — see {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}).
|
|
120
|
+
*
|
|
121
|
+
* `at` is the call/new node's anchor position `[line (1-based), col (0-based)]`
|
|
122
|
+
* — the SAME position the CALLS-edge resolution keys on (see
|
|
123
|
+
* {@link SiteRecord.at} for the KTD7 alignment); the harvester passes its
|
|
124
|
+
* `visitCall`/`visitNew` node's `startPosition` so the downstream resolved-id
|
|
125
|
+
* join lands by exact position.
|
|
126
|
+
*/
|
|
127
|
+
openCallSite(kind: 'call' | 'new', at?: readonly [number, number]): number;
|
|
128
|
+
pushFrame(siteIdx: number): void;
|
|
129
|
+
popFrame(): void;
|
|
130
|
+
/** Set the argument position the top frame is currently walking. */
|
|
131
|
+
setFrameArg(argIdx: number): void;
|
|
132
|
+
/**
|
|
133
|
+
* Run `fn` with all open arg frames temporarily detached (argIdx = -1), so
|
|
134
|
+
* identifier reads inside still record USES but do NOT fan occurrences into
|
|
135
|
+
* the enclosing sink-argument position (e.g. the non-value operands of a
|
|
136
|
+
* comma expression — only the final operand's value flows).
|
|
137
|
+
*/
|
|
138
|
+
suppressOccurrences(fn: () => void): void;
|
|
139
|
+
setSiteCallee(siteIdx: number, callee: string): void;
|
|
140
|
+
setSiteReceiver(siteIdx: number, receiver: number): void;
|
|
141
|
+
setSiteResultDefs(siteIdx: number, resultDefs: readonly number[]): void;
|
|
142
|
+
setSiteSpread(siteIdx: number, firstSpreadArg: number): void;
|
|
143
|
+
/**
|
|
144
|
+
* Record a value-position member read. Exact duplicates within the statement
|
|
145
|
+
* (same object/property/parent position) dedup; reads at DIFFERENT argument
|
|
146
|
+
* positions stay distinct (`exec(req.body, req.body)` is two occurrences).
|
|
147
|
+
*/
|
|
148
|
+
addMemberRead(object: number, property: string): void;
|
|
149
|
+
private innermostArgPosition;
|
|
150
|
+
/**
|
|
151
|
+
* Fan a binding occurrence out to every arg-active open frame, via-tagged
|
|
152
|
+
* with the site of the IMMEDIATELY nested frame when one exists:
|
|
153
|
+
* `exec(escape(x))` puts a plain `x` in escape's arg 0 and `[x, escapeIdx]`
|
|
154
|
+
* in exec's arg 0 — the sanitizer-interposition substrate.
|
|
155
|
+
*/
|
|
156
|
+
private recordOccurrence;
|
|
157
|
+
private pushArgEntry;
|
|
158
|
+
finish(): StatementFacts;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Per-grammar hooks the shared {@link finalizeChain} terminal needs but cannot
|
|
162
|
+
* name itself (it carries no tree-sitter literals — see the file header). Each
|
|
163
|
+
* harvester supplies the two callbacks bound to its own `this`.
|
|
164
|
+
*/
|
|
165
|
+
export interface ChainTerminalHooks {
|
|
166
|
+
/** Resolve a binding-target node to its function-table binding index. */
|
|
167
|
+
resolve(node: SyntaxNode): number;
|
|
168
|
+
/**
|
|
169
|
+
* Walk a NON-identifier chain root for its uses + nested sites (the terminal's
|
|
170
|
+
* `else` branch — `self.x.f()`, `foo().bar`, a tuple index, etc.).
|
|
171
|
+
*/
|
|
172
|
+
walkRoot(node: SyntaxNode): void;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Shared `walkChain` TERMINAL (#2227 follow-up, plan KTD5/U8) — the byte-identical
|
|
176
|
+
* post-unwind block the Go / Kotlin / Swift / Rust / Python harvesters all ran
|
|
177
|
+
* after walking their grammar-specific access chain (`selector_expression` /
|
|
178
|
+
* `navigation_expression` / `field_expression` / `attribute`) into an
|
|
179
|
+
* `accesses: string[]` list and a resolved root node `cur`.
|
|
180
|
+
*
|
|
181
|
+
* It records the chain-root identifier as a use, emits at most ONE member-read
|
|
182
|
+
* site — the INNERMOST access — when the root is an identifier (suppressed by
|
|
183
|
+
* `skipFinalRead` when that access IS the callee, carried by the dotted path
|
|
184
|
+
* instead), and builds the dotted path `[root, ...accesses].join('.')`. The only
|
|
185
|
+
* per-grammar bit is the root identifier node type, supplied via `isRootIdType`
|
|
186
|
+
* (`'identifier'` for Go/Rust/Python, `'simple_identifier'` for Kotlin/Swift);
|
|
187
|
+
* the `resolve` / `walkRoot` callbacks bind the harvester's own methods. The
|
|
188
|
+
* `addUse` / `addMemberRead` machinery is on the accumulator itself, so it is
|
|
189
|
+
* called directly (no callback). Behavior is identical to the inlined terminals
|
|
190
|
+
* this replaces — the per-language harvest tests are the characterization lock.
|
|
191
|
+
*/
|
|
192
|
+
export declare function finalizeChain(acc: CallSiteFactAccumulator, cur: SyntaxNode, accesses: readonly string[], skipFinalRead: boolean, isRootIdType: (type: string) => boolean, hooks: ChainTerminalHooks): {
|
|
193
|
+
path?: string;
|
|
194
|
+
rootIdx?: number;
|
|
195
|
+
};
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal ordered, deduplicating def/use collector for one statement record,
|
|
3
|
+
* with NO call-site machinery (#2195 U7). The Kotlin / Python / Ruby / Rust /
|
|
4
|
+
* Dart / Swift harvesters each carried a BYTE-IDENTICAL copy of this class:
|
|
5
|
+
* those units harvest NO call sites (the taint substrate is a later step), so a
|
|
6
|
+
* site-free accumulator keeps their emitted facts free of any `sites` key
|
|
7
|
+
* (matching the Python harvester) and byte-identical to one another. This is the
|
|
8
|
+
* no-site sibling of {@link CallSiteFactAccumulator}; `finish` omits `sites`
|
|
9
|
+
* entirely. `useCount` is live (Ruby's emit guard is `defCount() ||
|
|
10
|
+
* useCount()`).
|
|
11
|
+
*/
|
|
12
|
+
export class DefUseAccumulator {
|
|
13
|
+
line;
|
|
14
|
+
defs = [];
|
|
15
|
+
uses = [];
|
|
16
|
+
mayDefs = [];
|
|
17
|
+
defSeen = new Set();
|
|
18
|
+
useSeen = new Set();
|
|
19
|
+
mayDefSeen = new Set();
|
|
20
|
+
constructor(line) {
|
|
21
|
+
this.line = line;
|
|
22
|
+
}
|
|
23
|
+
addDef(idx) {
|
|
24
|
+
if (this.defSeen.has(idx))
|
|
25
|
+
return;
|
|
26
|
+
this.defSeen.add(idx);
|
|
27
|
+
this.defs.push(idx);
|
|
28
|
+
}
|
|
29
|
+
/** A def that may not execute (conditional context) — gen without kill. */
|
|
30
|
+
addMayDef(idx) {
|
|
31
|
+
if (this.mayDefSeen.has(idx))
|
|
32
|
+
return;
|
|
33
|
+
this.mayDefSeen.add(idx);
|
|
34
|
+
this.mayDefs.push(idx);
|
|
35
|
+
}
|
|
36
|
+
addUse(idx) {
|
|
37
|
+
if (this.useSeen.has(idx))
|
|
38
|
+
return;
|
|
39
|
+
this.useSeen.add(idx);
|
|
40
|
+
this.uses.push(idx);
|
|
41
|
+
}
|
|
42
|
+
defCount() {
|
|
43
|
+
return this.defs.length + this.mayDefs.length;
|
|
44
|
+
}
|
|
45
|
+
useCount() {
|
|
46
|
+
return this.uses.length;
|
|
47
|
+
}
|
|
48
|
+
finish() {
|
|
49
|
+
return {
|
|
50
|
+
line: this.line,
|
|
51
|
+
defs: this.defs,
|
|
52
|
+
uses: this.uses,
|
|
53
|
+
// Stay absent when empty — keeps the serialized side-channel payload lean.
|
|
54
|
+
...(this.mayDefs.length > 0 ? { mayDefs: this.mayDefs } : {}),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Defensive per-statement cap on harvested taint `sites` (#2195 U11). A real
|
|
60
|
+
* statement carries a handful of call / member-read sites; this only bounds a
|
|
61
|
+
* pathological or machine-generated statement (e.g. hundreds of nested calls)
|
|
62
|
+
* from producing an unbounded site list. Mirrors the PDG edge/fact caps' style
|
|
63
|
+
* (a generous-but-finite limit, checked before each push). Overflow is silent
|
|
64
|
+
* but observable via {@link CallSiteFactAccumulator.sitesTruncated}; the first
|
|
65
|
+
* `DEFAULT_PDG_MAX_SITES_PER_STATEMENT` sites are kept fully intact (callee,
|
|
66
|
+
* args, parent), the over-cap tail is dropped.
|
|
67
|
+
*/
|
|
68
|
+
export const DEFAULT_PDG_MAX_SITES_PER_STATEMENT = 512;
|
|
69
|
+
/**
|
|
70
|
+
* Ordered, deduplicating def/use collector for one statement record, PLUS the
|
|
71
|
+
* call-site harvest machinery (#2195 U6). A drop-in superset of the simple
|
|
72
|
+
* def/use accumulator the C-family harvesters used before the substrate landed
|
|
73
|
+
* — `addDef`/`addMayDef`/`addUse`/`defCount`/`useCount`/`finish` are unchanged,
|
|
74
|
+
* so harvesters that never open a site emit byte-identical facts (no `sites`
|
|
75
|
+
* key, since `finish` omits it when empty).
|
|
76
|
+
*/
|
|
77
|
+
export class CallSiteFactAccumulator {
|
|
78
|
+
line;
|
|
79
|
+
defs = [];
|
|
80
|
+
uses = [];
|
|
81
|
+
mayDefs = [];
|
|
82
|
+
defSeen = new Set();
|
|
83
|
+
useSeen = new Set();
|
|
84
|
+
mayDefSeen = new Set();
|
|
85
|
+
/** Taint sites recorded for this statement. */
|
|
86
|
+
sites = [];
|
|
87
|
+
/** Composite (object|property|parent) keys of recorded member-read sites — O(1) dedup. */
|
|
88
|
+
memberReadKeys = new Set();
|
|
89
|
+
/** Stack of open call/new sites — the occurrence fan-out targets. */
|
|
90
|
+
frames = [];
|
|
91
|
+
/** Set once the per-statement site cap is hit; over-cap sites are dropped. */
|
|
92
|
+
_sitesTruncated = false;
|
|
93
|
+
constructor(line) {
|
|
94
|
+
this.line = line;
|
|
95
|
+
}
|
|
96
|
+
/** True iff this statement hit {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}. */
|
|
97
|
+
get sitesTruncated() {
|
|
98
|
+
return this._sitesTruncated;
|
|
99
|
+
}
|
|
100
|
+
addDef(idx) {
|
|
101
|
+
if (this.defSeen.has(idx))
|
|
102
|
+
return;
|
|
103
|
+
this.defSeen.add(idx);
|
|
104
|
+
this.defs.push(idx);
|
|
105
|
+
}
|
|
106
|
+
/** A def that may not execute (conditional context) — gen without kill. */
|
|
107
|
+
addMayDef(idx) {
|
|
108
|
+
if (this.mayDefSeen.has(idx))
|
|
109
|
+
return;
|
|
110
|
+
this.mayDefSeen.add(idx);
|
|
111
|
+
this.mayDefs.push(idx);
|
|
112
|
+
}
|
|
113
|
+
addUse(idx) {
|
|
114
|
+
// Occurrence fan-out happens BEFORE the statement-level dedup: `exec(x, x)`
|
|
115
|
+
// records x at BOTH arg positions even though `uses` lists it once.
|
|
116
|
+
this.recordOccurrence(idx);
|
|
117
|
+
this.addUseWithoutOccurrence(idx);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Statement-level use that is NOT a value occurrence in any open site
|
|
121
|
+
* argument — bare callee names only (see each harvester's `visitCall`).
|
|
122
|
+
*/
|
|
123
|
+
addUseWithoutOccurrence(idx) {
|
|
124
|
+
if (this.useSeen.has(idx))
|
|
125
|
+
return;
|
|
126
|
+
this.useSeen.add(idx);
|
|
127
|
+
this.uses.push(idx);
|
|
128
|
+
}
|
|
129
|
+
defCount() {
|
|
130
|
+
return this.defs.length + this.mayDefs.length;
|
|
131
|
+
}
|
|
132
|
+
useCount() {
|
|
133
|
+
return this.uses.length;
|
|
134
|
+
}
|
|
135
|
+
// ── site machinery (#2195 U6, mirrors the TS harvester) ──────────────────
|
|
136
|
+
/** `[defs.length, mayDefs.length]` marker for {@link defsSince}. */
|
|
137
|
+
defSnapshot() {
|
|
138
|
+
return [this.defs.length, this.mayDefs.length];
|
|
139
|
+
}
|
|
140
|
+
/** Binding indices def'd (must- OR may-) since the snapshot was taken. */
|
|
141
|
+
defsSince(snap) {
|
|
142
|
+
return [...this.defs.slice(snap[0]), ...this.mayDefs.slice(snap[1])];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Open a call/new site; parent = innermost enclosing argument position.
|
|
146
|
+
* Returns the new site index, or -1 when the per-statement site cap is hit
|
|
147
|
+
* (the caller threads -1 through `pushFrame`/`setSite*`, all of which no-op on
|
|
148
|
+
* a sentinel index — see {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}).
|
|
149
|
+
*
|
|
150
|
+
* `at` is the call/new node's anchor position `[line (1-based), col (0-based)]`
|
|
151
|
+
* — the SAME position the CALLS-edge resolution keys on (see
|
|
152
|
+
* {@link SiteRecord.at} for the KTD7 alignment); the harvester passes its
|
|
153
|
+
* `visitCall`/`visitNew` node's `startPosition` so the downstream resolved-id
|
|
154
|
+
* join lands by exact position.
|
|
155
|
+
*/
|
|
156
|
+
openCallSite(kind, at) {
|
|
157
|
+
if (this.sites.length >= DEFAULT_PDG_MAX_SITES_PER_STATEMENT) {
|
|
158
|
+
this._sitesTruncated = true;
|
|
159
|
+
return -1;
|
|
160
|
+
}
|
|
161
|
+
const site = { kind };
|
|
162
|
+
const parent = this.innermostArgPosition();
|
|
163
|
+
if (parent)
|
|
164
|
+
site.parent = parent;
|
|
165
|
+
if (at)
|
|
166
|
+
site.at = [at[0], at[1]];
|
|
167
|
+
this.sites.push(site);
|
|
168
|
+
return this.sites.length - 1;
|
|
169
|
+
}
|
|
170
|
+
pushFrame(siteIdx) {
|
|
171
|
+
this.frames.push({ siteIdx, argIdx: -1 });
|
|
172
|
+
}
|
|
173
|
+
popFrame() {
|
|
174
|
+
this.frames.pop();
|
|
175
|
+
}
|
|
176
|
+
/** Set the argument position the top frame is currently walking. */
|
|
177
|
+
setFrameArg(argIdx) {
|
|
178
|
+
const top = this.frames[this.frames.length - 1];
|
|
179
|
+
if (top)
|
|
180
|
+
top.argIdx = argIdx;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Run `fn` with all open arg frames temporarily detached (argIdx = -1), so
|
|
184
|
+
* identifier reads inside still record USES but do NOT fan occurrences into
|
|
185
|
+
* the enclosing sink-argument position (e.g. the non-value operands of a
|
|
186
|
+
* comma expression — only the final operand's value flows).
|
|
187
|
+
*/
|
|
188
|
+
suppressOccurrences(fn) {
|
|
189
|
+
const saved = this.frames.map((f) => f.argIdx);
|
|
190
|
+
for (const f of this.frames)
|
|
191
|
+
f.argIdx = -1;
|
|
192
|
+
try {
|
|
193
|
+
fn();
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
this.frames.forEach((f, i) => {
|
|
197
|
+
f.argIdx = saved[i];
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
setSiteCallee(siteIdx, callee) {
|
|
202
|
+
const site = this.sites[siteIdx];
|
|
203
|
+
if (site)
|
|
204
|
+
site.callee = callee;
|
|
205
|
+
}
|
|
206
|
+
setSiteReceiver(siteIdx, receiver) {
|
|
207
|
+
const site = this.sites[siteIdx];
|
|
208
|
+
if (site)
|
|
209
|
+
site.receiver = receiver;
|
|
210
|
+
}
|
|
211
|
+
setSiteResultDefs(siteIdx, resultDefs) {
|
|
212
|
+
const site = this.sites[siteIdx];
|
|
213
|
+
if (site)
|
|
214
|
+
site.resultDefs = [...resultDefs];
|
|
215
|
+
}
|
|
216
|
+
setSiteSpread(siteIdx, firstSpreadArg) {
|
|
217
|
+
const site = this.sites[siteIdx];
|
|
218
|
+
if (site && site.spread === undefined)
|
|
219
|
+
site.spread = firstSpreadArg;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Record a value-position member read. Exact duplicates within the statement
|
|
223
|
+
* (same object/property/parent position) dedup; reads at DIFFERENT argument
|
|
224
|
+
* positions stay distinct (`exec(req.body, req.body)` is two occurrences).
|
|
225
|
+
*/
|
|
226
|
+
addMemberRead(object, property) {
|
|
227
|
+
const parent = this.innermostArgPosition();
|
|
228
|
+
const dedupKey = `${object}|${property}|${parent ? `${parent[0]}:${parent[1]}` : 'top'}`;
|
|
229
|
+
if (this.memberReadKeys.has(dedupKey))
|
|
230
|
+
return;
|
|
231
|
+
if (this.sites.length >= DEFAULT_PDG_MAX_SITES_PER_STATEMENT) {
|
|
232
|
+
this._sitesTruncated = true;
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this.memberReadKeys.add(dedupKey);
|
|
236
|
+
const site = { kind: 'member-read' };
|
|
237
|
+
if (parent)
|
|
238
|
+
site.parent = parent;
|
|
239
|
+
site.object = object;
|
|
240
|
+
site.property = property;
|
|
241
|
+
this.sites.push(site);
|
|
242
|
+
}
|
|
243
|
+
innermostArgPosition() {
|
|
244
|
+
for (let i = this.frames.length - 1; i >= 0; i--) {
|
|
245
|
+
const f = this.frames[i];
|
|
246
|
+
if (f.argIdx >= 0)
|
|
247
|
+
return [f.siteIdx, f.argIdx];
|
|
248
|
+
}
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Fan a binding occurrence out to every arg-active open frame, via-tagged
|
|
253
|
+
* with the site of the IMMEDIATELY nested frame when one exists:
|
|
254
|
+
* `exec(escape(x))` puts a plain `x` in escape's arg 0 and `[x, escapeIdx]`
|
|
255
|
+
* in exec's arg 0 — the sanitizer-interposition substrate.
|
|
256
|
+
*/
|
|
257
|
+
recordOccurrence(idx) {
|
|
258
|
+
for (let i = this.frames.length - 1; i >= 0; i--) {
|
|
259
|
+
const f = this.frames[i];
|
|
260
|
+
if (f.argIdx < 0)
|
|
261
|
+
continue;
|
|
262
|
+
// A nested frame whose site was cap-dropped (siteIdx -1) is not a real via.
|
|
263
|
+
const next = i + 1 < this.frames.length ? this.frames[i + 1].siteIdx : undefined;
|
|
264
|
+
const via = next !== undefined && next >= 0 ? next : undefined;
|
|
265
|
+
this.pushArgEntry(f.siteIdx, f.argIdx, idx, via);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
pushArgEntry(siteIdx, argIdx, bindingIdx, via) {
|
|
269
|
+
const site = this.sites[siteIdx];
|
|
270
|
+
if (!site)
|
|
271
|
+
return; // cap-dropped frame (siteIdx -1) — no target to fan into
|
|
272
|
+
const args = (site.args ??= []);
|
|
273
|
+
while (args.length <= argIdx)
|
|
274
|
+
args.push([]);
|
|
275
|
+
const list = args[argIdx];
|
|
276
|
+
// Dedup exact (binding, via) pairs per position — `f(x + x)` is one entry;
|
|
277
|
+
// `f(x + g(x))` keeps the plain AND the via-tagged entry (distinct paths).
|
|
278
|
+
for (const e of list) {
|
|
279
|
+
const match = typeof e === 'number'
|
|
280
|
+
? via === undefined && e === bindingIdx
|
|
281
|
+
: via !== undefined && e[0] === bindingIdx && e[1] === via;
|
|
282
|
+
if (match)
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
list.push(via === undefined ? bindingIdx : [bindingIdx, via]);
|
|
286
|
+
}
|
|
287
|
+
finish() {
|
|
288
|
+
return {
|
|
289
|
+
line: this.line,
|
|
290
|
+
defs: this.defs,
|
|
291
|
+
uses: this.uses,
|
|
292
|
+
// Optional fields stay absent when empty — keeps the serialized
|
|
293
|
+
// side-channel payload lean (most statements have no may-defs / sites).
|
|
294
|
+
...(this.mayDefs.length > 0 ? { mayDefs: this.mayDefs } : {}),
|
|
295
|
+
...(this.sites.length > 0 ? { sites: this.sites.map(finalizeSite) } : {}),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** Trim trailing empty arg positions; drop `args` entirely when all-empty. */
|
|
300
|
+
const finalizeSite = (site) => {
|
|
301
|
+
const args = site.args;
|
|
302
|
+
if (args !== undefined) {
|
|
303
|
+
let end = args.length;
|
|
304
|
+
while (end > 0 && args[end - 1].length === 0)
|
|
305
|
+
end--;
|
|
306
|
+
if (end === 0)
|
|
307
|
+
delete site.args;
|
|
308
|
+
else if (end < args.length)
|
|
309
|
+
site.args = args.slice(0, end);
|
|
310
|
+
}
|
|
311
|
+
return site;
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Shared `walkChain` TERMINAL (#2227 follow-up, plan KTD5/U8) — the byte-identical
|
|
315
|
+
* post-unwind block the Go / Kotlin / Swift / Rust / Python harvesters all ran
|
|
316
|
+
* after walking their grammar-specific access chain (`selector_expression` /
|
|
317
|
+
* `navigation_expression` / `field_expression` / `attribute`) into an
|
|
318
|
+
* `accesses: string[]` list and a resolved root node `cur`.
|
|
319
|
+
*
|
|
320
|
+
* It records the chain-root identifier as a use, emits at most ONE member-read
|
|
321
|
+
* site — the INNERMOST access — when the root is an identifier (suppressed by
|
|
322
|
+
* `skipFinalRead` when that access IS the callee, carried by the dotted path
|
|
323
|
+
* instead), and builds the dotted path `[root, ...accesses].join('.')`. The only
|
|
324
|
+
* per-grammar bit is the root identifier node type, supplied via `isRootIdType`
|
|
325
|
+
* (`'identifier'` for Go/Rust/Python, `'simple_identifier'` for Kotlin/Swift);
|
|
326
|
+
* the `resolve` / `walkRoot` callbacks bind the harvester's own methods. The
|
|
327
|
+
* `addUse` / `addMemberRead` machinery is on the accumulator itself, so it is
|
|
328
|
+
* called directly (no callback). Behavior is identical to the inlined terminals
|
|
329
|
+
* this replaces — the per-language harvest tests are the characterization lock.
|
|
330
|
+
*/
|
|
331
|
+
export function finalizeChain(acc, cur, accesses, skipFinalRead, isRootIdType, hooks) {
|
|
332
|
+
let rootIdx;
|
|
333
|
+
let rootSegment;
|
|
334
|
+
if (isRootIdType(cur.type) && cur.text !== '_') {
|
|
335
|
+
rootIdx = hooks.resolve(cur);
|
|
336
|
+
acc.addUse(rootIdx);
|
|
337
|
+
rootSegment = cur.text;
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
hooks.walkRoot(cur);
|
|
341
|
+
}
|
|
342
|
+
const innermost = accesses[0];
|
|
343
|
+
if (rootIdx !== undefined && innermost && !(skipFinalRead && accesses.length === 1)) {
|
|
344
|
+
acc.addMemberRead(rootIdx, innermost);
|
|
345
|
+
}
|
|
346
|
+
const path = rootSegment !== undefined && accesses.every((a) => a !== '')
|
|
347
|
+
? [rootSegment, ...accesses].join('.')
|
|
348
|
+
: undefined;
|
|
349
|
+
return { path, rootIdx };
|
|
350
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C# def/use harvester (#2195 U3, plan KTD2) — the C# analogue of
|
|
3
|
+
* {@link import('./typescript-harvest.js').TsHarvester} and the closely-related
|
|
4
|
+
* {@link import('./c-cpp-harvest.js').CCppHarvester}.
|
|
5
|
+
*
|
|
6
|
+
* Runs in the parse worker next to the C# CFG visitor, extracting per-statement
|
|
7
|
+
* variable definition/use facts that ride the side channel for the reaching-defs
|
|
8
|
+
* / CDG solvers. Output is the per-function binding table ({@link BindingEntry}[])
|
|
9
|
+
* plus {@link StatementFacts} the visitor attaches to blocks as it walks.
|
|
10
|
+
*
|
|
11
|
+
* TWO-PHASE, ORDER-INDEPENDENT (load-bearing — mirrors the TS / C-C++ harvesters):
|
|
12
|
+
* the CFG walk is NOT source-order (`visitFor` builds the init block after the
|
|
13
|
+
* body, `visitDoWhile` the condition before the body), so resolving names against
|
|
14
|
+
* a scope stack populated *during* the walk would mis-resolve. Phase 1 pre-scans
|
|
15
|
+
* the whole function subtree once into a completed lexical scope tree; phase 2
|
|
16
|
+
* resolves defs/uses against that finished tree from any walk order.
|
|
17
|
+
*
|
|
18
|
+
* v1 def-semantics scope:
|
|
19
|
+
* - `local_declaration_statement` → `variable_declaration` → `variable_declarator`
|
|
20
|
+
* (an INITIALIZED local is a def; a bare `int x;` with no initializer writes
|
|
21
|
+
* nothing at runtime — not a def, like the TS bare-`var` rule).
|
|
22
|
+
* - `assignment_expression` (plain + compound `+=` etc.), `postfix_unary_expression`
|
|
23
|
+
* / `prefix_unary_expression` (`x++` / `--x`) — define and (for compound /
|
|
24
|
+
* update) also use the lvalue.
|
|
25
|
+
* - parameters (`parameter` → `name` field), the `foreach` loop variable
|
|
26
|
+
* (`foreach_statement` field `left`), pattern bindings (`declaration_pattern`
|
|
27
|
+
* `name`, e.g. `o is string s` / `case int n:`), and catch-clause names
|
|
28
|
+
* (`catch_declaration` `name`).
|
|
29
|
+
* EXCLUDED, deliberately (TypeScript-CFA precedent): member / element / pointer
|
|
30
|
+
* writes (`obj.F = …`, `a[i] = …`) are NOT scalar defs — their identifiers are
|
|
31
|
+
* uses only. Nested-function (lambda / local-function / anonymous-method) bodies
|
|
32
|
+
* are opaque in BOTH directions (writes to and reads of captured outer variables
|
|
33
|
+
* are invisible).
|
|
34
|
+
*
|
|
35
|
+
* MAY-DEFS: a def inside a conditionally-evaluated subexpression — the right
|
|
36
|
+
* operand of `&&` / `||` / `??` (`a ?? (a = load())`), a ternary arm, or a switch
|
|
37
|
+
* arm/case test — is a may-def (gen without kill), so the not-taken path's prior
|
|
38
|
+
* def is not falsely killed.
|
|
39
|
+
*
|
|
40
|
+
* Identifiers with no in-function declaration (fields, properties, statics,
|
|
41
|
+
* namespaced names) resolve to a SYNTHETIC module-level binding (`name@module`),
|
|
42
|
+
* applied identically by def and use harvesting.
|
|
43
|
+
*
|
|
44
|
+
* NOTE: nothing serialized here may carry a field named `nodeId` — the durable
|
|
45
|
+
* parsedfile-store reviver dedups objects keyed on that field name.
|
|
46
|
+
*/
|
|
47
|
+
import type { SyntaxNode } from '../../utils/ast-helpers.js';
|
|
48
|
+
import type { StatementFacts } from '../types.js';
|
|
49
|
+
import { ScopeTreeHarvester, type Scope } from './scope-tree-harvest.js';
|
|
50
|
+
export declare class CsharpHarvester extends ScopeTreeHarvester {
|
|
51
|
+
constructor(fnNode: SyntaxNode);
|
|
52
|
+
/** The function/lambda body node (a `block` or an expression for `=> expr`). */
|
|
53
|
+
private bodyOf;
|
|
54
|
+
private declareParams;
|
|
55
|
+
protected prescan(node: SyntaxNode, scope: Scope): void;
|
|
56
|
+
/** Declare every `variable_declarator` name in a `variable_declaration`. */
|
|
57
|
+
private declareVariableDeclaration;
|
|
58
|
+
/** Declare a `foreach` target — an identifier or a `tuple_pattern`. */
|
|
59
|
+
private declareForeachTarget;
|
|
60
|
+
/** Def/use facts for one statement (or construct-header expression) node. */
|
|
61
|
+
facts(node: SyntaxNode): StatementFacts;
|
|
62
|
+
/** Facts for an expression whose WHOLE evaluation is conditional (case tests). */
|
|
63
|
+
factsConditional(node: SyntaxNode): StatementFacts;
|
|
64
|
+
/**
|
|
65
|
+
* Def-ONLY facts for a value-position binding carrier (`var x = k switch {…}`,
|
|
66
|
+
* #2207): just the declared name(s)' def, attached to the continuation block the
|
|
67
|
+
* switch arms rejoin. The discriminant + arm-value USES are already harvested
|
|
68
|
+
* onto the branch's own blocks ({@link facts} on each arm), so this must NOT
|
|
69
|
+
* re-walk the initializer — only each `variable_declarator`'s name is a def here.
|
|
70
|
+
*/
|
|
71
|
+
bindingDefFacts(stmt: SyntaxNode): StatementFacts | undefined;
|
|
72
|
+
/** Facts for a `foreach (decl in right)` head: decl binds, right is used. */
|
|
73
|
+
forEachHeadFacts(stmt: SyntaxNode): StatementFacts;
|
|
74
|
+
/** ENTRY-block facts for the function's parameters (defs only). */
|
|
75
|
+
paramFacts(): StatementFacts | undefined;
|
|
76
|
+
/** Def fact for a `catch (T e)` declaration — prepend to the handler entry block. */
|
|
77
|
+
catchParamFacts(catchClause: SyntaxNode): StatementFacts | undefined;
|
|
78
|
+
/** Strip parenthesized wrappers around an lvalue (`(x) = 1`). */
|
|
79
|
+
private unwrapLvalue;
|
|
80
|
+
/** Def a `foreach` target (identifier or tuple) in a header fact accumulator. */
|
|
81
|
+
private defForeachTarget;
|
|
82
|
+
/** Value-position walk: collect uses; route def positions to the lvalue handler. */
|
|
83
|
+
private walkValue;
|
|
84
|
+
/**
|
|
85
|
+
* When `value`'s root (after stripping parens) is an invocation/creation
|
|
86
|
+
* node, remember that its site should carry `resultDefs: defs` — consumed by
|
|
87
|
+
* {@link visitCall} once the value walk reaches the node.
|
|
88
|
+
*/
|
|
89
|
+
private registerResultDefs;
|
|
90
|
+
/**
|
|
91
|
+
* Explicit invocation / object-creation handler: records a call site (callee
|
|
92
|
+
* path, receiver, per-arg occurrence entries, result defs) while reproducing
|
|
93
|
+
* EXACTLY the uses the old default descent recorded. C# wraps each argument in
|
|
94
|
+
* an `argument` node; `new Foo(...)` reads the `type` field as the callee.
|
|
95
|
+
*/
|
|
96
|
+
private visitCall;
|
|
97
|
+
/**
|
|
98
|
+
* The value expression inside an `argument` node. A named argument
|
|
99
|
+
* (`name: x`) carries the label on the `name` field and the value as a
|
|
100
|
+
* sibling; a positional argument is just the value. Returns the last named
|
|
101
|
+
* child that is not the `name`-field label (and skips `ref`/`out`/`in`
|
|
102
|
+
* modifier keywords, which are anonymous tokens, not named children).
|
|
103
|
+
*/
|
|
104
|
+
private argumentValue;
|
|
105
|
+
/**
|
|
106
|
+
* Member chain walk shared by value position and callee position. Records the
|
|
107
|
+
* chain-root identifier as a use (identical to the old default descent), plus
|
|
108
|
+
* at most ONE member-read site — the INNERMOST access — when the root is an
|
|
109
|
+
* identifier; `skipFinalRead` suppresses it when that access is the callee.
|
|
110
|
+
*/
|
|
111
|
+
private walkChain;
|
|
112
|
+
/**
|
|
113
|
+
* The initializer value of a `variable_declarator` — the named child after
|
|
114
|
+
* `name`. NOTE: deliberately duplicated in `csharp.ts` (the visitor is a
|
|
115
|
+
* standalone class with no shared base — repo convention). The two copies must
|
|
116
|
+
* stay in sync; there is no C#-specific shared module to host it, and the only
|
|
117
|
+
* module both files share is the generic `utils/ast-helpers` (types only).
|
|
118
|
+
*/
|
|
119
|
+
private declaratorInit;
|
|
120
|
+
/** Whether a unary expression is `++`/`--` (the only writing unary ops). */
|
|
121
|
+
private isIncDec;
|
|
122
|
+
/** Def each identifier in a `(a, b) = …` tuple deconstruction target. */
|
|
123
|
+
private defTupleTargets;
|
|
124
|
+
}
|