gitnexus 1.6.5-rc.2 → 1.6.5-rc.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +30 -12
- package/dist/cli/analyze.d.ts +18 -0
- package/dist/cli/analyze.js +33 -4
- package/dist/cli/augment.d.ts +1 -1
- package/dist/cli/augment.js +1 -1
- package/dist/cli/index.js +6 -1
- package/dist/cli/setup.js +6 -0
- package/dist/core/augmentation/engine.d.ts +2 -2
- package/dist/core/augmentation/engine.js +26 -6
- package/dist/core/embeddings/ast-utils.js +2 -1
- package/dist/core/embeddings/http-client.js +22 -6
- package/dist/core/group/extractors/grpc-extractor.js +2 -1
- package/dist/core/group/extractors/http-patterns/python.js +175 -0
- package/dist/core/group/extractors/http-route-extractor.js +2 -1
- package/dist/core/group/extractors/include-extractor.js +2 -1
- package/dist/core/group/extractors/thrift-extractor.js +2 -1
- package/dist/core/group/extractors/tree-sitter-scanner.js +2 -1
- 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.js +166 -47
- package/dist/core/ingestion/community-processor.js +18 -0
- package/dist/core/ingestion/heritage-processor.js +3 -2
- package/dist/core/ingestion/import-processor.js +2 -1
- package/dist/core/ingestion/import-resolvers/standard.d.ts +5 -0
- package/dist/core/ingestion/import-resolvers/standard.js +27 -1
- package/dist/core/ingestion/import-resolvers/utils.js +4 -0
- package/dist/core/ingestion/languages/c/arity-metadata.d.ts +14 -0
- package/dist/core/ingestion/languages/c/arity-metadata.js +94 -0
- package/dist/core/ingestion/languages/c/arity.d.ts +6 -0
- package/dist/core/ingestion/languages/c/arity.js +18 -0
- package/dist/core/ingestion/languages/c/captures.d.ts +2 -0
- package/dist/core/ingestion/languages/c/captures.js +105 -0
- package/dist/core/ingestion/languages/c/header-scan.d.ts +7 -0
- package/dist/core/ingestion/languages/c/header-scan.js +55 -0
- package/dist/core/ingestion/languages/c/import-decomposer.d.ts +8 -0
- package/dist/core/ingestion/languages/c/import-decomposer.js +50 -0
- package/dist/core/ingestion/languages/c/import-target.d.ts +14 -0
- package/dist/core/ingestion/languages/c/import-target.js +57 -0
- package/dist/core/ingestion/languages/c/index.d.ts +11 -0
- package/dist/core/ingestion/languages/c/index.js +11 -0
- package/dist/core/ingestion/languages/c/interpret.d.ts +14 -0
- package/dist/core/ingestion/languages/c/interpret.js +48 -0
- package/dist/core/ingestion/languages/c/merge-bindings.d.ts +7 -0
- package/dist/core/ingestion/languages/c/merge-bindings.js +23 -0
- package/dist/core/ingestion/languages/c/query.d.ts +3 -0
- package/dist/core/ingestion/languages/c/query.js +161 -0
- package/dist/core/ingestion/languages/c/scope-resolver.d.ts +13 -0
- package/dist/core/ingestion/languages/c/scope-resolver.js +60 -0
- package/dist/core/ingestion/languages/c/simple-hooks.d.ts +14 -0
- package/dist/core/ingestion/languages/c/simple-hooks.js +19 -0
- package/dist/core/ingestion/languages/c/static-linkage.d.ts +13 -0
- package/dist/core/ingestion/languages/c/static-linkage.js +57 -0
- package/dist/core/ingestion/languages/c-cpp.js +10 -0
- package/dist/core/ingestion/languages/csharp/captures.js +2 -1
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +3 -2
- package/dist/core/ingestion/languages/go/captures.js +2 -1
- package/dist/core/ingestion/languages/go/range-binding.js +2 -1
- 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/languages/python/captures.js +2 -1
- package/dist/core/ingestion/languages/typescript/captures.js +2 -1
- package/dist/core/ingestion/parsing-processor.d.ts +22 -2
- package/dist/core/ingestion/parsing-processor.js +85 -50
- 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-resolution/contract/scope-resolver.d.ts +65 -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 +5 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +25 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +79 -7
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +7 -3
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +24 -4
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +21 -2
- 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 +31 -7
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -1
- package/dist/core/ingestion/tree-sitter-queries.js +10 -0
- package/dist/core/ingestion/workers/parse-worker.js +2 -1
- package/dist/core/lbug/lbug-adapter.d.ts +26 -0
- package/dist/core/lbug/lbug-adapter.js +174 -40
- package/dist/core/lbug/pool-adapter.js +19 -2
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +323 -29
- package/dist/core/tree-sitter/safe-parse.d.ts +6 -0
- package/dist/core/tree-sitter/safe-parse.js +32 -0
- package/dist/server/git-clone.js +10 -13
- package/dist/storage/file-hash.d.ts +47 -0
- package/dist/storage/file-hash.js +86 -0
- package/dist/storage/git.d.ts +17 -6
- package/dist/storage/git.js +46 -12
- package/dist/storage/parse-cache.d.ts +67 -0
- package/dist/storage/parse-cache.js +182 -0
- package/dist/storage/repo-manager.d.ts +41 -1
- package/dist/storage/repo-manager.js +17 -2
- package/hooks/claude/gitnexus-hook.cjs +8 -1
- package/hooks/claude/hook-lock.cjs +119 -0
- package/package.json +1 -1
- package/web/assets/{agent-BpHQleHE.js → agent-BG6RCOzz.js} +1 -1
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-F-tujre-.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-2GL7nOvO.js +36 -0
- package/web/assets/blockDiagram-7IZFK4PR-5AjX0pPU.js +132 -0
- package/web/assets/{c4Diagram-DFAF54RM-DeJV1rCn.js → c4Diagram-Y2BXMSZH-hLOeq7xC.js} +2 -2
- package/web/assets/chunk-2T2R6R2M-B_pq_2nf.js +4 -0
- package/web/assets/chunk-2UTLFMKG-CpoohCFN.js +1 -0
- package/web/assets/{chunk-7RZVMHOQ-BdIU-RGO.js → chunk-3SSMPTDK-CfqpR3Nr.js} +1 -1
- package/web/assets/chunk-4R4BOZG6-D3gm7tYj.js +159 -0
- package/web/assets/chunk-6764PJDD-WcI965eO.js +1 -0
- package/web/assets/chunk-AQ6EADP3-BpMj3rQl.js +1 -0
- package/web/assets/{chunk-KSICW3F5-C2tZmXwv.js → chunk-AZZRMDJM-DSoCJlUA.js} +1 -1
- package/web/assets/chunk-C62D2QBJ-CvFF2PnB.js +1 -0
- package/web/assets/chunk-CEXFNPSA-DdNtJtrF.js +1 -0
- package/web/assets/chunk-J5EP6P6S-DtcVaAJI.js +1 -0
- package/web/assets/{chunk-AEOMTBSW-D7qjBMHW.js → chunk-JQRUD6KW-DElaNjc0.js} +1 -1
- package/web/assets/chunk-KGYTTC2M-D0K5or7e.js +1 -0
- package/web/assets/chunk-KRXBNO2N-DpR8iDt8.js +1 -0
- package/web/assets/chunk-LCXTWHL2-DdMObOEk.js +231 -0
- package/web/assets/chunk-LII3EMHJ-I78zXtzi.js +1 -0
- package/web/assets/chunk-RERM46MO-Betu1cSy.js +1 -0
- package/web/assets/chunk-RG4AUYOV-BUCJ2JP5.js +206 -0
- package/web/assets/chunk-RKZBBQEN-Cutpza0t.js +1 -0
- package/web/assets/chunk-RLI5ZMPA-BFUxCvX2.js +1 -0
- package/web/assets/chunk-T5OCTHI4-DKwlkuvB.js +1 -0
- package/web/assets/chunk-UP6H54XL-0YWa0NDg.js +1 -0
- package/web/assets/chunk-UXSXWOXI-CSz0OXpz.js +1 -0
- package/web/assets/chunk-W44A43WB-AOmgoT-X.js +1 -0
- package/web/assets/{chunk-RWUO3TPN-DTWzAhQ1.js → chunk-ZXARS5L4-DIzgxjMw.js} +1 -1
- package/web/assets/classDiagram-KGZ6W3CR-BT-rn7LF.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-uR3nDadY.js +1 -0
- package/web/assets/{cose-bilkent-PNC4W37J-DdZq7Qz_.js → cose-bilkent-UX7MHV2Q-DCSCD1TK.js} +1 -1
- package/web/assets/dagre-ND4H6XIP-CsciHSij.js +4 -0
- package/web/assets/diagram-3NCE3AQN-BKUT5Rpc.js +43 -0
- package/web/assets/diagram-GF46GFSD-Dxb4hZSo.js +24 -0
- package/web/assets/diagram-HNR7UZ2L-D3qus9Cn.js +3 -0
- package/web/assets/diagram-QXG6HAR7-r9BMLGGP.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-BGXqs7-m.js +10 -0
- package/web/assets/{erDiagram-GCSMX5X6-DfdN6iqF.js → erDiagram-L5TCEMPS-LgSWVrkZ.js} +2 -2
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-By7r3bla.js +1 -0
- package/web/assets/flowDiagram-H6V6AXG4-Bj_vV5ky.js +162 -0
- package/web/assets/ganttDiagram-JCBTUEKG-B1eVITSh.js +292 -0
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-ClEP6RdE.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-BP0R-_FD.js +106 -0
- package/web/assets/{index-3NUCUW2s.js → index-oL-ZNYwb.js} +80 -81
- package/web/assets/info-J43DQDTF-KCYPFFUO-bBJRjmP5.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-Dmj4OEO3.js +2 -0
- package/web/assets/{ishikawaDiagram-YMYX4NHK-BF8AtDaj.js → ishikawaDiagram-BNXS4ZKH-B3NgQ4lJ.js} +2 -2
- package/web/assets/{journeyDiagram-SO5T7YLQ-BW8oKa3N.js → journeyDiagram-M6C3CM3L-DALmL4_N.js} +3 -3
- package/web/assets/{kanban-definition-LJHFXRCJ-DzbOsR-2.js → kanban-definition-75IXJCU3-AvVbHpnN.js} +4 -4
- package/web/assets/{katex-GD7MH7QM-CJiOjBBJ.js → katex-K3KEBU37-CqF6_ZN-.js} +1 -1
- package/web/assets/{mindmap-definition-2EUWGEK5-BIXGQALq.js → mindmap-definition-2TDM6QVE-B5c9VOzs.js} +28 -28
- package/web/assets/packet-YPE3B663-LP52Z2RK-1ZCldnu3.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-EhjHC5EE.js +1 -0
- package/web/assets/pieDiagram-CU6KROY3-Po2HSSR4.js +30 -0
- package/web/assets/quadrantDiagram-VICAPDV7-C47UxSZD.js +7 -0
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-CvXjgxlW.js +1 -0
- package/web/assets/{requirementDiagram-M5DCFWZL-CzUUrhQD.js → requirementDiagram-JXO7QTGE-CpECN_Hq.js} +6 -6
- package/web/assets/sankeyDiagram-URQDO5SZ-B3b7cLrS.js +40 -0
- package/web/assets/sequenceDiagram-VS2MUI6T-CRJ95oVP.js +162 -0
- package/web/assets/stateDiagram-7D4R322I-C7U9b3ks.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-BQajbtov.js +1 -0
- package/web/assets/{timeline-definition-5SPVSISX-DkMiGj4Z.js → timeline-definition-O6YCAMPW-rtbk6BBo.js} +4 -4
- package/web/assets/treeView-BLDUP644-QA4HXRO3-R2o5gwfP.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-Cesmac_u.js +1 -0
- package/web/assets/{vennDiagram-IE5QUKF5-BCxMmf9q.js → vennDiagram-MWXL3ELB-W8Yoaayh.js} +3 -3
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-B9HYoRgA.js +1 -0
- package/web/assets/wardleyDiagram-CUQ6CDDI-DIZw5Abj.js +78 -0
- package/web/assets/{xychartDiagram-ZHJ5623Y-DZ7fP1_3.js → xychartDiagram-N2JHSOCM-DGRtrj4P.js} +3 -3
- package/web/index.html +2 -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-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/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/flowDiagram-OTCZ4VVT-aAZw4c_M.js +0 -162
- 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/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +0 -1
- package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +0 -2
- 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/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/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +0 -1
- package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +0 -1
- 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-CG-ydtp4.js} +0 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree-sitter query for PHP scope captures (RFC #909 Ring 3 LANG-php).
|
|
3
|
+
*
|
|
4
|
+
* Captures the structural skeleton the generic scope-resolution pipeline
|
|
5
|
+
* consumes: scopes (program/namespace/class/function), declarations
|
|
6
|
+
* (class-likes, method-likes, properties, variables), imports
|
|
7
|
+
* (namespace_use_declaration), type bindings (parameter annotations,
|
|
8
|
+
* property types, constructor-inferred locals, return types), and
|
|
9
|
+
* references (call sites, member writes).
|
|
10
|
+
*
|
|
11
|
+
* PHP specifics that shape this query:
|
|
12
|
+
*
|
|
13
|
+
* - `namespace_use_declaration` is an import only at top level / inside
|
|
14
|
+
* namespace blocks. Class-body `use_declaration` (trait-use) is a
|
|
15
|
+
* different node type and is NOT captured here.
|
|
16
|
+
*
|
|
17
|
+
* - `object_creation_expression` has `name` and `qualified_name` as
|
|
18
|
+
* direct children (no wrapping node).
|
|
19
|
+
*
|
|
20
|
+
* - `method_declaration` exposes a `return_type:` named field containing
|
|
21
|
+
* a `type` node, which may be `named_type`, `optional_type`, etc.
|
|
22
|
+
*
|
|
23
|
+
* - `property_element` has a `name:` field of type `variable_name`.
|
|
24
|
+
*
|
|
25
|
+
* - `variable_name` nodes always include the `$` sigil in their text.
|
|
26
|
+
*
|
|
27
|
+
* Exposes lazy `Parser` and `Query` singletons so callers don't pay
|
|
28
|
+
* tree-sitter init cost per file.
|
|
29
|
+
*/
|
|
30
|
+
import Parser from 'tree-sitter';
|
|
31
|
+
import Php from 'tree-sitter-php';
|
|
32
|
+
// tree-sitter-php exports `{ php, php_only, html }` in recent versions, or the
|
|
33
|
+
// language directly in older versions.
|
|
34
|
+
//
|
|
35
|
+
// IMPORTANT: must match the grammar used by the central parse phase
|
|
36
|
+
// (`src/core/tree-sitter/parser-loader.ts` line: `[SupportedLanguages.PHP]: PHP.php_only`).
|
|
37
|
+
// Using a different grammar variant causes tree-sitter to throw when running
|
|
38
|
+
// a query built against grammar A on a tree parsed by grammar B — this error
|
|
39
|
+
// is swallowed by `scope-extractor-bridge.ts`, producing silent empty results.
|
|
40
|
+
const Php_typed = Php;
|
|
41
|
+
const PHP_LANG = Php_typed.php_only ?? Php_typed.php ?? Php;
|
|
42
|
+
const PHP_SCOPE_QUERY = `
|
|
43
|
+
;; ── Scopes ────────────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
(program) @scope.module
|
|
46
|
+
|
|
47
|
+
;; Both block-scoped and statement-scoped namespace declarations.
|
|
48
|
+
(namespace_definition) @scope.namespace
|
|
49
|
+
|
|
50
|
+
(class_declaration) @scope.class
|
|
51
|
+
(interface_declaration) @scope.class
|
|
52
|
+
(trait_declaration) @scope.class
|
|
53
|
+
(enum_declaration) @scope.class
|
|
54
|
+
|
|
55
|
+
(method_declaration) @scope.function
|
|
56
|
+
(function_definition) @scope.function
|
|
57
|
+
(anonymous_function) @scope.function
|
|
58
|
+
(arrow_function) @scope.function
|
|
59
|
+
|
|
60
|
+
;; ── Declarations — types ──────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
(class_declaration
|
|
63
|
+
name: (name) @declaration.name) @declaration.class
|
|
64
|
+
|
|
65
|
+
(interface_declaration
|
|
66
|
+
name: (name) @declaration.name) @declaration.interface
|
|
67
|
+
|
|
68
|
+
(trait_declaration
|
|
69
|
+
name: (name) @declaration.name) @declaration.trait
|
|
70
|
+
|
|
71
|
+
(enum_declaration
|
|
72
|
+
name: (name) @declaration.name) @declaration.enum
|
|
73
|
+
|
|
74
|
+
;; ── Declarations — methods / functions / constructors ─────────────────────
|
|
75
|
+
|
|
76
|
+
(method_declaration
|
|
77
|
+
name: (name) @declaration.name) @declaration.method
|
|
78
|
+
|
|
79
|
+
(function_definition
|
|
80
|
+
name: (name) @declaration.name) @declaration.function
|
|
81
|
+
|
|
82
|
+
;; ── Declarations — properties ─────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
;; PHP 7.4+ typed property: private UserRepo $repo;
|
|
85
|
+
;; property_element has name: (variable_name) field.
|
|
86
|
+
;; Emits BOTH a declaration (so SemanticModel registers the property) AND a type-binding.
|
|
87
|
+
(property_declaration
|
|
88
|
+
type: (_) @type-binding.type
|
|
89
|
+
(property_element
|
|
90
|
+
name: (variable_name) @type-binding.name)) @type-binding.annotation
|
|
91
|
+
|
|
92
|
+
(property_declaration
|
|
93
|
+
type: (_)
|
|
94
|
+
(property_element
|
|
95
|
+
name: (variable_name) @declaration.name)) @declaration.property
|
|
96
|
+
|
|
97
|
+
;; Untyped property: public $id; — capture as plain declaration.
|
|
98
|
+
(property_declaration
|
|
99
|
+
(property_element
|
|
100
|
+
name: (variable_name) @declaration.name)) @declaration.variable
|
|
101
|
+
|
|
102
|
+
;; ── Imports — namespace_use_declaration ───────────────────────────────────
|
|
103
|
+
;;
|
|
104
|
+
;; Captures ALL forms: plain, alias, function/const qualifiers, and grouped.
|
|
105
|
+
;; The import-decomposer in captures.ts fans out grouped uses.
|
|
106
|
+
;;
|
|
107
|
+
;; NOTE: class-body use_declaration = trait-use, NOT an import.
|
|
108
|
+
;; Only namespace_use_declaration (top-level / namespace scope) is an import.
|
|
109
|
+
|
|
110
|
+
(namespace_use_declaration) @import.statement
|
|
111
|
+
|
|
112
|
+
;; ── Type bindings — parameters ────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
;; simple_parameter with a type hint: function f(User $u)
|
|
115
|
+
;; type field is a 'type' supertype (named_type, optional_type, union_type, etc.)
|
|
116
|
+
(simple_parameter
|
|
117
|
+
type: (_) @type-binding.type
|
|
118
|
+
name: (variable_name) @type-binding.name) @type-binding.parameter
|
|
119
|
+
|
|
120
|
+
;; property_promotion_parameter: function __construct(private User $u)
|
|
121
|
+
;; Emits type-binding so the constructor body can resolve $u as the typed param.
|
|
122
|
+
(property_promotion_parameter
|
|
123
|
+
type: (_) @type-binding.type
|
|
124
|
+
name: (variable_name) @type-binding.name) @type-binding.parameter
|
|
125
|
+
|
|
126
|
+
;; Also emit a @type-binding.annotation for the promoted parameter so that
|
|
127
|
+
;; phpBindingScopeFor can hoist it to the Class scope (stripping the $ sigil).
|
|
128
|
+
;; This enables compound-receiver resolution: $user->address->save() resolves
|
|
129
|
+
;; address → Address via the Class scope's typeBindings.
|
|
130
|
+
;; The @type-binding.parameter above stays for constructor-body resolution ($address).
|
|
131
|
+
(property_promotion_parameter
|
|
132
|
+
type: (_) @type-binding.type
|
|
133
|
+
name: (variable_name) @type-binding.name) @type-binding.annotation
|
|
134
|
+
|
|
135
|
+
;; Also emit a @declaration.property so SemanticModel registers the promoted
|
|
136
|
+
;; parameter as a class-owned property (enabling $obj->propName lookups).
|
|
137
|
+
(property_promotion_parameter
|
|
138
|
+
name: (variable_name) @declaration.name) @declaration.property
|
|
139
|
+
|
|
140
|
+
;; ── Type bindings — local assignment: $u = new User() ─────────────────────
|
|
141
|
+
|
|
142
|
+
;; new ClassName() — name is a direct child of object_creation_expression
|
|
143
|
+
(assignment_expression
|
|
144
|
+
left: (variable_name) @type-binding.name
|
|
145
|
+
right: (object_creation_expression
|
|
146
|
+
(name) @type-binding.type)) @type-binding.constructor
|
|
147
|
+
|
|
148
|
+
;; new Foo\Bar\ClassName() — qualified_name wraps name
|
|
149
|
+
(assignment_expression
|
|
150
|
+
left: (variable_name) @type-binding.name
|
|
151
|
+
right: (object_creation_expression
|
|
152
|
+
(qualified_name
|
|
153
|
+
(name) @type-binding.type))) @type-binding.constructor
|
|
154
|
+
|
|
155
|
+
;; ── Type bindings — $alias = $u (identifier alias) ───────────────────────
|
|
156
|
+
|
|
157
|
+
(assignment_expression
|
|
158
|
+
left: (variable_name) @type-binding.name
|
|
159
|
+
right: (variable_name) @type-binding.type) @type-binding.alias
|
|
160
|
+
|
|
161
|
+
;; ── Type bindings — $u = factory() (free call return alias) ──────────────
|
|
162
|
+
|
|
163
|
+
(assignment_expression
|
|
164
|
+
left: (variable_name) @type-binding.name
|
|
165
|
+
right: (function_call_expression
|
|
166
|
+
function: (name) @type-binding.type)) @type-binding.alias
|
|
167
|
+
|
|
168
|
+
;; ── Type bindings — $u = $svc->getUser() (method call return alias) ───────
|
|
169
|
+
|
|
170
|
+
(assignment_expression
|
|
171
|
+
left: (variable_name) @type-binding.name
|
|
172
|
+
right: (member_call_expression
|
|
173
|
+
name: (name) @type-binding.type)) @type-binding.alias
|
|
174
|
+
|
|
175
|
+
;; ── Type bindings — method return type ───────────────────────────────────
|
|
176
|
+
|
|
177
|
+
;; method_declaration exposes return_type: field (type node supertype).
|
|
178
|
+
;; named_type wraps the class name: function getUser(): User
|
|
179
|
+
(method_declaration
|
|
180
|
+
name: (name) @type-binding.name
|
|
181
|
+
return_type: (named_type
|
|
182
|
+
(name) @type-binding.type)) @type-binding.return
|
|
183
|
+
|
|
184
|
+
;; nullable return type via optional_type: function getUser(): ?User
|
|
185
|
+
(method_declaration
|
|
186
|
+
name: (name) @type-binding.name
|
|
187
|
+
return_type: (optional_type
|
|
188
|
+
(named_type
|
|
189
|
+
(name) @type-binding.type))) @type-binding.return
|
|
190
|
+
|
|
191
|
+
;; function_definition (top-level or namespace-level) return type: User
|
|
192
|
+
;; Enables cross-file return-type propagation for free functions.
|
|
193
|
+
(function_definition
|
|
194
|
+
name: (name) @type-binding.name
|
|
195
|
+
return_type: (named_type
|
|
196
|
+
(name) @type-binding.type)) @type-binding.return
|
|
197
|
+
|
|
198
|
+
;; nullable return type for function_definition: ?User
|
|
199
|
+
(function_definition
|
|
200
|
+
name: (name) @type-binding.name
|
|
201
|
+
return_type: (optional_type
|
|
202
|
+
(named_type
|
|
203
|
+
(name) @type-binding.type))) @type-binding.return
|
|
204
|
+
|
|
205
|
+
;; ── References — free calls: foo() ───────────────────────────────────────
|
|
206
|
+
|
|
207
|
+
(function_call_expression
|
|
208
|
+
function: (name) @reference.name) @reference.call.free
|
|
209
|
+
|
|
210
|
+
;; ── References — member calls: $obj->method() ────────────────────────────
|
|
211
|
+
;;
|
|
212
|
+
;; SAFETY-INVARIANT (Finding 1 of PR #1497 adversarial review): the name:
|
|
213
|
+
;; field is constrained to (name), NOT (_) — tree-sitter-php emits
|
|
214
|
+
;; variable_name nodes for dynamic method names ($obj->$method(),
|
|
215
|
+
;; $obj->{$method}()). Keeping the pattern at (name) is what suppresses
|
|
216
|
+
;; capture of those dynamic shapes. The resolver is structural-only and
|
|
217
|
+
;; cannot infer the bound method name from runtime values; relaxing this
|
|
218
|
+
;; pattern to (_) would silently emit zero-confidence false-positive
|
|
219
|
+
;; edges. Regression: test/fixtures/lang-resolution/php-dynamic-calls/.
|
|
220
|
+
|
|
221
|
+
(member_call_expression
|
|
222
|
+
object: (_) @reference.receiver
|
|
223
|
+
name: (name) @reference.name) @reference.call.member
|
|
224
|
+
|
|
225
|
+
;; ── References — null-safe member calls: $obj?->method() (PHP 8+) ─────────
|
|
226
|
+
|
|
227
|
+
(nullsafe_member_call_expression
|
|
228
|
+
object: (_) @reference.receiver
|
|
229
|
+
name: (name) @reference.name) @reference.call.member
|
|
230
|
+
|
|
231
|
+
;; ── References — static calls: X::method() ───────────────────────────────
|
|
232
|
+
;;
|
|
233
|
+
;; Same SAFETY-INVARIANT as member_call_expression above: name: (name)
|
|
234
|
+
;; deliberately excludes variable_name so Class::$method() and
|
|
235
|
+
;; $className::$method() shapes do not capture. The receiver field uses
|
|
236
|
+
;; (_) because static dispatch on a variable receiver
|
|
237
|
+
;; ($className::method()) IS captured — but resolution falls through
|
|
238
|
+
;; harmlessly when $className has no class type binding. See
|
|
239
|
+
;; php-dynamic-calls/ regression suite.
|
|
240
|
+
|
|
241
|
+
(scoped_call_expression
|
|
242
|
+
scope: (_) @reference.receiver
|
|
243
|
+
name: (name) @reference.name) @reference.call.member
|
|
244
|
+
|
|
245
|
+
;; ── Type bindings — $x = X::Constant or $x = X::CASE (enum case) ─────────
|
|
246
|
+
;; Binds the variable to the class name X so member calls on $x dispatch
|
|
247
|
+
;; to X's methods (e.g. UserRole::Viewer → label()).
|
|
248
|
+
;;
|
|
249
|
+
;; tree-sitter-php emits class_constant_access_expression with two name
|
|
250
|
+
;; children: [0]=class/enum name, [1]=constant/case name. The dot-anchor
|
|
251
|
+
;; before (name) matches only the FIRST name child (the class).
|
|
252
|
+
|
|
253
|
+
(assignment_expression
|
|
254
|
+
left: (variable_name) @type-binding.name
|
|
255
|
+
right: (class_constant_access_expression
|
|
256
|
+
. (name) @type-binding.type)) @type-binding.alias
|
|
257
|
+
|
|
258
|
+
(assignment_expression
|
|
259
|
+
left: (variable_name) @type-binding.name
|
|
260
|
+
right: (class_constant_access_expression
|
|
261
|
+
(qualified_name
|
|
262
|
+
(name) @type-binding.type))) @type-binding.alias
|
|
263
|
+
|
|
264
|
+
;; ── Type bindings — $x = SomeClass::staticFactory() ──────────────────────
|
|
265
|
+
;; Binds $x to the type returned by the static factory method, anchored on
|
|
266
|
+
;; the method name (chain-follow resolves the actual return type later).
|
|
267
|
+
|
|
268
|
+
(assignment_expression
|
|
269
|
+
left: (variable_name) @type-binding.name
|
|
270
|
+
right: (scoped_call_expression
|
|
271
|
+
name: (name) @type-binding.type)) @type-binding.alias
|
|
272
|
+
|
|
273
|
+
;; ── Type bindings — null-safe member-call result: $x = $a?->getY() ───────
|
|
274
|
+
|
|
275
|
+
(assignment_expression
|
|
276
|
+
left: (variable_name) @type-binding.name
|
|
277
|
+
right: (nullsafe_member_call_expression
|
|
278
|
+
name: (name) @type-binding.type)) @type-binding.alias
|
|
279
|
+
|
|
280
|
+
;; ── References — constructor calls: new User() ───────────────────────────
|
|
281
|
+
|
|
282
|
+
(object_creation_expression
|
|
283
|
+
(name) @reference.name) @reference.call.constructor
|
|
284
|
+
|
|
285
|
+
(object_creation_expression
|
|
286
|
+
(qualified_name
|
|
287
|
+
(name) @reference.name)) @reference.call.constructor
|
|
288
|
+
|
|
289
|
+
;; ── References — member writes: $obj->prop = $x ──────────────────────────
|
|
290
|
+
|
|
291
|
+
(assignment_expression
|
|
292
|
+
left: (member_access_expression
|
|
293
|
+
object: (_) @reference.receiver
|
|
294
|
+
name: (name) @reference.name)) @reference.write.member
|
|
295
|
+
|
|
296
|
+
;; ── References — static property writes: User::$count = $x ──────────────
|
|
297
|
+
;; Uses @reference.write.static anchor so captures.ts can strip the leading
|
|
298
|
+
;; $ from the variable_name capture (static props are stored without $ in graph).
|
|
299
|
+
;;
|
|
300
|
+
;; SAFETY-INVARIANT (Finding 2 of PR #1497 adversarial review): no
|
|
301
|
+
;; read-access property capture exists in this query — dynamic property
|
|
302
|
+
;; reads ($obj->$prop, $obj->{$prop}) produce no captures, which is the
|
|
303
|
+
;; desired behavior for a structural-only resolver. Adding a read pattern
|
|
304
|
+
;; in the future MUST keep name: (name) (not (_)) to preserve the
|
|
305
|
+
;; suppression. Regression: php-dynamic-calls/ fixture dynamicPropertyRead.
|
|
306
|
+
|
|
307
|
+
(assignment_expression
|
|
308
|
+
left: (scoped_property_access_expression
|
|
309
|
+
scope: (_) @reference.receiver
|
|
310
|
+
name: (variable_name) @reference.name)) @reference.write.static
|
|
311
|
+
`;
|
|
312
|
+
let _parser = null;
|
|
313
|
+
let _query = null;
|
|
314
|
+
export function getPhpParser() {
|
|
315
|
+
if (_parser === null) {
|
|
316
|
+
_parser = new Parser();
|
|
317
|
+
_parser.setLanguage(PHP_LANG);
|
|
318
|
+
}
|
|
319
|
+
return _parser;
|
|
320
|
+
}
|
|
321
|
+
export function getPhpScopeQuery() {
|
|
322
|
+
if (_query === null) {
|
|
323
|
+
_query = new Parser.Query(PHP_LANG, PHP_SCOPE_QUERY);
|
|
324
|
+
}
|
|
325
|
+
return _query;
|
|
326
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesize `@type-binding.self` captures for PHP instance methods —
|
|
3
|
+
* one for `$this` (always on non-static methods inside a type
|
|
4
|
+
* declaration) and optionally one for `parent` (only on class methods
|
|
5
|
+
* when the enclosing class has an explicit `base_clause`).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors `languages/csharp/receiver-binding.ts` in structure. PHP's
|
|
8
|
+
* grammar doesn't give us a clean `.scm` pattern for "implicit receiver
|
|
9
|
+
* on every instance method inside an enclosing type" because `$this` is
|
|
10
|
+
* not a parameter — it's an implicit receiver. Synthesis in code is the
|
|
11
|
+
* same approach C# uses for `this` / `base`.
|
|
12
|
+
*
|
|
13
|
+
* ## Known limitations
|
|
14
|
+
*
|
|
15
|
+
* - **Trait `$this`**: for methods defined in a trait, `$this` is
|
|
16
|
+
* synthesized as a binding to the trait itself. The actual using-class
|
|
17
|
+
* type is not known at single-file parse time. V1 limitation —
|
|
18
|
+
* documented in `index.ts`.
|
|
19
|
+
* - **Anonymous classes**: skipped (no stable enclosing class name).
|
|
20
|
+
*/
|
|
21
|
+
import type { CaptureMatch } from '../../../../_shared/index.js';
|
|
22
|
+
import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
23
|
+
/**
|
|
24
|
+
* Build zero, one, or two `@type-binding.self` matches for `fnNode`:
|
|
25
|
+
*
|
|
26
|
+
* - Returns `[]` if the function is free (no enclosing type), static,
|
|
27
|
+
* or the enclosing type has no resolvable name.
|
|
28
|
+
* - Returns one match (`$this`) for non-static methods inside a
|
|
29
|
+
* class / trait / interface / enum body.
|
|
30
|
+
* - Returns two matches (`$this` + `parent`) only when the function
|
|
31
|
+
* lives in a `class_declaration` that has an explicit `base_clause`.
|
|
32
|
+
*
|
|
33
|
+
* The caller is responsible for guaranteeing
|
|
34
|
+
* `FUNCTION_NODE_TYPES.has(fnNode.type)`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function synthesizePhpReceiverBinding(fnNode: SyntaxNode): CaptureMatch[];
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesize `@type-binding.self` captures for PHP instance methods —
|
|
3
|
+
* one for `$this` (always on non-static methods inside a type
|
|
4
|
+
* declaration) and optionally one for `parent` (only on class methods
|
|
5
|
+
* when the enclosing class has an explicit `base_clause`).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors `languages/csharp/receiver-binding.ts` in structure. PHP's
|
|
8
|
+
* grammar doesn't give us a clean `.scm` pattern for "implicit receiver
|
|
9
|
+
* on every instance method inside an enclosing type" because `$this` is
|
|
10
|
+
* not a parameter — it's an implicit receiver. Synthesis in code is the
|
|
11
|
+
* same approach C# uses for `this` / `base`.
|
|
12
|
+
*
|
|
13
|
+
* ## Known limitations
|
|
14
|
+
*
|
|
15
|
+
* - **Trait `$this`**: for methods defined in a trait, `$this` is
|
|
16
|
+
* synthesized as a binding to the trait itself. The actual using-class
|
|
17
|
+
* type is not known at single-file parse time. V1 limitation —
|
|
18
|
+
* documented in `index.ts`.
|
|
19
|
+
* - **Anonymous classes**: skipped (no stable enclosing class name).
|
|
20
|
+
*/
|
|
21
|
+
import { nodeToCapture, syntheticCapture } from '../../utils/ast-helpers.js';
|
|
22
|
+
const TYPE_DECL_NODE_TYPES = new Set([
|
|
23
|
+
'class_declaration',
|
|
24
|
+
'interface_declaration',
|
|
25
|
+
'trait_declaration',
|
|
26
|
+
'enum_declaration',
|
|
27
|
+
]);
|
|
28
|
+
const FUNCTION_NODE_TYPES = new Set([
|
|
29
|
+
'method_declaration',
|
|
30
|
+
'function_definition',
|
|
31
|
+
'anonymous_function',
|
|
32
|
+
'arrow_function',
|
|
33
|
+
]);
|
|
34
|
+
/** Walk up to find the enclosing type declaration. */
|
|
35
|
+
function findEnclosingTypeDeclaration(node) {
|
|
36
|
+
let cur = node.parent;
|
|
37
|
+
while (cur !== null) {
|
|
38
|
+
if (TYPE_DECL_NODE_TYPES.has(cur.type))
|
|
39
|
+
return cur;
|
|
40
|
+
cur = cur.parent;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function typeName(typeNode) {
|
|
45
|
+
return typeNode.childForFieldName('name')?.text ?? null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Return the base class name from a `base_clause` child of the class node.
|
|
49
|
+
* `base_clause` contains a `qualified_name` or `name` child.
|
|
50
|
+
*/
|
|
51
|
+
function baseClauseText(typeNode) {
|
|
52
|
+
for (let i = 0; i < typeNode.namedChildCount; i++) {
|
|
53
|
+
const child = typeNode.namedChild(i);
|
|
54
|
+
if (child === null || child.type !== 'base_clause')
|
|
55
|
+
continue;
|
|
56
|
+
const nameNode = child.firstNamedChild;
|
|
57
|
+
if (nameNode === null)
|
|
58
|
+
return null;
|
|
59
|
+
// Take last segment of qualified name (e.g. \App\Models\BaseModel → BaseModel)
|
|
60
|
+
const text = nameNode.text.trim();
|
|
61
|
+
const segments = text.split('\\').filter(Boolean);
|
|
62
|
+
return segments[segments.length - 1] ?? text;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
/** Check whether this method has a `static_modifier` child. */
|
|
67
|
+
function isStaticMethod(fnNode) {
|
|
68
|
+
for (let i = 0; i < fnNode.namedChildCount; i++) {
|
|
69
|
+
const child = fnNode.namedChild(i);
|
|
70
|
+
if (child !== null && child.type === 'static_modifier')
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build zero, one, or two `@type-binding.self` matches for `fnNode`:
|
|
77
|
+
*
|
|
78
|
+
* - Returns `[]` if the function is free (no enclosing type), static,
|
|
79
|
+
* or the enclosing type has no resolvable name.
|
|
80
|
+
* - Returns one match (`$this`) for non-static methods inside a
|
|
81
|
+
* class / trait / interface / enum body.
|
|
82
|
+
* - Returns two matches (`$this` + `parent`) only when the function
|
|
83
|
+
* lives in a `class_declaration` that has an explicit `base_clause`.
|
|
84
|
+
*
|
|
85
|
+
* The caller is responsible for guaranteeing
|
|
86
|
+
* `FUNCTION_NODE_TYPES.has(fnNode.type)`.
|
|
87
|
+
*/
|
|
88
|
+
export function synthesizePhpReceiverBinding(fnNode) {
|
|
89
|
+
if (!FUNCTION_NODE_TYPES.has(fnNode.type))
|
|
90
|
+
return [];
|
|
91
|
+
if (isStaticMethod(fnNode))
|
|
92
|
+
return [];
|
|
93
|
+
const enclosingType = findEnclosingTypeDeclaration(fnNode);
|
|
94
|
+
if (enclosingType === null)
|
|
95
|
+
return [];
|
|
96
|
+
// Anonymous class — skip (no stable name).
|
|
97
|
+
if (enclosingType.type === 'anonymous_class_declaration')
|
|
98
|
+
return [];
|
|
99
|
+
const enclosingName = typeName(enclosingType);
|
|
100
|
+
if (enclosingName === null)
|
|
101
|
+
return [];
|
|
102
|
+
// Anchor the synthesized captures to the method body (compound_statement)
|
|
103
|
+
// so they land inside the function scope, not at the class scope.
|
|
104
|
+
// For interface/abstract methods that have no body, skip.
|
|
105
|
+
const bodyNode = fnNode.childForFieldName('body') ??
|
|
106
|
+
// arrow_function: body is the expression after `=>`
|
|
107
|
+
fnNode.childForFieldName('return_value');
|
|
108
|
+
if (bodyNode === null)
|
|
109
|
+
return [];
|
|
110
|
+
const out = [];
|
|
111
|
+
out.push(buildReceiverMatch(bodyNode, '$this', enclosingName));
|
|
112
|
+
// `parent` applies only to class methods with an explicit base_clause.
|
|
113
|
+
if (enclosingType.type === 'class_declaration') {
|
|
114
|
+
const baseText = baseClauseText(enclosingType);
|
|
115
|
+
if (baseText !== null) {
|
|
116
|
+
out.push(buildReceiverMatch(bodyNode, 'parent', baseText));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
function buildReceiverMatch(anchorNode, name, typeText) {
|
|
122
|
+
const m = {
|
|
123
|
+
'@type-binding.self': nodeToCapture('@type-binding.self', anchorNode),
|
|
124
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', anchorNode, name),
|
|
125
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', anchorNode, typeText),
|
|
126
|
+
};
|
|
127
|
+
return m;
|
|
128
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PHP `ScopeResolver` registered in `SCOPE_RESOLVERS` and consumed by
|
|
3
|
+
* the generic `runScopeResolution` orchestrator (RFC #909 Ring 3 LANG-php).
|
|
4
|
+
*
|
|
5
|
+
* Third migration after Python and C#. See `pythonScopeResolver` for the
|
|
6
|
+
* canonical shape.
|
|
7
|
+
*
|
|
8
|
+
* ## Circular-import avoidance
|
|
9
|
+
*
|
|
10
|
+
* The old PR had `php/scope-resolver.ts` importing `phpProvider` from
|
|
11
|
+
* `../php.js` while `php.ts` imported `phpScopeResolver` from `./php/index.js`
|
|
12
|
+
* — undefined at module load. The canonical fix (mirroring C#):
|
|
13
|
+
*
|
|
14
|
+
* - `scope-resolver.ts` imports `phpProvider` from `../php.js` ✓
|
|
15
|
+
* - `php.ts` imports individual hook FUNCTIONS from `./php/index.js` ✗
|
|
16
|
+
*
|
|
17
|
+
* Node's ESM handles the cycle correctly because `phpProvider` is a named
|
|
18
|
+
* export that is live-binding — by the time `phpScopeResolver` is first
|
|
19
|
+
* read (lazily, at resolution time), `phpProvider` is fully initialized.
|
|
20
|
+
*/
|
|
21
|
+
import type { ScopeResolver } from '../../scope-resolution/contract/scope-resolver.js';
|
|
22
|
+
declare const phpScopeResolver: ScopeResolver;
|
|
23
|
+
export { phpScopeResolver };
|