gitnexus 1.6.5-rc.8 → 1.6.5
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/dist/_shared/scope-resolution/finalize-algorithm.js +10 -2
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +26 -0
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/method-dispatch-index.js +22 -3
- package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js +18 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +2 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +70 -16
- package/dist/cli/analyze.d.ts +30 -2
- package/dist/cli/analyze.js +45 -5
- package/dist/cli/index.js +8 -1
- package/dist/cli/setup.js +18 -0
- package/dist/cli/wiki.d.ts +2 -0
- package/dist/cli/wiki.js +11 -0
- package/dist/core/augmentation/engine.js +24 -4
- package/dist/core/embeddings/http-client.js +22 -6
- package/dist/core/incremental/shadow-candidates.d.ts +44 -0
- package/dist/core/incremental/shadow-candidates.js +74 -0
- package/dist/core/incremental/subgraph-extract.d.ts +64 -0
- package/dist/core/incremental/subgraph-extract.js +111 -0
- package/dist/core/ingestion/call-processor.d.ts +12 -1
- package/dist/core/ingestion/call-processor.js +183 -47
- package/dist/core/ingestion/class-extractors/configs/c-cpp.js +38 -0
- package/dist/core/ingestion/class-extractors/generic.js +8 -0
- package/dist/core/ingestion/class-types.d.ts +15 -0
- package/dist/core/ingestion/community-processor.js +18 -0
- package/dist/core/ingestion/import-resolvers/standard.d.ts +5 -0
- package/dist/core/ingestion/import-resolvers/standard.js +31 -1
- package/dist/core/ingestion/import-resolvers/utils.js +4 -0
- package/dist/core/ingestion/languages/c-cpp.js +20 -2
- package/dist/core/ingestion/languages/cpp/adl.d.ts +141 -0
- package/dist/core/ingestion/languages/cpp/adl.js +478 -0
- package/dist/core/ingestion/languages/cpp/arity-metadata.d.ts +18 -0
- package/dist/core/ingestion/languages/cpp/arity-metadata.js +170 -0
- package/dist/core/ingestion/languages/cpp/arity.d.ts +17 -0
- package/dist/core/ingestion/languages/cpp/arity.js +31 -0
- package/dist/core/ingestion/languages/cpp/captures.d.ts +2 -0
- package/dist/core/ingestion/languages/cpp/captures.js +1131 -0
- package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +31 -0
- package/dist/core/ingestion/languages/cpp/conversion-rank.js +47 -0
- package/dist/core/ingestion/languages/cpp/file-local-linkage.d.ts +118 -0
- package/dist/core/ingestion/languages/cpp/file-local-linkage.js +266 -0
- package/dist/core/ingestion/languages/cpp/header-scan.d.ts +8 -0
- package/dist/core/ingestion/languages/cpp/header-scan.js +50 -0
- package/dist/core/ingestion/languages/cpp/import-decomposer.d.ts +19 -0
- package/dist/core/ingestion/languages/cpp/import-decomposer.js +111 -0
- package/dist/core/ingestion/languages/cpp/import-target.d.ts +10 -0
- package/dist/core/ingestion/languages/cpp/import-target.js +13 -0
- package/dist/core/ingestion/languages/cpp/index.d.ts +11 -0
- package/dist/core/ingestion/languages/cpp/index.js +11 -0
- package/dist/core/ingestion/languages/cpp/inline-namespaces.d.ts +67 -0
- package/dist/core/ingestion/languages/cpp/inline-namespaces.js +176 -0
- package/dist/core/ingestion/languages/cpp/interpret.d.ts +35 -0
- package/dist/core/ingestion/languages/cpp/interpret.js +113 -0
- package/dist/core/ingestion/languages/cpp/merge-bindings.d.ts +13 -0
- package/dist/core/ingestion/languages/cpp/merge-bindings.js +29 -0
- package/dist/core/ingestion/languages/cpp/query.d.ts +3 -0
- package/dist/core/ingestion/languages/cpp/query.js +508 -0
- package/dist/core/ingestion/languages/cpp/range-bindings.d.ts +20 -0
- package/dist/core/ingestion/languages/cpp/range-bindings.js +212 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.d.ts +17 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +246 -0
- package/dist/core/ingestion/languages/cpp/simple-hooks.d.ts +24 -0
- package/dist/core/ingestion/languages/cpp/simple-hooks.js +62 -0
- package/dist/core/ingestion/languages/cpp/two-phase-lookup.d.ts +76 -0
- package/dist/core/ingestion/languages/cpp/two-phase-lookup.js +195 -0
- package/dist/core/ingestion/languages/java/arity-metadata.d.ts +18 -0
- package/dist/core/ingestion/languages/java/arity-metadata.js +40 -0
- package/dist/core/ingestion/languages/java/arity.d.ts +10 -0
- package/dist/core/ingestion/languages/java/arity.js +24 -0
- package/dist/core/ingestion/languages/java/cache-stats.d.ts +15 -0
- package/dist/core/ingestion/languages/java/cache-stats.js +26 -0
- package/dist/core/ingestion/languages/java/captures.d.ts +17 -0
- package/dist/core/ingestion/languages/java/captures.js +187 -0
- package/dist/core/ingestion/languages/java/import-decomposer.d.ts +18 -0
- package/dist/core/ingestion/languages/java/import-decomposer.js +85 -0
- package/dist/core/ingestion/languages/java/import-target.d.ts +17 -0
- package/dist/core/ingestion/languages/java/import-target.js +100 -0
- package/dist/core/ingestion/languages/java/index.d.ts +29 -0
- package/dist/core/ingestion/languages/java/index.js +29 -0
- package/dist/core/ingestion/languages/java/interpret.d.ts +13 -0
- package/dist/core/ingestion/languages/java/interpret.js +131 -0
- package/dist/core/ingestion/languages/java/merge-bindings.d.ts +12 -0
- package/dist/core/ingestion/languages/java/merge-bindings.js +40 -0
- package/dist/core/ingestion/languages/java/query.d.ts +30 -0
- package/dist/core/ingestion/languages/java/query.js +192 -0
- package/dist/core/ingestion/languages/java/receiver-binding.d.ts +11 -0
- package/dist/core/ingestion/languages/java/receiver-binding.js +95 -0
- package/dist/core/ingestion/languages/java/scope-resolver.d.ts +50 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +74 -0
- package/dist/core/ingestion/languages/java/simple-hooks.d.ts +13 -0
- package/dist/core/ingestion/languages/java/simple-hooks.js +34 -0
- package/dist/core/ingestion/languages/java.js +11 -0
- package/dist/core/ingestion/languages/php/arity-metadata.d.ts +28 -0
- package/dist/core/ingestion/languages/php/arity-metadata.js +63 -0
- package/dist/core/ingestion/languages/php/arity.d.ts +25 -0
- package/dist/core/ingestion/languages/php/arity.js +40 -0
- package/dist/core/ingestion/languages/php/cache-stats.d.ts +15 -0
- package/dist/core/ingestion/languages/php/cache-stats.js +26 -0
- package/dist/core/ingestion/languages/php/captures.d.ts +34 -0
- package/dist/core/ingestion/languages/php/captures.js +739 -0
- package/dist/core/ingestion/languages/php/import-decomposer.d.ts +28 -0
- package/dist/core/ingestion/languages/php/import-decomposer.js +265 -0
- package/dist/core/ingestion/languages/php/import-target.d.ts +47 -0
- package/dist/core/ingestion/languages/php/import-target.js +100 -0
- package/dist/core/ingestion/languages/php/index.d.ts +68 -0
- package/dist/core/ingestion/languages/php/index.js +72 -0
- package/dist/core/ingestion/languages/php/interpret.d.ts +36 -0
- package/dist/core/ingestion/languages/php/interpret.js +241 -0
- package/dist/core/ingestion/languages/php/merge-bindings.d.ts +19 -0
- package/dist/core/ingestion/languages/php/merge-bindings.js +47 -0
- package/dist/core/ingestion/languages/php/namespace-siblings.d.ts +51 -0
- package/dist/core/ingestion/languages/php/namespace-siblings.js +288 -0
- package/dist/core/ingestion/languages/php/query.d.ts +32 -0
- package/dist/core/ingestion/languages/php/query.js +326 -0
- package/dist/core/ingestion/languages/php/receiver-binding.d.ts +36 -0
- package/dist/core/ingestion/languages/php/receiver-binding.js +128 -0
- package/dist/core/ingestion/languages/php/scope-resolver.d.ts +23 -0
- package/dist/core/ingestion/languages/php/scope-resolver.js +358 -0
- package/dist/core/ingestion/languages/php/simple-hooks.d.ts +42 -0
- package/dist/core/ingestion/languages/php/simple-hooks.js +111 -0
- package/dist/core/ingestion/languages/php.d.ts +0 -7
- package/dist/core/ingestion/languages/php.js +15 -0
- package/dist/core/ingestion/markdown-processor.js +6 -1
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
- package/dist/core/ingestion/model/symbol-table.js +3 -0
- package/dist/core/ingestion/parsing-processor.d.ts +22 -2
- package/dist/core/ingestion/parsing-processor.js +123 -50
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +54 -2
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +5 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +119 -11
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +14 -0
- package/dist/core/ingestion/pipeline.d.ts +13 -0
- package/dist/core/ingestion/registry-primary-flag.js +2 -0
- package/dist/core/ingestion/scope-extractor.js +4 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +167 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +3 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +1 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +12 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.d.ts +1 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +12 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +16 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +36 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +204 -13
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +1 -1
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +55 -4
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +186 -5
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +10 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +207 -9
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +13 -1
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +6 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +17 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +86 -8
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +30 -0
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +90 -8
- package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
- package/dist/core/ingestion/tree-sitter-queries.js +23 -0
- package/dist/core/ingestion/utils/ast-helpers.js +6 -1
- package/dist/core/ingestion/utils/template-arguments.d.ts +11 -0
- package/dist/core/ingestion/utils/template-arguments.js +65 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +3 -0
- package/dist/core/ingestion/workers/parse-worker.js +42 -1
- package/dist/core/lbug/lbug-adapter.d.ts +39 -0
- package/dist/core/lbug/lbug-adapter.js +348 -48
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +323 -29
- package/dist/core/search/hybrid-search.d.ts +3 -0
- package/dist/core/search/hybrid-search.js +23 -6
- package/dist/core/wiki/generator.js +4 -3
- package/dist/core/wiki/html-viewer.js +2 -1
- package/dist/core/wiki/llm-client.d.ts +4 -0
- package/dist/core/wiki/llm-client.js +3 -3
- package/dist/core/wiki/mermaid-sanitizer.d.ts +2 -0
- package/dist/core/wiki/mermaid-sanitizer.js +100 -0
- package/dist/mcp/local/local-backend.js +20 -7
- package/dist/storage/file-hash.d.ts +47 -0
- package/dist/storage/file-hash.js +86 -0
- package/dist/storage/parse-cache.d.ts +73 -0
- package/dist/storage/parse-cache.js +253 -0
- package/dist/storage/repo-manager.d.ts +41 -1
- package/dist/storage/repo-manager.js +61 -6
- package/hooks/claude/gitnexus-hook.cjs +42 -4
- package/hooks/claude/hook-db-lock-probe.cjs +238 -0
- package/hooks/claude/hook-lock.cjs +119 -0
- package/hooks/claude/win-rm-list-json.ps1 +76 -0
- package/package.json +1 -1
- package/scripts/build.js +6 -2
- package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +16 -16
- package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +16 -16
- package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +16 -16
- package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +16 -16
- package/web/assets/{agent-BpHQleHE.js → agent-D2kLt6Dl.js} +91 -91
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-DvIkEGkp.js +36 -0
- package/web/assets/blockDiagram-7IZFK4PR-B4niSLvR.js +132 -0
- package/web/assets/{c4Diagram-DFAF54RM-DeJV1rCn.js → c4Diagram-Y2BXMSZH-DIzEXalR.js} +6 -6
- package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +4 -0
- package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +1 -0
- package/web/assets/{chunk-7RZVMHOQ-BdIU-RGO.js → chunk-3SSMPTDK-BzGeeheI.js} +1 -1
- package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +159 -0
- package/web/assets/chunk-5IMINLNL-CnTLsXIV.js +1 -0
- package/web/assets/chunk-5VCL7Z4A-w1BCx98Z.js +1 -0
- package/web/assets/chunk-6764PJDD-ChwMM2z4.js +1 -0
- package/web/assets/chunk-67TQ5CYL-CChC2cAv.js +124 -0
- package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +10 -0
- package/web/assets/chunk-7W6UQGC5-CgFyfZ6k.js +1 -0
- package/web/assets/chunk-AQ6EADP3-CCFje6lL.js +1 -0
- package/web/assets/{chunk-KSICW3F5-C2tZmXwv.js → chunk-AZZRMDJM-5E9ARdDQ.js} +1 -1
- package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +1 -0
- package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +1 -0
- package/web/assets/chunk-INKRHTLW-ELpfuk9h.js +70 -0
- package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +1 -0
- package/web/assets/{chunk-AEOMTBSW-D7qjBMHW.js → chunk-JQRUD6KW-Dcq_Qnyy.js} +1 -1
- package/web/assets/chunk-KGFNY3KK-W-VR57xb.js +62 -0
- package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +1 -0
- package/web/assets/chunk-KNLZD3CH-BuZBOcso.js +1 -0
- package/web/assets/chunk-KRXBNO2N-DH2NPM7I.js +1 -0
- package/web/assets/chunk-LCXTWHL2-CqJ0oo1x.js +231 -0
- package/web/assets/chunk-LII3EMHJ-3X33tCpU.js +1 -0
- package/web/assets/chunk-QA3QBVWF-D5Ha3GgB.js +2 -0
- package/web/assets/chunk-RERM46MO-DQNbXtfw.js +1 -0
- package/web/assets/chunk-RG4AUYOV-D0M6vdq9.js +206 -0
- package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +1 -0
- package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +1 -0
- package/web/assets/chunk-T2UQINTJ-kGYG7ppP.js +1 -0
- package/web/assets/chunk-T5OCTHI4--9wWpVws.js +1 -0
- package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +1 -0
- package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +1 -0
- package/web/assets/chunk-UY5QBCOK-Du-c56gs.js +1 -0
- package/web/assets/chunk-W44A43WB-lrCpuupA.js +1 -0
- package/web/assets/chunk-ZXARS5L4-CSZRiyOf.js +1 -0
- package/web/assets/classDiagram-KGZ6W3CR-BB-saqC1.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-Bp2bAlS5.js +1 -0
- package/web/assets/cose-bilkent-UX7MHV2Q-BHv2bbtl.js +1 -0
- package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +4 -0
- package/web/assets/diagram-3NCE3AQN-BUxnDPOY.js +43 -0
- package/web/assets/diagram-GF46GFSD-BJTyqqvI.js +24 -0
- package/web/assets/diagram-HNR7UZ2L-fUWreZzx.js +3 -0
- package/web/assets/diagram-QXG6HAR7-DilMHamP.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-8KUrarg1.js +10 -0
- package/web/assets/erDiagram-L5TCEMPS-Doj9mSiW.js +85 -0
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +1 -0
- package/web/assets/{flowDiagram-OTCZ4VVT-aAZw4c_M.js → flowDiagram-H6V6AXG4-BOSR-i3p.js} +12 -12
- package/web/assets/ganttDiagram-JCBTUEKG-BHQssTz6.js +292 -0
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +106 -0
- package/web/assets/index-j4-NuleT.js +623 -0
- package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-Ce_TvtaV.js +2 -0
- package/web/assets/{ishikawaDiagram-YMYX4NHK-BF8AtDaj.js → ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js} +6 -6
- package/web/assets/journeyDiagram-M6C3CM3L-DNPYCpvq.js +139 -0
- package/web/assets/kanban-definition-75IXJCU3-yYdfm8Kk.js +89 -0
- package/web/assets/{katex-GD7MH7QM-CJiOjBBJ.js → katex-K3KEBU37-CrVLz8l7.js} +1 -1
- package/web/assets/mindmap-definition-2TDM6QVE-DFNEKM77.js +96 -0
- package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +1 -0
- package/web/assets/pieDiagram-CU6KROY3-iZAqpvhd.js +30 -0
- package/web/assets/quadrantDiagram-VICAPDV7-bAm6Hi_5.js +7 -0
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +1 -0
- package/web/assets/requirementDiagram-JXO7QTGE-CtDijhnf.js +84 -0
- package/web/assets/sankeyDiagram-URQDO5SZ-LFJz53u5.js +40 -0
- package/web/assets/sequenceDiagram-VS2MUI6T-BdjvyCHM.js +162 -0
- package/web/assets/stateDiagram-7D4R322I-e5odN9fG.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-vPsvjR2D.js +1 -0
- package/web/assets/timeline-definition-O6YCAMPW-DPAksNQp.js +120 -0
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +1 -0
- package/web/assets/vennDiagram-MWXL3ELB-Dtlfdt7J.js +34 -0
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +1 -0
- package/web/assets/wardleyDiagram-CUQ6CDDI-B23uRMUC.js +78 -0
- package/web/assets/{xychartDiagram-ZHJ5623Y-DZ7fP1_3.js → xychartDiagram-N2JHSOCM-DxwHeksW.js} +6 -6
- package/web/index.html +13 -2
- package/web/assets/architecture-YZFGNWBL-S5CXDPWN-BUzkWgDl.js +0 -1
- package/web/assets/architectureDiagram-EMZXCZ2Q-CXbzok1G.js +0 -36
- package/web/assets/blockDiagram-IGV67L2C-DA1QJ4ZB.js +0 -132
- package/web/assets/chunk-3GS5O3IE-B8hpnia8.js +0 -231
- package/web/assets/chunk-3YCYZ6SJ-B-BVu21C.js +0 -1
- package/web/assets/chunk-6NTNNK5N-DW-jYSDr.js +0 -1
- package/web/assets/chunk-A34GCYZU-BbZl-IKy.js +0 -1
- package/web/assets/chunk-DJ7UZH7F-B5tMfF87.js +0 -1
- package/web/assets/chunk-DKKBVRCY-Djm-6K_e.js +0 -4
- package/web/assets/chunk-DU5LTGQ6-QPoynYcp.js +0 -1
- package/web/assets/chunk-FXACKDTF-jieSmbe2.js +0 -159
- package/web/assets/chunk-H3VCZNTA-8EMHZ3SV.js +0 -1
- package/web/assets/chunk-HN6EAY2L-CgE_agsD.js +0 -1
- package/web/assets/chunk-O5ABG6QK-DEZV1O19.js +0 -1
- package/web/assets/chunk-PK6DOVAG-BXv0JnsJ.js +0 -206
- package/web/assets/chunk-RNJOYNJ4-BiBkF9dN.js +0 -1
- package/web/assets/chunk-RWUO3TPN-DTWzAhQ1.js +0 -1
- package/web/assets/chunk-TBF5ZNIQ-BSl6s9lT.js +0 -1
- package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +0 -1
- package/web/assets/chunk-TYMNRAUI-D1NDLIMG.js +0 -1
- package/web/assets/chunk-VELTKBKT-C9dVN39o.js +0 -1
- package/web/assets/chunk-W7ZLLLMY-Bu-cdLzs.js +0 -1
- package/web/assets/chunk-WSB5WSVC-Dor71SOz.js +0 -1
- package/web/assets/chunk-XGPFEOL4-CUonLRle.js +0 -1
- package/web/assets/classDiagram-PPOCWD7C-Cdd6UdVv.js +0 -1
- package/web/assets/classDiagram-v2-23LJLIIU-DNhxY2Ib.js +0 -1
- package/web/assets/cose-bilkent-PNC4W37J-DdZq7Qz_.js +0 -1
- package/web/assets/dagre-E77IOHMT-Cfj_6e17.js +0 -4
- package/web/assets/diagram-H7BISOXX-BNvpsrBv.js +0 -43
- package/web/assets/diagram-JC5VWROH-Cn0rtDbJ.js +0 -24
- package/web/assets/diagram-LXUTUG65-CHfoVKNm.js +0 -10
- package/web/assets/diagram-WEHSV5V5-BLxHksnu.js +0 -24
- package/web/assets/erDiagram-GCSMX5X6-DfdN6iqF.js +0 -85
- package/web/assets/ganttDiagram-MUNLMDZQ-BEfC_7Or.js +0 -292
- package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-B6ZeRLP0.js +0 -1
- package/web/assets/gitGraphDiagram-3HKGZ4G3-CG0kC8Q5.js +0 -106
- package/web/assets/index-3NUCUW2s.js +0 -886
- package/web/assets/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +0 -1
- package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +0 -2
- package/web/assets/journeyDiagram-SO5T7YLQ-BW8oKa3N.js +0 -139
- package/web/assets/kanban-definition-LJHFXRCJ-DzbOsR-2.js +0 -89
- package/web/assets/mindmap-definition-2EUWGEK5-BIXGQALq.js +0 -96
- package/web/assets/packet-4T2RLAQJ-EV4IVRXR-Bs7ysNMU.js +0 -1
- package/web/assets/pie-ZZUOXDRM-N23DN5KN-Csi8nnbH.js +0 -1
- package/web/assets/pieDiagram-3IATQBI2-QY-u7P6a.js +0 -30
- package/web/assets/quadrantDiagram-E256RVCF-Di4aNiU8.js +0 -7
- package/web/assets/radar-PYXPWWZC-P6TP7ZYP-DJlyXh2-.js +0 -1
- package/web/assets/requirementDiagram-M5DCFWZL-CzUUrhQD.js +0 -84
- package/web/assets/sankeyDiagram-L3NBLAOT-D2fbMiIU.js +0 -10
- package/web/assets/sequenceDiagram-ZOUHS735-BNdkqguh.js +0 -157
- package/web/assets/stateDiagram-MLPALWAM-51_Q2w2L.js +0 -1
- package/web/assets/stateDiagram-v2-B5LQ5ZB2-8nHs2aNE.js +0 -1
- package/web/assets/timeline-definition-5SPVSISX-DkMiGj4Z.js +0 -120
- package/web/assets/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +0 -1
- package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +0 -1
- package/web/assets/vennDiagram-IE5QUKF5-BCxMmf9q.js +0 -34
- package/web/assets/wardley-RL74JXVD-BCRCBASE-CMStJhpn.js +0 -1
- package/web/assets/wardleyDiagram-XU3VSMPF-ijlLF77s.js +0 -20
- /package/web/assets/{context-builder-CqQNhRj1.js → context-builder-_HS0v2ma.js} +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C++ conversion-rank scoring for overload resolution (#1578).
|
|
3
|
+
*
|
|
4
|
+
* Operates on **normalized** type strings (output of
|
|
5
|
+
* `normalizeCppParamType` in `arity-metadata.ts`). After normalization:
|
|
6
|
+
* - int/long/short/unsigned → 'int'
|
|
7
|
+
* - float/double → 'double'
|
|
8
|
+
* - char → 'char', bool → 'bool'
|
|
9
|
+
*
|
|
10
|
+
* Because the normalizer collapses promotion pairs (int↔long,
|
|
11
|
+
* float↔double) to the same string, those promotions are invisible at
|
|
12
|
+
* this layer — they appear as exact matches (rank 0).
|
|
13
|
+
*
|
|
14
|
+
* Post-normalization ranking:
|
|
15
|
+
* - rank 0 — exact (same normalized type)
|
|
16
|
+
* - rank 1 — integral promotion (char→int, bool→int)
|
|
17
|
+
* - rank 2 — standard arithmetic conversion (int↔double, char→double,
|
|
18
|
+
* bool→double)
|
|
19
|
+
* - Infinity — mismatch (string↔int, user types, pointers, etc.)
|
|
20
|
+
*
|
|
21
|
+
* This function is intentionally C++-specific (issue #1578 pitfall:
|
|
22
|
+
* keep conversion-rank tables out of shared overload-narrowing). Other
|
|
23
|
+
* languages may define their own `ConversionRankFn` in the future.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Return the conversion rank from `argType` to `paramType`.
|
|
27
|
+
*
|
|
28
|
+
* @returns 0 for exact match, 1 for integral promotion (char/bool→int),
|
|
29
|
+
* 2 for standard arithmetic conversion, Infinity for mismatch.
|
|
30
|
+
*/
|
|
31
|
+
export declare function cppConversionRank(argType: string, paramType: string): number;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C++ conversion-rank scoring for overload resolution (#1578).
|
|
3
|
+
*
|
|
4
|
+
* Operates on **normalized** type strings (output of
|
|
5
|
+
* `normalizeCppParamType` in `arity-metadata.ts`). After normalization:
|
|
6
|
+
* - int/long/short/unsigned → 'int'
|
|
7
|
+
* - float/double → 'double'
|
|
8
|
+
* - char → 'char', bool → 'bool'
|
|
9
|
+
*
|
|
10
|
+
* Because the normalizer collapses promotion pairs (int↔long,
|
|
11
|
+
* float↔double) to the same string, those promotions are invisible at
|
|
12
|
+
* this layer — they appear as exact matches (rank 0).
|
|
13
|
+
*
|
|
14
|
+
* Post-normalization ranking:
|
|
15
|
+
* - rank 0 — exact (same normalized type)
|
|
16
|
+
* - rank 1 — integral promotion (char→int, bool→int)
|
|
17
|
+
* - rank 2 — standard arithmetic conversion (int↔double, char→double,
|
|
18
|
+
* bool→double)
|
|
19
|
+
* - Infinity — mismatch (string↔int, user types, pointers, etc.)
|
|
20
|
+
*
|
|
21
|
+
* This function is intentionally C++-specific (issue #1578 pitfall:
|
|
22
|
+
* keep conversion-rank tables out of shared overload-narrowing). Other
|
|
23
|
+
* languages may define their own `ConversionRankFn` in the future.
|
|
24
|
+
*/
|
|
25
|
+
/** Set of normalized arithmetic types that support implicit conversion. */
|
|
26
|
+
const ARITHMETIC = new Set(['int', 'double', 'char', 'bool']);
|
|
27
|
+
/** Integral promotion targets: char→int and bool→int are rank 1. */
|
|
28
|
+
const INTEGRAL_PROMOTION = new Map([
|
|
29
|
+
['char', 'int'],
|
|
30
|
+
['bool', 'int'],
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Return the conversion rank from `argType` to `paramType`.
|
|
34
|
+
*
|
|
35
|
+
* @returns 0 for exact match, 1 for integral promotion (char/bool→int),
|
|
36
|
+
* 2 for standard arithmetic conversion, Infinity for mismatch.
|
|
37
|
+
*/
|
|
38
|
+
export function cppConversionRank(argType, paramType) {
|
|
39
|
+
if (argType === paramType)
|
|
40
|
+
return 0;
|
|
41
|
+
// Integral promotions: char→int, bool→int (ISO C++ [conv.prom])
|
|
42
|
+
if (INTEGRAL_PROMOTION.get(argType) === paramType)
|
|
43
|
+
return 1;
|
|
44
|
+
if (ARITHMETIC.has(argType) && ARITHMETIC.has(paramType))
|
|
45
|
+
return 2;
|
|
46
|
+
return Infinity;
|
|
47
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { ParsedFile, ScopeId } from '../../../../_shared/index.js';
|
|
2
|
+
interface RangeKeyShape {
|
|
3
|
+
readonly startLine: number;
|
|
4
|
+
readonly startCol: number;
|
|
5
|
+
readonly endLine: number;
|
|
6
|
+
readonly endCol: number;
|
|
7
|
+
}
|
|
8
|
+
/** Record a symbol name as file-local (static or anonymous namespace). */
|
|
9
|
+
export declare function markFileLocal(filePath: string, name: string): void;
|
|
10
|
+
/** Check whether a symbol name has file-local linkage in the given file. */
|
|
11
|
+
export declare function isFileLocal(filePath: string, name: string): boolean;
|
|
12
|
+
/** Capture-time: record an anonymous `namespace_definition` source range. */
|
|
13
|
+
export declare function markCppAnonymousNamespaceRange(filePath: string, range: RangeKeyShape): void;
|
|
14
|
+
/** Predicate consumed by `populateCppNonGloballyVisible` and
|
|
15
|
+
* `expandCppWildcardNames` to exempt anonymous-namespace scopes from
|
|
16
|
+
* the cross-file unqualified-lookup exclusion that applies to ordinary
|
|
17
|
+
* named namespaces. */
|
|
18
|
+
export declare function isCppAnonymousNamespaceScope(scopeId: ScopeId): boolean;
|
|
19
|
+
/** Clear tracked file-local names (call at start of each resolution pass). */
|
|
20
|
+
export declare function clearFileLocalNames(): void;
|
|
21
|
+
/** Resolve recorded anonymous-namespace source ranges to `ScopeId`s.
|
|
22
|
+
* Must run inside `populateOwners` BEFORE `populateCppNonGloballyVisible`
|
|
23
|
+
* consults the resolved set. */
|
|
24
|
+
export declare function populateCppAnonymousNamespaceScopes(parsed: {
|
|
25
|
+
readonly filePath: string;
|
|
26
|
+
readonly scopes: readonly {
|
|
27
|
+
readonly id: ScopeId;
|
|
28
|
+
readonly kind: string;
|
|
29
|
+
readonly range: RangeKeyShape;
|
|
30
|
+
}[];
|
|
31
|
+
}): void;
|
|
32
|
+
/**
|
|
33
|
+
* Populate per-file "not globally visible" nodeIds by walking the parsed
|
|
34
|
+
* file's scopes. Run as part of the `populateOwners` hook so every C++
|
|
35
|
+
* scope is reflected before any cross-file resolution pass consults the
|
|
36
|
+
* set.
|
|
37
|
+
*
|
|
38
|
+
* A def is "not globally visible" when its nearest structurally enclosing
|
|
39
|
+
* scope is a `Namespace` or `Class` — those require qualification
|
|
40
|
+
* (`ns::name`, `Class::method`) for cross-file unqualified lookup.
|
|
41
|
+
* Module-scoped defs remain globally visible.
|
|
42
|
+
*/
|
|
43
|
+
export declare function populateCppNonGloballyVisible(parsed: {
|
|
44
|
+
readonly filePath: string;
|
|
45
|
+
readonly scopes: readonly {
|
|
46
|
+
readonly id: ScopeId;
|
|
47
|
+
readonly kind: string;
|
|
48
|
+
readonly ownedDefs: readonly {
|
|
49
|
+
readonly nodeId: string;
|
|
50
|
+
}[];
|
|
51
|
+
}[];
|
|
52
|
+
}): void;
|
|
53
|
+
/**
|
|
54
|
+
* Check whether a def is visible by unqualified lookup from outside its
|
|
55
|
+
* own file. Returns `false` for class-owned and namespace-nested defs.
|
|
56
|
+
*
|
|
57
|
+
* Used by the global free-call fallback's `isFileLocalDef` hook (which
|
|
58
|
+
* historically meant "static / anonymous-namespace" but semantically
|
|
59
|
+
* stands for "logically invisible cross-file"). Including class methods
|
|
60
|
+
* and namespace members under the same negative answer fixes the leak
|
|
61
|
+
* where unqualified `save()` resolved to `User::save` through a shared
|
|
62
|
+
* workspace registry walk.
|
|
63
|
+
*/
|
|
64
|
+
export declare function isCppDefGloballyVisible(filePath: string, nodeId: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Return the names visible through a C++ wildcard import (`#include` or
|
|
67
|
+
* `using namespace`).
|
|
68
|
+
*
|
|
69
|
+
* ## Contract
|
|
70
|
+
*
|
|
71
|
+
* C++ unqualified name lookup only sees names at the importer's enclosing
|
|
72
|
+
* scope. Class members and namespace-nested symbols are NOT visible by
|
|
73
|
+
* unqualified lookup from a free function in an including TU — they must
|
|
74
|
+
* be reached via `Class::method`, `ns::name`, or a working `using`
|
|
75
|
+
* declaration. The filter below enforces that contract for header
|
|
76
|
+
* propagation: only defs whose nearest enclosing scope is the header's
|
|
77
|
+
* `Module` scope are emitted as wildcard-binding names.
|
|
78
|
+
*
|
|
79
|
+
* ## Why scope-aware and not predicate-on-qualifiedName
|
|
80
|
+
*
|
|
81
|
+
* A naive `def.qualifiedName.indexOf('.') === -1` check is unreliable
|
|
82
|
+
* because `populateClassOwnedMembers`
|
|
83
|
+
* (`gitnexus/src/core/ingestion/scope-resolution/scope/walkers.ts`)
|
|
84
|
+
* only dot-qualifies `qualifiedName` for `Class` scopes. Namespace-nested
|
|
85
|
+
* defs (`namespace ns { void foo(); }`) arrive in `localDefs` with
|
|
86
|
+
* `qualifiedName === 'foo'` and `ownerId === undefined`, indistinguishable
|
|
87
|
+
* from a top-level free function. The structural truth lives in
|
|
88
|
+
* `Scope.ownedDefs`: each scope lists what it structurally owns; the
|
|
89
|
+
* Module scope owns only top-level symbols. We look the def up by
|
|
90
|
+
* `nodeId` against the scope tree to identify its owning kind.
|
|
91
|
+
*
|
|
92
|
+
* ## `localDefs` consumer survey (recorded for future maintainers)
|
|
93
|
+
*
|
|
94
|
+
* Other consumers of `ParsedFile.localDefs` were audited at the time
|
|
95
|
+
* this filter was introduced (see PR #1520 / plan
|
|
96
|
+
* `docs/plans/2026-05-12-002-fix-cpp-resolver-followups-plan.md`):
|
|
97
|
+
*
|
|
98
|
+
* - `finalize-orchestrator.ts:113,163` — flattens defs into a workspace
|
|
99
|
+
* registry keyed by `ownerId` + `qualifiedName`; class-owned and
|
|
100
|
+
* namespace-owned symbols are registered under their owner, not as
|
|
101
|
+
* unqualified names. Not a leak surface.
|
|
102
|
+
* - `csharp/namespace-siblings.ts:307`, `go/expand-wildcards.ts:86`,
|
|
103
|
+
* `php/scope-resolver.ts:141,151`, `c/static-linkage.ts:51` — other
|
|
104
|
+
* languages' own wildcard / sibling expansions. Each owns its own
|
|
105
|
+
* visibility contract.
|
|
106
|
+
* - `receiver-bound-calls.ts:99`, `reconcile-ownership.ts:66,119`,
|
|
107
|
+
* `mro.ts:61` — keyed by `ownerId` for member lookup, never used
|
|
108
|
+
* as unqualified bindings.
|
|
109
|
+
* - `go/interface-impls.ts:40,53`, `go/package-siblings.ts:41` — Go-
|
|
110
|
+
* specific, sibling-package scoped.
|
|
111
|
+
*
|
|
112
|
+
* No other consumer treats `localDefs` as a flat unqualified-binding
|
|
113
|
+
* set the way this function did before the fix. If a future consumer
|
|
114
|
+
* does, mirror this filter or harden registration so class/namespace
|
|
115
|
+
* members never enter `localDefs` unqualified.
|
|
116
|
+
*/
|
|
117
|
+
export declare function expandCppWildcardNames(targetModuleScope: ScopeId, parsedFiles: readonly ParsedFile[]): readonly string[];
|
|
118
|
+
export {};
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { isCppInlineNamespaceScope } from './inline-namespaces.js';
|
|
2
|
+
/**
|
|
3
|
+
* Per-file set of symbol names with file-local linkage.
|
|
4
|
+
* In C++ there are two sources of file-local linkage:
|
|
5
|
+
* 1. `static` storage class (same as C)
|
|
6
|
+
* 2. Anonymous namespace (`namespace { ... }`)
|
|
7
|
+
*
|
|
8
|
+
* Populated during `emitCppScopeCaptures` and consumed by
|
|
9
|
+
* `expandCppWildcardNames` to exclude file-local symbols from
|
|
10
|
+
* cross-file wildcard import visibility.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: module-level state, single-process-single-repo use only.
|
|
13
|
+
* Call `clearFileLocalNames()` at the start of each resolution pass.
|
|
14
|
+
*
|
|
15
|
+
* Key: filePath, Value: Set of file-local symbol names.
|
|
16
|
+
*/
|
|
17
|
+
const fileLocalNames = new Map();
|
|
18
|
+
/**
|
|
19
|
+
* Per-file set of `SymbolDefinition.nodeId`s that are NOT visible by
|
|
20
|
+
* unqualified lookup from outside the file — class-owned methods/fields
|
|
21
|
+
* and namespace-nested symbols. Populated by `populateCppNonGloballyVisible`
|
|
22
|
+
* during the per-file `populateOwners` hook; consumed by
|
|
23
|
+
* `isCppDefGloballyVisible` from both `expandCppWildcardNames` (wildcard
|
|
24
|
+
* propagation) and the global free-call fallback's `isFileLocalDef` hook.
|
|
25
|
+
*
|
|
26
|
+
* Tracked per filePath rather than as a single global set so cross-file
|
|
27
|
+
* lookup correctly compares the candidate's owning file's non-visible
|
|
28
|
+
* set without leaking across pipeline invocations (the global free-call
|
|
29
|
+
* fallback checks `def.filePath !== callerFilePath` and then asks "is
|
|
30
|
+
* this def visible from outside its own file?" — that's exactly what
|
|
31
|
+
* this set encodes).
|
|
32
|
+
*/
|
|
33
|
+
const nonGloballyVisibleNodeIds = new Map();
|
|
34
|
+
/**
|
|
35
|
+
* Per-file set of source-range keys identifying `namespace { ... }` blocks.
|
|
36
|
+
* Resolved to `ScopeId`s in `populateCppAnonymousNamespaceScopes` and
|
|
37
|
+
* consumed via `isCppAnonymousNamespaceScope`.
|
|
38
|
+
*
|
|
39
|
+
* Anonymous namespaces have file-local linkage but, unlike `static`, their
|
|
40
|
+
* members propagate to any TU that `#include`s the declaring file — each
|
|
41
|
+
* including TU gets its own internal-linkage copy. So for wildcard import
|
|
42
|
+
* expansion (`expandCppWildcardNames`) we treat anonymous-namespace owned
|
|
43
|
+
* defs as if declared at the enclosing scope. Cross-file unqualified
|
|
44
|
+
* lookup that does NOT go through `#include` is still blocked by the
|
|
45
|
+
* `isFileLocal` mark recorded on the def's name.
|
|
46
|
+
*/
|
|
47
|
+
const anonymousNamespaceRangesByFile = new Map();
|
|
48
|
+
const anonymousNamespaceScopeIds = new Set();
|
|
49
|
+
function rangeKey(r) {
|
|
50
|
+
return `${r.startLine}:${r.startCol}:${r.endLine}:${r.endCol}`;
|
|
51
|
+
}
|
|
52
|
+
/** Record a symbol name as file-local (static or anonymous namespace). */
|
|
53
|
+
export function markFileLocal(filePath, name) {
|
|
54
|
+
let names = fileLocalNames.get(filePath);
|
|
55
|
+
if (names === undefined) {
|
|
56
|
+
names = new Set();
|
|
57
|
+
fileLocalNames.set(filePath, names);
|
|
58
|
+
}
|
|
59
|
+
names.add(name);
|
|
60
|
+
}
|
|
61
|
+
/** Check whether a symbol name has file-local linkage in the given file. */
|
|
62
|
+
export function isFileLocal(filePath, name) {
|
|
63
|
+
return fileLocalNames.get(filePath)?.has(name) ?? false;
|
|
64
|
+
}
|
|
65
|
+
/** Capture-time: record an anonymous `namespace_definition` source range. */
|
|
66
|
+
export function markCppAnonymousNamespaceRange(filePath, range) {
|
|
67
|
+
let set = anonymousNamespaceRangesByFile.get(filePath);
|
|
68
|
+
if (set === undefined) {
|
|
69
|
+
set = new Set();
|
|
70
|
+
anonymousNamespaceRangesByFile.set(filePath, set);
|
|
71
|
+
}
|
|
72
|
+
set.add(rangeKey(range));
|
|
73
|
+
}
|
|
74
|
+
/** Predicate consumed by `populateCppNonGloballyVisible` and
|
|
75
|
+
* `expandCppWildcardNames` to exempt anonymous-namespace scopes from
|
|
76
|
+
* the cross-file unqualified-lookup exclusion that applies to ordinary
|
|
77
|
+
* named namespaces. */
|
|
78
|
+
export function isCppAnonymousNamespaceScope(scopeId) {
|
|
79
|
+
return anonymousNamespaceScopeIds.has(scopeId);
|
|
80
|
+
}
|
|
81
|
+
/** Clear tracked file-local names (call at start of each resolution pass). */
|
|
82
|
+
export function clearFileLocalNames() {
|
|
83
|
+
fileLocalNames.clear();
|
|
84
|
+
nonGloballyVisibleNodeIds.clear();
|
|
85
|
+
anonymousNamespaceRangesByFile.clear();
|
|
86
|
+
anonymousNamespaceScopeIds.clear();
|
|
87
|
+
}
|
|
88
|
+
/** Resolve recorded anonymous-namespace source ranges to `ScopeId`s.
|
|
89
|
+
* Must run inside `populateOwners` BEFORE `populateCppNonGloballyVisible`
|
|
90
|
+
* consults the resolved set. */
|
|
91
|
+
export function populateCppAnonymousNamespaceScopes(parsed) {
|
|
92
|
+
const ranges = anonymousNamespaceRangesByFile.get(parsed.filePath);
|
|
93
|
+
if (ranges === undefined || ranges.size === 0)
|
|
94
|
+
return;
|
|
95
|
+
for (const scope of parsed.scopes) {
|
|
96
|
+
if (scope.kind !== 'Namespace')
|
|
97
|
+
continue;
|
|
98
|
+
if (ranges.has(rangeKey(scope.range))) {
|
|
99
|
+
anonymousNamespaceScopeIds.add(scope.id);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Populate per-file "not globally visible" nodeIds by walking the parsed
|
|
105
|
+
* file's scopes. Run as part of the `populateOwners` hook so every C++
|
|
106
|
+
* scope is reflected before any cross-file resolution pass consults the
|
|
107
|
+
* set.
|
|
108
|
+
*
|
|
109
|
+
* A def is "not globally visible" when its nearest structurally enclosing
|
|
110
|
+
* scope is a `Namespace` or `Class` — those require qualification
|
|
111
|
+
* (`ns::name`, `Class::method`) for cross-file unqualified lookup.
|
|
112
|
+
* Module-scoped defs remain globally visible.
|
|
113
|
+
*/
|
|
114
|
+
export function populateCppNonGloballyVisible(parsed) {
|
|
115
|
+
let set = nonGloballyVisibleNodeIds.get(parsed.filePath);
|
|
116
|
+
if (set === undefined) {
|
|
117
|
+
set = new Set();
|
|
118
|
+
nonGloballyVisibleNodeIds.set(parsed.filePath, set);
|
|
119
|
+
}
|
|
120
|
+
for (const scope of parsed.scopes) {
|
|
121
|
+
if (scope.kind !== 'Namespace' && scope.kind !== 'Class')
|
|
122
|
+
continue;
|
|
123
|
+
// Inline namespaces (`inline namespace v1 { ... }`) propagate their
|
|
124
|
+
// members to the enclosing namespace's unqualified-lookup scope per
|
|
125
|
+
// ISO C++ `[namespace.def]/p4`. Skip them here so cross-file
|
|
126
|
+
// unqualified lookup can still see their callable defs.
|
|
127
|
+
if (scope.kind === 'Namespace' && isCppInlineNamespaceScope(scope.id))
|
|
128
|
+
continue;
|
|
129
|
+
// Anonymous namespaces give internal linkage but their contents are
|
|
130
|
+
// visible at the enclosing scope within the same TU and propagate to
|
|
131
|
+
// any TU that `#include`s the declaring file. The `isFileLocal` mark
|
|
132
|
+
// (recorded on the def's name in this file) still blocks cross-file
|
|
133
|
+
// unqualified lookup that does not go through #include, so dropping
|
|
134
|
+
// the structural visibility exclusion here is safe.
|
|
135
|
+
if (scope.kind === 'Namespace' && anonymousNamespaceScopeIds.has(scope.id))
|
|
136
|
+
continue;
|
|
137
|
+
for (const def of scope.ownedDefs) {
|
|
138
|
+
set.add(def.nodeId);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check whether a def is visible by unqualified lookup from outside its
|
|
144
|
+
* own file. Returns `false` for class-owned and namespace-nested defs.
|
|
145
|
+
*
|
|
146
|
+
* Used by the global free-call fallback's `isFileLocalDef` hook (which
|
|
147
|
+
* historically meant "static / anonymous-namespace" but semantically
|
|
148
|
+
* stands for "logically invisible cross-file"). Including class methods
|
|
149
|
+
* and namespace members under the same negative answer fixes the leak
|
|
150
|
+
* where unqualified `save()` resolved to `User::save` through a shared
|
|
151
|
+
* workspace registry walk.
|
|
152
|
+
*/
|
|
153
|
+
export function isCppDefGloballyVisible(filePath, nodeId) {
|
|
154
|
+
return nonGloballyVisibleNodeIds.get(filePath)?.has(nodeId) !== true;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Return the names visible through a C++ wildcard import (`#include` or
|
|
158
|
+
* `using namespace`).
|
|
159
|
+
*
|
|
160
|
+
* ## Contract
|
|
161
|
+
*
|
|
162
|
+
* C++ unqualified name lookup only sees names at the importer's enclosing
|
|
163
|
+
* scope. Class members and namespace-nested symbols are NOT visible by
|
|
164
|
+
* unqualified lookup from a free function in an including TU — they must
|
|
165
|
+
* be reached via `Class::method`, `ns::name`, or a working `using`
|
|
166
|
+
* declaration. The filter below enforces that contract for header
|
|
167
|
+
* propagation: only defs whose nearest enclosing scope is the header's
|
|
168
|
+
* `Module` scope are emitted as wildcard-binding names.
|
|
169
|
+
*
|
|
170
|
+
* ## Why scope-aware and not predicate-on-qualifiedName
|
|
171
|
+
*
|
|
172
|
+
* A naive `def.qualifiedName.indexOf('.') === -1` check is unreliable
|
|
173
|
+
* because `populateClassOwnedMembers`
|
|
174
|
+
* (`gitnexus/src/core/ingestion/scope-resolution/scope/walkers.ts`)
|
|
175
|
+
* only dot-qualifies `qualifiedName` for `Class` scopes. Namespace-nested
|
|
176
|
+
* defs (`namespace ns { void foo(); }`) arrive in `localDefs` with
|
|
177
|
+
* `qualifiedName === 'foo'` and `ownerId === undefined`, indistinguishable
|
|
178
|
+
* from a top-level free function. The structural truth lives in
|
|
179
|
+
* `Scope.ownedDefs`: each scope lists what it structurally owns; the
|
|
180
|
+
* Module scope owns only top-level symbols. We look the def up by
|
|
181
|
+
* `nodeId` against the scope tree to identify its owning kind.
|
|
182
|
+
*
|
|
183
|
+
* ## `localDefs` consumer survey (recorded for future maintainers)
|
|
184
|
+
*
|
|
185
|
+
* Other consumers of `ParsedFile.localDefs` were audited at the time
|
|
186
|
+
* this filter was introduced (see PR #1520 / plan
|
|
187
|
+
* `docs/plans/2026-05-12-002-fix-cpp-resolver-followups-plan.md`):
|
|
188
|
+
*
|
|
189
|
+
* - `finalize-orchestrator.ts:113,163` — flattens defs into a workspace
|
|
190
|
+
* registry keyed by `ownerId` + `qualifiedName`; class-owned and
|
|
191
|
+
* namespace-owned symbols are registered under their owner, not as
|
|
192
|
+
* unqualified names. Not a leak surface.
|
|
193
|
+
* - `csharp/namespace-siblings.ts:307`, `go/expand-wildcards.ts:86`,
|
|
194
|
+
* `php/scope-resolver.ts:141,151`, `c/static-linkage.ts:51` — other
|
|
195
|
+
* languages' own wildcard / sibling expansions. Each owns its own
|
|
196
|
+
* visibility contract.
|
|
197
|
+
* - `receiver-bound-calls.ts:99`, `reconcile-ownership.ts:66,119`,
|
|
198
|
+
* `mro.ts:61` — keyed by `ownerId` for member lookup, never used
|
|
199
|
+
* as unqualified bindings.
|
|
200
|
+
* - `go/interface-impls.ts:40,53`, `go/package-siblings.ts:41` — Go-
|
|
201
|
+
* specific, sibling-package scoped.
|
|
202
|
+
*
|
|
203
|
+
* No other consumer treats `localDefs` as a flat unqualified-binding
|
|
204
|
+
* set the way this function did before the fix. If a future consumer
|
|
205
|
+
* does, mirror this filter or harden registration so class/namespace
|
|
206
|
+
* members never enter `localDefs` unqualified.
|
|
207
|
+
*/
|
|
208
|
+
export function expandCppWildcardNames(targetModuleScope, parsedFiles) {
|
|
209
|
+
const target = parsedFiles.find((p) => p.moduleScope === targetModuleScope);
|
|
210
|
+
if (target === undefined)
|
|
211
|
+
return [];
|
|
212
|
+
// Build nodeId → owning Scope map from the structural scope tree.
|
|
213
|
+
// `Scope.ownedDefs` is the canonical source of structural ownership;
|
|
214
|
+
// `localDefs` is its flattened union, which is why the original code
|
|
215
|
+
// leaked: walking only `localDefs` discards the owning-scope context.
|
|
216
|
+
const ownerScopeByNodeId = new Map();
|
|
217
|
+
for (const scope of target.scopes) {
|
|
218
|
+
for (const ownedDef of scope.ownedDefs) {
|
|
219
|
+
ownerScopeByNodeId.set(ownedDef.nodeId, scope);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const seen = new Set();
|
|
223
|
+
const names = [];
|
|
224
|
+
for (const def of target.localDefs) {
|
|
225
|
+
// Defense-in-depth: class methods carry a non-undefined ownerId after
|
|
226
|
+
// `populateClassOwnedMembers` runs. Skip them outright.
|
|
227
|
+
if (def.ownerId !== undefined)
|
|
228
|
+
continue;
|
|
229
|
+
// Structural visibility check: exclude defs whose owning scope is a
|
|
230
|
+
// Namespace or Class — these require qualification (`ns::name`,
|
|
231
|
+
// `Class::method`) and are NOT reachable by unqualified lookup in an
|
|
232
|
+
// including TU. When the owning scope is unknown we default to
|
|
233
|
+
// include (preserves prior behavior for any def whose structural
|
|
234
|
+
// ownership wasn't recorded in `Scope.ownedDefs`).
|
|
235
|
+
//
|
|
236
|
+
// Anonymous namespaces are exempt: their members propagate to the
|
|
237
|
+
// enclosing scope of any TU that #includes the declaring file (each
|
|
238
|
+
// including TU gets its own internal-linkage copy per ISO C++).
|
|
239
|
+
const ownerScope = ownerScopeByNodeId.get(def.nodeId);
|
|
240
|
+
const ownerIsAnonymousNamespace = ownerScope !== undefined &&
|
|
241
|
+
ownerScope.kind === 'Namespace' &&
|
|
242
|
+
anonymousNamespaceScopeIds.has(ownerScope.id);
|
|
243
|
+
if (ownerScope !== undefined &&
|
|
244
|
+
!ownerIsAnonymousNamespace &&
|
|
245
|
+
(ownerScope.kind === 'Namespace' || ownerScope.kind === 'Class')) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
const name = simpleName(def);
|
|
249
|
+
if (name === '')
|
|
250
|
+
continue;
|
|
251
|
+
// Same exemption for the `isFileLocal` mark — anonymous-namespace
|
|
252
|
+
// names are recorded as file-local to suppress the global free-call
|
|
253
|
+
// fallback's cross-file leak, but they MUST still propagate through
|
|
254
|
+
// wildcard import expansion to including TUs.
|
|
255
|
+
if (!ownerIsAnonymousNamespace && isFileLocal(target.filePath, name))
|
|
256
|
+
continue;
|
|
257
|
+
if (seen.has(name))
|
|
258
|
+
continue;
|
|
259
|
+
seen.add(name);
|
|
260
|
+
names.push(name);
|
|
261
|
+
}
|
|
262
|
+
return names;
|
|
263
|
+
}
|
|
264
|
+
function simpleName(def) {
|
|
265
|
+
return def.qualifiedName?.split('.').pop() ?? def.qualifiedName ?? '';
|
|
266
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk `repoPath` recursively and return relative paths of all C++ header files.
|
|
3
|
+
* Used by `loadResolutionConfig` so the C++ resolver can resolve `#include`
|
|
4
|
+
* targets that live in header files.
|
|
5
|
+
*
|
|
6
|
+
* Scans for: .h, .hpp, .hxx, .hh
|
|
7
|
+
*/
|
|
8
|
+
export declare function scanCppHeaderFiles(repoPath: string): ReadonlySet<string>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readdirSync } from 'fs';
|
|
2
|
+
import { join, relative } from 'path';
|
|
3
|
+
/** C++ header extensions to scan for in the workspace. */
|
|
4
|
+
const HEADER_EXTENSIONS = new Set(['.h', '.hpp', '.hxx', '.hh']);
|
|
5
|
+
/**
|
|
6
|
+
* Walk `repoPath` recursively and return relative paths of all C++ header files.
|
|
7
|
+
* Used by `loadResolutionConfig` so the C++ resolver can resolve `#include`
|
|
8
|
+
* targets that live in header files.
|
|
9
|
+
*
|
|
10
|
+
* Scans for: .h, .hpp, .hxx, .hh
|
|
11
|
+
*/
|
|
12
|
+
export function scanCppHeaderFiles(repoPath) {
|
|
13
|
+
const headers = new Set();
|
|
14
|
+
walk(repoPath, repoPath, headers);
|
|
15
|
+
return headers;
|
|
16
|
+
}
|
|
17
|
+
function walk(dir, root, out) {
|
|
18
|
+
let entries;
|
|
19
|
+
try {
|
|
20
|
+
entries = readdirSync(dir, { withFileTypes: true, encoding: 'utf8' });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return; // permission denied, etc.
|
|
24
|
+
}
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
const name = entry.name;
|
|
27
|
+
const full = join(dir, name);
|
|
28
|
+
if (entry.isDirectory()) {
|
|
29
|
+
if (name === 'node_modules' ||
|
|
30
|
+
name === '.git' ||
|
|
31
|
+
name === 'vendor' ||
|
|
32
|
+
name === 'dist' ||
|
|
33
|
+
name === 'build' ||
|
|
34
|
+
name === 'out' ||
|
|
35
|
+
name === 'target' ||
|
|
36
|
+
name === '_build' ||
|
|
37
|
+
name === '.next' ||
|
|
38
|
+
name.startsWith('cmake-build')) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
walk(full, root, out);
|
|
42
|
+
}
|
|
43
|
+
else if (entry.isFile()) {
|
|
44
|
+
const ext = name.slice(name.lastIndexOf('.'));
|
|
45
|
+
if (HEADER_EXTENSIONS.has(ext)) {
|
|
46
|
+
out.add(relative(root, full).replace(/\\/g, '/'));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CaptureMatch } from '../../../../_shared/index.js';
|
|
2
|
+
import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Decompose a `preproc_include` node into a CaptureMatch with structured
|
|
5
|
+
* import captures. C++ #include maps to a wildcard import (all symbols
|
|
6
|
+
* from the header are visible). Identical to C's splitCInclude.
|
|
7
|
+
*/
|
|
8
|
+
export declare function splitCppInclude(node: SyntaxNode): CaptureMatch | null;
|
|
9
|
+
/**
|
|
10
|
+
* Decompose a `using_declaration` node into a CaptureMatch.
|
|
11
|
+
*
|
|
12
|
+
* tree-sitter-cpp produces:
|
|
13
|
+
* using namespace std; → using_declaration { "using", "namespace", identifier("std"), ";" }
|
|
14
|
+
* using std::vector; → using_declaration { "using", qualified_identifier("std::vector"), ";" }
|
|
15
|
+
*
|
|
16
|
+
* The first form is a wildcard import (all names from namespace).
|
|
17
|
+
* The second form is a named import (single symbol).
|
|
18
|
+
*/
|
|
19
|
+
export declare function splitCppUsingDecl(node: SyntaxNode): CaptureMatch | null;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { nodeToCapture, syntheticCapture } from '../../utils/ast-helpers.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decompose a `preproc_include` node into a CaptureMatch with structured
|
|
4
|
+
* import captures. C++ #include maps to a wildcard import (all symbols
|
|
5
|
+
* from the header are visible). Identical to C's splitCInclude.
|
|
6
|
+
*/
|
|
7
|
+
export function splitCppInclude(node) {
|
|
8
|
+
const pathNode = node.childForFieldName?.('path') ?? null;
|
|
9
|
+
if (pathNode === null) {
|
|
10
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
11
|
+
const child = node.child(i);
|
|
12
|
+
if (child === null)
|
|
13
|
+
continue;
|
|
14
|
+
if (child.type === 'string_literal' || child.type === 'system_lib_string') {
|
|
15
|
+
return buildIncludeCapture(node, child);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return buildIncludeCapture(node, pathNode);
|
|
21
|
+
}
|
|
22
|
+
function buildIncludeCapture(node, pathNode) {
|
|
23
|
+
let raw;
|
|
24
|
+
if (pathNode.type === 'string_literal') {
|
|
25
|
+
const content = pathNode.namedChildren.find((c) => c.type === 'string_content');
|
|
26
|
+
raw = content?.text ?? pathNode.text.replace(/^"|"$/g, '');
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
raw = pathNode.text;
|
|
30
|
+
if (raw.startsWith('<') && raw.endsWith('>')) {
|
|
31
|
+
raw = raw.slice(1, -1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const isSystem = pathNode.type === 'system_lib_string';
|
|
35
|
+
const result = {
|
|
36
|
+
'@import.statement': nodeToCapture('@import.statement', node),
|
|
37
|
+
'@import.kind': syntheticCapture('@import.kind', node, 'wildcard'),
|
|
38
|
+
'@import.source': syntheticCapture('@import.source', node, raw),
|
|
39
|
+
};
|
|
40
|
+
if (isSystem) {
|
|
41
|
+
result['@import.system'] = syntheticCapture('@import.system', node, 'true');
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Decompose a `using_declaration` node into a CaptureMatch.
|
|
47
|
+
*
|
|
48
|
+
* tree-sitter-cpp produces:
|
|
49
|
+
* using namespace std; → using_declaration { "using", "namespace", identifier("std"), ";" }
|
|
50
|
+
* using std::vector; → using_declaration { "using", qualified_identifier("std::vector"), ";" }
|
|
51
|
+
*
|
|
52
|
+
* The first form is a wildcard import (all names from namespace).
|
|
53
|
+
* The second form is a named import (single symbol).
|
|
54
|
+
*/
|
|
55
|
+
export function splitCppUsingDecl(node) {
|
|
56
|
+
if (node.type !== 'using_declaration')
|
|
57
|
+
return null;
|
|
58
|
+
// Check for "namespace" keyword among anonymous children
|
|
59
|
+
let hasNamespaceKeyword = false;
|
|
60
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
61
|
+
const child = node.child(i);
|
|
62
|
+
if (child !== null && !child.isNamed && child.text === 'namespace') {
|
|
63
|
+
hasNamespaceKeyword = true;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (hasNamespaceKeyword) {
|
|
68
|
+
// using namespace <name>;
|
|
69
|
+
// The namespace name can be an identifier or qualified_identifier
|
|
70
|
+
let namespaceName = null;
|
|
71
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
72
|
+
const child = node.namedChild(i);
|
|
73
|
+
if (child === null)
|
|
74
|
+
continue;
|
|
75
|
+
if (child.type === 'identifier' || child.type === 'qualified_identifier') {
|
|
76
|
+
namespaceName = child.text;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (namespaceName === null)
|
|
81
|
+
return null;
|
|
82
|
+
return {
|
|
83
|
+
'@import.statement': nodeToCapture('@import.statement', node),
|
|
84
|
+
'@import.kind': syntheticCapture('@import.kind', node, 'wildcard'),
|
|
85
|
+
'@import.source': syntheticCapture('@import.source', node, namespaceName),
|
|
86
|
+
'@import.using-namespace': syntheticCapture('@import.using-namespace', node, 'true'),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// using <qualified_identifier>; (e.g. using std::vector)
|
|
90
|
+
let qualId = null;
|
|
91
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
92
|
+
const child = node.namedChild(i);
|
|
93
|
+
if (child !== null && child.type === 'qualified_identifier') {
|
|
94
|
+
qualId = child;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (qualId === null)
|
|
99
|
+
return null;
|
|
100
|
+
// Extract the imported name (last identifier) and source (namespace part)
|
|
101
|
+
const nameNode = qualId.childForFieldName?.('name') ?? null;
|
|
102
|
+
const scopeNode = qualId.childForFieldName?.('scope') ?? null;
|
|
103
|
+
const importedName = nameNode?.text ?? qualId.text.split('::').pop() ?? '';
|
|
104
|
+
const source = scopeNode?.text ?? qualId.text.replace(new RegExp('::' + importedName + '$'), '');
|
|
105
|
+
return {
|
|
106
|
+
'@import.statement': nodeToCapture('@import.statement', node),
|
|
107
|
+
'@import.kind': syntheticCapture('@import.kind', node, 'named'),
|
|
108
|
+
'@import.source': syntheticCapture('@import.source', node, source),
|
|
109
|
+
'@import.name': syntheticCapture('@import.name', node, importedName),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a C++ #include path to a file in the workspace.
|
|
3
|
+
* C++ #include path resolution is identical to C:
|
|
4
|
+
* 1. Same-directory sibling (relative lookup)
|
|
5
|
+
* 2. Exact match
|
|
6
|
+
* 3. Suffix match with depth + lexicographic tiebreak
|
|
7
|
+
*
|
|
8
|
+
* Re-exports the C implementation since the #include semantics are shared.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveCppImportTarget(targetRaw: string, fromFile: string, allFilePaths: ReadonlySet<string>): string | null;
|