gitnexus 1.6.8-rc.8 → 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 +23 -2
- package/dist/core/ingestion/languages/c-cpp.js +17 -5
- 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 +8 -1
- 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 +44 -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/clone-safety.d.ts +109 -0
- package/dist/core/ingestion/workers/clone-safety.js +465 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +23 -0
- package/dist/core/ingestion/workers/parse-worker.js +81 -53
- package/dist/core/ingestion/workers/post-result.d.ts +22 -0
- package/dist/core/ingestion/workers/post-result.js +87 -0
- package/dist/core/ingestion/workers/result-merge.d.ts +20 -0
- package/dist/core/ingestion/workers/result-merge.js +43 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +15 -40
- package/dist/core/ingestion/workers/worker-pool.js +43 -16
- 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-ipc.d.ts +58 -0
- package/dist/server/analyze-worker-ipc.js +16 -0
- package/dist/server/analyze-worker.d.ts +17 -1
- package/dist/server/analyze-worker.js +7 -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 +44 -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,584 @@
|
|
|
1
|
+
import { CfgBuilder } from '../cfg-builder.js';
|
|
2
|
+
import { CCppHarvester } from './c-cpp-harvest.js';
|
|
3
|
+
/** C function node — only `function_definition` owns a CFG-bearing body. */
|
|
4
|
+
const C_FUNCTION_TYPES = new Set(['function_definition']);
|
|
5
|
+
/** C++ adds the lambda as a CFG-bearing function. */
|
|
6
|
+
const CPP_FUNCTION_TYPES = new Set(['function_definition', 'lambda_expression']);
|
|
7
|
+
/** Statement node types that break a basic block (everything else coalesces). */
|
|
8
|
+
const C_CONTROL_FLOW_TYPES = new Set([
|
|
9
|
+
'if_statement',
|
|
10
|
+
'while_statement',
|
|
11
|
+
'do_statement',
|
|
12
|
+
'for_statement',
|
|
13
|
+
'switch_statement',
|
|
14
|
+
'return_statement',
|
|
15
|
+
'break_statement',
|
|
16
|
+
'continue_statement',
|
|
17
|
+
'goto_statement',
|
|
18
|
+
'labeled_statement',
|
|
19
|
+
'compound_statement',
|
|
20
|
+
]);
|
|
21
|
+
/** C++ control-flow node types (C set ∪ exceptions ∪ range-for). */
|
|
22
|
+
const CPP_CONTROL_FLOW_TYPES = new Set([
|
|
23
|
+
...C_CONTROL_FLOW_TYPES,
|
|
24
|
+
'for_range_loop',
|
|
25
|
+
'try_statement',
|
|
26
|
+
'throw_statement',
|
|
27
|
+
'co_return_statement',
|
|
28
|
+
]);
|
|
29
|
+
const LOOP_OR_SWITCH_TYPES = new Set([
|
|
30
|
+
'while_statement',
|
|
31
|
+
'do_statement',
|
|
32
|
+
'for_statement',
|
|
33
|
+
'for_range_loop',
|
|
34
|
+
'switch_statement',
|
|
35
|
+
]);
|
|
36
|
+
const startLineOf = (n) => n.startPosition.row + 1;
|
|
37
|
+
const endLineOf = (n) => n.endPosition.row + 1;
|
|
38
|
+
/**
|
|
39
|
+
* Per-function C walk state. One instance per function so the jump-target stack,
|
|
40
|
+
* exception-handler stack, and label tables are scoped to that function.
|
|
41
|
+
*
|
|
42
|
+
* Designed to be EXTENDED by the C++ walk: the dispatch table is open via the
|
|
43
|
+
* protected {@link visitStmt} override hook, so C++ adds its node types without
|
|
44
|
+
* any language conditional in the C core.
|
|
45
|
+
*/
|
|
46
|
+
class CCfgWalk {
|
|
47
|
+
builder;
|
|
48
|
+
harvest;
|
|
49
|
+
jumps = [];
|
|
50
|
+
/** Stack of exception-handler entry blocks (catch) a `throw` jumps to. */
|
|
51
|
+
handlers = [];
|
|
52
|
+
/** label name → its `labeled_statement` body's entry block (resolved on demand). */
|
|
53
|
+
labelBlocks = new Map();
|
|
54
|
+
/** Pending gotos to a label not yet seen: label → list of source blocks. */
|
|
55
|
+
pendingGotos = new Map();
|
|
56
|
+
/** Set of node types that break a block, used by {@link visitSeq}. */
|
|
57
|
+
controlFlowTypes;
|
|
58
|
+
constructor(builder, harvest, controlFlowTypes) {
|
|
59
|
+
this.builder = builder;
|
|
60
|
+
this.harvest = harvest;
|
|
61
|
+
this.controlFlowTypes = controlFlowTypes;
|
|
62
|
+
}
|
|
63
|
+
/** Statements of a block node, ignoring comments. */
|
|
64
|
+
statementsOf(block) {
|
|
65
|
+
return block.namedChildren.filter((c) => c.type !== 'comment');
|
|
66
|
+
}
|
|
67
|
+
/** The `body` block of a node (field, or the first compound_statement child). */
|
|
68
|
+
bodyBlockOf(node) {
|
|
69
|
+
return (node.childForFieldName('body') ??
|
|
70
|
+
node.namedChildren.find((c) => c.type === 'compound_statement'));
|
|
71
|
+
}
|
|
72
|
+
/** Visit a body that may be a `compound_statement` or a single statement. */
|
|
73
|
+
visitBody(node) {
|
|
74
|
+
return this.builder.withNesting(() => {
|
|
75
|
+
if (!node)
|
|
76
|
+
return null;
|
|
77
|
+
if (node.type === 'compound_statement')
|
|
78
|
+
return this.visitSeq(this.statementsOf(node));
|
|
79
|
+
return this.visitStmt(node);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Wire a sequence of statements, coalescing straight-line runs into blocks. */
|
|
83
|
+
visitSeq(stmts) {
|
|
84
|
+
return this.builder.withNesting(() => {
|
|
85
|
+
let entry;
|
|
86
|
+
let dangling = [];
|
|
87
|
+
let openSimple;
|
|
88
|
+
for (const stmt of stmts) {
|
|
89
|
+
if (this.controlFlowTypes.has(stmt.type)) {
|
|
90
|
+
openSimple = undefined; // close any open straight-line block
|
|
91
|
+
const res = this.visitStmt(stmt);
|
|
92
|
+
if (res === null)
|
|
93
|
+
continue; // transparent (empty nested block)
|
|
94
|
+
if (entry === undefined)
|
|
95
|
+
entry = res.entry;
|
|
96
|
+
else
|
|
97
|
+
this.builder.connect(dangling, res.entry, 'seq');
|
|
98
|
+
dangling = [...res.exits];
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
if (openSimple === undefined) {
|
|
102
|
+
const idx = this.builder.newBlock(startLineOf(stmt), endLineOf(stmt), stmt.text, 'normal', this.harvest.facts(stmt));
|
|
103
|
+
if (entry === undefined)
|
|
104
|
+
entry = idx;
|
|
105
|
+
else
|
|
106
|
+
this.builder.connect(dangling, idx, 'seq');
|
|
107
|
+
openSimple = idx;
|
|
108
|
+
dangling = [idx];
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.builder.extendBlock(openSimple, endLineOf(stmt), stmt.text, this.harvest.facts(stmt));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (entry === undefined)
|
|
116
|
+
return null;
|
|
117
|
+
return { entry, exits: dangling };
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/** Dispatch one statement to its handler. Non-null except for empty blocks. */
|
|
121
|
+
visitStmt(stmt) {
|
|
122
|
+
switch (stmt.type) {
|
|
123
|
+
case 'if_statement':
|
|
124
|
+
return this.visitIf(stmt);
|
|
125
|
+
case 'while_statement':
|
|
126
|
+
return this.visitWhile(stmt);
|
|
127
|
+
case 'do_statement':
|
|
128
|
+
return this.visitDoWhile(stmt);
|
|
129
|
+
case 'for_statement':
|
|
130
|
+
return this.visitFor(stmt);
|
|
131
|
+
case 'switch_statement':
|
|
132
|
+
return this.visitSwitch(stmt);
|
|
133
|
+
case 'return_statement':
|
|
134
|
+
return this.visitReturn(stmt);
|
|
135
|
+
case 'break_statement':
|
|
136
|
+
return this.visitBreak(stmt);
|
|
137
|
+
case 'continue_statement':
|
|
138
|
+
return this.visitContinue(stmt);
|
|
139
|
+
case 'goto_statement':
|
|
140
|
+
return this.visitGoto(stmt);
|
|
141
|
+
case 'labeled_statement':
|
|
142
|
+
return this.visitLabeled(stmt);
|
|
143
|
+
case 'compound_statement':
|
|
144
|
+
return this.visitSeq(this.statementsOf(stmt));
|
|
145
|
+
default:
|
|
146
|
+
return this.visitExtra(stmt) ?? this.visitSimple(stmt);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Extension hook for node types the C core does not handle (C++ try/catch/
|
|
151
|
+
* throw/for-range). Returns `undefined` to fall through to {@link visitSimple}.
|
|
152
|
+
* The C core has none, so this is a no-op here.
|
|
153
|
+
*/
|
|
154
|
+
visitExtra(_stmt) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
visitSimple(stmt) {
|
|
158
|
+
const idx = this.builder.newBlock(startLineOf(stmt), endLineOf(stmt), stmt.text, 'normal', this.harvest.facts(stmt));
|
|
159
|
+
return { entry: idx, exits: [idx] };
|
|
160
|
+
}
|
|
161
|
+
visitReturn(stmt) {
|
|
162
|
+
const idx = this.builder.newBlock(startLineOf(stmt), endLineOf(stmt), stmt.text, 'normal', this.harvest.facts(stmt));
|
|
163
|
+
this.builder.edge(idx, this.builder.exitIndex, 'return');
|
|
164
|
+
return { entry: idx, exits: [] };
|
|
165
|
+
}
|
|
166
|
+
visitBreak(stmt) {
|
|
167
|
+
const idx = this.builder.newBlock(startLineOf(stmt), endLineOf(stmt), stmt.text);
|
|
168
|
+
const target = this.nearestBreakTarget();
|
|
169
|
+
this.builder.edge(idx, target ?? this.builder.exitIndex, 'break');
|
|
170
|
+
return { entry: idx, exits: [] };
|
|
171
|
+
}
|
|
172
|
+
visitContinue(stmt) {
|
|
173
|
+
const idx = this.builder.newBlock(startLineOf(stmt), endLineOf(stmt), stmt.text);
|
|
174
|
+
const target = this.nearestContinueTarget();
|
|
175
|
+
this.builder.edge(idx, target ?? this.builder.exitIndex, 'continue');
|
|
176
|
+
return { entry: idx, exits: [] };
|
|
177
|
+
}
|
|
178
|
+
/** Nearest enclosing loop/switch `break` target, or undefined (→ EXIT). */
|
|
179
|
+
nearestBreakTarget() {
|
|
180
|
+
return this.jumps.length ? this.jumps[this.jumps.length - 1].breakTo : undefined;
|
|
181
|
+
}
|
|
182
|
+
/** Nearest enclosing loop `continue` target (switches don't catch continue). */
|
|
183
|
+
nearestContinueTarget() {
|
|
184
|
+
for (let i = this.jumps.length - 1; i >= 0; i--) {
|
|
185
|
+
if (this.jumps[i].kind === 'loop')
|
|
186
|
+
return this.jumps[i].continueTo;
|
|
187
|
+
}
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
/** `goto label;` — route to the label block if known, else defer / EXIT. */
|
|
191
|
+
visitGoto(stmt) {
|
|
192
|
+
const idx = this.builder.newBlock(startLineOf(stmt), endLineOf(stmt), stmt.text);
|
|
193
|
+
const label = this.labelOf(stmt);
|
|
194
|
+
if (label === undefined) {
|
|
195
|
+
// Computed goto (`goto *p;`) or malformed — route to EXIT (single-exit).
|
|
196
|
+
this.builder.edge(idx, this.builder.exitIndex, 'seq');
|
|
197
|
+
return { entry: idx, exits: [] };
|
|
198
|
+
}
|
|
199
|
+
const target = this.labelBlocks.get(label);
|
|
200
|
+
if (target !== undefined) {
|
|
201
|
+
this.builder.edge(idx, target, 'seq'); // backward goto: label already built
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Forward goto — wire once the label is created (or to EXIT at finish()).
|
|
205
|
+
const list = this.pendingGotos.get(label);
|
|
206
|
+
if (list)
|
|
207
|
+
list.push(idx);
|
|
208
|
+
else
|
|
209
|
+
this.pendingGotos.set(label, [idx]);
|
|
210
|
+
}
|
|
211
|
+
return { entry: idx, exits: [] };
|
|
212
|
+
}
|
|
213
|
+
visitLabeled(stmt) {
|
|
214
|
+
const label = this.labelOf(stmt);
|
|
215
|
+
// The labeled statement's body is the trailing named child (no `body` field
|
|
216
|
+
// on labeled_statement in C/C++).
|
|
217
|
+
const body = stmt.namedChildren.find((c) => c.type !== 'statement_identifier' && c.type !== 'comment') ??
|
|
218
|
+
null;
|
|
219
|
+
const res = this.visitBody(body);
|
|
220
|
+
if (label !== undefined) {
|
|
221
|
+
const entry = res?.entry ?? this.builder.newBlock(endLineOf(stmt), endLineOf(stmt), '');
|
|
222
|
+
this.labelBlocks.set(label, entry);
|
|
223
|
+
// Resolve any forward gotos that were waiting on this label.
|
|
224
|
+
const pending = this.pendingGotos.get(label);
|
|
225
|
+
if (pending) {
|
|
226
|
+
for (const from of pending)
|
|
227
|
+
this.builder.edge(from, entry, 'seq');
|
|
228
|
+
this.pendingGotos.delete(label);
|
|
229
|
+
}
|
|
230
|
+
if (!res)
|
|
231
|
+
return { entry, exits: [entry] };
|
|
232
|
+
}
|
|
233
|
+
return res;
|
|
234
|
+
}
|
|
235
|
+
visitIf(stmt) {
|
|
236
|
+
const cond = stmt.childForFieldName('condition') ?? stmt;
|
|
237
|
+
const condBlock = this.builder.newBlock(startLineOf(stmt), endLineOf(cond), cond.text, 'normal', this.harvest.facts(cond));
|
|
238
|
+
const exits = [];
|
|
239
|
+
const thenRes = this.visitBody(stmt.childForFieldName('consequence'));
|
|
240
|
+
if (thenRes) {
|
|
241
|
+
this.builder.edge(condBlock, thenRes.entry, 'cond-true');
|
|
242
|
+
exits.push(...thenRes.exits);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
exits.push(condBlock); // empty then — true path falls through
|
|
246
|
+
}
|
|
247
|
+
const elseNode = this.elseBodyOf(stmt);
|
|
248
|
+
if (elseNode) {
|
|
249
|
+
const elseRes = this.visitBody(elseNode);
|
|
250
|
+
if (elseRes) {
|
|
251
|
+
this.builder.edge(condBlock, elseRes.entry, 'cond-false');
|
|
252
|
+
exits.push(...elseRes.exits);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
exits.push(condBlock);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
exits.push(condBlock); // no else — false path falls through to the join
|
|
260
|
+
}
|
|
261
|
+
return { entry: condBlock, exits: [...new Set(exits)] };
|
|
262
|
+
}
|
|
263
|
+
/** The else body node (unwraps an `else_clause` wrapper if present). */
|
|
264
|
+
elseBodyOf(ifStmt) {
|
|
265
|
+
const alt = ifStmt.childForFieldName('alternative');
|
|
266
|
+
if (!alt)
|
|
267
|
+
return undefined;
|
|
268
|
+
if (alt.type === 'else_clause') {
|
|
269
|
+
return alt.childForFieldName('body') ?? alt.namedChildren[0];
|
|
270
|
+
}
|
|
271
|
+
return alt; // an `else if` is the nested if_statement directly
|
|
272
|
+
}
|
|
273
|
+
visitWhile(stmt) {
|
|
274
|
+
const cond = stmt.childForFieldName('condition') ?? stmt;
|
|
275
|
+
const header = this.builder.newBlock(startLineOf(stmt), endLineOf(cond), cond.text, 'normal', this.harvest.facts(cond));
|
|
276
|
+
const loopExit = this.builder.newBlock(endLineOf(stmt), endLineOf(stmt), '');
|
|
277
|
+
this.jumps.push({ kind: 'loop', breakTo: loopExit, continueTo: header });
|
|
278
|
+
const body = this.visitBody(this.bodyBlockOf(stmt));
|
|
279
|
+
this.jumps.pop();
|
|
280
|
+
if (body) {
|
|
281
|
+
this.builder.edge(header, body.entry, 'cond-true');
|
|
282
|
+
this.builder.connect(body.exits, header, 'loop-back');
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
this.builder.edge(header, header, 'loop-back'); // empty body re-tests
|
|
286
|
+
}
|
|
287
|
+
// Always emit the structural exit edge — even `while (1)` keeps EXIT
|
|
288
|
+
// reverse-reachable for the post-dominator / CDG pass.
|
|
289
|
+
this.builder.edge(header, loopExit, 'cond-false');
|
|
290
|
+
return { entry: header, exits: [loopExit] };
|
|
291
|
+
}
|
|
292
|
+
visitDoWhile(stmt) {
|
|
293
|
+
const cond = stmt.childForFieldName('condition') ?? stmt;
|
|
294
|
+
const condBlock = this.builder.newBlock(startLineOf(cond), endLineOf(cond), cond.text, 'normal', this.harvest.facts(cond));
|
|
295
|
+
const loopExit = this.builder.newBlock(endLineOf(stmt), endLineOf(stmt), '');
|
|
296
|
+
this.jumps.push({ kind: 'loop', breakTo: loopExit, continueTo: condBlock });
|
|
297
|
+
const body = this.visitBody(this.bodyBlockOf(stmt));
|
|
298
|
+
this.jumps.pop();
|
|
299
|
+
const backTarget = body ? body.entry : condBlock;
|
|
300
|
+
if (body)
|
|
301
|
+
this.builder.connect(body.exits, condBlock, 'seq');
|
|
302
|
+
this.builder.edge(condBlock, backTarget, 'loop-back'); // cond true → run body again
|
|
303
|
+
this.builder.edge(condBlock, loopExit, 'cond-false');
|
|
304
|
+
return { entry: backTarget, exits: [loopExit] };
|
|
305
|
+
}
|
|
306
|
+
visitFor(stmt) {
|
|
307
|
+
const init = stmt.childForFieldName('initializer');
|
|
308
|
+
const cond = stmt.childForFieldName('condition');
|
|
309
|
+
const incr = stmt.childForFieldName('update');
|
|
310
|
+
const header = this.builder.newBlock(startLineOf(stmt), cond ? endLineOf(cond) : startLineOf(stmt), cond ? cond.text : 'for(;;)', 'normal', cond ? this.harvest.facts(cond) : undefined);
|
|
311
|
+
const loopExit = this.builder.newBlock(endLineOf(stmt), endLineOf(stmt), '');
|
|
312
|
+
let incrBlock = header;
|
|
313
|
+
if (incr) {
|
|
314
|
+
incrBlock = this.builder.newBlock(startLineOf(incr), endLineOf(incr), incr.text, 'normal', this.harvest.facts(incr));
|
|
315
|
+
this.builder.edge(incrBlock, header, 'loop-back');
|
|
316
|
+
}
|
|
317
|
+
this.jumps.push({ kind: 'loop', breakTo: loopExit, continueTo: incrBlock });
|
|
318
|
+
const body = this.visitBody(this.bodyBlockOf(stmt));
|
|
319
|
+
this.jumps.pop();
|
|
320
|
+
if (body) {
|
|
321
|
+
this.builder.edge(header, body.entry, 'cond-true');
|
|
322
|
+
this.builder.connect(body.exits, incrBlock, incr ? 'seq' : 'loop-back');
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
this.builder.edge(header, incrBlock, 'cond-true');
|
|
326
|
+
if (!incr)
|
|
327
|
+
this.builder.edge(header, header, 'loop-back');
|
|
328
|
+
}
|
|
329
|
+
// Structural exit edge — `for (;;) {}` (no condition) still keeps EXIT
|
|
330
|
+
// reverse-reachable so CDG is not silently skipped for the function.
|
|
331
|
+
this.builder.edge(header, loopExit, 'cond-false');
|
|
332
|
+
let entry = header;
|
|
333
|
+
if (init) {
|
|
334
|
+
const initBlock = this.builder.newBlock(startLineOf(init), endLineOf(init), init.text, 'normal', this.harvest.facts(init));
|
|
335
|
+
this.builder.edge(initBlock, header, 'seq');
|
|
336
|
+
entry = initBlock;
|
|
337
|
+
}
|
|
338
|
+
return { entry, exits: [loopExit] };
|
|
339
|
+
}
|
|
340
|
+
visitSwitch(stmt) {
|
|
341
|
+
const value = stmt.childForFieldName('condition') ?? stmt;
|
|
342
|
+
const dispatch = this.builder.newBlock(startLineOf(stmt), endLineOf(value), value.text, 'normal', this.harvest.facts(value));
|
|
343
|
+
const switchExit = this.builder.newBlock(endLineOf(stmt), endLineOf(stmt), '');
|
|
344
|
+
this.jumps.push({ kind: 'switch', breakTo: switchExit, continueTo: -1 });
|
|
345
|
+
const body = stmt.childForFieldName('body');
|
|
346
|
+
// C/C++ uses ONE `case_statement` node for both `case X:` and `default:`;
|
|
347
|
+
// a default has no `value` field.
|
|
348
|
+
const cases = body ? body.namedChildren.filter((c) => c.type === 'case_statement') : [];
|
|
349
|
+
// `case X:` test expressions live in no block — harvest their uses onto the
|
|
350
|
+
// dispatch block as may-defs/uses (sound over-approx of in-order evaluation).
|
|
351
|
+
for (const c of cases) {
|
|
352
|
+
const caseValue = c.childForFieldName('value');
|
|
353
|
+
if (caseValue)
|
|
354
|
+
this.builder.attachFacts(dispatch, this.harvest.factsConditional(caseValue));
|
|
355
|
+
}
|
|
356
|
+
const caseResults = cases.map((c) => this.visitSeq(this.caseStatements(c)));
|
|
357
|
+
const hasDefault = cases.some((c) => !c.childForFieldName('value'));
|
|
358
|
+
const entryOf = new Array(cases.length);
|
|
359
|
+
let after = switchExit;
|
|
360
|
+
for (let i = cases.length - 1; i >= 0; i--) {
|
|
361
|
+
entryOf[i] = caseResults[i]?.entry ?? after;
|
|
362
|
+
after = entryOf[i];
|
|
363
|
+
}
|
|
364
|
+
for (let i = 0; i < cases.length; i++) {
|
|
365
|
+
this.builder.edge(dispatch, entryOf[i], 'switch-case');
|
|
366
|
+
}
|
|
367
|
+
if (!hasDefault)
|
|
368
|
+
this.builder.edge(dispatch, switchExit, 'switch-case'); // no-match path
|
|
369
|
+
for (let i = 0; i < cases.length; i++) {
|
|
370
|
+
const res = caseResults[i];
|
|
371
|
+
if (!res)
|
|
372
|
+
continue;
|
|
373
|
+
const fallTarget = i + 1 < cases.length ? entryOf[i + 1] : switchExit;
|
|
374
|
+
this.builder.connect(res.exits, fallTarget, 'fallthrough');
|
|
375
|
+
}
|
|
376
|
+
this.jumps.pop();
|
|
377
|
+
return { entry: dispatch, exits: [switchExit] };
|
|
378
|
+
}
|
|
379
|
+
/** A case's body statements (everything but the `value` test and comments). */
|
|
380
|
+
caseStatements(caseNode) {
|
|
381
|
+
const value = caseNode.childForFieldName('value');
|
|
382
|
+
return caseNode.namedChildren.filter((c) => c.id !== value?.id && c.type !== 'comment');
|
|
383
|
+
}
|
|
384
|
+
/** Nearest enclosing exception handler, or the function EXIT. */
|
|
385
|
+
currentHandler() {
|
|
386
|
+
return this.handlers.length ? this.handlers[this.handlers.length - 1] : this.builder.exitIndex;
|
|
387
|
+
}
|
|
388
|
+
labelOf(stmt) {
|
|
389
|
+
const id = stmt.childForFieldName('label') ??
|
|
390
|
+
stmt.namedChildren.find((c) => c.type === 'statement_identifier');
|
|
391
|
+
return id?.text;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Drain any forward gotos whose label never appeared in the function (a label
|
|
395
|
+
* defined in a header macro, or malformed source) — route them to EXIT so the
|
|
396
|
+
* graph stays single-exit. Logs via console.warn (the builder's warn path)
|
|
397
|
+
* so a dropped jump is never silent (R4). Called once after the body walk.
|
|
398
|
+
*/
|
|
399
|
+
finishGotos() {
|
|
400
|
+
for (const [label, froms] of this.pendingGotos) {
|
|
401
|
+
// eslint-disable-next-line no-console
|
|
402
|
+
console.warn(`[cfg] unresolved goto label "${label}" routed to EXIT (${froms.length} site(s))`);
|
|
403
|
+
for (const from of froms)
|
|
404
|
+
this.builder.edge(from, this.builder.exitIndex, 'seq');
|
|
405
|
+
}
|
|
406
|
+
this.pendingGotos.clear();
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* C++ walk — extends the C core with exception flow and the range-for loop.
|
|
411
|
+
* These node types never appear in a C parse, so no language conditional is
|
|
412
|
+
* needed; the C core dispatches them through {@link visitExtra}.
|
|
413
|
+
*/
|
|
414
|
+
class CppCfgWalk extends CCfgWalk {
|
|
415
|
+
visitExtra(stmt) {
|
|
416
|
+
switch (stmt.type) {
|
|
417
|
+
case 'for_range_loop':
|
|
418
|
+
return this.visitForRange(stmt);
|
|
419
|
+
case 'try_statement':
|
|
420
|
+
return this.visitTry(stmt);
|
|
421
|
+
case 'throw_statement':
|
|
422
|
+
return this.visitThrow(stmt);
|
|
423
|
+
case 'co_return_statement':
|
|
424
|
+
// A coroutine `co_return` terminates the coroutine like an ordinary
|
|
425
|
+
// return: edge to EXIT, no fallthrough (`co_await`/`co_yield` are plain
|
|
426
|
+
// expressions that continue, so they need no control-flow handling).
|
|
427
|
+
return this.visitReturn(stmt);
|
|
428
|
+
default:
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
visitThrow(stmt) {
|
|
433
|
+
const idx = this.builder.newBlock(startLineOf(stmt), endLineOf(stmt), stmt.text, 'normal', this.harvest.facts(stmt));
|
|
434
|
+
this.builder.edge(idx, this.currentHandler(), 'throw');
|
|
435
|
+
return { entry: idx, exits: [] };
|
|
436
|
+
}
|
|
437
|
+
visitForRange(stmt) {
|
|
438
|
+
// Header text is synthesized; facts come from the declarator (def) + the
|
|
439
|
+
// iterated expression (use) directly.
|
|
440
|
+
const header = this.builder.newBlock(startLineOf(stmt), startLineOf(stmt), this.forRangeHeaderText(stmt), 'normal', this.harvest.forRangeHeadFacts(stmt));
|
|
441
|
+
const loopExit = this.builder.newBlock(endLineOf(stmt), endLineOf(stmt), '');
|
|
442
|
+
this.jumps.push({ kind: 'loop', breakTo: loopExit, continueTo: header });
|
|
443
|
+
const body = this.visitBody(this.bodyBlockOf(stmt));
|
|
444
|
+
this.jumps.pop();
|
|
445
|
+
if (body) {
|
|
446
|
+
this.builder.edge(header, body.entry, 'cond-true');
|
|
447
|
+
this.builder.connect(body.exits, header, 'loop-back');
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
this.builder.edge(header, header, 'loop-back');
|
|
451
|
+
}
|
|
452
|
+
this.builder.edge(header, loopExit, 'cond-false');
|
|
453
|
+
return { entry: header, exits: [loopExit] };
|
|
454
|
+
}
|
|
455
|
+
forRangeHeaderText(stmt) {
|
|
456
|
+
const decl = stmt.childForFieldName('declarator')?.text ?? '';
|
|
457
|
+
const right = stmt.childForFieldName('right')?.text ?? '';
|
|
458
|
+
return decl || right ? `for(${decl} : ${right})` : 'for(… : …)';
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* try / catch (C++ has no `finally`). Conservative exceptional flow: every
|
|
462
|
+
* block created while walking the protected body edges to the (first) catch
|
|
463
|
+
* handler — an exception may fire mid-block, and a branched body must still
|
|
464
|
+
* reach the handler from any interior block (matching the TS visitTry
|
|
465
|
+
* over-approximation). Multiple `catch` clauses: a body throw routes to EVERY
|
|
466
|
+
* handler (the runtime type match is dynamic), and each handler's normal
|
|
467
|
+
* completion joins the post-try continuation.
|
|
468
|
+
*/
|
|
469
|
+
visitTry(stmt) {
|
|
470
|
+
const bodyNode = stmt.childForFieldName('body');
|
|
471
|
+
const catchClauses = [];
|
|
472
|
+
for (let i = 0; i < stmt.namedChildCount; i++) {
|
|
473
|
+
const c = stmt.namedChild(i);
|
|
474
|
+
if (c?.type === 'catch_clause')
|
|
475
|
+
catchClauses.push(c);
|
|
476
|
+
}
|
|
477
|
+
// Build each catch handler. The handler entry is the catch-param binding
|
|
478
|
+
// block (a facts-only block) in front of the body, so the exception's
|
|
479
|
+
// binding happens exactly once on handler entry.
|
|
480
|
+
const handlerEntries = [];
|
|
481
|
+
const handlerExits = [];
|
|
482
|
+
for (const clause of catchClauses) {
|
|
483
|
+
const clauseBody = this.bodyBlockOf(clause);
|
|
484
|
+
let res = clauseBody ? this.visitSeq(this.statementsOf(clauseBody)) : null;
|
|
485
|
+
if (res === null) {
|
|
486
|
+
// Empty catch body still CATCHES — synthesize one block so the
|
|
487
|
+
// exception lands somewhere and the post-try code stays reachable.
|
|
488
|
+
const idx = this.builder.newBlock(startLineOf(clause), endLineOf(clause), '');
|
|
489
|
+
res = { entry: idx, exits: [idx] };
|
|
490
|
+
}
|
|
491
|
+
const paramFacts = this.harvest.catchParamFacts(clause);
|
|
492
|
+
if (paramFacts) {
|
|
493
|
+
const paramBlock = this.builder.newBlock(startLineOf(clause), startLineOf(clause), '', 'normal', paramFacts);
|
|
494
|
+
this.builder.edge(paramBlock, res.entry, 'seq');
|
|
495
|
+
res = { entry: paramBlock, exits: res.exits };
|
|
496
|
+
}
|
|
497
|
+
handlerEntries.push(res.entry);
|
|
498
|
+
handlerExits.push(...res.exits);
|
|
499
|
+
}
|
|
500
|
+
// The protected body's handler is the FIRST catch (if any), else the outer.
|
|
501
|
+
const tryHandler = handlerEntries[0] ?? this.currentHandler();
|
|
502
|
+
const protectedStart = this.builder.blockCount;
|
|
503
|
+
this.handlers.push(tryHandler);
|
|
504
|
+
const bodyRes = bodyNode ? this.visitSeq(this.statementsOf(bodyNode)) : null;
|
|
505
|
+
this.handlers.pop();
|
|
506
|
+
// Conservative exceptional edges: every protected-region block → EVERY handler
|
|
507
|
+
// entry. The runtime catch that matches a thrown type is not statically known,
|
|
508
|
+
// so over-approximate to ALL clauses — wiring only the first (tryHandler)
|
|
509
|
+
// orphaned `catch` clauses 2..N, dropping their control/data flow entirely
|
|
510
|
+
// (the binding `catch(T2 e)` and the handler body became unreachable). Mirrors
|
|
511
|
+
// the Swift multi-catch handling.
|
|
512
|
+
if (catchClauses.length > 0) {
|
|
513
|
+
for (let b = protectedStart; b < this.builder.blockCount; b++) {
|
|
514
|
+
for (const handler of handlerEntries)
|
|
515
|
+
this.builder.edge(b, handler, 'throw');
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
const exits = [];
|
|
519
|
+
if (bodyRes)
|
|
520
|
+
exits.push(...bodyRes.exits);
|
|
521
|
+
exits.push(...handlerExits);
|
|
522
|
+
// No catch clause at all — an exception re-propagates to the outer handler.
|
|
523
|
+
if (catchClauses.length === 0 && bodyRes) {
|
|
524
|
+
// (A bare `try {}` with no catch is ill-formed C++, but stay robust.)
|
|
525
|
+
this.builder.connect(bodyRes.exits, this.currentHandler(), 'throw');
|
|
526
|
+
}
|
|
527
|
+
const entry = bodyRes?.entry ?? handlerEntries[0];
|
|
528
|
+
if (entry === undefined)
|
|
529
|
+
return null;
|
|
530
|
+
return { entry, exits: [...new Set(exits)] };
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
/** Build the CFG for one C/C++ function node, or `undefined` if not modelable. */
|
|
534
|
+
function buildFunctionCfg(fnNode, filePath, functionTypes, controlFlowTypes, WalkClass) {
|
|
535
|
+
try {
|
|
536
|
+
if (!functionTypes.has(fnNode.type))
|
|
537
|
+
return undefined;
|
|
538
|
+
const startLine = startLineOf(fnNode);
|
|
539
|
+
const endLine = endLineOf(fnNode);
|
|
540
|
+
const startColumn = fnNode.startPosition.column;
|
|
541
|
+
// The body is a compound_statement (field `body`, or first such child).
|
|
542
|
+
const body = fnNode.childForFieldName('body') ??
|
|
543
|
+
fnNode.namedChildren.find((c) => c.type === 'compound_statement');
|
|
544
|
+
if (!body || body.type !== 'compound_statement')
|
|
545
|
+
return undefined; // declaration / no body
|
|
546
|
+
const builder = new CfgBuilder(filePath, startLine, endLine, startColumn);
|
|
547
|
+
const harvest = new CCppHarvester(fnNode);
|
|
548
|
+
const paramFacts = harvest.paramFacts();
|
|
549
|
+
if (paramFacts)
|
|
550
|
+
builder.attachFacts(builder.entryIndex, paramFacts);
|
|
551
|
+
const walk = new WalkClass(builder, harvest, controlFlowTypes);
|
|
552
|
+
const res = walk.visitSeq(body.namedChildren.filter((c) => c.type !== 'comment'));
|
|
553
|
+
walk.finishGotos();
|
|
554
|
+
if (!res) {
|
|
555
|
+
builder.edge(builder.entryIndex, builder.exitIndex, 'seq'); // empty body
|
|
556
|
+
return builder.finish(harvest.bindingTable());
|
|
557
|
+
}
|
|
558
|
+
builder.edge(builder.entryIndex, res.entry, 'seq');
|
|
559
|
+
builder.connect(res.exits, builder.exitIndex, 'seq'); // normal fall-off → EXIT
|
|
560
|
+
return builder.finish(harvest.bindingTable());
|
|
561
|
+
}
|
|
562
|
+
catch (err) {
|
|
563
|
+
// Never throw out of buildFunctionCfg — a malformed AST shape must skip only
|
|
564
|
+
// this one function's CFG, never drop the whole file's language group (R4).
|
|
565
|
+
// eslint-disable-next-line no-console
|
|
566
|
+
console.warn(`[cfg] C/C++ buildFunctionCfg skipped a function in ${filePath}: ${String(err)}`);
|
|
567
|
+
return undefined;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
/** The C CFG visitor. */
|
|
571
|
+
export function createCCfgVisitor() {
|
|
572
|
+
return {
|
|
573
|
+
isFunction: (node) => C_FUNCTION_TYPES.has(node.type),
|
|
574
|
+
buildFunctionCfg: (fnNode, filePath) => buildFunctionCfg(fnNode, filePath, C_FUNCTION_TYPES, C_CONTROL_FLOW_TYPES, CCfgWalk),
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
/** The C++ CFG visitor (C core + exceptions + range-for + lambdas). */
|
|
578
|
+
export function createCppCfgVisitor() {
|
|
579
|
+
return {
|
|
580
|
+
isFunction: (node) => CPP_FUNCTION_TYPES.has(node.type),
|
|
581
|
+
buildFunctionCfg: (fnNode, filePath) => buildFunctionCfg(fnNode, filePath, CPP_FUNCTION_TYPES, CPP_CONTROL_FLOW_TYPES, CppCfgWalk),
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
export { C_FUNCTION_TYPES, CPP_FUNCTION_TYPES };
|