@bharanidev/bhgraph-darwin-x64 1.0.0
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/bin/bhgraph +19 -0
- package/lib/dist/bin/bhgraph.d.ts +26 -0
- package/lib/dist/bin/bhgraph.d.ts.map +1 -0
- package/lib/dist/bin/bhgraph.js +2207 -0
- package/lib/dist/bin/bhgraph.js.map +1 -0
- package/lib/dist/bin/command-supervision.d.ts +12 -0
- package/lib/dist/bin/command-supervision.d.ts.map +1 -0
- package/lib/dist/bin/command-supervision.js +89 -0
- package/lib/dist/bin/command-supervision.js.map +1 -0
- package/lib/dist/bin/fatal-handler.d.ts +20 -0
- package/lib/dist/bin/fatal-handler.d.ts.map +1 -0
- package/lib/dist/bin/fatal-handler.js +118 -0
- package/lib/dist/bin/fatal-handler.js.map +1 -0
- package/lib/dist/bin/node-version-check.d.ts +37 -0
- package/lib/dist/bin/node-version-check.d.ts.map +1 -0
- package/lib/dist/bin/node-version-check.js +79 -0
- package/lib/dist/bin/node-version-check.js.map +1 -0
- package/lib/dist/bin/uninstall.d.ts +14 -0
- package/lib/dist/bin/uninstall.d.ts.map +1 -0
- package/lib/dist/bin/uninstall.js +36 -0
- package/lib/dist/bin/uninstall.js.map +1 -0
- package/lib/dist/context/formatter.d.ts +30 -0
- package/lib/dist/context/formatter.d.ts.map +1 -0
- package/lib/dist/context/formatter.js +263 -0
- package/lib/dist/context/formatter.js.map +1 -0
- package/lib/dist/context/index.d.ts +119 -0
- package/lib/dist/context/index.d.ts.map +1 -0
- package/lib/dist/context/index.js +1296 -0
- package/lib/dist/context/index.js.map +1 -0
- package/lib/dist/context/markers.d.ts +19 -0
- package/lib/dist/context/markers.d.ts.map +1 -0
- package/lib/dist/context/markers.js +22 -0
- package/lib/dist/context/markers.js.map +1 -0
- package/lib/dist/db/index.d.ts +142 -0
- package/lib/dist/db/index.d.ts.map +1 -0
- package/lib/dist/db/index.js +335 -0
- package/lib/dist/db/index.js.map +1 -0
- package/lib/dist/db/migrations.d.ts +44 -0
- package/lib/dist/db/migrations.d.ts.map +1 -0
- package/lib/dist/db/migrations.js +182 -0
- package/lib/dist/db/migrations.js.map +1 -0
- package/lib/dist/db/queries.d.ts +452 -0
- package/lib/dist/db/queries.d.ts.map +1 -0
- package/lib/dist/db/queries.js +1740 -0
- package/lib/dist/db/queries.js.map +1 -0
- package/lib/dist/db/schema.sql +182 -0
- package/lib/dist/db/sqlite-adapter.d.ts +53 -0
- package/lib/dist/db/sqlite-adapter.d.ts.map +1 -0
- package/lib/dist/db/sqlite-adapter.js +117 -0
- package/lib/dist/db/sqlite-adapter.js.map +1 -0
- package/lib/dist/directory.d.ts +183 -0
- package/lib/dist/directory.d.ts.map +1 -0
- package/lib/dist/directory.js +797 -0
- package/lib/dist/directory.js.map +1 -0
- package/lib/dist/errors.d.ts +136 -0
- package/lib/dist/errors.d.ts.map +1 -0
- package/lib/dist/errors.js +219 -0
- package/lib/dist/errors.js.map +1 -0
- package/lib/dist/extraction/astro-extractor.d.ts +79 -0
- package/lib/dist/extraction/astro-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/astro-extractor.js +320 -0
- package/lib/dist/extraction/astro-extractor.js.map +1 -0
- package/lib/dist/extraction/cfml-extractor.d.ts +107 -0
- package/lib/dist/extraction/cfml-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/cfml-extractor.js +494 -0
- package/lib/dist/extraction/cfml-extractor.js.map +1 -0
- package/lib/dist/extraction/dfm-extractor.d.ts +31 -0
- package/lib/dist/extraction/dfm-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/dfm-extractor.js +151 -0
- package/lib/dist/extraction/dfm-extractor.js.map +1 -0
- package/lib/dist/extraction/extraction-version.d.ts +25 -0
- package/lib/dist/extraction/extraction-version.d.ts.map +1 -0
- package/lib/dist/extraction/extraction-version.js +28 -0
- package/lib/dist/extraction/extraction-version.js.map +1 -0
- package/lib/dist/extraction/function-ref.d.ts +118 -0
- package/lib/dist/extraction/function-ref.d.ts.map +1 -0
- package/lib/dist/extraction/function-ref.js +727 -0
- package/lib/dist/extraction/function-ref.js.map +1 -0
- package/lib/dist/extraction/generated-detection.d.ts +30 -0
- package/lib/dist/extraction/generated-detection.d.ts.map +1 -0
- package/lib/dist/extraction/generated-detection.js +83 -0
- package/lib/dist/extraction/generated-detection.js.map +1 -0
- package/lib/dist/extraction/grammars.d.ts +123 -0
- package/lib/dist/extraction/grammars.d.ts.map +1 -0
- package/lib/dist/extraction/grammars.js +589 -0
- package/lib/dist/extraction/grammars.js.map +1 -0
- package/lib/dist/extraction/index.d.ts +232 -0
- package/lib/dist/extraction/index.d.ts.map +1 -0
- package/lib/dist/extraction/index.js +2269 -0
- package/lib/dist/extraction/index.js.map +1 -0
- package/lib/dist/extraction/languages/arkts.d.ts +3 -0
- package/lib/dist/extraction/languages/arkts.d.ts.map +1 -0
- package/lib/dist/extraction/languages/arkts.js +127 -0
- package/lib/dist/extraction/languages/arkts.js.map +1 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts +110 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -0
- package/lib/dist/extraction/languages/c-cpp.js +837 -0
- package/lib/dist/extraction/languages/c-cpp.js.map +1 -0
- package/lib/dist/extraction/languages/cfquery.d.ts +12 -0
- package/lib/dist/extraction/languages/cfquery.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfquery.js +28 -0
- package/lib/dist/extraction/languages/cfquery.js.map +1 -0
- package/lib/dist/extraction/languages/cfscript.d.ts +3 -0
- package/lib/dist/extraction/languages/cfscript.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfscript.js +73 -0
- package/lib/dist/extraction/languages/cfscript.js.map +1 -0
- package/lib/dist/extraction/languages/cobol.d.ts +33 -0
- package/lib/dist/extraction/languages/cobol.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cobol.js +499 -0
- package/lib/dist/extraction/languages/cobol.js.map +1 -0
- package/lib/dist/extraction/languages/csharp.d.ts +25 -0
- package/lib/dist/extraction/languages/csharp.d.ts.map +1 -0
- package/lib/dist/extraction/languages/csharp.js +175 -0
- package/lib/dist/extraction/languages/csharp.js.map +1 -0
- package/lib/dist/extraction/languages/dart.d.ts +3 -0
- package/lib/dist/extraction/languages/dart.d.ts.map +1 -0
- package/lib/dist/extraction/languages/dart.js +374 -0
- package/lib/dist/extraction/languages/dart.js.map +1 -0
- package/lib/dist/extraction/languages/erlang.d.ts +3 -0
- package/lib/dist/extraction/languages/erlang.d.ts.map +1 -0
- package/lib/dist/extraction/languages/erlang.js +350 -0
- package/lib/dist/extraction/languages/erlang.js.map +1 -0
- package/lib/dist/extraction/languages/go.d.ts +3 -0
- package/lib/dist/extraction/languages/go.d.ts.map +1 -0
- package/lib/dist/extraction/languages/go.js +111 -0
- package/lib/dist/extraction/languages/go.js.map +1 -0
- package/lib/dist/extraction/languages/index.d.ts +10 -0
- package/lib/dist/extraction/languages/index.d.ts.map +1 -0
- package/lib/dist/extraction/languages/index.js +71 -0
- package/lib/dist/extraction/languages/index.js.map +1 -0
- package/lib/dist/extraction/languages/java.d.ts +3 -0
- package/lib/dist/extraction/languages/java.d.ts.map +1 -0
- package/lib/dist/extraction/languages/java.js +315 -0
- package/lib/dist/extraction/languages/java.js.map +1 -0
- package/lib/dist/extraction/languages/javascript.d.ts +3 -0
- package/lib/dist/extraction/languages/javascript.d.ts.map +1 -0
- package/lib/dist/extraction/languages/javascript.js +106 -0
- package/lib/dist/extraction/languages/javascript.js.map +1 -0
- package/lib/dist/extraction/languages/kotlin.d.ts +3 -0
- package/lib/dist/extraction/languages/kotlin.d.ts.map +1 -0
- package/lib/dist/extraction/languages/kotlin.js +379 -0
- package/lib/dist/extraction/languages/kotlin.js.map +1 -0
- package/lib/dist/extraction/languages/lua.d.ts +3 -0
- package/lib/dist/extraction/languages/lua.d.ts.map +1 -0
- package/lib/dist/extraction/languages/lua.js +150 -0
- package/lib/dist/extraction/languages/lua.js.map +1 -0
- package/lib/dist/extraction/languages/luau.d.ts +3 -0
- package/lib/dist/extraction/languages/luau.d.ts.map +1 -0
- package/lib/dist/extraction/languages/luau.js +37 -0
- package/lib/dist/extraction/languages/luau.js.map +1 -0
- package/lib/dist/extraction/languages/nix.d.ts +3 -0
- package/lib/dist/extraction/languages/nix.d.ts.map +1 -0
- package/lib/dist/extraction/languages/nix.js +294 -0
- package/lib/dist/extraction/languages/nix.js.map +1 -0
- package/lib/dist/extraction/languages/objc.d.ts +3 -0
- package/lib/dist/extraction/languages/objc.d.ts.map +1 -0
- package/lib/dist/extraction/languages/objc.js +175 -0
- package/lib/dist/extraction/languages/objc.js.map +1 -0
- package/lib/dist/extraction/languages/pascal.d.ts +3 -0
- package/lib/dist/extraction/languages/pascal.d.ts.map +1 -0
- package/lib/dist/extraction/languages/pascal.js +77 -0
- package/lib/dist/extraction/languages/pascal.js.map +1 -0
- package/lib/dist/extraction/languages/php.d.ts +3 -0
- package/lib/dist/extraction/languages/php.d.ts.map +1 -0
- package/lib/dist/extraction/languages/php.js +196 -0
- package/lib/dist/extraction/languages/php.js.map +1 -0
- package/lib/dist/extraction/languages/python.d.ts +3 -0
- package/lib/dist/extraction/languages/python.d.ts.map +1 -0
- package/lib/dist/extraction/languages/python.js +56 -0
- package/lib/dist/extraction/languages/python.js.map +1 -0
- package/lib/dist/extraction/languages/r.d.ts +3 -0
- package/lib/dist/extraction/languages/r.d.ts.map +1 -0
- package/lib/dist/extraction/languages/r.js +314 -0
- package/lib/dist/extraction/languages/r.js.map +1 -0
- package/lib/dist/extraction/languages/ruby.d.ts +3 -0
- package/lib/dist/extraction/languages/ruby.d.ts.map +1 -0
- package/lib/dist/extraction/languages/ruby.js +149 -0
- package/lib/dist/extraction/languages/ruby.js.map +1 -0
- package/lib/dist/extraction/languages/rust.d.ts +3 -0
- package/lib/dist/extraction/languages/rust.d.ts.map +1 -0
- package/lib/dist/extraction/languages/rust.js +142 -0
- package/lib/dist/extraction/languages/rust.js.map +1 -0
- package/lib/dist/extraction/languages/scala.d.ts +3 -0
- package/lib/dist/extraction/languages/scala.d.ts.map +1 -0
- package/lib/dist/extraction/languages/scala.js +209 -0
- package/lib/dist/extraction/languages/scala.js.map +1 -0
- package/lib/dist/extraction/languages/solidity.d.ts +3 -0
- package/lib/dist/extraction/languages/solidity.d.ts.map +1 -0
- package/lib/dist/extraction/languages/solidity.js +293 -0
- package/lib/dist/extraction/languages/solidity.js.map +1 -0
- package/lib/dist/extraction/languages/swift.d.ts +3 -0
- package/lib/dist/extraction/languages/swift.d.ts.map +1 -0
- package/lib/dist/extraction/languages/swift.js +152 -0
- package/lib/dist/extraction/languages/swift.js.map +1 -0
- package/lib/dist/extraction/languages/terraform.d.ts +3 -0
- package/lib/dist/extraction/languages/terraform.d.ts.map +1 -0
- package/lib/dist/extraction/languages/terraform.js +641 -0
- package/lib/dist/extraction/languages/terraform.js.map +1 -0
- package/lib/dist/extraction/languages/typescript.d.ts +16 -0
- package/lib/dist/extraction/languages/typescript.d.ts.map +1 -0
- package/lib/dist/extraction/languages/typescript.js +167 -0
- package/lib/dist/extraction/languages/typescript.js.map +1 -0
- package/lib/dist/extraction/languages/vbnet.d.ts +11 -0
- package/lib/dist/extraction/languages/vbnet.d.ts.map +1 -0
- package/lib/dist/extraction/languages/vbnet.js +141 -0
- package/lib/dist/extraction/languages/vbnet.js.map +1 -0
- package/lib/dist/extraction/liquid-extractor.d.ts +59 -0
- package/lib/dist/extraction/liquid-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/liquid-extractor.js +357 -0
- package/lib/dist/extraction/liquid-extractor.js.map +1 -0
- package/lib/dist/extraction/mybatis-extractor.d.ts +68 -0
- package/lib/dist/extraction/mybatis-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/mybatis-extractor.js +300 -0
- package/lib/dist/extraction/mybatis-extractor.js.map +1 -0
- package/lib/dist/extraction/parse-pool.d.ts +126 -0
- package/lib/dist/extraction/parse-pool.d.ts.map +1 -0
- package/lib/dist/extraction/parse-pool.js +319 -0
- package/lib/dist/extraction/parse-pool.js.map +1 -0
- package/lib/dist/extraction/parse-worker.d.ts +8 -0
- package/lib/dist/extraction/parse-worker.d.ts.map +1 -0
- package/lib/dist/extraction/parse-worker.js +97 -0
- package/lib/dist/extraction/parse-worker.js.map +1 -0
- package/lib/dist/extraction/razor-extractor.d.ts +42 -0
- package/lib/dist/extraction/razor-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/razor-extractor.js +285 -0
- package/lib/dist/extraction/razor-extractor.js.map +1 -0
- package/lib/dist/extraction/svelte-extractor.d.ts +56 -0
- package/lib/dist/extraction/svelte-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/svelte-extractor.js +275 -0
- package/lib/dist/extraction/svelte-extractor.js.map +1 -0
- package/lib/dist/extraction/tree-sitter-helpers.d.ts +28 -0
- package/lib/dist/extraction/tree-sitter-helpers.d.ts.map +1 -0
- package/lib/dist/extraction/tree-sitter-helpers.js +153 -0
- package/lib/dist/extraction/tree-sitter-helpers.js.map +1 -0
- package/lib/dist/extraction/tree-sitter-types.d.ts +258 -0
- package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -0
- package/lib/dist/extraction/tree-sitter-types.js +10 -0
- package/lib/dist/extraction/tree-sitter-types.js.map +1 -0
- package/lib/dist/extraction/tree-sitter.d.ts +706 -0
- package/lib/dist/extraction/tree-sitter.d.ts.map +1 -0
- package/lib/dist/extraction/tree-sitter.js +6506 -0
- package/lib/dist/extraction/tree-sitter.js.map +1 -0
- package/lib/dist/extraction/vue-extractor.d.ts +51 -0
- package/lib/dist/extraction/vue-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/vue-extractor.js +254 -0
- package/lib/dist/extraction/vue-extractor.js.map +1 -0
- package/lib/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/lib/dist/extraction/wasm-runtime-flags.d.ts +38 -0
- package/lib/dist/extraction/wasm-runtime-flags.d.ts.map +1 -0
- package/lib/dist/extraction/wasm-runtime-flags.js +106 -0
- package/lib/dist/extraction/wasm-runtime-flags.js.map +1 -0
- package/lib/dist/graph/index.d.ts +8 -0
- package/lib/dist/graph/index.d.ts.map +1 -0
- package/lib/dist/graph/index.js +13 -0
- package/lib/dist/graph/index.js.map +1 -0
- package/lib/dist/graph/queries.d.ts +106 -0
- package/lib/dist/graph/queries.d.ts.map +1 -0
- package/lib/dist/graph/queries.js +339 -0
- package/lib/dist/graph/queries.js.map +1 -0
- package/lib/dist/graph/traversal.d.ts +127 -0
- package/lib/dist/graph/traversal.d.ts.map +1 -0
- package/lib/dist/graph/traversal.js +599 -0
- package/lib/dist/graph/traversal.js.map +1 -0
- package/lib/dist/index.d.ts +642 -0
- package/lib/dist/index.d.ts.map +1 -0
- package/lib/dist/index.js +1387 -0
- package/lib/dist/index.js.map +1 -0
- package/lib/dist/installer/config-writer.d.ts +28 -0
- package/lib/dist/installer/config-writer.d.ts.map +1 -0
- package/lib/dist/installer/config-writer.js +91 -0
- package/lib/dist/installer/config-writer.js.map +1 -0
- package/lib/dist/installer/index.d.ts +100 -0
- package/lib/dist/installer/index.d.ts.map +1 -0
- package/lib/dist/installer/index.js +526 -0
- package/lib/dist/installer/index.js.map +1 -0
- package/lib/dist/installer/instructions-template.d.ts +41 -0
- package/lib/dist/installer/instructions-template.d.ts.map +1 -0
- package/lib/dist/installer/instructions-template.js +53 -0
- package/lib/dist/installer/instructions-template.js.map +1 -0
- package/lib/dist/installer/targets/antigravity.d.ts +57 -0
- package/lib/dist/installer/targets/antigravity.d.ts.map +1 -0
- package/lib/dist/installer/targets/antigravity.js +308 -0
- package/lib/dist/installer/targets/antigravity.js.map +1 -0
- package/lib/dist/installer/targets/claude.d.ts +62 -0
- package/lib/dist/installer/targets/claude.d.ts.map +1 -0
- package/lib/dist/installer/targets/claude.js +454 -0
- package/lib/dist/installer/targets/claude.js.map +1 -0
- package/lib/dist/installer/targets/codex.d.ts +18 -0
- package/lib/dist/installer/targets/codex.d.ts.map +1 -0
- package/lib/dist/installer/targets/codex.js +185 -0
- package/lib/dist/installer/targets/codex.js.map +1 -0
- package/lib/dist/installer/targets/cursor.d.ts +35 -0
- package/lib/dist/installer/targets/cursor.d.ts.map +1 -0
- package/lib/dist/installer/targets/cursor.js +254 -0
- package/lib/dist/installer/targets/cursor.js.map +1 -0
- package/lib/dist/installer/targets/gemini.d.ts +26 -0
- package/lib/dist/installer/targets/gemini.d.ts.map +1 -0
- package/lib/dist/installer/targets/gemini.js +165 -0
- package/lib/dist/installer/targets/gemini.js.map +1 -0
- package/lib/dist/installer/targets/hermes.d.ts +18 -0
- package/lib/dist/installer/targets/hermes.d.ts.map +1 -0
- package/lib/dist/installer/targets/hermes.js +359 -0
- package/lib/dist/installer/targets/hermes.js.map +1 -0
- package/lib/dist/installer/targets/kiro.d.ts +27 -0
- package/lib/dist/installer/targets/kiro.d.ts.map +1 -0
- package/lib/dist/installer/targets/kiro.js +178 -0
- package/lib/dist/installer/targets/kiro.js.map +1 -0
- package/lib/dist/installer/targets/opencode.d.ts +38 -0
- package/lib/dist/installer/targets/opencode.d.ts.map +1 -0
- package/lib/dist/installer/targets/opencode.js +288 -0
- package/lib/dist/installer/targets/opencode.js.map +1 -0
- package/lib/dist/installer/targets/registry.d.ts +35 -0
- package/lib/dist/installer/targets/registry.d.ts.map +1 -0
- package/lib/dist/installer/targets/registry.js +91 -0
- package/lib/dist/installer/targets/registry.js.map +1 -0
- package/lib/dist/installer/targets/shared.d.ts +101 -0
- package/lib/dist/installer/targets/shared.d.ts.map +1 -0
- package/lib/dist/installer/targets/shared.js +264 -0
- package/lib/dist/installer/targets/shared.js.map +1 -0
- package/lib/dist/installer/targets/toml.d.ts +52 -0
- package/lib/dist/installer/targets/toml.d.ts.map +1 -0
- package/lib/dist/installer/targets/toml.js +147 -0
- package/lib/dist/installer/targets/toml.js.map +1 -0
- package/lib/dist/installer/targets/types.d.ts +108 -0
- package/lib/dist/installer/targets/types.d.ts.map +1 -0
- package/lib/dist/installer/targets/types.js +16 -0
- package/lib/dist/installer/targets/types.js.map +1 -0
- package/lib/dist/mcp/daemon-manager.d.ts +42 -0
- package/lib/dist/mcp/daemon-manager.d.ts.map +1 -0
- package/lib/dist/mcp/daemon-manager.js +129 -0
- package/lib/dist/mcp/daemon-manager.js.map +1 -0
- package/lib/dist/mcp/daemon-paths.d.ts +73 -0
- package/lib/dist/mcp/daemon-paths.d.ts.map +1 -0
- package/lib/dist/mcp/daemon-paths.js +165 -0
- package/lib/dist/mcp/daemon-paths.js.map +1 -0
- package/lib/dist/mcp/daemon-registry.d.ts +47 -0
- package/lib/dist/mcp/daemon-registry.d.ts.map +1 -0
- package/lib/dist/mcp/daemon-registry.js +233 -0
- package/lib/dist/mcp/daemon-registry.js.map +1 -0
- package/lib/dist/mcp/daemon.d.ts +290 -0
- package/lib/dist/mcp/daemon.d.ts.map +1 -0
- package/lib/dist/mcp/daemon.js +840 -0
- package/lib/dist/mcp/daemon.js.map +1 -0
- package/lib/dist/mcp/dynamic-boundaries.d.ts +41 -0
- package/lib/dist/mcp/dynamic-boundaries.d.ts.map +1 -0
- package/lib/dist/mcp/dynamic-boundaries.js +360 -0
- package/lib/dist/mcp/dynamic-boundaries.js.map +1 -0
- package/lib/dist/mcp/early-ppid.d.ts +26 -0
- package/lib/dist/mcp/early-ppid.d.ts.map +1 -0
- package/lib/dist/mcp/early-ppid.js +29 -0
- package/lib/dist/mcp/early-ppid.js.map +1 -0
- package/lib/dist/mcp/engine.d.ts +122 -0
- package/lib/dist/mcp/engine.d.ts.map +1 -0
- package/lib/dist/mcp/engine.js +350 -0
- package/lib/dist/mcp/engine.js.map +1 -0
- package/lib/dist/mcp/index.d.ts +113 -0
- package/lib/dist/mcp/index.d.ts.map +1 -0
- package/lib/dist/mcp/index.js +498 -0
- package/lib/dist/mcp/index.js.map +1 -0
- package/lib/dist/mcp/liveness-watchdog.d.ts +18 -0
- package/lib/dist/mcp/liveness-watchdog.d.ts.map +1 -0
- package/lib/dist/mcp/liveness-watchdog.js +207 -0
- package/lib/dist/mcp/liveness-watchdog.js.map +1 -0
- package/lib/dist/mcp/ppid-watchdog.d.ts +62 -0
- package/lib/dist/mcp/ppid-watchdog.d.ts.map +1 -0
- package/lib/dist/mcp/ppid-watchdog.js +64 -0
- package/lib/dist/mcp/ppid-watchdog.js.map +1 -0
- package/lib/dist/mcp/proxy.d.ts +87 -0
- package/lib/dist/mcp/proxy.d.ts.map +1 -0
- package/lib/dist/mcp/proxy.js +659 -0
- package/lib/dist/mcp/proxy.js.map +1 -0
- package/lib/dist/mcp/query-pool.d.ts +94 -0
- package/lib/dist/mcp/query-pool.d.ts.map +1 -0
- package/lib/dist/mcp/query-pool.js +297 -0
- package/lib/dist/mcp/query-pool.js.map +1 -0
- package/lib/dist/mcp/query-worker.d.ts +24 -0
- package/lib/dist/mcp/query-worker.d.ts.map +1 -0
- package/lib/dist/mcp/query-worker.js +87 -0
- package/lib/dist/mcp/query-worker.js.map +1 -0
- package/lib/dist/mcp/server-instructions.d.ts +34 -0
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -0
- package/lib/dist/mcp/server-instructions.js +106 -0
- package/lib/dist/mcp/server-instructions.js.map +1 -0
- package/lib/dist/mcp/session.d.ts +79 -0
- package/lib/dist/mcp/session.d.ts.map +1 -0
- package/lib/dist/mcp/session.js +330 -0
- package/lib/dist/mcp/session.js.map +1 -0
- package/lib/dist/mcp/startup-handshake.d.ts +44 -0
- package/lib/dist/mcp/startup-handshake.d.ts.map +1 -0
- package/lib/dist/mcp/startup-handshake.js +73 -0
- package/lib/dist/mcp/startup-handshake.js.map +1 -0
- package/lib/dist/mcp/stdin-teardown.d.ts +27 -0
- package/lib/dist/mcp/stdin-teardown.d.ts.map +1 -0
- package/lib/dist/mcp/stdin-teardown.js +49 -0
- package/lib/dist/mcp/stdin-teardown.js.map +1 -0
- package/lib/dist/mcp/tools.d.ts +613 -0
- package/lib/dist/mcp/tools.d.ts.map +1 -0
- package/lib/dist/mcp/tools.js +4424 -0
- package/lib/dist/mcp/tools.js.map +1 -0
- package/lib/dist/mcp/transport.d.ts +188 -0
- package/lib/dist/mcp/transport.d.ts.map +1 -0
- package/lib/dist/mcp/transport.js +359 -0
- package/lib/dist/mcp/transport.js.map +1 -0
- package/lib/dist/mcp/version.d.ts +19 -0
- package/lib/dist/mcp/version.d.ts.map +1 -0
- package/lib/dist/mcp/version.js +71 -0
- package/lib/dist/mcp/version.js.map +1 -0
- package/lib/dist/project-config.d.ts +94 -0
- package/lib/dist/project-config.d.ts.map +1 -0
- package/lib/dist/project-config.js +374 -0
- package/lib/dist/project-config.js.map +1 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts +5 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.js +1038 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.js.map +1 -0
- package/lib/dist/resolution/callback-synthesizer.d.ts +15 -0
- package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -0
- package/lib/dist/resolution/callback-synthesizer.js +3658 -0
- package/lib/dist/resolution/callback-synthesizer.js.map +1 -0
- package/lib/dist/resolution/cooperative-yield.d.ts +32 -0
- package/lib/dist/resolution/cooperative-yield.d.ts.map +1 -0
- package/lib/dist/resolution/cooperative-yield.js +42 -0
- package/lib/dist/resolution/cooperative-yield.js.map +1 -0
- package/lib/dist/resolution/frameworks/astro.d.ts +9 -0
- package/lib/dist/resolution/frameworks/astro.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/astro.js +169 -0
- package/lib/dist/resolution/frameworks/astro.js.map +1 -0
- package/lib/dist/resolution/frameworks/cargo-workspace.d.ts +18 -0
- package/lib/dist/resolution/frameworks/cargo-workspace.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/cargo-workspace.js +225 -0
- package/lib/dist/resolution/frameworks/cargo-workspace.js.map +1 -0
- package/lib/dist/resolution/frameworks/cics.d.ts +20 -0
- package/lib/dist/resolution/frameworks/cics.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/cics.js +90 -0
- package/lib/dist/resolution/frameworks/cics.js.map +1 -0
- package/lib/dist/resolution/frameworks/csharp.d.ts +8 -0
- package/lib/dist/resolution/frameworks/csharp.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/csharp.js +241 -0
- package/lib/dist/resolution/frameworks/csharp.js.map +1 -0
- package/lib/dist/resolution/frameworks/drupal.d.ts +51 -0
- package/lib/dist/resolution/frameworks/drupal.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/drupal.js +367 -0
- package/lib/dist/resolution/frameworks/drupal.js.map +1 -0
- package/lib/dist/resolution/frameworks/expo-modules.d.ts +3 -0
- package/lib/dist/resolution/frameworks/expo-modules.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/expo-modules.js +148 -0
- package/lib/dist/resolution/frameworks/expo-modules.js.map +1 -0
- package/lib/dist/resolution/frameworks/express.d.ts +8 -0
- package/lib/dist/resolution/frameworks/express.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/express.js +308 -0
- package/lib/dist/resolution/frameworks/express.js.map +1 -0
- package/lib/dist/resolution/frameworks/fabric.d.ts +3 -0
- package/lib/dist/resolution/frameworks/fabric.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/fabric.js +354 -0
- package/lib/dist/resolution/frameworks/fabric.js.map +1 -0
- package/lib/dist/resolution/frameworks/go.d.ts +8 -0
- package/lib/dist/resolution/frameworks/go.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/go.js +161 -0
- package/lib/dist/resolution/frameworks/go.js.map +1 -0
- package/lib/dist/resolution/frameworks/goframe.d.ts +41 -0
- package/lib/dist/resolution/frameworks/goframe.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/goframe.js +112 -0
- package/lib/dist/resolution/frameworks/goframe.js.map +1 -0
- package/lib/dist/resolution/frameworks/index.d.ts +50 -0
- package/lib/dist/resolution/frameworks/index.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/index.js +175 -0
- package/lib/dist/resolution/frameworks/index.js.map +1 -0
- package/lib/dist/resolution/frameworks/java.d.ts +8 -0
- package/lib/dist/resolution/frameworks/java.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/java.js +517 -0
- package/lib/dist/resolution/frameworks/java.js.map +1 -0
- package/lib/dist/resolution/frameworks/laravel.d.ts +13 -0
- package/lib/dist/resolution/frameworks/laravel.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/laravel.js +257 -0
- package/lib/dist/resolution/frameworks/laravel.js.map +1 -0
- package/lib/dist/resolution/frameworks/nestjs.d.ts +26 -0
- package/lib/dist/resolution/frameworks/nestjs.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/nestjs.js +698 -0
- package/lib/dist/resolution/frameworks/nestjs.js.map +1 -0
- package/lib/dist/resolution/frameworks/play.d.ts +19 -0
- package/lib/dist/resolution/frameworks/play.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/play.js +111 -0
- package/lib/dist/resolution/frameworks/play.js.map +1 -0
- package/lib/dist/resolution/frameworks/python.d.ts +10 -0
- package/lib/dist/resolution/frameworks/python.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/python.js +400 -0
- package/lib/dist/resolution/frameworks/python.js.map +1 -0
- package/lib/dist/resolution/frameworks/react-native.d.ts +3 -0
- package/lib/dist/resolution/frameworks/react-native.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/react-native.js +410 -0
- package/lib/dist/resolution/frameworks/react-native.js.map +1 -0
- package/lib/dist/resolution/frameworks/react.d.ts +8 -0
- package/lib/dist/resolution/frameworks/react.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/react.js +334 -0
- package/lib/dist/resolution/frameworks/react.js.map +1 -0
- package/lib/dist/resolution/frameworks/ruby.d.ts +8 -0
- package/lib/dist/resolution/frameworks/ruby.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/ruby.js +302 -0
- package/lib/dist/resolution/frameworks/ruby.js.map +1 -0
- package/lib/dist/resolution/frameworks/rust.d.ts +8 -0
- package/lib/dist/resolution/frameworks/rust.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/rust.js +304 -0
- package/lib/dist/resolution/frameworks/rust.js.map +1 -0
- package/lib/dist/resolution/frameworks/svelte.d.ts +9 -0
- package/lib/dist/resolution/frameworks/svelte.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/svelte.js +253 -0
- package/lib/dist/resolution/frameworks/svelte.js.map +1 -0
- package/lib/dist/resolution/frameworks/swift-objc.d.ts +37 -0
- package/lib/dist/resolution/frameworks/swift-objc.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/swift-objc.js +252 -0
- package/lib/dist/resolution/frameworks/swift-objc.js.map +1 -0
- package/lib/dist/resolution/frameworks/swift.d.ts +10 -0
- package/lib/dist/resolution/frameworks/swift.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/swift.js +400 -0
- package/lib/dist/resolution/frameworks/swift.js.map +1 -0
- package/lib/dist/resolution/frameworks/terraform.d.ts +38 -0
- package/lib/dist/resolution/frameworks/terraform.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/terraform.js +277 -0
- package/lib/dist/resolution/frameworks/terraform.js.map +1 -0
- package/lib/dist/resolution/frameworks/vue.d.ts +9 -0
- package/lib/dist/resolution/frameworks/vue.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/vue.js +303 -0
- package/lib/dist/resolution/frameworks/vue.js.map +1 -0
- package/lib/dist/resolution/go-module.d.ts +26 -0
- package/lib/dist/resolution/go-module.d.ts.map +1 -0
- package/lib/dist/resolution/go-module.js +78 -0
- package/lib/dist/resolution/go-module.js.map +1 -0
- package/lib/dist/resolution/goframe-synthesizer.d.ts +28 -0
- package/lib/dist/resolution/goframe-synthesizer.d.ts.map +1 -0
- package/lib/dist/resolution/goframe-synthesizer.js +158 -0
- package/lib/dist/resolution/goframe-synthesizer.js.map +1 -0
- package/lib/dist/resolution/import-resolver.d.ts +85 -0
- package/lib/dist/resolution/import-resolver.d.ts.map +1 -0
- package/lib/dist/resolution/import-resolver.js +1974 -0
- package/lib/dist/resolution/import-resolver.js.map +1 -0
- package/lib/dist/resolution/index.d.ts +238 -0
- package/lib/dist/resolution/index.d.ts.map +1 -0
- package/lib/dist/resolution/index.js +1633 -0
- package/lib/dist/resolution/index.js.map +1 -0
- package/lib/dist/resolution/lru-cache.d.ts +24 -0
- package/lib/dist/resolution/lru-cache.d.ts.map +1 -0
- package/lib/dist/resolution/lru-cache.js +62 -0
- package/lib/dist/resolution/lru-cache.js.map +1 -0
- package/lib/dist/resolution/name-matcher.d.ts +112 -0
- package/lib/dist/resolution/name-matcher.d.ts.map +1 -0
- package/lib/dist/resolution/name-matcher.js +1701 -0
- package/lib/dist/resolution/name-matcher.js.map +1 -0
- package/lib/dist/resolution/path-aliases.d.ts +68 -0
- package/lib/dist/resolution/path-aliases.d.ts.map +1 -0
- package/lib/dist/resolution/path-aliases.js +238 -0
- package/lib/dist/resolution/path-aliases.js.map +1 -0
- package/lib/dist/resolution/strip-comments.d.ts +27 -0
- package/lib/dist/resolution/strip-comments.d.ts.map +1 -0
- package/lib/dist/resolution/strip-comments.js +492 -0
- package/lib/dist/resolution/strip-comments.js.map +1 -0
- package/lib/dist/resolution/swift-objc-bridge.d.ts +134 -0
- package/lib/dist/resolution/swift-objc-bridge.d.ts.map +1 -0
- package/lib/dist/resolution/swift-objc-bridge.js +256 -0
- package/lib/dist/resolution/swift-objc-bridge.js.map +1 -0
- package/lib/dist/resolution/types.d.ts +253 -0
- package/lib/dist/resolution/types.d.ts.map +1 -0
- package/lib/dist/resolution/types.js +8 -0
- package/lib/dist/resolution/types.js.map +1 -0
- package/lib/dist/resolution/workspace-packages.d.ts +58 -0
- package/lib/dist/resolution/workspace-packages.d.ts.map +1 -0
- package/lib/dist/resolution/workspace-packages.js +346 -0
- package/lib/dist/resolution/workspace-packages.js.map +1 -0
- package/lib/dist/search/identifier-segments.d.ts +60 -0
- package/lib/dist/search/identifier-segments.d.ts.map +1 -0
- package/lib/dist/search/identifier-segments.js +176 -0
- package/lib/dist/search/identifier-segments.js.map +1 -0
- package/lib/dist/search/query-parser.d.ts +57 -0
- package/lib/dist/search/query-parser.d.ts.map +1 -0
- package/lib/dist/search/query-parser.js +177 -0
- package/lib/dist/search/query-parser.js.map +1 -0
- package/lib/dist/search/query-utils.d.ts +87 -0
- package/lib/dist/search/query-utils.d.ts.map +1 -0
- package/lib/dist/search/query-utils.js +449 -0
- package/lib/dist/search/query-utils.js.map +1 -0
- package/lib/dist/sync/git-hooks.d.ts +45 -0
- package/lib/dist/sync/git-hooks.d.ts.map +1 -0
- package/lib/dist/sync/git-hooks.js +227 -0
- package/lib/dist/sync/git-hooks.js.map +1 -0
- package/lib/dist/sync/index.d.ts +19 -0
- package/lib/dist/sync/index.d.ts.map +1 -0
- package/lib/dist/sync/index.js +35 -0
- package/lib/dist/sync/index.js.map +1 -0
- package/lib/dist/sync/watch-policy.d.ts +48 -0
- package/lib/dist/sync/watch-policy.d.ts.map +1 -0
- package/lib/dist/sync/watch-policy.js +124 -0
- package/lib/dist/sync/watch-policy.js.map +1 -0
- package/lib/dist/sync/watcher.d.ts +355 -0
- package/lib/dist/sync/watcher.d.ts.map +1 -0
- package/lib/dist/sync/watcher.js +848 -0
- package/lib/dist/sync/watcher.js.map +1 -0
- package/lib/dist/sync/worktree.d.ts +63 -0
- package/lib/dist/sync/worktree.d.ts.map +1 -0
- package/lib/dist/sync/worktree.js +182 -0
- package/lib/dist/sync/worktree.js.map +1 -0
- package/lib/dist/telemetry/index.d.ts +143 -0
- package/lib/dist/telemetry/index.d.ts.map +1 -0
- package/lib/dist/telemetry/index.js +541 -0
- package/lib/dist/telemetry/index.js.map +1 -0
- package/lib/dist/types.d.ts +415 -0
- package/lib/dist/types.d.ts.map +1 -0
- package/lib/dist/types.js +91 -0
- package/lib/dist/types.js.map +1 -0
- package/lib/dist/ui/glyphs.d.ts +42 -0
- package/lib/dist/ui/glyphs.d.ts.map +1 -0
- package/lib/dist/ui/glyphs.js +78 -0
- package/lib/dist/ui/glyphs.js.map +1 -0
- package/lib/dist/ui/shimmer-progress.d.ts +11 -0
- package/lib/dist/ui/shimmer-progress.d.ts.map +1 -0
- package/lib/dist/ui/shimmer-progress.js +90 -0
- package/lib/dist/ui/shimmer-progress.js.map +1 -0
- package/lib/dist/ui/shimmer-worker.d.ts +2 -0
- package/lib/dist/ui/shimmer-worker.d.ts.map +1 -0
- package/lib/dist/ui/shimmer-worker.js +118 -0
- package/lib/dist/ui/shimmer-worker.js.map +1 -0
- package/lib/dist/ui/types.d.ts +17 -0
- package/lib/dist/ui/types.d.ts.map +1 -0
- package/lib/dist/ui/types.js +3 -0
- package/lib/dist/ui/types.js.map +1 -0
- package/lib/dist/upgrade/index.d.ts +132 -0
- package/lib/dist/upgrade/index.d.ts.map +1 -0
- package/lib/dist/upgrade/index.js +498 -0
- package/lib/dist/upgrade/index.js.map +1 -0
- package/lib/dist/utils.d.ts +224 -0
- package/lib/dist/utils.d.ts.map +1 -0
- package/lib/dist/utils.js +583 -0
- package/lib/dist/utils.js.map +1 -0
- package/lib/node_modules/.package-lock.json +125 -0
- package/lib/node_modules/@clack/core/CHANGELOG.md +348 -0
- package/lib/node_modules/@clack/core/LICENSE +9 -0
- package/lib/node_modules/@clack/core/README.md +22 -0
- package/lib/node_modules/@clack/core/dist/index.d.mts +363 -0
- package/lib/node_modules/@clack/core/dist/index.mjs +17 -0
- package/lib/node_modules/@clack/core/dist/index.mjs.map +1 -0
- package/lib/node_modules/@clack/core/package.json +63 -0
- package/lib/node_modules/@clack/prompts/CHANGELOG.md +591 -0
- package/lib/node_modules/@clack/prompts/LICENSE +9 -0
- package/lib/node_modules/@clack/prompts/README.md +375 -0
- package/lib/node_modules/@clack/prompts/dist/index.d.mts +396 -0
- package/lib/node_modules/@clack/prompts/dist/index.mjs +144 -0
- package/lib/node_modules/@clack/prompts/dist/index.mjs.map +1 -0
- package/lib/node_modules/@clack/prompts/package.json +68 -0
- package/lib/node_modules/commander/LICENSE +22 -0
- package/lib/node_modules/commander/Readme.md +1176 -0
- package/lib/node_modules/commander/esm.mjs +16 -0
- package/lib/node_modules/commander/index.js +24 -0
- package/lib/node_modules/commander/lib/argument.js +150 -0
- package/lib/node_modules/commander/lib/command.js +2777 -0
- package/lib/node_modules/commander/lib/error.js +39 -0
- package/lib/node_modules/commander/lib/help.js +747 -0
- package/lib/node_modules/commander/lib/option.js +380 -0
- package/lib/node_modules/commander/lib/suggestSimilar.js +101 -0
- package/lib/node_modules/commander/package-support.json +19 -0
- package/lib/node_modules/commander/package.json +82 -0
- package/lib/node_modules/commander/typings/esm.d.mts +3 -0
- package/lib/node_modules/commander/typings/index.d.ts +1113 -0
- package/lib/node_modules/fast-string-truncated-width/dist/index.d.ts +4 -0
- package/lib/node_modules/fast-string-truncated-width/dist/index.js +111 -0
- package/lib/node_modules/fast-string-truncated-width/dist/types.d.ts +19 -0
- package/lib/node_modules/fast-string-truncated-width/dist/types.js +2 -0
- package/lib/node_modules/fast-string-truncated-width/dist/utils.d.ts +4 -0
- package/lib/node_modules/fast-string-truncated-width/dist/utils.js +20 -0
- package/lib/node_modules/fast-string-truncated-width/license +21 -0
- package/lib/node_modules/fast-string-truncated-width/package.json +35 -0
- package/lib/node_modules/fast-string-truncated-width/readme.md +59 -0
- package/lib/node_modules/fast-string-width/dist/index.d.ts +4 -0
- package/lib/node_modules/fast-string-width/dist/index.js +14 -0
- package/lib/node_modules/fast-string-width/license +21 -0
- package/lib/node_modules/fast-string-width/package.json +34 -0
- package/lib/node_modules/fast-string-width/readme.md +42 -0
- package/lib/node_modules/fast-wrap-ansi/LICENSE +23 -0
- package/lib/node_modules/fast-wrap-ansi/README.md +26 -0
- package/lib/node_modules/fast-wrap-ansi/lib/main.d.ts +6 -0
- package/lib/node_modules/fast-wrap-ansi/lib/main.js +219 -0
- package/lib/node_modules/fast-wrap-ansi/lib/main.js.map +1 -0
- package/lib/node_modules/fast-wrap-ansi/package.json +51 -0
- package/lib/node_modules/ignore/LICENSE-MIT +21 -0
- package/lib/node_modules/ignore/README.md +452 -0
- package/lib/node_modules/ignore/index.d.ts +81 -0
- package/lib/node_modules/ignore/index.js +784 -0
- package/lib/node_modules/ignore/legacy.js +681 -0
- package/lib/node_modules/ignore/package.json +87 -0
- package/lib/node_modules/jsonc-parser/CHANGELOG.md +76 -0
- package/lib/node_modules/jsonc-parser/LICENSE.md +21 -0
- package/lib/node_modules/jsonc-parser/README.md +364 -0
- package/lib/node_modules/jsonc-parser/SECURITY.md +41 -0
- package/lib/node_modules/jsonc-parser/lib/esm/impl/edit.js +185 -0
- package/lib/node_modules/jsonc-parser/lib/esm/impl/format.js +261 -0
- package/lib/node_modules/jsonc-parser/lib/esm/impl/parser.js +659 -0
- package/lib/node_modules/jsonc-parser/lib/esm/impl/scanner.js +443 -0
- package/lib/node_modules/jsonc-parser/lib/esm/impl/string-intern.js +29 -0
- package/lib/node_modules/jsonc-parser/lib/esm/main.d.ts +351 -0
- package/lib/node_modules/jsonc-parser/lib/esm/main.js +178 -0
- package/lib/node_modules/jsonc-parser/lib/umd/impl/edit.js +201 -0
- package/lib/node_modules/jsonc-parser/lib/umd/impl/format.js +275 -0
- package/lib/node_modules/jsonc-parser/lib/umd/impl/parser.js +682 -0
- package/lib/node_modules/jsonc-parser/lib/umd/impl/scanner.js +456 -0
- package/lib/node_modules/jsonc-parser/lib/umd/impl/string-intern.js +42 -0
- package/lib/node_modules/jsonc-parser/lib/umd/main.d.ts +351 -0
- package/lib/node_modules/jsonc-parser/lib/umd/main.js +194 -0
- package/lib/node_modules/jsonc-parser/package.json +37 -0
- package/lib/node_modules/picomatch/LICENSE +21 -0
- package/lib/node_modules/picomatch/README.md +738 -0
- package/lib/node_modules/picomatch/index.js +17 -0
- package/lib/node_modules/picomatch/lib/constants.js +180 -0
- package/lib/node_modules/picomatch/lib/parse.js +1085 -0
- package/lib/node_modules/picomatch/lib/picomatch.js +341 -0
- package/lib/node_modules/picomatch/lib/scan.js +391 -0
- package/lib/node_modules/picomatch/lib/utils.js +72 -0
- package/lib/node_modules/picomatch/package.json +83 -0
- package/lib/node_modules/picomatch/posix.js +3 -0
- package/lib/node_modules/sisteransi/license +21 -0
- package/lib/node_modules/sisteransi/package.json +34 -0
- package/lib/node_modules/sisteransi/readme.md +113 -0
- package/lib/node_modules/sisteransi/src/index.js +58 -0
- package/lib/node_modules/sisteransi/src/sisteransi.d.ts +35 -0
- package/lib/node_modules/tree-sitter-wasms/LICENSE +24 -0
- package/lib/node_modules/tree-sitter-wasms/README.md +23 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-bash.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-c.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-c_sharp.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-cpp.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-css.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-dart.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-elisp.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-elixir.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-elm.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-embedded_template.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-go.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-html.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-java.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-javascript.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-json.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-kotlin.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-lua.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-objc.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-ocaml.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-php.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-python.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-ql.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-rescript.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-ruby.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-rust.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-scala.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-solidity.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-swift.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-systemrdl.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-tlaplus.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-toml.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-tsx.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-typescript.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-vue.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-yaml.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/out/tree-sitter-zig.wasm +0 -0
- package/lib/node_modules/tree-sitter-wasms/package.json +64 -0
- package/lib/node_modules/web-tree-sitter/LICENSE +21 -0
- package/lib/node_modules/web-tree-sitter/README.md +269 -0
- package/lib/node_modules/web-tree-sitter/debug/tree-sitter.cjs +4558 -0
- package/lib/node_modules/web-tree-sitter/debug/tree-sitter.cjs.map +7 -0
- package/lib/node_modules/web-tree-sitter/debug/tree-sitter.js +4516 -0
- package/lib/node_modules/web-tree-sitter/debug/tree-sitter.js.map +7 -0
- package/lib/node_modules/web-tree-sitter/debug/tree-sitter.wasm +0 -0
- package/lib/node_modules/web-tree-sitter/debug/tree-sitter.wasm.map +31 -0
- package/lib/node_modules/web-tree-sitter/lib/alloc.c +48 -0
- package/lib/node_modules/web-tree-sitter/lib/alloc.h +41 -0
- package/lib/node_modules/web-tree-sitter/lib/array.h +291 -0
- package/lib/node_modules/web-tree-sitter/lib/atomic.h +68 -0
- package/lib/node_modules/web-tree-sitter/lib/clock.h +146 -0
- package/lib/node_modules/web-tree-sitter/lib/error_costs.h +11 -0
- package/lib/node_modules/web-tree-sitter/lib/get_changed_ranges.c +523 -0
- package/lib/node_modules/web-tree-sitter/lib/get_changed_ranges.h +36 -0
- package/lib/node_modules/web-tree-sitter/lib/host.h +21 -0
- package/lib/node_modules/web-tree-sitter/lib/language.c +293 -0
- package/lib/node_modules/web-tree-sitter/lib/language.h +293 -0
- package/lib/node_modules/web-tree-sitter/lib/length.h +52 -0
- package/lib/node_modules/web-tree-sitter/lib/lexer.c +483 -0
- package/lib/node_modules/web-tree-sitter/lib/lexer.h +54 -0
- package/lib/node_modules/web-tree-sitter/lib/lib.c +12 -0
- package/lib/node_modules/web-tree-sitter/lib/node.c +875 -0
- package/lib/node_modules/web-tree-sitter/lib/parser.c +2297 -0
- package/lib/node_modules/web-tree-sitter/lib/parser.h +286 -0
- package/lib/node_modules/web-tree-sitter/lib/point.h +48 -0
- package/lib/node_modules/web-tree-sitter/lib/query.c +4347 -0
- package/lib/node_modules/web-tree-sitter/lib/reduce_action.h +34 -0
- package/lib/node_modules/web-tree-sitter/lib/reusable_node.h +95 -0
- package/lib/node_modules/web-tree-sitter/lib/stack.c +912 -0
- package/lib/node_modules/web-tree-sitter/lib/stack.h +133 -0
- package/lib/node_modules/web-tree-sitter/lib/subtree.c +1034 -0
- package/lib/node_modules/web-tree-sitter/lib/subtree.h +399 -0
- package/lib/node_modules/web-tree-sitter/lib/tree-sitter.c +987 -0
- package/lib/node_modules/web-tree-sitter/lib/tree-sitter.cjs +2988 -0
- package/lib/node_modules/web-tree-sitter/lib/tree-sitter.wasm +0 -0
- package/lib/node_modules/web-tree-sitter/lib/tree-sitter.wasm.map +1 -0
- package/lib/node_modules/web-tree-sitter/lib/tree.c +170 -0
- package/lib/node_modules/web-tree-sitter/lib/tree.h +31 -0
- package/lib/node_modules/web-tree-sitter/lib/tree_cursor.c +716 -0
- package/lib/node_modules/web-tree-sitter/lib/tree_cursor.h +48 -0
- package/lib/node_modules/web-tree-sitter/lib/ts_assert.h +11 -0
- package/lib/node_modules/web-tree-sitter/lib/unicode.h +75 -0
- package/lib/node_modules/web-tree-sitter/lib/wasm_store.c +1937 -0
- package/lib/node_modules/web-tree-sitter/lib/wasm_store.h +31 -0
- package/lib/node_modules/web-tree-sitter/package.json +98 -0
- package/lib/node_modules/web-tree-sitter/src/bindings.ts +26 -0
- package/lib/node_modules/web-tree-sitter/src/constants.ts +133 -0
- package/lib/node_modules/web-tree-sitter/src/index.ts +31 -0
- package/lib/node_modules/web-tree-sitter/src/language.ts +291 -0
- package/lib/node_modules/web-tree-sitter/src/lookahead_iterator.ts +75 -0
- package/lib/node_modules/web-tree-sitter/src/marshal.ts +176 -0
- package/lib/node_modules/web-tree-sitter/src/node.ts +646 -0
- package/lib/node_modules/web-tree-sitter/src/parser.ts +325 -0
- package/lib/node_modules/web-tree-sitter/src/query.ts +973 -0
- package/lib/node_modules/web-tree-sitter/src/tree.ts +145 -0
- package/lib/node_modules/web-tree-sitter/src/tree_cursor.ts +318 -0
- package/lib/node_modules/web-tree-sitter/tree-sitter.cjs +4031 -0
- package/lib/node_modules/web-tree-sitter/tree-sitter.cjs.map +7 -0
- package/lib/node_modules/web-tree-sitter/tree-sitter.js +3980 -0
- package/lib/node_modules/web-tree-sitter/tree-sitter.js.map +7 -0
- package/lib/node_modules/web-tree-sitter/tree-sitter.wasm +0 -0
- package/lib/node_modules/web-tree-sitter/tree-sitter.wasm.map +30 -0
- package/lib/node_modules/web-tree-sitter/web-tree-sitter.d.ts +1030 -0
- package/lib/node_modules/web-tree-sitter/web-tree-sitter.d.ts.map +56 -0
- package/lib/package.json +64 -0
- package/node +0 -0
- package/package.json +17 -0
|
@@ -0,0 +1,1038 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.cFnPointerDispatchEdges = cFnPointerDispatchEdges;
|
|
37
|
+
/**
|
|
38
|
+
* C/C++ function-pointer dispatch synthesis (#932).
|
|
39
|
+
*
|
|
40
|
+
* C/C++ polymorphism is the function pointer: a struct carries a fn-pointer
|
|
41
|
+
* field (`int (*fn)(int)`, or a fn-pointer-typedef field `hook_func func`),
|
|
42
|
+
* concrete functions are *registered* into it through a table
|
|
43
|
+
* (`static struct cmd cmds[] = {{"add", cmd_add}, …}`, a designated
|
|
44
|
+
* `.fn = cmd_add`, or `x->fn = cmd_add`), and the dispatcher calls through it
|
|
45
|
+
* indirectly (`p->fn(argv)`). Static extraction captures neither the
|
|
46
|
+
* registration→field binding nor the indirect call, so the dispatcher→handler
|
|
47
|
+
* edge is missing and `git`'s `run_builtin` looks like it calls nothing, the
|
|
48
|
+
* hooks in `hook_demo.c` are unreachable, etc.
|
|
49
|
+
*
|
|
50
|
+
* This bridges it, keyed by **(struct type, fn-pointer field)**:
|
|
51
|
+
* • registrations — a function bound to `S.field` via a positional
|
|
52
|
+
* initializer (matched by field index), a designated `.field = fn`, or a
|
|
53
|
+
* direct `x.field = fn` / `x->field = fn` assignment;
|
|
54
|
+
* • dispatch — `recv->field(…)` / `recv.field(…)` where `recv` resolves to a
|
|
55
|
+
* value of struct type `S` (from the enclosing function's params / locals,
|
|
56
|
+
* or by walking a chained/array receiver `c->cmd->proc` across field types),
|
|
57
|
+
* falling back to the field name when it is unique to one struct;
|
|
58
|
+
* • field←field propagation — `a->f = b->g` merges `B.g`'s handlers into
|
|
59
|
+
* `A.f`, so a generic single-slot hook that is reassigned from a registry
|
|
60
|
+
* (the `hook_demo.c` shape: `h->func = found->fn`) still resolves.
|
|
61
|
+
*
|
|
62
|
+
* Also handles **macro-built tables** (#991) — the dominant real-world shape,
|
|
63
|
+
* e.g. redis' command table, sqlite's builtin functions, and vim's `:ex` /
|
|
64
|
+
* normal-mode commands. The fn-pointer arg lives inside a macro call
|
|
65
|
+
* (`MAKE_CMD(…,proc,…)` / `FUNCTION(…,xFunc)` / `EXCMD(…,fn,…)`) in a generated
|
|
66
|
+
* or `#include`-d file; the table's struct type may itself be an object-macro
|
|
67
|
+
* alias; the field may use a function-TYPE typedef; the struct may be defined
|
|
68
|
+
* INLINE with the array; and the whole thing may sit behind `#ifdef` switched on
|
|
69
|
+
* by the includer. The registration pass reads each `#include`-d file as a unit
|
|
70
|
+
* with the includer's effective macro env (own + headers) in scope, evaluates
|
|
71
|
+
* its `#ifdef`s against the includer's defined set, expands object/function
|
|
72
|
+
* macros, peels a brace-wrapped element, and parses an inline struct in place —
|
|
73
|
+
* then reads the positional/designated bindings. Dispatch additionally resolves
|
|
74
|
+
* an array subscript through a file-scope table (`(cmdnames[i].cmd_func)(…)`).
|
|
75
|
+
*
|
|
76
|
+
* Also bridges **bare arrays of function pointers** (no struct, no field) —
|
|
77
|
+
* `opcode_t *opcodes[256] = {nop,…}` dispatched `opcodes[op](…)` (SameBoy's CPU),
|
|
78
|
+
* `zend_rc_dtor_func_t t[] = {[IS_STRING]=(cast)fn,…}` dispatched `t[GC_TYPE(p)](…)`
|
|
79
|
+
* (php's Zend) — keyed by the array VARIABLE name. The element type must be a
|
|
80
|
+
* function typedef (the precision gate), entries are literal function names, and
|
|
81
|
+
* the same-file table wins on a name collision (two file-local `opcodes[256]`).
|
|
82
|
+
*
|
|
83
|
+
* Whole-graph pass after base resolution; all edges are `provenance:'heuristic'`
|
|
84
|
+
* (`synthesizedBy:'fn-pointer-dispatch'`). High precision via the (type, field)
|
|
85
|
+
* key + a real-function gate; a project with no fn-pointer dispatch is a no-op.
|
|
86
|
+
*/
|
|
87
|
+
const path = __importStar(require("node:path"));
|
|
88
|
+
const strip_comments_1 = require("./strip-comments");
|
|
89
|
+
const C_CPP_EXT = /\.(c|h|cc|cpp|cxx|hpp|hh|hxx|cppm|ipp|inl|tcc)$/i;
|
|
90
|
+
const FN_KINDS = new Set(['function', 'method']);
|
|
91
|
+
const FANOUT_CAP = 300; // a real command table (git ~150) is legitimate fan-out; this only stops pathological cases.
|
|
92
|
+
function sliceLines(content, startLine, endLine) {
|
|
93
|
+
if (!startLine)
|
|
94
|
+
return '';
|
|
95
|
+
return content.split('\n').slice(startLine - 1, endLine ?? startLine).join('\n');
|
|
96
|
+
}
|
|
97
|
+
/** Index of the `}` matching the `{` at `open` (which must point at a `{`). -1 if unbalanced. */
|
|
98
|
+
function matchBrace(src, open) {
|
|
99
|
+
let depth = 0;
|
|
100
|
+
for (let i = open; i < src.length; i++) {
|
|
101
|
+
const c = src[i];
|
|
102
|
+
if (c === '{')
|
|
103
|
+
depth++;
|
|
104
|
+
else if (c === '}') {
|
|
105
|
+
depth--;
|
|
106
|
+
if (depth === 0)
|
|
107
|
+
return i;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return -1;
|
|
111
|
+
}
|
|
112
|
+
/** Split `body` on `sep` at brace/paren/bracket depth 0 (commas inside `{…}` / `(…)` stay together). */
|
|
113
|
+
function splitTopLevel(body, sep) {
|
|
114
|
+
const out = [];
|
|
115
|
+
let depth = 0;
|
|
116
|
+
let start = 0;
|
|
117
|
+
for (let i = 0; i < body.length; i++) {
|
|
118
|
+
const c = body[i];
|
|
119
|
+
if (c === '{' || c === '(' || c === '[')
|
|
120
|
+
depth++;
|
|
121
|
+
else if (c === '}' || c === ')' || c === ']')
|
|
122
|
+
depth--;
|
|
123
|
+
else if (c === sep && depth === 0) {
|
|
124
|
+
out.push(body.slice(start, i));
|
|
125
|
+
start = i + 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
out.push(body.slice(start));
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
/** Index of the `)` matching the `(` at `open` (which must point at a `(`). -1 if unbalanced. */
|
|
132
|
+
function matchParen(src, open) {
|
|
133
|
+
let depth = 0;
|
|
134
|
+
for (let i = open; i < src.length; i++) {
|
|
135
|
+
const c = src[i];
|
|
136
|
+
if (c === '(')
|
|
137
|
+
depth++;
|
|
138
|
+
else if (c === ')') {
|
|
139
|
+
depth--;
|
|
140
|
+
if (depth === 0)
|
|
141
|
+
return i;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return -1;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Collect function-like macros from (comment-stripped) source, joining
|
|
148
|
+
* `\`-continuations first. Only object/positional table macros matter here, so
|
|
149
|
+
* variadic macros are skipped. Used to expand registration tables built through
|
|
150
|
+
* a macro (redis' `MAKE_CMD(…)`) before reading the struct-field bindings.
|
|
151
|
+
*/
|
|
152
|
+
function parseFunctionMacros(stripped) {
|
|
153
|
+
const out = new Map();
|
|
154
|
+
if (!stripped.includes('#define') && !stripped.includes('# define'))
|
|
155
|
+
return out;
|
|
156
|
+
const joined = stripped.replace(/\\\r?\n/g, ' ');
|
|
157
|
+
const RE = /^[ \t]*#[ \t]*define[ \t]+(\w+)\(([^)]*)\)\s+(.+)$/gm;
|
|
158
|
+
let m;
|
|
159
|
+
while ((m = RE.exec(joined))) {
|
|
160
|
+
const params = m[2].split(',').map((p) => p.trim()).filter(Boolean);
|
|
161
|
+
if (params.some((p) => p === '...' || p.endsWith('...')))
|
|
162
|
+
continue; // variadic — skip
|
|
163
|
+
out.set(m[1], { params, expansion: m[3].trim() });
|
|
164
|
+
}
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Collect object-like macros `#define NAME value` (NAME not immediately followed
|
|
169
|
+
* by `(`). redis aliases the table's struct type this way:
|
|
170
|
+
* `#define COMMAND_STRUCT redisCommand`, used as `struct COMMAND_STRUCT table[]`.
|
|
171
|
+
*/
|
|
172
|
+
function parseObjectMacros(stripped) {
|
|
173
|
+
const out = new Map();
|
|
174
|
+
if (!stripped.includes('#define') && !stripped.includes('# define'))
|
|
175
|
+
return out;
|
|
176
|
+
const joined = stripped.replace(/\\\r?\n/g, ' ');
|
|
177
|
+
const RE = /^[ \t]*#[ \t]*define[ \t]+(\w+)[ \t]+(\S[^\n]*)$/gm;
|
|
178
|
+
let m;
|
|
179
|
+
while ((m = RE.exec(joined)))
|
|
180
|
+
out.set(m[1], m[2].trim());
|
|
181
|
+
return out;
|
|
182
|
+
}
|
|
183
|
+
/** All macro names a file `#define`s (value-ful or not) — the "defined" set for #ifdef. */
|
|
184
|
+
function parseDefinedNames(stripped) {
|
|
185
|
+
const out = new Set();
|
|
186
|
+
if (!stripped.includes('#define') && !stripped.includes('# define'))
|
|
187
|
+
return out;
|
|
188
|
+
const RE = /^[ \t]*#[ \t]*define[ \t]+(\w+)/gm;
|
|
189
|
+
let m;
|
|
190
|
+
while ((m = RE.exec(stripped)))
|
|
191
|
+
out.add(m[1]);
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Drop the inactive arms of `#ifdef`/`#ifndef`/`#if defined(X)`/`#else`/`#elif`/
|
|
196
|
+
* `#endif` given a set of defined macro names, keeping line offsets (inactive
|
|
197
|
+
* lines are blanked, not removed). A conditional whose expression we can't
|
|
198
|
+
* evaluate (`#if SOME_EXPR`) keeps its body — better to over-keep than to drop
|
|
199
|
+
* live code. This is what makes a header included with a switch macro defined
|
|
200
|
+
* (vim's `ex_cmds.h` under `DO_DECLARE_EXCMD`) expose only its active table.
|
|
201
|
+
*/
|
|
202
|
+
function evalConditionals(text, defined) {
|
|
203
|
+
if (!/#\s*if/.test(text))
|
|
204
|
+
return text;
|
|
205
|
+
const lines = text.split('\n');
|
|
206
|
+
// stack frame: parentActive = enclosing kept?; active = this arm kept?; taken = any arm taken yet
|
|
207
|
+
const stack = [];
|
|
208
|
+
const activeNow = () => (stack.length === 0 ? true : stack[stack.length - 1].active);
|
|
209
|
+
const condDefined = (expr) => {
|
|
210
|
+
let mm = expr.match(/^defined\s*\(?\s*(\w+)\s*\)?$/);
|
|
211
|
+
if (mm)
|
|
212
|
+
return defined.has(mm[1]);
|
|
213
|
+
mm = expr.match(/^!\s*defined\s*\(?\s*(\w+)\s*\)?$/);
|
|
214
|
+
if (mm)
|
|
215
|
+
return !defined.has(mm[1]);
|
|
216
|
+
return null; // unevaluable
|
|
217
|
+
};
|
|
218
|
+
for (let i = 0; i < lines.length; i++) {
|
|
219
|
+
const t = lines[i].trim();
|
|
220
|
+
let mm;
|
|
221
|
+
if ((mm = t.match(/^#\s*ifdef\s+(\w+)/))) {
|
|
222
|
+
const pa = activeNow();
|
|
223
|
+
const cond = defined.has(mm[1]);
|
|
224
|
+
stack.push({ parentActive: pa, active: pa && cond, taken: cond });
|
|
225
|
+
lines[i] = '';
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if ((mm = t.match(/^#\s*ifndef\s+(\w+)/))) {
|
|
229
|
+
const pa = activeNow();
|
|
230
|
+
const cond = !defined.has(mm[1]);
|
|
231
|
+
stack.push({ parentActive: pa, active: pa && cond, taken: cond });
|
|
232
|
+
lines[i] = '';
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if ((mm = t.match(/^#\s*if\s+(.+)$/))) {
|
|
236
|
+
const pa = activeNow();
|
|
237
|
+
const c = condDefined(mm[1].trim());
|
|
238
|
+
const cond = c === null ? true : c; // unevaluable → keep
|
|
239
|
+
stack.push({ parentActive: pa, active: pa && cond, taken: cond });
|
|
240
|
+
lines[i] = '';
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (/^#\s*elif\b/.test(t)) {
|
|
244
|
+
const top = stack[stack.length - 1];
|
|
245
|
+
if (top) {
|
|
246
|
+
top.active = top.parentActive && !top.taken;
|
|
247
|
+
top.taken = true;
|
|
248
|
+
}
|
|
249
|
+
lines[i] = '';
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (/^#\s*else\b/.test(t)) {
|
|
253
|
+
const top = stack[stack.length - 1];
|
|
254
|
+
if (top) {
|
|
255
|
+
top.active = top.parentActive && !top.taken;
|
|
256
|
+
top.taken = true;
|
|
257
|
+
}
|
|
258
|
+
lines[i] = '';
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (/^#\s*endif\b/.test(t)) {
|
|
262
|
+
stack.pop();
|
|
263
|
+
lines[i] = '';
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (!activeNow())
|
|
267
|
+
lines[i] = ''; // blank an inactive line (keep the newline)
|
|
268
|
+
}
|
|
269
|
+
return lines.join('\n');
|
|
270
|
+
}
|
|
271
|
+
/** Resolve a type token through object-like macro aliases (transitive, capped). */
|
|
272
|
+
function resolveTypeName(name, objEnv) {
|
|
273
|
+
let n = name;
|
|
274
|
+
for (let i = 0; objEnv && i < 5; i++) {
|
|
275
|
+
const v = objEnv.get(n);
|
|
276
|
+
const t = v?.trim().match(/^(?:struct\s+)?(\w+)$/);
|
|
277
|
+
if (!t)
|
|
278
|
+
break;
|
|
279
|
+
n = t[1];
|
|
280
|
+
}
|
|
281
|
+
return n;
|
|
282
|
+
}
|
|
283
|
+
/** Substitute call args for the macro's params (whole-token) in its expansion. */
|
|
284
|
+
function substituteMacro(def, args) {
|
|
285
|
+
const map = new Map();
|
|
286
|
+
def.params.forEach((p, i) => map.set(p, args[i] ?? ''));
|
|
287
|
+
return def.expansion.replace(/\b\w+\b/g, (tok) => (map.has(tok) ? map.get(tok) : tok));
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Expand known function-like macro calls in `text` to a fixpoint (depth-capped).
|
|
291
|
+
* `MAKE_CMD("get",…,getCommand,…)` → the positional value list whose slots line
|
|
292
|
+
* up with the struct's fields, so the existing positional registration can read
|
|
293
|
+
* `getCommand` straight out of the `proc` slot.
|
|
294
|
+
*/
|
|
295
|
+
function expandMacroCalls(text, env) {
|
|
296
|
+
if (env.size === 0)
|
|
297
|
+
return text;
|
|
298
|
+
let out = text;
|
|
299
|
+
for (let pass = 0; pass < 6; pass++) {
|
|
300
|
+
let changed = false;
|
|
301
|
+
const RE = /\b(\w+)\s*\(/g;
|
|
302
|
+
let m;
|
|
303
|
+
while ((m = RE.exec(out))) {
|
|
304
|
+
const def = env.get(m[1]);
|
|
305
|
+
if (!def)
|
|
306
|
+
continue;
|
|
307
|
+
const open = m.index + m[0].length - 1; // index of the `(`
|
|
308
|
+
const close = matchParen(out, open);
|
|
309
|
+
if (close < 0)
|
|
310
|
+
continue;
|
|
311
|
+
const args = splitTopLevel(out.slice(open + 1, close), ',').map((a) => a.trim());
|
|
312
|
+
out = out.slice(0, m.index) + substituteMacro(def, args) + out.slice(close + 1);
|
|
313
|
+
changed = true;
|
|
314
|
+
break; // restart scan — offsets shifted
|
|
315
|
+
}
|
|
316
|
+
if (!changed)
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
return out;
|
|
320
|
+
}
|
|
321
|
+
/** A fn-pointer field looks like `… (*name)(…)` — capture `name`. A
|
|
322
|
+
* calling-convention / attribute macro may precede the `*`
|
|
323
|
+
* (`(ZEND_FASTCALL *name)`), so allow leading word tokens. */
|
|
324
|
+
const FNPTR_DECL_RE = /\(\s*(?:\w+\s+)*\*\s*(\w+)\s*\)\s*\(/;
|
|
325
|
+
/** `typedef RET (*NAME)(…)` — a function-pointer typedef (CC/attr macro before
|
|
326
|
+
* the `*` allowed, as in php's `typedef void (ZEND_FASTCALL *fn_t)(…)`). */
|
|
327
|
+
const FNPTR_TYPEDEF_RE = /\btypedef\b[^;{}]*?\(\s*(?:\w+\s+)*\*\s*(\w+)\s*\)\s*\(/g;
|
|
328
|
+
/** A whole brace-free `typedef … ;` statement — capture the guts to spot the
|
|
329
|
+
* function-TYPE form `typedef RET NAME(params)` (no `(*name)` pointer form). */
|
|
330
|
+
const FNTYPE_TYPEDEF_STMT_RE = /\btypedef\b([^;{}]*);/g;
|
|
331
|
+
/** Return-type keywords that must never be mistaken for the typedef's name. */
|
|
332
|
+
const C_TYPE_KEYWORDS = new Set([
|
|
333
|
+
'void', 'int', 'char', 'short', 'long', 'unsigned', 'signed', 'float', 'double',
|
|
334
|
+
'const', 'struct', 'union', 'enum', 'static', 'volatile', 'register', 'inline',
|
|
335
|
+
]);
|
|
336
|
+
/** `#include "local/header"` — captured from RAW source (string contents survive). */
|
|
337
|
+
const INCLUDE_RE = /#[ \t]*include[ \t]+"([^"\n]+)"/g;
|
|
338
|
+
/** Included files worth scanning for registration tables (e.g. a generated `.def`). */
|
|
339
|
+
const INCLUDABLE_EXT = /\.(def|inc|h|hh|hpp|hxx|c|cc|cpp|cxx|ipp|tcc|tbl)$/i;
|
|
340
|
+
function cFnPointerDispatchEdges(queries, ctx) {
|
|
341
|
+
const files = ctx.getAllFiles().filter((f) => C_CPP_EXT.test(f));
|
|
342
|
+
if (files.length === 0)
|
|
343
|
+
return [];
|
|
344
|
+
// Cache raw + stripped source per file (read once, reused across passes).
|
|
345
|
+
// Raw is needed for `#include "…"` directives — strip blanks string contents.
|
|
346
|
+
const rawCache = new Map();
|
|
347
|
+
const raw = (file) => {
|
|
348
|
+
if (rawCache.has(file))
|
|
349
|
+
return rawCache.get(file);
|
|
350
|
+
const r = ctx.readFile(file);
|
|
351
|
+
rawCache.set(file, r);
|
|
352
|
+
return r;
|
|
353
|
+
};
|
|
354
|
+
const srcCache = new Map();
|
|
355
|
+
const src = (file) => {
|
|
356
|
+
if (srcCache.has(file))
|
|
357
|
+
return srcCache.get(file);
|
|
358
|
+
const r = raw(file);
|
|
359
|
+
const s = r == null ? '' : (0, strip_comments_1.stripCommentsForRegex)(r, 'c');
|
|
360
|
+
srcCache.set(file, s);
|
|
361
|
+
return r == null ? null : s;
|
|
362
|
+
};
|
|
363
|
+
// Resolve a quoted include relative to the includer's directory, then the
|
|
364
|
+
// project root. Returns a project-root-relative path that exists on disk
|
|
365
|
+
// (even if it was never indexed — e.g. redis' generated `commands.def`).
|
|
366
|
+
const resolveInclude = (includer, inc) => {
|
|
367
|
+
const dir = path.posix.dirname(includer.replace(/\\/g, '/'));
|
|
368
|
+
const cand = path.posix.normalize(path.posix.join(dir, inc));
|
|
369
|
+
if (ctx.fileExists(cand))
|
|
370
|
+
return cand;
|
|
371
|
+
if (ctx.fileExists(inc))
|
|
372
|
+
return inc;
|
|
373
|
+
return null;
|
|
374
|
+
};
|
|
375
|
+
// ---- Pass A: function-pointer AND function-type typedefs (cross-file) ----
|
|
376
|
+
// fn-pointer: typedef RET (*NAME)(…) → a field `NAME f` is a fn ptr
|
|
377
|
+
// fn-type: typedef RET NAME(params) → a field `NAME *f` is a fn ptr
|
|
378
|
+
// The fn-type form is redis' command idiom: `typedef void redisCommandProc(client*)`
|
|
379
|
+
// declared as `redisCommandProc *proc;`. Without this, `proc` reads as data.
|
|
380
|
+
const fnPtrTypedefs = new Set();
|
|
381
|
+
const fnTypeTypedefs = new Set();
|
|
382
|
+
for (const file of files) {
|
|
383
|
+
const s = src(file);
|
|
384
|
+
if (!s || !s.includes('typedef'))
|
|
385
|
+
continue;
|
|
386
|
+
FNPTR_TYPEDEF_RE.lastIndex = 0;
|
|
387
|
+
let m;
|
|
388
|
+
while ((m = FNPTR_TYPEDEF_RE.exec(s)))
|
|
389
|
+
fnPtrTypedefs.add(m[1]);
|
|
390
|
+
FNTYPE_TYPEDEF_STMT_RE.lastIndex = 0;
|
|
391
|
+
while ((m = FNTYPE_TYPEDEF_STMT_RE.exec(s))) {
|
|
392
|
+
const guts = m[1];
|
|
393
|
+
if (guts.includes('(*') || guts.includes('( *'))
|
|
394
|
+
continue; // pointer form — handled above
|
|
395
|
+
const fm = guts.match(/\b(\w+)\s*\(/); // last identifier before the param list
|
|
396
|
+
if (fm && !C_TYPE_KEYWORDS.has(fm[1]))
|
|
397
|
+
fnTypeTypedefs.add(fm[1]);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// ---- Pass B: struct field layouts ----
|
|
401
|
+
// structLayout: struct name → ordered fields, for structs with ≥1 fn-pointer
|
|
402
|
+
// field (drives positional registration + dispatch).
|
|
403
|
+
// allStructFields: EVERY struct name → ALL its field layouts (a name can be
|
|
404
|
+
// reused across files — e.g. redis has two unrelated `client` structs), used
|
|
405
|
+
// to walk a chained receiver's field types (`c->cmd->proc`: client.cmd →
|
|
406
|
+
// redisCommand). The walk searches every same-named layout for the field.
|
|
407
|
+
// fieldToStructs: fn-pointer field name → set of struct names that declare it.
|
|
408
|
+
const structLayout = new Map();
|
|
409
|
+
const allStructFields = new Map();
|
|
410
|
+
const fieldToStructs = new Map();
|
|
411
|
+
// Parse a struct body (the text between its `{` and `}`) into ordered fields.
|
|
412
|
+
const parseStructFields = (inner) => {
|
|
413
|
+
const fields = [];
|
|
414
|
+
let idx = 0;
|
|
415
|
+
for (const rawDecl of splitTopLevel(inner, ';')) {
|
|
416
|
+
const decl = rawDecl.trim();
|
|
417
|
+
if (!decl)
|
|
418
|
+
continue;
|
|
419
|
+
// A field decl can declare several names sharing a leading type:
|
|
420
|
+
// `struct redisCommand *cmd, *lastcmd;`. Each declarator is its own
|
|
421
|
+
// positional slot and carries that type (so `client.cmd → redisCommand`).
|
|
422
|
+
const parts = splitTopLevel(decl, ',');
|
|
423
|
+
const firstTyped = parts[0].match(/(\w+)\s+\**\s*(\w+)\s*$/);
|
|
424
|
+
const sharedType = firstTyped ? firstTyped[1] : '';
|
|
425
|
+
for (let pi = 0; pi < parts.length; pi++) {
|
|
426
|
+
const p = parts[pi].trim();
|
|
427
|
+
let name = null;
|
|
428
|
+
let type = '';
|
|
429
|
+
let isFnPtr = false;
|
|
430
|
+
const ptr = p.match(FNPTR_DECL_RE);
|
|
431
|
+
if (ptr) {
|
|
432
|
+
name = ptr[1]; // `… (*name)(…)` — a function pointer
|
|
433
|
+
isFnPtr = true;
|
|
434
|
+
}
|
|
435
|
+
else if (pi === 0) {
|
|
436
|
+
if (firstTyped) {
|
|
437
|
+
name = firstTyped[2];
|
|
438
|
+
type = sharedType;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
// a subsequent declarator: `*name` / `**name` / `name`
|
|
443
|
+
const dm = p.match(/^\**\s*(\w+)/);
|
|
444
|
+
if (dm) {
|
|
445
|
+
name = dm[1];
|
|
446
|
+
type = sharedType;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (!ptr && type)
|
|
450
|
+
isFnPtr = fnPtrTypedefs.has(type) || fnTypeTypedefs.has(type);
|
|
451
|
+
// Always advance the positional index. An unparsed field (anonymous
|
|
452
|
+
// union, exotic declarator) still occupies one slot, and macro-expanded
|
|
453
|
+
// positional tables (redis' MAKE_CMD) only align if every field counts.
|
|
454
|
+
fields.push({ name: name ?? '', index: idx, isFnPtr: !!name && isFnPtr, type });
|
|
455
|
+
idx++;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return fields;
|
|
459
|
+
};
|
|
460
|
+
// Register a parsed struct under `name` into the three indexes.
|
|
461
|
+
const registerStructLayout = (name, fields) => {
|
|
462
|
+
if (!allStructFields.has(name))
|
|
463
|
+
allStructFields.set(name, []);
|
|
464
|
+
allStructFields.get(name).push(fields);
|
|
465
|
+
for (const f of fields) {
|
|
466
|
+
if (f.name && f.isFnPtr) {
|
|
467
|
+
if (!fieldToStructs.has(f.name))
|
|
468
|
+
fieldToStructs.set(f.name, new Set());
|
|
469
|
+
fieldToStructs.get(f.name).add(name);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (fields.some((f) => f.isFnPtr))
|
|
473
|
+
structLayout.set(name, fields);
|
|
474
|
+
};
|
|
475
|
+
for (const st of ctx.getNodesByKind('struct')) {
|
|
476
|
+
if (!C_CPP_EXT.test(st.filePath))
|
|
477
|
+
continue;
|
|
478
|
+
const s = srcCache.get(st.filePath) ?? src(st.filePath);
|
|
479
|
+
if (!s)
|
|
480
|
+
continue;
|
|
481
|
+
const body = sliceLines(s, st.startLine, st.endLine);
|
|
482
|
+
const open = body.indexOf('{');
|
|
483
|
+
const close = open >= 0 ? matchBrace(body, open) : -1;
|
|
484
|
+
if (open < 0 || close < 0)
|
|
485
|
+
continue;
|
|
486
|
+
registerStructLayout(st.name, parseStructFields(body.slice(open + 1, close)));
|
|
487
|
+
}
|
|
488
|
+
// NB: no early return on an empty structLayout here — an inline `struct TAG
|
|
489
|
+
// { … } var[]` table whose struct never became a node (vim's `cmdname`, broken
|
|
490
|
+
// up by `#ifdef`) is discovered later during the unit scan. The `reg.size === 0`
|
|
491
|
+
// guard after registration still short-circuits when nothing bridges.
|
|
492
|
+
const fnPtrFieldOf = (struct, field) => !!structLayout.get(struct)?.some((f) => f.name === field && f.isFnPtr);
|
|
493
|
+
// C/C++ function + method nodes, materialized once (bounded by C/C++ files).
|
|
494
|
+
const cFns = [];
|
|
495
|
+
for (const fn of iterateFns(queries)) {
|
|
496
|
+
if (C_CPP_EXT.test(fn.filePath))
|
|
497
|
+
cFns.push(fn);
|
|
498
|
+
}
|
|
499
|
+
// ---- function-name → node resolution (prefer a function in the same file) ----
|
|
500
|
+
const resolveFn = (name, preferFile) => {
|
|
501
|
+
const cands = ctx.getNodesByName(name).filter((n) => FN_KINDS.has(n.kind));
|
|
502
|
+
if (cands.length === 0)
|
|
503
|
+
return null;
|
|
504
|
+
if (cands.length === 1)
|
|
505
|
+
return cands[0];
|
|
506
|
+
if (preferFile) {
|
|
507
|
+
const same = cands.find((n) => n.filePath === preferFile);
|
|
508
|
+
if (same)
|
|
509
|
+
return same;
|
|
510
|
+
}
|
|
511
|
+
return cands[0];
|
|
512
|
+
};
|
|
513
|
+
// ---- Pass C: registrations — Map<"struct.field", Set<funcNodeId>> ----
|
|
514
|
+
const reg = new Map();
|
|
515
|
+
const idToNode = new Map();
|
|
516
|
+
const addReg = (struct, field, fn) => {
|
|
517
|
+
const key = `${struct}.${field}`;
|
|
518
|
+
if (!reg.has(key))
|
|
519
|
+
reg.set(key, new Set());
|
|
520
|
+
reg.get(key).add(fn.id);
|
|
521
|
+
idToNode.set(fn.id, fn);
|
|
522
|
+
};
|
|
523
|
+
// Bare arrays-of-fn-pointers (no struct): array VARIABLE name → per-file sets
|
|
524
|
+
// of registered function ids. Multi-entry because a file-scope `static` table
|
|
525
|
+
// name can recur across files (SameBoy declares `static opcode_t *opcodes[256]`
|
|
526
|
+
// in BOTH sm83_cpu.c and sm83_disassembler.c), so dispatch resolves same-file.
|
|
527
|
+
const arrayReg = new Map();
|
|
528
|
+
const addArrayReg = (name, file, fn) => {
|
|
529
|
+
let entries = arrayReg.get(name);
|
|
530
|
+
if (!entries) {
|
|
531
|
+
entries = [];
|
|
532
|
+
arrayReg.set(name, entries);
|
|
533
|
+
}
|
|
534
|
+
let e = entries.find((x) => x.file === file);
|
|
535
|
+
if (!e) {
|
|
536
|
+
e = { file, ids: new Set() };
|
|
537
|
+
entries.push(e);
|
|
538
|
+
}
|
|
539
|
+
e.ids.add(fn.id);
|
|
540
|
+
idToNode.set(fn.id, fn);
|
|
541
|
+
};
|
|
542
|
+
// A struct value `{ … }` (one element) — register its function entries to the
|
|
543
|
+
// struct's fields, by `.field = fn` designators or by positional slot.
|
|
544
|
+
const registerStructValue = (struct, valueBody, file, env) => {
|
|
545
|
+
const layout = structLayout.get(struct);
|
|
546
|
+
if (!layout)
|
|
547
|
+
return;
|
|
548
|
+
if (env && env.size)
|
|
549
|
+
valueBody = expandMacroCalls(valueBody, env);
|
|
550
|
+
// A macro can expand to a whole brace-wrapped element (sqlite's
|
|
551
|
+
// `FUNCTION(…)` → `{nArg, …, xFunc, …}`); peel one outer layer so the
|
|
552
|
+
// positional slots are visible.
|
|
553
|
+
valueBody = valueBody.trim();
|
|
554
|
+
if (valueBody.startsWith('{')) {
|
|
555
|
+
const e = matchBrace(valueBody, 0);
|
|
556
|
+
if (e > 0 && valueBody.slice(e + 1).trim() === '')
|
|
557
|
+
valueBody = valueBody.slice(1, e);
|
|
558
|
+
}
|
|
559
|
+
const items = splitTopLevel(valueBody, ',');
|
|
560
|
+
let pos = 0;
|
|
561
|
+
for (const rawItem of items) {
|
|
562
|
+
const item = rawItem.trim();
|
|
563
|
+
if (!item)
|
|
564
|
+
continue;
|
|
565
|
+
const des = item.match(/^\.\s*(\w+)\s*=\s*(?:&\s*)?(\w+)\s*$/);
|
|
566
|
+
if (des) {
|
|
567
|
+
const field = des[1];
|
|
568
|
+
if (fnPtrFieldOf(struct, field)) {
|
|
569
|
+
const fn = resolveFn(des[2], file);
|
|
570
|
+
if (fn)
|
|
571
|
+
addReg(struct, field, fn);
|
|
572
|
+
}
|
|
573
|
+
// a designated item does not advance positional counting
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
const field = layout.find((f) => f.index === pos);
|
|
577
|
+
if (field?.isFnPtr) {
|
|
578
|
+
const id = item.match(/^&?\s*(\w+)\s*$/);
|
|
579
|
+
if (id) {
|
|
580
|
+
const fn = resolveFn(id[1], file);
|
|
581
|
+
if (fn)
|
|
582
|
+
addReg(struct, field.name, fn);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
pos++;
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
// Collect the literal function entries of an array-of-fn-pointers initializer
|
|
589
|
+
// and register them under the array's variable name. Entries may be positional
|
|
590
|
+
// (`fn`, `&fn`), designated by index (`[OP] = fn`), or cast-wrapped
|
|
591
|
+
// (`(handler_t)fn`, as in php's Zend dtor table). Non-identifier entries
|
|
592
|
+
// (`NULL`, `0`, a nested expression) are skipped — a miss, never a wrong edge.
|
|
593
|
+
// No index tracking: a runtime subscript fans the dispatch out to the whole
|
|
594
|
+
// set, exactly like a command table reaches every command.
|
|
595
|
+
const registerArrayValue = (name, body, file, env) => {
|
|
596
|
+
if (env && env.size)
|
|
597
|
+
body = expandMacroCalls(body, env);
|
|
598
|
+
for (const rawItem of splitTopLevel(body, ',')) {
|
|
599
|
+
let item = rawItem.trim();
|
|
600
|
+
if (!item)
|
|
601
|
+
continue;
|
|
602
|
+
const des = item.match(/^\[[^\]]*\]\s*=\s*([\s\S]*)$/); // `[IDX] = …` designator
|
|
603
|
+
if (des)
|
|
604
|
+
item = des[1].trim();
|
|
605
|
+
item = item.replace(/^\((?:[\w\s*]+)\)\s*/, '').replace(/^&\s*/, '').trim(); // (cast) / &
|
|
606
|
+
const id = item.match(/^(\w+)$/);
|
|
607
|
+
if (!id)
|
|
608
|
+
continue;
|
|
609
|
+
const fn = resolveFn(id[1], file);
|
|
610
|
+
if (fn)
|
|
611
|
+
addArrayReg(name, file, fn);
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
// Per-file macro + include parsing (any file, indexed or not), cached.
|
|
615
|
+
const fnMacroCache = new Map();
|
|
616
|
+
const fileFnMacros = (file) => {
|
|
617
|
+
let m = fnMacroCache.get(file);
|
|
618
|
+
if (!m) {
|
|
619
|
+
m = parseFunctionMacros(src(file) ?? '');
|
|
620
|
+
fnMacroCache.set(file, m);
|
|
621
|
+
}
|
|
622
|
+
return m;
|
|
623
|
+
};
|
|
624
|
+
const objMacroCache = new Map();
|
|
625
|
+
const fileObjMacros = (file) => {
|
|
626
|
+
let m = objMacroCache.get(file);
|
|
627
|
+
if (!m) {
|
|
628
|
+
m = parseObjectMacros(src(file) ?? '');
|
|
629
|
+
objMacroCache.set(file, m);
|
|
630
|
+
}
|
|
631
|
+
return m;
|
|
632
|
+
};
|
|
633
|
+
const definedCache = new Map();
|
|
634
|
+
const fileDefinedNames = (file) => {
|
|
635
|
+
let d = definedCache.get(file);
|
|
636
|
+
if (!d) {
|
|
637
|
+
d = parseDefinedNames(src(file) ?? '');
|
|
638
|
+
definedCache.set(file, d);
|
|
639
|
+
}
|
|
640
|
+
return d;
|
|
641
|
+
};
|
|
642
|
+
const includeCache = new Map();
|
|
643
|
+
const localIncludesOf = (file) => {
|
|
644
|
+
let out = includeCache.get(file);
|
|
645
|
+
if (out)
|
|
646
|
+
return out;
|
|
647
|
+
out = [];
|
|
648
|
+
const rawText = raw(file);
|
|
649
|
+
if (rawText && rawText.includes('include')) {
|
|
650
|
+
INCLUDE_RE.lastIndex = 0;
|
|
651
|
+
let im;
|
|
652
|
+
while ((im = INCLUDE_RE.exec(rawText))) {
|
|
653
|
+
if (!INCLUDABLE_EXT.test(im[1]))
|
|
654
|
+
continue;
|
|
655
|
+
const t = resolveInclude(file, im[1]);
|
|
656
|
+
if (t)
|
|
657
|
+
out.push(t);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
includeCache.set(file, out);
|
|
661
|
+
return out;
|
|
662
|
+
};
|
|
663
|
+
// A file's effective macro environment = its own #defines PLUS those of the
|
|
664
|
+
// headers it #includes (redis' `MAKE_CMD` sits beside the table; sqlite's
|
|
665
|
+
// `FUNCTION` lives in `sqliteInt.h`, included by the file with the table).
|
|
666
|
+
// First writer wins, so the file's own defs override included ones; depth-2
|
|
667
|
+
// covers a macro defined in a header-of-a-header.
|
|
668
|
+
const buildEnv = (file, depth, seen, fn, obj, def) => {
|
|
669
|
+
if (depth < 0 || seen.has(file))
|
|
670
|
+
return;
|
|
671
|
+
seen.add(file);
|
|
672
|
+
for (const [k, v] of fileFnMacros(file))
|
|
673
|
+
if (!fn.has(k))
|
|
674
|
+
fn.set(k, v);
|
|
675
|
+
for (const [k, v] of fileObjMacros(file))
|
|
676
|
+
if (!obj.has(k))
|
|
677
|
+
obj.set(k, v);
|
|
678
|
+
for (const n of fileDefinedNames(file))
|
|
679
|
+
def.add(n);
|
|
680
|
+
for (const inc of localIncludesOf(file))
|
|
681
|
+
buildEnv(inc, depth - 1, seen, fn, obj, def);
|
|
682
|
+
};
|
|
683
|
+
const indexedSet = new Set(files);
|
|
684
|
+
const units = [];
|
|
685
|
+
const seenInclude = new Set();
|
|
686
|
+
for (const file of files) {
|
|
687
|
+
const env = new Map();
|
|
688
|
+
const objEnv = new Map();
|
|
689
|
+
const defined = new Set();
|
|
690
|
+
buildEnv(file, 2, new Set(), env, objEnv, defined);
|
|
691
|
+
const s = src(file);
|
|
692
|
+
if (s)
|
|
693
|
+
units.push({ text: s, file, env, objEnv });
|
|
694
|
+
for (const target of localIncludesOf(file)) {
|
|
695
|
+
if (seenInclude.has(`${file}>${target}`))
|
|
696
|
+
continue;
|
|
697
|
+
const incSrc = src(target);
|
|
698
|
+
if (!incSrc)
|
|
699
|
+
continue;
|
|
700
|
+
if (indexedSet.has(target)) {
|
|
701
|
+
// Re-scan an indexed header only when this includer unlocks guarded code.
|
|
702
|
+
const ownDef = fileDefinedNames(target);
|
|
703
|
+
const adds = [...defined].some((n) => !ownDef.has(n));
|
|
704
|
+
if (!adds || !/#\s*if/.test(incSrc))
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
seenInclude.add(`${file}>${target}`);
|
|
708
|
+
// The include is pasted into the includer — evaluate its conditionals in
|
|
709
|
+
// the includer's defined set (a no-op when it has none). Re-parse the
|
|
710
|
+
// included file's OWN macros from that resolved text so a macro it defines
|
|
711
|
+
// conditionally (vim's `EXCMD`, whose plain last-wins parse picks the enum
|
|
712
|
+
// arm) overrides with the ARM THAT IS ACTUALLY ACTIVE here.
|
|
713
|
+
const text = evalConditionals(incSrc, defined);
|
|
714
|
+
const incEnv = new Map(env);
|
|
715
|
+
for (const [k, v] of parseFunctionMacros(text))
|
|
716
|
+
incEnv.set(k, v);
|
|
717
|
+
const incObjEnv = new Map(objEnv);
|
|
718
|
+
for (const [k, v] of parseObjectMacros(text))
|
|
719
|
+
incObjEnv.set(k, v);
|
|
720
|
+
units.push({ text, file: target, env: incEnv, objEnv: incObjEnv });
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
// Global variable → struct type, for resolving a dispatch through a file-scope
|
|
724
|
+
// table by subscript (`cmdnames[i].cmd_func(…)`).
|
|
725
|
+
const globalVarType = new Map();
|
|
726
|
+
// Process a `{ … }` initializer body (array of elements or a single struct).
|
|
727
|
+
const processInit = (struct, body, isArray, file, env) => {
|
|
728
|
+
if (isArray) {
|
|
729
|
+
for (const el of splitTopLevel(body, ',')) {
|
|
730
|
+
const t = el.trim();
|
|
731
|
+
if (t.startsWith('{')) {
|
|
732
|
+
const e = matchBrace(t, 0);
|
|
733
|
+
if (e > 0)
|
|
734
|
+
registerStructValue(struct, t.slice(1, e), file, env);
|
|
735
|
+
}
|
|
736
|
+
else if (t) {
|
|
737
|
+
// an element built by a macro (`MAKE_CMD(…)`/`FUNCTION(…)`) or a bare value
|
|
738
|
+
registerStructValue(struct, t, file, env);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
else {
|
|
743
|
+
registerStructValue(struct, body, file, env);
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
// `(?:struct )?TYPE name[opt] = {` initializers, where TYPE is a struct that
|
|
747
|
+
// has ≥1 fn-pointer field. Handles both single (`= {…}`) and array
|
|
748
|
+
// (`[] = { {…}, {…} }`) forms. Macro calls inside an element are expanded first.
|
|
749
|
+
const INIT_RE = /(?:^|[;{}])\s*(?:(?:static|const|extern|register|volatile)\s+)*(?:struct\s+)?(\w+)\s+(\w+)\s*(\[[^\]]*\])?\s*=\s*\{/g;
|
|
750
|
+
// `struct TAG { … } var[opt] [= {…}]` — the struct is defined INLINE with the
|
|
751
|
+
// table (vim's `cmdname`/`nv_cmd`); its layout never became a node, so parse it
|
|
752
|
+
// here and register it before reading the entries. No leading anchor: a
|
|
753
|
+
// `struct TAG {` with a brace body is always a definition (it may be preceded
|
|
754
|
+
// by a `#define …` line ending in a digit, as in vim), and the trailing
|
|
755
|
+
// `var … = {` check below is what distinguishes a TABLE from a plain type.
|
|
756
|
+
const INLINE_STRUCT_RE = /\bstruct\s+(\w+)\s*\{/g;
|
|
757
|
+
// `(?:static …)* ELEMTYPE [*] name[…] = { … }` — a bare array of function
|
|
758
|
+
// pointers (no struct wrapper). The optional `*` covers a function-TYPE
|
|
759
|
+
// typedef element (`opcode_t *opcodes[]`); a function-pointer typedef element
|
|
760
|
+
// (`zend_rc_dtor_func_t t[]`) needs none. The typedef-set membership gate
|
|
761
|
+
// (below) is what separates this from a plain data/struct array.
|
|
762
|
+
const ARRAY_TABLE_RE = /(?:^|[;{}])\s*(?:(?:static|const|extern|register|volatile)\s+)*(\w+)\s+(\*\s*)?(\w+)\s*\[[^\]]*\]\s*=\s*\{/g;
|
|
763
|
+
for (const unit of units) {
|
|
764
|
+
const s = unit.text;
|
|
765
|
+
if (!s || !s.includes('{'))
|
|
766
|
+
continue;
|
|
767
|
+
INLINE_STRUCT_RE.lastIndex = 0;
|
|
768
|
+
let im;
|
|
769
|
+
while ((im = INLINE_STRUCT_RE.exec(s))) {
|
|
770
|
+
const tag = im[1];
|
|
771
|
+
const sOpen = im.index + im[0].length - 1; // the struct body's `{`
|
|
772
|
+
const sClose = matchBrace(s, sOpen);
|
|
773
|
+
if (sClose < 0)
|
|
774
|
+
continue;
|
|
775
|
+
// After `}`, expect `var [opt] [= {…}]` to be a table; else it's a plain type.
|
|
776
|
+
const after = s.slice(sClose + 1);
|
|
777
|
+
const vm = after.match(/^\s*(\w+)\s*(\[[^\]]*\])?\s*(=\s*\{)?/);
|
|
778
|
+
if (!vm || !vm[1])
|
|
779
|
+
continue;
|
|
780
|
+
const fields = parseStructFields(s.slice(sOpen + 1, sClose));
|
|
781
|
+
if (!fields.some((f) => f.isFnPtr))
|
|
782
|
+
continue; // only tables of fn pointers matter
|
|
783
|
+
if (!structLayout.has(tag))
|
|
784
|
+
registerStructLayout(tag, fields);
|
|
785
|
+
globalVarType.set(vm[1], tag);
|
|
786
|
+
if (vm[3]) {
|
|
787
|
+
const aOpen = sClose + 1 + after.indexOf('{', vm[0].length - 1);
|
|
788
|
+
const aClose = matchBrace(s, aOpen);
|
|
789
|
+
if (aClose > 0) {
|
|
790
|
+
processInit(tag, s.slice(aOpen + 1, aClose), !!vm[2], unit.file, unit.env);
|
|
791
|
+
INLINE_STRUCT_RE.lastIndex = aClose;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
if (!s.includes('='))
|
|
796
|
+
continue;
|
|
797
|
+
INIT_RE.lastIndex = 0;
|
|
798
|
+
let m;
|
|
799
|
+
while ((m = INIT_RE.exec(s))) {
|
|
800
|
+
let struct = m[1];
|
|
801
|
+
if (!structLayout.has(struct))
|
|
802
|
+
struct = resolveTypeName(struct, unit.objEnv);
|
|
803
|
+
if (!structLayout.has(struct))
|
|
804
|
+
continue;
|
|
805
|
+
const isArray = !!m[3];
|
|
806
|
+
const open = m.index + m[0].length - 1; // points at the `{`
|
|
807
|
+
const close = matchBrace(s, open);
|
|
808
|
+
if (close < 0)
|
|
809
|
+
continue;
|
|
810
|
+
globalVarType.set(m[2], struct);
|
|
811
|
+
processInit(struct, s.slice(open + 1, close), isArray, unit.file, unit.env);
|
|
812
|
+
INIT_RE.lastIndex = close;
|
|
813
|
+
}
|
|
814
|
+
// Bare arrays-of-function-pointers (no struct, no field). Gated on the
|
|
815
|
+
// element type being a function typedef — a fn-TYPE typedef needs the `*`
|
|
816
|
+
// (array of pointers to it), a fn-pointer typedef does not. A data or
|
|
817
|
+
// struct array's element type is never in these sets, so it never fires.
|
|
818
|
+
ARRAY_TABLE_RE.lastIndex = 0;
|
|
819
|
+
let am;
|
|
820
|
+
while ((am = ARRAY_TABLE_RE.exec(s))) {
|
|
821
|
+
const elemType = am[1];
|
|
822
|
+
const hasStar = !!am[2];
|
|
823
|
+
if (!((fnTypeTypedefs.has(elemType) && hasStar) || fnPtrTypedefs.has(elemType)))
|
|
824
|
+
continue;
|
|
825
|
+
const open = am.index + am[0].length - 1; // the `{`
|
|
826
|
+
const close = matchBrace(s, open);
|
|
827
|
+
if (close < 0)
|
|
828
|
+
continue;
|
|
829
|
+
registerArrayValue(am[3], s.slice(open + 1, close), unit.file, unit.env);
|
|
830
|
+
ARRAY_TABLE_RE.lastIndex = close;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
// ---- receiver-type resolution within a function's source ----
|
|
834
|
+
// `(?:struct )?TYPE [*]recv` declared in the params or body → TYPE (if a known
|
|
835
|
+
// fn-pointer-bearing struct).
|
|
836
|
+
const recvTypeIn = (fnSrc, recv) => {
|
|
837
|
+
const re = new RegExp(`(?:struct\\s+)?(\\w+)\\s*\\*?\\s*\\b${recv}\\b\\s*(?:[,)=;]|\\[)`, 'g');
|
|
838
|
+
let m;
|
|
839
|
+
while ((m = re.exec(fnSrc))) {
|
|
840
|
+
if (structLayout.has(m[1]))
|
|
841
|
+
return m[1];
|
|
842
|
+
}
|
|
843
|
+
return null;
|
|
844
|
+
};
|
|
845
|
+
// Declared type of a local/param `v` — ANY type token, not just fn-pointer
|
|
846
|
+
// structs (the base of a chained receiver needn't carry a fn pointer itself).
|
|
847
|
+
// Falls back to a file-scope table variable (`cmdnames` in `cmdnames[i].fn()`).
|
|
848
|
+
const escapeRe = (x) => x.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
849
|
+
const varTypeIn = (fnSrc, v) => {
|
|
850
|
+
const re = new RegExp(`(?:struct\\s+)?(\\w+)\\s*\\*?\\s*\\b${escapeRe(v)}\\b\\s*(?:[,)=;]|\\[)`, 'g');
|
|
851
|
+
let m;
|
|
852
|
+
while ((m = re.exec(fnSrc))) {
|
|
853
|
+
if (!C_TYPE_KEYWORDS.has(m[1]))
|
|
854
|
+
return m[1];
|
|
855
|
+
}
|
|
856
|
+
return globalVarType.get(v) ?? null;
|
|
857
|
+
};
|
|
858
|
+
// Resolve a member-access chain (`c->cmd`, or just `p`) to a struct type,
|
|
859
|
+
// walking each segment's declared field type. `c->cmd->proc` dispatch:
|
|
860
|
+
// base chain `c->cmd` → client.cmd's type `redisCommand`, the proc owner.
|
|
861
|
+
// Array subscripts (`cmdnames[i]`) are stripped — an index yields one element.
|
|
862
|
+
const resolveChainType = (fnSrc, chain) => {
|
|
863
|
+
const segs = chain.replace(/\s*\[[^\]]*\]/g, '').split(/\s*(?:->|\.)\s*/).filter(Boolean);
|
|
864
|
+
if (segs.length === 0)
|
|
865
|
+
return null;
|
|
866
|
+
let t = varTypeIn(fnSrc, segs[0]);
|
|
867
|
+
for (let i = 1; t && i < segs.length; i++) {
|
|
868
|
+
let next = null;
|
|
869
|
+
for (const fields of allStructFields.get(t) ?? []) {
|
|
870
|
+
const f = fields.find((fl) => fl.name === segs[i] && fl.type);
|
|
871
|
+
if (f) {
|
|
872
|
+
next = f.type;
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
t = next;
|
|
877
|
+
}
|
|
878
|
+
return t;
|
|
879
|
+
};
|
|
880
|
+
// ---- Pass D: field←field propagation (`a->f = b->g`) ----
|
|
881
|
+
// Collected as (targetStruct.field ← sourceStruct.field) pairs, then merged to
|
|
882
|
+
// a fixpoint so a hook slot inherits a registry field's handlers.
|
|
883
|
+
const FIELD_ASSIGN_RE = /(\w+)\s*(?:->|\.)\s*(\w+)\s*=\s*(\w+)\s*(?:->|\.)\s*(\w+)/g;
|
|
884
|
+
const propagations = [];
|
|
885
|
+
for (const fn of cFns) {
|
|
886
|
+
const s = srcCache.get(fn.filePath);
|
|
887
|
+
if (!s)
|
|
888
|
+
continue;
|
|
889
|
+
const body = sliceLines(s, fn.startLine, fn.endLine);
|
|
890
|
+
if (!body.includes('='))
|
|
891
|
+
continue;
|
|
892
|
+
FIELD_ASSIGN_RE.lastIndex = 0;
|
|
893
|
+
let m;
|
|
894
|
+
while ((m = FIELD_ASSIGN_RE.exec(body))) {
|
|
895
|
+
const [, lrecv, lfield, rrecv, rfield] = m;
|
|
896
|
+
const lt = recvTypeIn(body, lrecv);
|
|
897
|
+
const rt = recvTypeIn(body, rrecv);
|
|
898
|
+
if (lt && rt && fnPtrFieldOf(lt, lfield) && fnPtrFieldOf(rt, rfield)) {
|
|
899
|
+
propagations.push({ to: `${lt}.${lfield}`, from: `${rt}.${rfield}` });
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
for (let pass = 0; pass < 3 && propagations.length; pass++) {
|
|
904
|
+
let changed = false;
|
|
905
|
+
for (const { to, from } of propagations) {
|
|
906
|
+
const fromSet = reg.get(from);
|
|
907
|
+
if (!fromSet)
|
|
908
|
+
continue;
|
|
909
|
+
if (!reg.has(to))
|
|
910
|
+
reg.set(to, new Set());
|
|
911
|
+
const toSet = reg.get(to);
|
|
912
|
+
for (const id of fromSet) {
|
|
913
|
+
if (!toSet.has(id)) {
|
|
914
|
+
toSet.add(id);
|
|
915
|
+
changed = true;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (!changed)
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
if (reg.size === 0 && arrayReg.size === 0)
|
|
923
|
+
return [];
|
|
924
|
+
// ---- Pass E: dispatch sites → edges ----
|
|
925
|
+
// `base->…->field(` or `base.…field(` where `field` is a known fn-pointer field.
|
|
926
|
+
// The base may be a chain (`c->cmd->proc`) or carry array subscripts
|
|
927
|
+
// (`cmdnames[i].cmd_func`). An optional `)` before the call covers the
|
|
928
|
+
// parenthesized form `(cmdnames[i].cmd_func)(&ea)` vim uses.
|
|
929
|
+
const DISPATCH_RE = /((?:\w+(?:\s*\[[^\][]*\])?\s*(?:->|\.)\s*)+)(\w+)\s*\)?\s*\(/g;
|
|
930
|
+
// Bare-array dispatch: `tbl[i](…)` or the explicit-deref `(*tbl[i])(…)`. The
|
|
931
|
+
// subscript may itself contain a call (`tbl[GC_TYPE(p)](…)`), so the index
|
|
932
|
+
// class excludes only brackets. Precision comes from the `arrayReg` gate below
|
|
933
|
+
// — this fires only when `tbl` is a known fn-pointer array.
|
|
934
|
+
const ARRAY_DISPATCH_RE = /(?:\(\s*\*\s*)?\b(\w+)\s*\[[^\][]*\]\s*\)?\s*\(/g;
|
|
935
|
+
const edges = [];
|
|
936
|
+
const seen = new Set();
|
|
937
|
+
for (const fn of cFns) {
|
|
938
|
+
const s = srcCache.get(fn.filePath);
|
|
939
|
+
if (!s)
|
|
940
|
+
continue;
|
|
941
|
+
const body = sliceLines(s, fn.startLine, fn.endLine);
|
|
942
|
+
DISPATCH_RE.lastIndex = 0;
|
|
943
|
+
let m;
|
|
944
|
+
let added = 0;
|
|
945
|
+
while ((m = DISPATCH_RE.exec(body)) && added < FANOUT_CAP) {
|
|
946
|
+
const baseChain = m[1].replace(/\s*(?:->|\.)\s*$/, '').trim(); // receiver, minus the trailing arrow
|
|
947
|
+
const field = m[2];
|
|
948
|
+
const owners = fieldToStructs.get(field);
|
|
949
|
+
if (!owners || owners.size === 0)
|
|
950
|
+
continue;
|
|
951
|
+
// 1) resolve the receiver chain's struct type precisely (handles c->cmd->proc);
|
|
952
|
+
// 2) else the last segment as a simple local/param of a fn-pointer-bearing struct;
|
|
953
|
+
// 3) else fall back to a field name that belongs to exactly one struct.
|
|
954
|
+
let struct = resolveChainType(body, baseChain);
|
|
955
|
+
if (!struct || !owners.has(struct)) {
|
|
956
|
+
const lastSeg = baseChain.replace(/\s*\[[^\]]*\]/g, '').split(/\s*(?:->|\.)\s*/).pop();
|
|
957
|
+
const t = recvTypeIn(body, lastSeg);
|
|
958
|
+
struct = t && owners.has(t) ? t : null;
|
|
959
|
+
}
|
|
960
|
+
if (!struct || !owners.has(struct))
|
|
961
|
+
struct = owners.size === 1 ? [...owners][0] : null;
|
|
962
|
+
if (!struct)
|
|
963
|
+
continue;
|
|
964
|
+
const targets = reg.get(`${struct}.${field}`);
|
|
965
|
+
if (!targets)
|
|
966
|
+
continue;
|
|
967
|
+
const line = fn.startLine + body.slice(0, m.index).split('\n').length - 1;
|
|
968
|
+
for (const tid of targets) {
|
|
969
|
+
if (tid === fn.id)
|
|
970
|
+
continue;
|
|
971
|
+
const key = `${fn.id}>${tid}`;
|
|
972
|
+
if (seen.has(key))
|
|
973
|
+
continue;
|
|
974
|
+
seen.add(key);
|
|
975
|
+
edges.push({
|
|
976
|
+
source: fn.id,
|
|
977
|
+
target: tid,
|
|
978
|
+
kind: 'calls',
|
|
979
|
+
line,
|
|
980
|
+
provenance: 'heuristic',
|
|
981
|
+
metadata: {
|
|
982
|
+
synthesizedBy: 'fn-pointer-dispatch',
|
|
983
|
+
via: `${struct}.${field}`,
|
|
984
|
+
registeredAt: `${fn.filePath}:${line}`,
|
|
985
|
+
},
|
|
986
|
+
});
|
|
987
|
+
if (++added >= FANOUT_CAP)
|
|
988
|
+
break;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
// ---- bare array-of-fn-pointers dispatch (`tbl[i](…)`) ----
|
|
992
|
+
if (arrayReg.size && added < FANOUT_CAP) {
|
|
993
|
+
ARRAY_DISPATCH_RE.lastIndex = 0;
|
|
994
|
+
while ((m = ARRAY_DISPATCH_RE.exec(body)) && added < FANOUT_CAP) {
|
|
995
|
+
const entries = arrayReg.get(m[1]);
|
|
996
|
+
if (!entries)
|
|
997
|
+
continue;
|
|
998
|
+
// Same-file table wins on a name collision (two file-local `opcodes`);
|
|
999
|
+
// a unique name resolves cross-file; otherwise ambiguous — bail.
|
|
1000
|
+
const ids = entries.length === 1
|
|
1001
|
+
? entries[0].ids
|
|
1002
|
+
: (entries.find((e) => e.file === fn.filePath)?.ids ?? null);
|
|
1003
|
+
if (!ids)
|
|
1004
|
+
continue;
|
|
1005
|
+
const line = fn.startLine + body.slice(0, m.index).split('\n').length - 1;
|
|
1006
|
+
for (const tid of ids) {
|
|
1007
|
+
if (tid === fn.id)
|
|
1008
|
+
continue;
|
|
1009
|
+
const key = `${fn.id}>${tid}`;
|
|
1010
|
+
if (seen.has(key))
|
|
1011
|
+
continue;
|
|
1012
|
+
seen.add(key);
|
|
1013
|
+
edges.push({
|
|
1014
|
+
source: fn.id,
|
|
1015
|
+
target: tid,
|
|
1016
|
+
kind: 'calls',
|
|
1017
|
+
line,
|
|
1018
|
+
provenance: 'heuristic',
|
|
1019
|
+
metadata: {
|
|
1020
|
+
synthesizedBy: 'fn-pointer-dispatch',
|
|
1021
|
+
via: `${m[1]}[]`,
|
|
1022
|
+
registeredAt: `${fn.filePath}:${line}`,
|
|
1023
|
+
},
|
|
1024
|
+
});
|
|
1025
|
+
if (++added >= FANOUT_CAP)
|
|
1026
|
+
break;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
return edges;
|
|
1032
|
+
}
|
|
1033
|
+
/** C/C++ function + method nodes, streamed (memory-safe on symbol-dense repos). */
|
|
1034
|
+
function* iterateFns(queries) {
|
|
1035
|
+
yield* queries.iterateNodesByKind('function');
|
|
1036
|
+
yield* queries.iterateNodesByKind('method');
|
|
1037
|
+
}
|
|
1038
|
+
//# sourceMappingURL=c-fnptr-synthesizer.js.map
|