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,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Java def/use harvester (#2195 U4, plan KTD2) — the Java analogue of
|
|
3
|
+
* {@link import('./typescript-harvest.js').TsHarvester} and the closely-related
|
|
4
|
+
* {@link import('./csharp-harvest.js').CsharpHarvester}.
|
|
5
|
+
*
|
|
6
|
+
* Runs in the parse worker next to the Java 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# 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_variable_declaration` → `variable_declarator` (an INITIALIZED local
|
|
20
|
+
* is a def; a bare `int x;` with no initializer writes nothing at runtime —
|
|
21
|
+
* not a def, like the TS bare-`var` rule).
|
|
22
|
+
* - `assignment_expression` (plain + compound `+=` etc.) and `update_expression`
|
|
23
|
+
* (`x++` / `--x`) — define and (for compound / update) also use the lvalue.
|
|
24
|
+
* - parameters (`formal_parameter` / `spread_parameter` → `name`), the
|
|
25
|
+
* enhanced-for loop variable (`enhanced_for_statement` field `name`), and
|
|
26
|
+
* catch parameters (`catch_formal_parameter` → `name`), incl. multi-catch.
|
|
27
|
+
* EXCLUDED, deliberately (TypeScript-CFA precedent): field / array writes
|
|
28
|
+
* (`obj.f = …`, `a[i] = …`) are NOT scalar defs — their identifiers are uses
|
|
29
|
+
* only. Nested-function (lambda) bodies are opaque in BOTH directions (writes to
|
|
30
|
+
* and reads of captured outer variables are invisible).
|
|
31
|
+
*
|
|
32
|
+
* MAY-DEFS: a def inside a conditionally-evaluated subexpression — the right
|
|
33
|
+
* operand of `&&` / `||` (`a && (x = f())`), a ternary arm, or a switch case test
|
|
34
|
+
* — is a may-def (gen without kill), so the not-taken path's prior def is not
|
|
35
|
+
* falsely killed. (Java has no `??`.)
|
|
36
|
+
*
|
|
37
|
+
* Identifiers with no in-function declaration (fields, statics, imported names)
|
|
38
|
+
* resolve to a SYNTHETIC module-level binding (`name@module`), applied
|
|
39
|
+
* identically by def and use harvesting.
|
|
40
|
+
*
|
|
41
|
+
* NOTE: nothing serialized here may carry a field named `nodeId` — the durable
|
|
42
|
+
* parsedfile-store reviver dedups objects keyed on that field name.
|
|
43
|
+
*/
|
|
44
|
+
import type { SyntaxNode } from '../../utils/ast-helpers.js';
|
|
45
|
+
import type { StatementFacts } from '../types.js';
|
|
46
|
+
import { ScopeTreeHarvester, type Scope } from './scope-tree-harvest.js';
|
|
47
|
+
export declare class JavaHarvester extends ScopeTreeHarvester {
|
|
48
|
+
constructor(fnNode: SyntaxNode);
|
|
49
|
+
/** The function/lambda body node (a `block`, or an expression for `x -> expr`). */
|
|
50
|
+
private bodyOf;
|
|
51
|
+
private declareParams;
|
|
52
|
+
/** The `name` identifier of a `formal_parameter` / `spread_parameter`. */
|
|
53
|
+
private paramName;
|
|
54
|
+
protected prescan(node: SyntaxNode, scope: Scope): void;
|
|
55
|
+
/** Declare every `variable_declarator` name in a `local_variable_declaration`. */
|
|
56
|
+
private declareVariableDeclaration;
|
|
57
|
+
/** Def/use facts for one statement (or construct-header expression) node. */
|
|
58
|
+
facts(node: SyntaxNode): StatementFacts;
|
|
59
|
+
/** Facts for an expression whose WHOLE evaluation is conditional (case tests). */
|
|
60
|
+
factsConditional(node: SyntaxNode): StatementFacts;
|
|
61
|
+
/**
|
|
62
|
+
* Def-ONLY facts for a value-position binding carrier (`var x = switch (…) {…}`,
|
|
63
|
+
* #2207): just the declared name(s)' def, attached to the continuation block the
|
|
64
|
+
* switch arms rejoin. The switch subject + arm-value USES are already harvested
|
|
65
|
+
* onto the branch's own blocks ({@link facts} on each arm), so this must NOT
|
|
66
|
+
* re-walk the value — only each `variable_declarator`'s `name` is a def here.
|
|
67
|
+
*/
|
|
68
|
+
bindingDefFacts(stmt: SyntaxNode): StatementFacts | undefined;
|
|
69
|
+
/** Facts for a `for (T name : value)` head: name binds, value is used. */
|
|
70
|
+
forEachHeadFacts(stmt: SyntaxNode): StatementFacts;
|
|
71
|
+
/** Facts for the resource-close finalizer: each resource is USED on close. */
|
|
72
|
+
resourceCloseFacts(resources: readonly SyntaxNode[]): StatementFacts | undefined;
|
|
73
|
+
/** ENTRY-block facts for the function's parameters (defs only). */
|
|
74
|
+
paramFacts(): StatementFacts | undefined;
|
|
75
|
+
/** Def fact for a `catch (T e)` parameter — prepend to the handler entry block. */
|
|
76
|
+
catchParamFacts(catchClause: SyntaxNode): StatementFacts | undefined;
|
|
77
|
+
/** Strip parenthesized wrappers around an lvalue (`(x) = 1`). */
|
|
78
|
+
private unwrapLvalue;
|
|
79
|
+
/** Value-position walk: collect uses; route def positions to the lvalue handler. */
|
|
80
|
+
private walkValue;
|
|
81
|
+
/**
|
|
82
|
+
* When `value`'s root (after stripping parens) is a method-invocation /
|
|
83
|
+
* object-creation node, remember its site should carry `resultDefs: defs`.
|
|
84
|
+
*/
|
|
85
|
+
private registerResultDefs;
|
|
86
|
+
/**
|
|
87
|
+
* Explicit `method_invocation` handler. Unlike a member-chain callee, Java
|
|
88
|
+
* carries the method NAME on the `name` field and the receiver on a sibling
|
|
89
|
+
* `object` field (`db.query(x)` ⇒ object `db`, name `query`); a bare call
|
|
90
|
+
* (`exec(x)`) has no `object`. Reproduces EXACTLY the uses the old default
|
|
91
|
+
* descent recorded (object root + arguments) and adds the call site.
|
|
92
|
+
*/
|
|
93
|
+
private visitCall;
|
|
94
|
+
/** Explicit `object_creation_expression` (`new Foo(x)`) handler. */
|
|
95
|
+
private visitNew;
|
|
96
|
+
/** Walk an `argument_list`, tagging each positional argument for occurrences. */
|
|
97
|
+
private walkArgs;
|
|
98
|
+
/**
|
|
99
|
+
* `field_access` chain walk shared by value position and the method-invocation
|
|
100
|
+
* receiver. Records the chain-root identifier as a use (identical to the old
|
|
101
|
+
* default descent) plus at most ONE member-read site — the INNERMOST access —
|
|
102
|
+
* when the root is an identifier; `skipFinalRead` suppresses it when that
|
|
103
|
+
* access is the callee (never the case for `field_access`, which is value-only).
|
|
104
|
+
*/
|
|
105
|
+
private walkChain;
|
|
106
|
+
/** The operand identifier of an `update_expression` (`x++` / `--x`). */
|
|
107
|
+
private updateOperand;
|
|
108
|
+
}
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import { CallSiteFactAccumulator } from './call-site-harvest.js';
|
|
2
|
+
import { ScopeTreeHarvester } from './scope-tree-harvest.js';
|
|
3
|
+
/** Node types that own a nested CFG — their subtrees are opaque to harvesting. */
|
|
4
|
+
const NESTED_FUNCTION_TYPES = new Set([
|
|
5
|
+
'lambda_expression',
|
|
6
|
+
'method_declaration',
|
|
7
|
+
'constructor_declaration',
|
|
8
|
+
'compact_constructor_declaration',
|
|
9
|
+
]);
|
|
10
|
+
/**
|
|
11
|
+
* Nodes that open a lexical scope for block-local declarations. A `block` is one
|
|
12
|
+
* scope; the loop constructs open a scope for their loop variable; a
|
|
13
|
+
* `catch_clause` scopes its exception name; a `try_with_resources_statement`
|
|
14
|
+
* scopes its resource declarations; a switch group/rule scopes its statements.
|
|
15
|
+
*/
|
|
16
|
+
const SCOPE_TYPES = new Set([
|
|
17
|
+
'block',
|
|
18
|
+
'for_statement',
|
|
19
|
+
'enhanced_for_statement',
|
|
20
|
+
'while_statement',
|
|
21
|
+
'do_statement',
|
|
22
|
+
'catch_clause',
|
|
23
|
+
'try_with_resources_statement',
|
|
24
|
+
'switch_block_statement_group',
|
|
25
|
+
'switch_rule',
|
|
26
|
+
]);
|
|
27
|
+
/** Comment node types tree-sitter-java surfaces (NOT `comment`). */
|
|
28
|
+
const COMMENT_TYPES = new Set(['line_comment', 'block_comment']);
|
|
29
|
+
export class JavaHarvester extends ScopeTreeHarvester {
|
|
30
|
+
constructor(fnNode) {
|
|
31
|
+
super(fnNode);
|
|
32
|
+
this.declareParams(fnNode);
|
|
33
|
+
const body = this.bodyOf(fnNode);
|
|
34
|
+
if (body && body.type === 'block')
|
|
35
|
+
this.prescan(body, this.openScope(body));
|
|
36
|
+
}
|
|
37
|
+
/** The function/lambda body node (a `block`, or an expression for `x -> expr`). */
|
|
38
|
+
bodyOf(fnNode) {
|
|
39
|
+
const body = fnNode.childForFieldName('body');
|
|
40
|
+
if (body)
|
|
41
|
+
return body;
|
|
42
|
+
return fnNode.namedChildren.find((c) => c.type === 'block');
|
|
43
|
+
}
|
|
44
|
+
// ── phase 1: declaration pre-scan ────────────────────────────────────────
|
|
45
|
+
declareParams(fnNode) {
|
|
46
|
+
const params = fnNode.childForFieldName('parameters');
|
|
47
|
+
if (!params) {
|
|
48
|
+
// Lambda single un-parenthesized parameter: `x -> …` (a bare identifier).
|
|
49
|
+
const lambdaParam = fnNode.namedChildren.find((c) => c.type === 'identifier');
|
|
50
|
+
if (fnNode.type === 'lambda_expression' && lambdaParam) {
|
|
51
|
+
this.declare(lambdaParam, 'param', this.root);
|
|
52
|
+
}
|
|
53
|
+
// Lambda inferred parameters: `(x, y) -> …`.
|
|
54
|
+
const inferred = fnNode.namedChildren.find((c) => c.type === 'inferred_parameters');
|
|
55
|
+
if (inferred) {
|
|
56
|
+
for (let i = 0; i < inferred.namedChildCount; i++) {
|
|
57
|
+
const p = inferred.namedChild(i);
|
|
58
|
+
if (p?.type === 'identifier')
|
|
59
|
+
this.declare(p, 'param', this.root);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
for (let i = 0; i < params.namedChildCount; i++) {
|
|
65
|
+
const p = params.namedChild(i);
|
|
66
|
+
if (p?.type !== 'formal_parameter' && p?.type !== 'spread_parameter')
|
|
67
|
+
continue;
|
|
68
|
+
const name = this.paramName(p);
|
|
69
|
+
if (name)
|
|
70
|
+
this.declare(name, 'param', this.root);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** The `name` identifier of a `formal_parameter` / `spread_parameter`. */
|
|
74
|
+
paramName(param) {
|
|
75
|
+
const named = param.childForFieldName('name');
|
|
76
|
+
if (named)
|
|
77
|
+
return named;
|
|
78
|
+
// `spread_parameter` (`int... xs`) exposes its name through a nested
|
|
79
|
+
// variable_declarator rather than a `name` field.
|
|
80
|
+
const declarator = param.namedChildren.find((c) => c.type === 'variable_declarator');
|
|
81
|
+
return declarator?.childForFieldName('name');
|
|
82
|
+
}
|
|
83
|
+
prescan(node, scope) {
|
|
84
|
+
this.nearestScopeCache.set(node.id, scope);
|
|
85
|
+
const t = node.type;
|
|
86
|
+
if (NESTED_FUNCTION_TYPES.has(t) && node.id !== this.fnId) {
|
|
87
|
+
// A nested function / lambda body is opaque — do not descend.
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
let childScope = scope;
|
|
91
|
+
if (SCOPE_TYPES.has(t))
|
|
92
|
+
childScope = this.openScope(node);
|
|
93
|
+
switch (t) {
|
|
94
|
+
case 'local_variable_declaration':
|
|
95
|
+
this.declareVariableDeclaration(node, childScope);
|
|
96
|
+
break;
|
|
97
|
+
case 'enhanced_for_statement': {
|
|
98
|
+
const name = node.childForFieldName('name');
|
|
99
|
+
if (name)
|
|
100
|
+
this.declare(name, 'var', childScope);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
case 'resource': {
|
|
104
|
+
// `try (var f = open())` — the resource binds in the try scope.
|
|
105
|
+
const name = node.childForFieldName('name');
|
|
106
|
+
if (name)
|
|
107
|
+
this.declare(name, 'var', childScope);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'catch_clause': {
|
|
111
|
+
const param = node.namedChildren.find((c) => c.type === 'catch_formal_parameter');
|
|
112
|
+
const name = param?.childForFieldName('name');
|
|
113
|
+
if (name)
|
|
114
|
+
this.declare(name, 'catch', childScope);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
default:
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
121
|
+
const c = node.namedChild(i);
|
|
122
|
+
if (c)
|
|
123
|
+
this.prescan(c, childScope);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Declare every `variable_declarator` name in a `local_variable_declaration`. */
|
|
127
|
+
declareVariableDeclaration(declNode, scope) {
|
|
128
|
+
for (let i = 0; i < declNode.namedChildCount; i++) {
|
|
129
|
+
const d = declNode.namedChild(i);
|
|
130
|
+
if (d?.type !== 'variable_declarator')
|
|
131
|
+
continue;
|
|
132
|
+
const name = d.childForFieldName('name');
|
|
133
|
+
if (name)
|
|
134
|
+
this.declare(name, 'var', scope);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ── phase 2: per-statement fact extraction ───────────────────────────────
|
|
138
|
+
/** Def/use facts for one statement (or construct-header expression) node. */
|
|
139
|
+
facts(node) {
|
|
140
|
+
const acc = new FactAccumulator(node.startPosition.row + 1);
|
|
141
|
+
this.walkValue(node, acc);
|
|
142
|
+
return acc.finish();
|
|
143
|
+
}
|
|
144
|
+
/** Facts for an expression whose WHOLE evaluation is conditional (case tests). */
|
|
145
|
+
factsConditional(node) {
|
|
146
|
+
const acc = new FactAccumulator(node.startPosition.row + 1);
|
|
147
|
+
this.conditional(() => this.walkValue(node, acc));
|
|
148
|
+
return acc.finish();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Def-ONLY facts for a value-position binding carrier (`var x = switch (…) {…}`,
|
|
152
|
+
* #2207): just the declared name(s)' def, attached to the continuation block the
|
|
153
|
+
* switch arms rejoin. The switch subject + arm-value USES are already harvested
|
|
154
|
+
* onto the branch's own blocks ({@link facts} on each arm), so this must NOT
|
|
155
|
+
* re-walk the value — only each `variable_declarator`'s `name` is a def here.
|
|
156
|
+
*/
|
|
157
|
+
bindingDefFacts(stmt) {
|
|
158
|
+
const acc = new FactAccumulator(stmt.startPosition.row + 1);
|
|
159
|
+
for (let i = 0; i < stmt.namedChildCount; i++) {
|
|
160
|
+
const d = stmt.namedChild(i);
|
|
161
|
+
if (d?.type !== 'variable_declarator')
|
|
162
|
+
continue;
|
|
163
|
+
const name = d.childForFieldName('name');
|
|
164
|
+
if (name)
|
|
165
|
+
this.def(name, acc);
|
|
166
|
+
}
|
|
167
|
+
return acc.defCount() ? acc.finish() : undefined;
|
|
168
|
+
}
|
|
169
|
+
/** Facts for a `for (T name : value)` head: name binds, value is used. */
|
|
170
|
+
forEachHeadFacts(stmt) {
|
|
171
|
+
const acc = new FactAccumulator(stmt.startPosition.row + 1);
|
|
172
|
+
const name = stmt.childForFieldName('name');
|
|
173
|
+
const value = stmt.childForFieldName('value');
|
|
174
|
+
if (name)
|
|
175
|
+
this.def(name, acc);
|
|
176
|
+
if (value)
|
|
177
|
+
this.walkValue(value, acc);
|
|
178
|
+
return acc.finish();
|
|
179
|
+
}
|
|
180
|
+
/** Facts for the resource-close finalizer: each resource is USED on close. */
|
|
181
|
+
resourceCloseFacts(resources) {
|
|
182
|
+
const first = resources[0];
|
|
183
|
+
if (!first)
|
|
184
|
+
return undefined;
|
|
185
|
+
const acc = new FactAccumulator(first.startPosition.row + 1);
|
|
186
|
+
for (const r of resources) {
|
|
187
|
+
const name = r.childForFieldName('name');
|
|
188
|
+
if (name)
|
|
189
|
+
this.use(name, acc);
|
|
190
|
+
}
|
|
191
|
+
return acc.useCount() ? acc.finish() : undefined;
|
|
192
|
+
}
|
|
193
|
+
/** ENTRY-block facts for the function's parameters (defs only). */
|
|
194
|
+
paramFacts() {
|
|
195
|
+
const acc = new FactAccumulator(this.fnNode.startPosition.row + 1);
|
|
196
|
+
const params = this.fnNode.childForFieldName('parameters');
|
|
197
|
+
if (params) {
|
|
198
|
+
for (let i = 0; i < params.namedChildCount; i++) {
|
|
199
|
+
const p = params.namedChild(i);
|
|
200
|
+
if (p?.type !== 'formal_parameter' && p?.type !== 'spread_parameter')
|
|
201
|
+
continue;
|
|
202
|
+
const name = this.paramName(p);
|
|
203
|
+
if (name)
|
|
204
|
+
this.def(name, acc);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else if (this.fnNode.type === 'lambda_expression') {
|
|
208
|
+
const lambdaParam = this.fnNode.namedChildren.find((c) => c.type === 'identifier');
|
|
209
|
+
if (lambdaParam)
|
|
210
|
+
this.def(lambdaParam, acc);
|
|
211
|
+
const inferred = this.fnNode.namedChildren.find((c) => c.type === 'inferred_parameters');
|
|
212
|
+
if (inferred) {
|
|
213
|
+
for (let i = 0; i < inferred.namedChildCount; i++) {
|
|
214
|
+
const p = inferred.namedChild(i);
|
|
215
|
+
if (p?.type === 'identifier')
|
|
216
|
+
this.def(p, acc);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return acc.defCount() ? acc.finish() : undefined;
|
|
221
|
+
}
|
|
222
|
+
/** Def fact for a `catch (T e)` parameter — prepend to the handler entry block. */
|
|
223
|
+
catchParamFacts(catchClause) {
|
|
224
|
+
const param = catchClause.namedChildren.find((c) => c.type === 'catch_formal_parameter');
|
|
225
|
+
const name = param?.childForFieldName('name');
|
|
226
|
+
if (!name)
|
|
227
|
+
return undefined;
|
|
228
|
+
const acc = new FactAccumulator(catchClause.startPosition.row + 1);
|
|
229
|
+
this.def(name, acc);
|
|
230
|
+
return acc.defCount() ? acc.finish() : undefined;
|
|
231
|
+
}
|
|
232
|
+
/** Strip parenthesized wrappers around an lvalue (`(x) = 1`). */
|
|
233
|
+
unwrapLvalue(node) {
|
|
234
|
+
let n = node;
|
|
235
|
+
let hops = 8;
|
|
236
|
+
while (n.type === 'parenthesized_expression' && hops-- > 0) {
|
|
237
|
+
const inner = n.namedChildren.find((c) => !COMMENT_TYPES.has(c.type));
|
|
238
|
+
if (!inner)
|
|
239
|
+
break;
|
|
240
|
+
n = inner;
|
|
241
|
+
}
|
|
242
|
+
return n;
|
|
243
|
+
}
|
|
244
|
+
/** Value-position walk: collect uses; route def positions to the lvalue handler. */
|
|
245
|
+
walkValue(node, acc) {
|
|
246
|
+
const t = node.type;
|
|
247
|
+
if (NESTED_FUNCTION_TYPES.has(t) && node.id !== this.fnId) {
|
|
248
|
+
// Opaque nested function / lambda — captured reads/writes are invisible.
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
switch (t) {
|
|
252
|
+
case 'identifier':
|
|
253
|
+
this.use(node, acc);
|
|
254
|
+
return;
|
|
255
|
+
case 'local_variable_declaration': {
|
|
256
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
257
|
+
const d = node.namedChild(i);
|
|
258
|
+
if (d?.type !== 'variable_declarator')
|
|
259
|
+
continue;
|
|
260
|
+
const name = d.childForFieldName('name');
|
|
261
|
+
const value = d.childForFieldName('value');
|
|
262
|
+
// Only an INITIALIZED declarator writes (`int x = e;`). A bare
|
|
263
|
+
// `int x;` is not a def (it writes nothing at runtime), matching the
|
|
264
|
+
// TS bare-`var` rule.
|
|
265
|
+
if (name && value) {
|
|
266
|
+
const snap = acc.defSnapshot();
|
|
267
|
+
this.def(name, acc);
|
|
268
|
+
this.registerResultDefs(value, acc.defsSince(snap));
|
|
269
|
+
}
|
|
270
|
+
if (value)
|
|
271
|
+
this.walkValue(value, acc);
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
case 'assignment_expression': {
|
|
276
|
+
const left = node.childForFieldName('left');
|
|
277
|
+
const right = node.childForFieldName('right');
|
|
278
|
+
const op = node.childForFieldName('operator')?.text ?? '=';
|
|
279
|
+
if (left) {
|
|
280
|
+
const lv = this.unwrapLvalue(left);
|
|
281
|
+
if (lv.type === 'identifier') {
|
|
282
|
+
const snap = acc.defSnapshot();
|
|
283
|
+
this.def(lv, acc);
|
|
284
|
+
if (op !== '=')
|
|
285
|
+
this.use(lv, acc); // compound assign reads too
|
|
286
|
+
if (op === '=' && right)
|
|
287
|
+
this.registerResultDefs(right, acc.defsSince(snap));
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
this.walkValue(lv, acc); // field/array target — uses only
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (right)
|
|
294
|
+
this.walkValue(right, acc);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
case 'update_expression': {
|
|
298
|
+
// `x++` / `++x` / `x--` / `--x` — the only writing unary ops. The operand
|
|
299
|
+
// is an anonymous (non-field) child; treat as def+use when it's an
|
|
300
|
+
// identifier.
|
|
301
|
+
const operand = this.updateOperand(node);
|
|
302
|
+
const lv = operand ? this.unwrapLvalue(operand) : null;
|
|
303
|
+
if (lv?.type === 'identifier') {
|
|
304
|
+
this.def(lv, acc);
|
|
305
|
+
this.use(lv, acc);
|
|
306
|
+
}
|
|
307
|
+
else if (operand) {
|
|
308
|
+
this.walkValue(operand, acc);
|
|
309
|
+
}
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
case 'binary_expression': {
|
|
313
|
+
const left = node.childForFieldName('left');
|
|
314
|
+
const right = node.childForFieldName('right');
|
|
315
|
+
const op = node.childForFieldName('operator')?.text ?? '';
|
|
316
|
+
if (left)
|
|
317
|
+
this.walkValue(left, acc);
|
|
318
|
+
if (right) {
|
|
319
|
+
if (op === '&&' || op === '||')
|
|
320
|
+
this.conditional(() => this.walkValue(right, acc));
|
|
321
|
+
else
|
|
322
|
+
this.walkValue(right, acc);
|
|
323
|
+
}
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
case 'ternary_expression': {
|
|
327
|
+
const cond = node.childForFieldName('condition');
|
|
328
|
+
const cons = node.childForFieldName('consequence');
|
|
329
|
+
const alt = node.childForFieldName('alternative');
|
|
330
|
+
if (cond)
|
|
331
|
+
this.walkValue(cond, acc);
|
|
332
|
+
if (cons)
|
|
333
|
+
this.conditional(() => this.walkValue(cons, acc));
|
|
334
|
+
if (alt)
|
|
335
|
+
this.conditional(() => this.walkValue(alt, acc));
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
case 'method_invocation':
|
|
339
|
+
// #2195 U6: explicit case (previously default-descended) — same uses,
|
|
340
|
+
// plus a taint-site record. Defs/uses stay byte-identical.
|
|
341
|
+
this.visitCall(node, acc);
|
|
342
|
+
return;
|
|
343
|
+
case 'object_creation_expression':
|
|
344
|
+
// `new Foo(x)` — constructor call site (`type` field is the callee).
|
|
345
|
+
this.visitNew(node, acc);
|
|
346
|
+
return;
|
|
347
|
+
case 'field_access': {
|
|
348
|
+
// `a.b` — value read of the object root only; the field name is not a
|
|
349
|
+
// scalar binding. Mirrors the TS member-read use semantics, plus a
|
|
350
|
+
// member-read site for the innermost identifier-rooted access.
|
|
351
|
+
this.walkChain(node, acc, false);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
default:
|
|
355
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
356
|
+
const c = node.namedChild(i);
|
|
357
|
+
if (c)
|
|
358
|
+
this.walkValue(c, acc);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// ── taint-site harvest (#2195 U6) ────────────────────────────────────────
|
|
363
|
+
/**
|
|
364
|
+
* When `value`'s root (after stripping parens) is a method-invocation /
|
|
365
|
+
* object-creation node, remember its site should carry `resultDefs: defs`.
|
|
366
|
+
*/
|
|
367
|
+
registerResultDefs(value, defs) {
|
|
368
|
+
if (defs.length === 0)
|
|
369
|
+
return;
|
|
370
|
+
const root = this.unwrapLvalue(value);
|
|
371
|
+
if (root.type === 'method_invocation' || root.type === 'object_creation_expression') {
|
|
372
|
+
this.resultDefTargets.set(root.id, [...defs]);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Explicit `method_invocation` handler. Unlike a member-chain callee, Java
|
|
377
|
+
* carries the method NAME on the `name` field and the receiver on a sibling
|
|
378
|
+
* `object` field (`db.query(x)` ⇒ object `db`, name `query`); a bare call
|
|
379
|
+
* (`exec(x)`) has no `object`. Reproduces EXACTLY the uses the old default
|
|
380
|
+
* descent recorded (object root + arguments) and adds the call site.
|
|
381
|
+
*/
|
|
382
|
+
visitCall(node, acc) {
|
|
383
|
+
const objectNode = node.childForFieldName('object');
|
|
384
|
+
const nameNode = node.childForFieldName('name');
|
|
385
|
+
const argsNode = node.childForFieldName('arguments');
|
|
386
|
+
// `node` IS the method_invocation — the SAME node the scope-extractor
|
|
387
|
+
// anchors `@reference.call.*` (its `atRange`) on (KTD7).
|
|
388
|
+
const siteIdx = acc.openCallSite('call', [
|
|
389
|
+
node.startPosition.row + 1,
|
|
390
|
+
node.startPosition.column,
|
|
391
|
+
]);
|
|
392
|
+
acc.pushFrame(siteIdx);
|
|
393
|
+
let receiverPath;
|
|
394
|
+
if (objectNode) {
|
|
395
|
+
// The receiver is a value read (object chain root) — record its uses and
|
|
396
|
+
// the member-read sites, and capture its dotted path + binding root.
|
|
397
|
+
const chain = this.walkChain(objectNode, acc, false);
|
|
398
|
+
receiverPath = chain.path;
|
|
399
|
+
if (chain.rootIdx !== undefined)
|
|
400
|
+
acc.setSiteReceiver(siteIdx, chain.rootIdx);
|
|
401
|
+
}
|
|
402
|
+
if (nameNode) {
|
|
403
|
+
// The method NAME was a (synthetic) statement-level use under the old
|
|
404
|
+
// default descent — preserve it byte-identically, but never as a value
|
|
405
|
+
// occurrence in an enclosing argument (`exec(escape(x))` must not put the
|
|
406
|
+
// `escape` name into exec's arg 0).
|
|
407
|
+
acc.addUseWithoutOccurrence(this.resolve(nameNode));
|
|
408
|
+
const callee = receiverPath !== undefined ? `${receiverPath}.${nameNode.text}` : nameNode.text;
|
|
409
|
+
acc.setSiteCallee(siteIdx, callee);
|
|
410
|
+
}
|
|
411
|
+
const resultDefs = this.resultDefTargets.get(node.id);
|
|
412
|
+
if (resultDefs !== undefined)
|
|
413
|
+
acc.setSiteResultDefs(siteIdx, resultDefs);
|
|
414
|
+
this.walkArgs(argsNode, acc);
|
|
415
|
+
acc.popFrame();
|
|
416
|
+
}
|
|
417
|
+
/** Explicit `object_creation_expression` (`new Foo(x)`) handler. */
|
|
418
|
+
visitNew(node, acc) {
|
|
419
|
+
const typeNode = node.childForFieldName('type');
|
|
420
|
+
const argsNode = node.childForFieldName('arguments');
|
|
421
|
+
// `node` IS the object_creation_expression — the SAME node the
|
|
422
|
+
// scope-extractor anchors `@reference.call.constructor` (its `atRange`) on.
|
|
423
|
+
const siteIdx = acc.openCallSite('new', [
|
|
424
|
+
node.startPosition.row + 1,
|
|
425
|
+
node.startPosition.column,
|
|
426
|
+
]);
|
|
427
|
+
acc.pushFrame(siteIdx);
|
|
428
|
+
if (typeNode) {
|
|
429
|
+
// The type name is not a scalar binding — record it only as the callee
|
|
430
|
+
// path, never a use/occurrence (matches the type-position semantics).
|
|
431
|
+
acc.setSiteCallee(siteIdx, typeNode.text.replace(/\s+/g, ''));
|
|
432
|
+
}
|
|
433
|
+
const resultDefs = this.resultDefTargets.get(node.id);
|
|
434
|
+
if (resultDefs !== undefined)
|
|
435
|
+
acc.setSiteResultDefs(siteIdx, resultDefs);
|
|
436
|
+
this.walkArgs(argsNode, acc);
|
|
437
|
+
acc.popFrame();
|
|
438
|
+
}
|
|
439
|
+
/** Walk an `argument_list`, tagging each positional argument for occurrences. */
|
|
440
|
+
walkArgs(argsNode, acc) {
|
|
441
|
+
if (!argsNode)
|
|
442
|
+
return;
|
|
443
|
+
let pos = 0;
|
|
444
|
+
for (let i = 0; i < argsNode.namedChildCount; i++) {
|
|
445
|
+
const arg = argsNode.namedChild(i);
|
|
446
|
+
if (!arg || COMMENT_TYPES.has(arg.type))
|
|
447
|
+
continue;
|
|
448
|
+
acc.setFrameArg(pos);
|
|
449
|
+
this.walkValue(arg, acc);
|
|
450
|
+
pos++;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* `field_access` chain walk shared by value position and the method-invocation
|
|
455
|
+
* receiver. Records the chain-root identifier as a use (identical to the old
|
|
456
|
+
* default descent) plus at most ONE member-read site — the INNERMOST access —
|
|
457
|
+
* when the root is an identifier; `skipFinalRead` suppresses it when that
|
|
458
|
+
* access is the callee (never the case for `field_access`, which is value-only).
|
|
459
|
+
*/
|
|
460
|
+
walkChain(node, acc, skipFinalRead) {
|
|
461
|
+
const accesses = [];
|
|
462
|
+
let cur = this.unwrapLvalue(node);
|
|
463
|
+
for (;;) {
|
|
464
|
+
if (cur.type === 'field_access') {
|
|
465
|
+
const field = cur.childForFieldName('field');
|
|
466
|
+
accesses.unshift(field?.text ?? '');
|
|
467
|
+
const obj = cur.childForFieldName('object');
|
|
468
|
+
if (!obj)
|
|
469
|
+
break;
|
|
470
|
+
cur = this.unwrapLvalue(obj);
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
let rootIdx;
|
|
477
|
+
let rootSegment;
|
|
478
|
+
if (cur.type === 'identifier') {
|
|
479
|
+
rootIdx = this.resolve(cur);
|
|
480
|
+
acc.addUse(rootIdx);
|
|
481
|
+
rootSegment = cur.text;
|
|
482
|
+
}
|
|
483
|
+
else if (cur.type === 'this' || cur.type === 'super') {
|
|
484
|
+
rootSegment = cur.text; // `this`/`super` are path segments, never bind
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
this.walkValue(cur, acc);
|
|
488
|
+
}
|
|
489
|
+
const innermost = accesses[0];
|
|
490
|
+
if (rootIdx !== undefined && innermost && !(skipFinalRead && accesses.length === 1)) {
|
|
491
|
+
acc.addMemberRead(rootIdx, innermost);
|
|
492
|
+
}
|
|
493
|
+
const path = rootSegment !== undefined && accesses.every((a) => a !== '')
|
|
494
|
+
? [rootSegment, ...accesses].join('.')
|
|
495
|
+
: undefined;
|
|
496
|
+
return { path, rootIdx };
|
|
497
|
+
}
|
|
498
|
+
/** The operand identifier of an `update_expression` (`x++` / `--x`). */
|
|
499
|
+
updateOperand(node) {
|
|
500
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
501
|
+
const c = node.namedChild(i);
|
|
502
|
+
if (c && !COMMENT_TYPES.has(c.type))
|
|
503
|
+
return c;
|
|
504
|
+
}
|
|
505
|
+
return undefined;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Ordered, deduplicating def/use + call-site collector for one statement record.
|
|
510
|
+
* The shared {@link CallSiteFactAccumulator} carries the def/use machinery the
|
|
511
|
+
* old local class had, plus the taint-site harvest (#2195 U6).
|
|
512
|
+
*/
|
|
513
|
+
const FactAccumulator = CallSiteFactAccumulator;
|