gitnexus 1.6.4-rc.2 → 1.6.4-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 +35 -0
- package/dist/_shared/index.d.ts +1 -1
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +22 -14
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +298 -37
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts +23 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.js +36 -2
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +47 -3
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/types.js +10 -2
- package/dist/_shared/scope-resolution/types.js.map +1 -1
- package/dist/cli/analyze.d.ts +6 -0
- package/dist/cli/analyze.js +35 -0
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.js +31 -0
- package/dist/cli/index.js +13 -0
- package/dist/cli/setup.js +2 -2
- package/dist/core/embeddings/config.d.ts +2 -0
- package/dist/core/embeddings/config.js +36 -0
- package/dist/core/embeddings/embedder.js +11 -6
- package/dist/core/embeddings/embedding-pipeline.d.ts +7 -1
- package/dist/core/embeddings/embedding-pipeline.js +93 -29
- package/dist/core/embeddings/exact-search.d.ts +15 -0
- package/dist/core/embeddings/exact-search.js +27 -0
- package/dist/core/embeddings/types.d.ts +4 -0
- package/dist/core/embeddings/types.js +2 -0
- package/dist/core/group/config-parser.js +2 -0
- package/dist/core/group/matching.d.ts +3 -3
- package/dist/core/group/matching.js +46 -6
- package/dist/core/group/storage.js +2 -0
- package/dist/core/group/sync.js +1 -1
- package/dist/core/group/types.d.ts +18 -0
- package/dist/core/ingestion/call-processor.d.ts +3 -3
- package/dist/core/ingestion/call-processor.js +58 -65
- package/dist/core/ingestion/constants.d.ts +4 -3
- package/dist/core/ingestion/constants.js +8 -3
- package/dist/core/ingestion/finalize-orchestrator.js +6 -3
- package/dist/core/ingestion/heritage-processor.js +2 -2
- package/dist/core/ingestion/import-processor.js +1 -1
- package/dist/core/ingestion/language-provider.d.ts +8 -0
- package/dist/core/ingestion/languages/csharp/captures.js +4 -1
- package/dist/core/ingestion/languages/csharp/namespace-siblings.d.ts +14 -13
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +62 -50
- package/dist/core/ingestion/languages/python/captures.js +9 -1
- package/dist/core/ingestion/languages/python/index.d.ts +1 -1
- package/dist/core/ingestion/languages/python/index.js +1 -1
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +3 -1
- package/dist/core/ingestion/languages/python/simple-hooks.js +8 -0
- package/dist/core/ingestion/languages/python.js +28 -1
- package/dist/core/ingestion/languages/swift.js +14 -0
- package/dist/core/ingestion/languages/typescript/arity-metadata.d.ts +59 -0
- package/dist/core/ingestion/languages/typescript/arity-metadata.js +103 -0
- package/dist/core/ingestion/languages/typescript/arity.d.ts +37 -0
- package/dist/core/ingestion/languages/typescript/arity.js +54 -0
- package/dist/core/ingestion/languages/typescript/cache-stats.d.ts +17 -0
- package/dist/core/ingestion/languages/typescript/cache-stats.js +28 -0
- package/dist/core/ingestion/languages/typescript/captures.d.ts +28 -0
- package/dist/core/ingestion/languages/typescript/captures.js +451 -0
- package/dist/core/ingestion/languages/typescript/import-decomposer.d.ts +49 -0
- package/dist/core/ingestion/languages/typescript/import-decomposer.js +371 -0
- package/dist/core/ingestion/languages/typescript/import-target.d.ts +50 -0
- package/dist/core/ingestion/languages/typescript/import-target.js +61 -0
- package/dist/core/ingestion/languages/typescript/index.d.ts +94 -0
- package/dist/core/ingestion/languages/typescript/index.js +94 -0
- package/dist/core/ingestion/languages/typescript/interpret.d.ts +35 -0
- package/dist/core/ingestion/languages/typescript/interpret.js +317 -0
- package/dist/core/ingestion/languages/typescript/merge-bindings.d.ts +62 -0
- package/dist/core/ingestion/languages/typescript/merge-bindings.js +158 -0
- package/dist/core/ingestion/languages/typescript/query.d.ts +77 -0
- package/dist/core/ingestion/languages/typescript/query.js +778 -0
- package/dist/core/ingestion/languages/typescript/receiver-binding.d.ts +59 -0
- package/dist/core/ingestion/languages/typescript/receiver-binding.js +171 -0
- package/dist/core/ingestion/languages/typescript/scope-resolver.d.ts +16 -0
- package/dist/core/ingestion/languages/typescript/scope-resolver.js +113 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +71 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.js +131 -0
- package/dist/core/ingestion/languages/typescript.js +19 -0
- package/dist/core/ingestion/method-extractors/configs/swift.js +3 -4
- package/dist/core/ingestion/model/scope-resolution-indexes.d.ts +14 -1
- package/dist/core/ingestion/parsing-processor.js +20 -9
- package/dist/core/ingestion/pipeline-phases/processes.js +9 -4
- package/dist/core/ingestion/pipeline-phases/tools.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/tools.js +10 -4
- package/dist/core/ingestion/registry-primary-flag.d.ts +3 -1
- package/dist/core/ingestion/registry-primary-flag.js +4 -1
- package/dist/core/ingestion/scope-extractor-bridge.d.ts +5 -2
- package/dist/core/ingestion/scope-extractor-bridge.js +7 -2
- package/dist/core/ingestion/scope-extractor.js +19 -18
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +73 -11
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +48 -10
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +283 -14
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.d.ts +23 -2
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +109 -37
- package/dist/core/ingestion/scope-resolution/passes/mro.js +3 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +13 -5
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +11 -2
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +8 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +21 -5
- package/dist/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.d.ts +39 -0
- package/dist/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +65 -0
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +54 -11
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +105 -30
- package/dist/core/ingestion/type-extractors/swift.js +7 -4
- package/dist/core/ingestion/utils/ast-helpers.d.ts +2 -0
- package/dist/core/ingestion/utils/ast-helpers.js +12 -0
- package/dist/core/ingestion/utils/env.d.ts +10 -0
- package/dist/core/ingestion/utils/env.js +14 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +1 -0
- package/dist/core/ingestion/workers/parse-worker.js +15 -9
- package/dist/core/ingestion/workers/worker-pool.d.ts +11 -4
- package/dist/core/ingestion/workers/worker-pool.js +244 -48
- package/dist/core/lbug/extension-loader.d.ts +86 -0
- package/dist/core/lbug/extension-loader.js +184 -0
- package/dist/core/lbug/lbug-adapter.d.ts +18 -17
- package/dist/core/lbug/lbug-adapter.js +45 -73
- package/dist/core/lbug/pool-adapter.js +10 -28
- package/dist/core/platform/capabilities.d.ts +24 -0
- package/dist/core/platform/capabilities.js +54 -0
- package/dist/core/run-analyze.js +36 -9
- package/dist/core/search/bm25-index.d.ts +0 -17
- package/dist/core/search/bm25-index.js +10 -118
- package/dist/core/search/fts-indexes.d.ts +1 -0
- package/dist/core/search/fts-indexes.js +7 -0
- package/dist/core/search/fts-schema.d.ts +6 -0
- package/dist/core/search/fts-schema.js +7 -0
- package/dist/mcp/core/embedder.js +11 -4
- package/dist/mcp/local/local-backend.js +50 -15
- package/dist/server/api.d.ts +5 -0
- package/dist/server/api.js +113 -0
- package/hooks/claude/gitnexus-hook.cjs +11 -1
- package/package.json +6 -5
- package/scripts/build-tree-sitter-dart.cjs +42 -0
- package/scripts/build-tree-sitter-proto.cjs +1 -1
- package/scripts/build.js +22 -2
- package/scripts/install-duckdb-extension.mjs +37 -0
- package/vendor/tree-sitter-dart/README.md +18 -0
- package/vendor/tree-sitter-dart/binding.gyp +31 -0
- package/vendor/tree-sitter-dart/bindings/node/binding.cc +20 -0
- package/vendor/tree-sitter-dart/bindings/node/index.d.ts +28 -0
- package/vendor/tree-sitter-dart/bindings/node/index.js +7 -0
- package/vendor/tree-sitter-dart/grammar.js +2895 -0
- package/vendor/tree-sitter-dart/package.json +18 -0
- package/vendor/tree-sitter-dart/queries/highlights.scm +246 -0
- package/vendor/tree-sitter-dart/queries/tags.scm +92 -0
- package/vendor/tree-sitter-dart/queries/test.scm +1 -0
- package/vendor/tree-sitter-dart/src/grammar.json +12459 -0
- package/vendor/tree-sitter-dart/src/node-types.json +15055 -0
- package/vendor/tree-sitter-dart/src/parser.c +196127 -0
- package/vendor/tree-sitter-dart/src/scanner.c +130 -0
- package/vendor/tree-sitter-dart/src/tree_sitter/alloc.h +54 -0
- package/vendor/tree-sitter-dart/src/tree_sitter/array.h +290 -0
- package/vendor/tree-sitter-dart/src/tree_sitter/parser.h +265 -0
- package/vendor/tree-sitter-swift/LICENSE +21 -0
- package/vendor/tree-sitter-swift/README.md +139 -0
- package/vendor/tree-sitter-swift/bindings/node/index.d.ts +28 -0
- package/vendor/tree-sitter-swift/bindings/node/index.js +7 -0
- package/vendor/tree-sitter-swift/package.json +28 -0
- package/vendor/tree-sitter-swift/prebuilds/darwin-arm64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/darwin-x64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/linux-arm64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/linux-x64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/win32-arm64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/win32-x64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/src/node-types.json +30694 -0
- package/web/assets/agent-DaprsFSX.js +597 -0
- package/web/assets/architecture-YZFGNWBL-S5CXDPWN-DEdGaPg2.js +1 -0
- package/web/assets/architectureDiagram-EMZXCZ2Q-Domyk_gO.js +36 -0
- package/web/assets/blockDiagram-IGV67L2C-B_2kD7tM.js +132 -0
- package/web/assets/c4Diagram-DFAF54RM-BhJJW8Gg.js +10 -0
- package/web/assets/chunk-3GS5O3IE-jlWIjPsl.js +231 -0
- package/web/assets/chunk-3YCYZ6SJ-Blq_IzZs.js +1 -0
- package/web/assets/chunk-6NTNNK5N-DyPc58pp.js +1 -0
- package/web/assets/chunk-7RZVMHOQ-BdIU-RGO.js +321 -0
- package/web/assets/chunk-A34GCYZU-BI2i_LdU.js +1 -0
- package/web/assets/chunk-AEOMTBSW-D7qjBMHW.js +1 -0
- package/web/assets/chunk-CilyBKbf.js +1 -0
- package/web/assets/chunk-DJ7UZH7F-i11ywiBl.js +1 -0
- package/web/assets/chunk-DKKBVRCY-1SffGI1N.js +4 -0
- package/web/assets/chunk-DU5LTGQ6-DaPeiwD5.js +1 -0
- package/web/assets/chunk-FXACKDTF-uhhi2PC2.js +159 -0
- package/web/assets/chunk-H3VCZNTA-IchcISDt.js +1 -0
- package/web/assets/chunk-HN6EAY2L-D7ZFMNrB.js +1 -0
- package/web/assets/chunk-KSICW3F5-C2tZmXwv.js +15 -0
- package/web/assets/chunk-O5ABG6QK-Bt-Km84H.js +1 -0
- package/web/assets/chunk-PK6DOVAG-ChlWY0BQ.js +206 -0
- package/web/assets/chunk-RNJOYNJ4-B724K7cW.js +1 -0
- package/web/assets/chunk-RWUO3TPN-DYn1XriD.js +1 -0
- package/web/assets/chunk-TBF5ZNIQ-DKtDz6ae.js +1 -0
- package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +1 -0
- package/web/assets/chunk-TYMNRAUI-g1h33cq-.js +1 -0
- package/web/assets/chunk-VELTKBKT-C9dVN39o.js +1 -0
- package/web/assets/chunk-W7ZLLLMY-Du-Hb9yb.js +1 -0
- package/web/assets/chunk-WSB5WSVC-B123clsZ.js +1 -0
- package/web/assets/chunk-XGPFEOL4-BR7Eue38.js +1 -0
- package/web/assets/classDiagram-PPOCWD7C-BglfKSs_.js +1 -0
- package/web/assets/classDiagram-v2-23LJLIIU-BSzTM28O.js +1 -0
- package/web/assets/context-builder-CqQNhRj1.js +15 -0
- package/web/assets/cose-bilkent-PNC4W37J-DCfErU-A.js +1 -0
- package/web/assets/dagre-E77IOHMT-tDRRhDoN.js +4 -0
- package/web/assets/diagram-H7BISOXX-CUVHlmAh.js +43 -0
- package/web/assets/diagram-JC5VWROH-BoyOxulB.js +24 -0
- package/web/assets/diagram-LXUTUG65-osr9hb7N.js +10 -0
- package/web/assets/diagram-WEHSV5V5-d8nUqS39.js +24 -0
- package/web/assets/erDiagram-GCSMX5X6-b-IwOhPS.js +85 -0
- package/web/assets/flowDiagram-OTCZ4VVT-Ott2Q0AP.js +162 -0
- package/web/assets/ganttDiagram-MUNLMDZQ-BYtgN_5s.js +292 -0
- package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-CFyBIGZq.js +1 -0
- package/web/assets/gitGraphDiagram-3HKGZ4G3-CsVD2gn4.js +106 -0
- package/web/assets/index-BleGLU8S.css +2 -0
- package/web/assets/index-C_xK08EW.js +885 -0
- package/web/assets/info-OMHHGYJF-BF2H5H6G-yjAxKEzh.js +1 -0
- package/web/assets/infoDiagram-MN7RKWGX-DXK0Unn5.js +2 -0
- package/web/assets/ishikawaDiagram-YMYX4NHK-CXsnC2FA.js +70 -0
- package/web/assets/journeyDiagram-SO5T7YLQ-BzZ07B-X.js +139 -0
- package/web/assets/kanban-definition-LJHFXRCJ-C6_EpAd9.js +89 -0
- package/web/assets/katex-GD7MH7QM-CJiOjBBJ.js +261 -0
- package/web/assets/mindmap-definition-2EUWGEK5-CCYGWZ1m.js +96 -0
- package/web/assets/packet-4T2RLAQJ-EV4IVRXR-B8k4E3IT.js +1 -0
- package/web/assets/pie-ZZUOXDRM-N23DN5KN-DdvfY118.js +1 -0
- package/web/assets/pieDiagram-3IATQBI2-RyvRlQb4.js +30 -0
- package/web/assets/quadrantDiagram-E256RVCF-Bfb6sxCx.js +7 -0
- package/web/assets/radar-PYXPWWZC-P6TP7ZYP-1EEDC_yU.js +1 -0
- package/web/assets/requirementDiagram-M5DCFWZL-DjvHDyvN.js +84 -0
- package/web/assets/sankeyDiagram-L3NBLAOT-CBCbbl8s.js +10 -0
- package/web/assets/sequenceDiagram-ZOUHS735-BscU8TUR.js +157 -0
- package/web/assets/stateDiagram-MLPALWAM-CJusEK2D.js +1 -0
- package/web/assets/stateDiagram-v2-B5LQ5ZB2-DImJ3PXD.js +1 -0
- package/web/assets/timeline-definition-5SPVSISX-DigPA1X8.js +120 -0
- package/web/assets/treeView-SZITEDCU-5DXDK3XO-CzPDt3aG.js +1 -0
- package/web/assets/treemap-W4RFUUIX-WYLRDWKO-B9Iqiorr.js +1 -0
- package/web/assets/vennDiagram-IE5QUKF5-C91UkZIf.js +34 -0
- package/web/assets/wardley-RL74JXVD-BCRCBASE-x42Qw7hp.js +1 -0
- package/web/assets/wardleyDiagram-XU3VSMPF-DloBhI0U.js +20 -0
- package/web/assets/xychartDiagram-ZHJ5623Y-BGWJvgwI.js +7 -0
- package/web/index.html +21 -0
- package/scripts/patch-tree-sitter-swift.cjs +0 -78
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesize `@type-binding.this` captures for TypeScript instance-like
|
|
3
|
+
* methods.
|
|
4
|
+
*
|
|
5
|
+
* Tree-sitter can't cleanly express "the implicit `this` receiver of a
|
|
6
|
+
* non-static member of a class / interface / abstract class" via a
|
|
7
|
+
* static `.scm` pattern, so we walk up the AST in code — mirrors
|
|
8
|
+
* Python's `self` / `cls` and C#'s `this` / `base` synthesis.
|
|
9
|
+
*
|
|
10
|
+
* Scope coverage:
|
|
11
|
+
*
|
|
12
|
+
* - `method_definition` inside `class_declaration`,
|
|
13
|
+
* `abstract_class_declaration`, or `class_expression` → synthesize
|
|
14
|
+
* `this` → enclosing class name.
|
|
15
|
+
* - `method_signature` / `abstract_method_signature` inside
|
|
16
|
+
* `interface_declaration` or `abstract_class_declaration` →
|
|
17
|
+
* synthesize `this` → enclosing type's name (so interface method
|
|
18
|
+
* bodies' `this.x` chains resolve via the interface's field
|
|
19
|
+
* annotations).
|
|
20
|
+
* - `arrow_function` / `function_expression` that is a direct value
|
|
21
|
+
* of a `public_field_definition` (class field) — `m = () => {}` —
|
|
22
|
+
* synthesize `this` → enclosing class name. These capture `this`
|
|
23
|
+
* lexically; without synthesis, their body's `this.foo` wouldn't
|
|
24
|
+
* resolve.
|
|
25
|
+
*
|
|
26
|
+
* Not synthesized (intentionally):
|
|
27
|
+
*
|
|
28
|
+
* - `static` methods / static fields. `this` in a static context
|
|
29
|
+
* refers to the class constructor, not an instance; we leave the
|
|
30
|
+
* binding empty and let chain resolution fall through to the
|
|
31
|
+
* class's static members lookup.
|
|
32
|
+
* - Regular `function_declaration` / `function_expression` at
|
|
33
|
+
* module level or in a non-class context. No enclosing type, no
|
|
34
|
+
* `this` semantics.
|
|
35
|
+
* - Arrow functions nested inside a method body. The scope-chain
|
|
36
|
+
* walk in `tsReceiverBinding` finds the outer method's `this`
|
|
37
|
+
* naturally, matching TS's lexical-this rule for arrow functions.
|
|
38
|
+
*
|
|
39
|
+
* Each synthesized match emits the anchor captures needed by
|
|
40
|
+
* `interpretTsTypeBinding`:
|
|
41
|
+
*
|
|
42
|
+
* `@type-binding.this` (source discriminator — interpret maps to 'self')
|
|
43
|
+
* `@type-binding.name` (the literal `'this'`)
|
|
44
|
+
* `@type-binding.type` (the enclosing type's name)
|
|
45
|
+
*/
|
|
46
|
+
import type { CaptureMatch } from '../../../../_shared/index.js';
|
|
47
|
+
import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
48
|
+
/**
|
|
49
|
+
* Produce zero or one `CaptureMatch` synthesizing `this` for `fnNode`.
|
|
50
|
+
*
|
|
51
|
+
* - `null` — function has no synthetic `this` (free / static /
|
|
52
|
+
* not-in-class / no name on enclosing type).
|
|
53
|
+
* - One match — anchor on the function body so the synthetic binding
|
|
54
|
+
* attaches to the function's scope (not the outer class scope).
|
|
55
|
+
*
|
|
56
|
+
* The caller is responsible for passing a `fnNode` whose type is one
|
|
57
|
+
* of the scope function nodes the scope query emits.
|
|
58
|
+
*/
|
|
59
|
+
export declare function synthesizeTsReceiverBinding(fnNode: SyntaxNode): CaptureMatch | null;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesize `@type-binding.this` captures for TypeScript instance-like
|
|
3
|
+
* methods.
|
|
4
|
+
*
|
|
5
|
+
* Tree-sitter can't cleanly express "the implicit `this` receiver of a
|
|
6
|
+
* non-static member of a class / interface / abstract class" via a
|
|
7
|
+
* static `.scm` pattern, so we walk up the AST in code — mirrors
|
|
8
|
+
* Python's `self` / `cls` and C#'s `this` / `base` synthesis.
|
|
9
|
+
*
|
|
10
|
+
* Scope coverage:
|
|
11
|
+
*
|
|
12
|
+
* - `method_definition` inside `class_declaration`,
|
|
13
|
+
* `abstract_class_declaration`, or `class_expression` → synthesize
|
|
14
|
+
* `this` → enclosing class name.
|
|
15
|
+
* - `method_signature` / `abstract_method_signature` inside
|
|
16
|
+
* `interface_declaration` or `abstract_class_declaration` →
|
|
17
|
+
* synthesize `this` → enclosing type's name (so interface method
|
|
18
|
+
* bodies' `this.x` chains resolve via the interface's field
|
|
19
|
+
* annotations).
|
|
20
|
+
* - `arrow_function` / `function_expression` that is a direct value
|
|
21
|
+
* of a `public_field_definition` (class field) — `m = () => {}` —
|
|
22
|
+
* synthesize `this` → enclosing class name. These capture `this`
|
|
23
|
+
* lexically; without synthesis, their body's `this.foo` wouldn't
|
|
24
|
+
* resolve.
|
|
25
|
+
*
|
|
26
|
+
* Not synthesized (intentionally):
|
|
27
|
+
*
|
|
28
|
+
* - `static` methods / static fields. `this` in a static context
|
|
29
|
+
* refers to the class constructor, not an instance; we leave the
|
|
30
|
+
* binding empty and let chain resolution fall through to the
|
|
31
|
+
* class's static members lookup.
|
|
32
|
+
* - Regular `function_declaration` / `function_expression` at
|
|
33
|
+
* module level or in a non-class context. No enclosing type, no
|
|
34
|
+
* `this` semantics.
|
|
35
|
+
* - Arrow functions nested inside a method body. The scope-chain
|
|
36
|
+
* walk in `tsReceiverBinding` finds the outer method's `this`
|
|
37
|
+
* naturally, matching TS's lexical-this rule for arrow functions.
|
|
38
|
+
*
|
|
39
|
+
* Each synthesized match emits the anchor captures needed by
|
|
40
|
+
* `interpretTsTypeBinding`:
|
|
41
|
+
*
|
|
42
|
+
* `@type-binding.this` (source discriminator — interpret maps to 'self')
|
|
43
|
+
* `@type-binding.name` (the literal `'this'`)
|
|
44
|
+
* `@type-binding.type` (the enclosing type's name)
|
|
45
|
+
*/
|
|
46
|
+
import { nodeToCapture, syntheticCapture } from '../../utils/ast-helpers.js';
|
|
47
|
+
/** Node types that define a TypeScript "type with instance members". */
|
|
48
|
+
const TYPE_DECL_NODE_TYPES = new Set([
|
|
49
|
+
'class_declaration',
|
|
50
|
+
'abstract_class_declaration',
|
|
51
|
+
'class',
|
|
52
|
+
'class_expression',
|
|
53
|
+
'interface_declaration',
|
|
54
|
+
]);
|
|
55
|
+
/** Scope function nodes that could be a class method body. */
|
|
56
|
+
const CLASS_MEMBER_FUNCTION_TYPES = new Set([
|
|
57
|
+
'method_definition',
|
|
58
|
+
'method_signature',
|
|
59
|
+
'abstract_method_signature',
|
|
60
|
+
]);
|
|
61
|
+
/** Function-like values that can back a class field (`m = () => {}`). */
|
|
62
|
+
const CLASS_FIELD_FUNCTION_TYPES = new Set(['arrow_function', 'function_expression']);
|
|
63
|
+
/**
|
|
64
|
+
* Produce zero or one `CaptureMatch` synthesizing `this` for `fnNode`.
|
|
65
|
+
*
|
|
66
|
+
* - `null` — function has no synthetic `this` (free / static /
|
|
67
|
+
* not-in-class / no name on enclosing type).
|
|
68
|
+
* - One match — anchor on the function body so the synthetic binding
|
|
69
|
+
* attaches to the function's scope (not the outer class scope).
|
|
70
|
+
*
|
|
71
|
+
* The caller is responsible for passing a `fnNode` whose type is one
|
|
72
|
+
* of the scope function nodes the scope query emits.
|
|
73
|
+
*/
|
|
74
|
+
export function synthesizeTsReceiverBinding(fnNode) {
|
|
75
|
+
// Classify the function's role.
|
|
76
|
+
const role = classifyFunctionRole(fnNode);
|
|
77
|
+
if (role === null)
|
|
78
|
+
return null;
|
|
79
|
+
// Static methods / static fields don't have an instance `this`.
|
|
80
|
+
if (isStaticMember(role.memberNode))
|
|
81
|
+
return null;
|
|
82
|
+
// Find enclosing type declaration. Walking past function-like
|
|
83
|
+
// boundaries is fine — nested local functions inside a method can
|
|
84
|
+
// still reference outer `this` through the lexical chain, but we
|
|
85
|
+
// only synthesize on the immediate function body. The resolver's
|
|
86
|
+
// scope-chain walk reaches ancestor synthesized bindings for nested
|
|
87
|
+
// arrow functions.
|
|
88
|
+
const enclosingType = findEnclosingType(role.memberNode);
|
|
89
|
+
if (enclosingType === null)
|
|
90
|
+
return null;
|
|
91
|
+
const typeName = getTypeDeclName(enclosingType);
|
|
92
|
+
if (typeName === null)
|
|
93
|
+
return null;
|
|
94
|
+
// Anchor the synthetic capture on the function body so the binding
|
|
95
|
+
// lands in the method's scope, not its parent type scope. Method
|
|
96
|
+
// signatures in interfaces / abstract classes have no body — use
|
|
97
|
+
// the method node itself as the anchor; scope-extractor attaches
|
|
98
|
+
// it to the function scope created by the `@scope.function`
|
|
99
|
+
// anchor at the same range.
|
|
100
|
+
const anchorNode = fnNode.childForFieldName('body') ?? fnNode;
|
|
101
|
+
return buildThisBinding(anchorNode, typeName);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Decide whether `fnNode` participates as a class member. Returns
|
|
105
|
+
* `null` when the function is not structurally "a class instance
|
|
106
|
+
* member" — e.g. a free function, a non-method arrow expression, an
|
|
107
|
+
* arrow inside a method body (those inherit `this` via scope chain
|
|
108
|
+
* lookup, no synthesis needed).
|
|
109
|
+
*/
|
|
110
|
+
function classifyFunctionRole(fnNode) {
|
|
111
|
+
if (CLASS_MEMBER_FUNCTION_TYPES.has(fnNode.type)) {
|
|
112
|
+
return { memberNode: fnNode };
|
|
113
|
+
}
|
|
114
|
+
if (CLASS_FIELD_FUNCTION_TYPES.has(fnNode.type)) {
|
|
115
|
+
// `public_field_definition` represents a class field. Only when
|
|
116
|
+
// the arrow/function-expression is a DIRECT value of a field do
|
|
117
|
+
// we treat it as a class method with synthesized `this`.
|
|
118
|
+
const parent = fnNode.parent;
|
|
119
|
+
if (parent !== null && parent.type === 'public_field_definition') {
|
|
120
|
+
const valueField = parent.childForFieldName('value');
|
|
121
|
+
if (valueField !== null && valueField.startIndex === fnNode.startIndex) {
|
|
122
|
+
return { memberNode: parent };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/** Class-body definitions carry an optional `accessibility_modifier` and
|
|
129
|
+
* optional `static` keyword as named children. The `static` token is
|
|
130
|
+
* usually a plain child of the member node — not a named field — so
|
|
131
|
+
* we scan children for a token whose text is exactly `static`. */
|
|
132
|
+
function isStaticMember(memberNode) {
|
|
133
|
+
for (let i = 0; i < memberNode.childCount; i++) {
|
|
134
|
+
const c = memberNode.child(i);
|
|
135
|
+
if (c === null)
|
|
136
|
+
continue;
|
|
137
|
+
// `static` can appear as an unnamed token or as a `readonly` /
|
|
138
|
+
// `static` keyword node depending on grammar version; check text.
|
|
139
|
+
if (c.text === 'static')
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
function findEnclosingType(node) {
|
|
145
|
+
let cur = node.parent;
|
|
146
|
+
while (cur !== null) {
|
|
147
|
+
if (TYPE_DECL_NODE_TYPES.has(cur.type))
|
|
148
|
+
return cur;
|
|
149
|
+
cur = cur.parent;
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
/** Return the declared name of a class / interface / abstract-class.
|
|
154
|
+
* `class_expression` ( `const X = class { … }` ) may lack a name —
|
|
155
|
+
* in that case we return `null` and the caller skips synthesis (the
|
|
156
|
+
* outer variable's name is the usable handle, but wiring it would
|
|
157
|
+
* require a separate walk; defer to a follow-up). */
|
|
158
|
+
function getTypeDeclName(typeNode) {
|
|
159
|
+
const nameField = typeNode.childForFieldName('name');
|
|
160
|
+
if (nameField === null)
|
|
161
|
+
return null;
|
|
162
|
+
return nameField.text;
|
|
163
|
+
}
|
|
164
|
+
function buildThisBinding(anchorNode, typeText) {
|
|
165
|
+
const m = {
|
|
166
|
+
'@type-binding.this': nodeToCapture('@type-binding.this', anchorNode),
|
|
167
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', anchorNode, 'this'),
|
|
168
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', anchorNode, typeText),
|
|
169
|
+
};
|
|
170
|
+
return m;
|
|
171
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript `ScopeResolver` registered in `SCOPE_RESOLVERS` and
|
|
3
|
+
* consumed by the generic `runScopeResolution` orchestrator
|
|
4
|
+
* (RFC #909 Ring 3).
|
|
5
|
+
*
|
|
6
|
+
* Third migration after Python and C#. Follows the same minimal
|
|
7
|
+
* wiring-only pattern — per-hook logic lives in the sibling modules
|
|
8
|
+
* (`arity.ts`, `merge-bindings.ts`, `import-target.ts`, etc.).
|
|
9
|
+
*
|
|
10
|
+
* See ./index.ts for the per-module rationale and the full list of
|
|
11
|
+
* known limitations. The canonical capture vocabulary is pinned in
|
|
12
|
+
* ./query.ts (TYPESCRIPT_SCOPE_QUERY constant).
|
|
13
|
+
*/
|
|
14
|
+
import type { ScopeResolver } from '../../scope-resolution/contract/scope-resolver.js';
|
|
15
|
+
declare const typescriptScopeResolver: ScopeResolver;
|
|
16
|
+
export { typescriptScopeResolver };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript `ScopeResolver` registered in `SCOPE_RESOLVERS` and
|
|
3
|
+
* consumed by the generic `runScopeResolution` orchestrator
|
|
4
|
+
* (RFC #909 Ring 3).
|
|
5
|
+
*
|
|
6
|
+
* Third migration after Python and C#. Follows the same minimal
|
|
7
|
+
* wiring-only pattern — per-hook logic lives in the sibling modules
|
|
8
|
+
* (`arity.ts`, `merge-bindings.ts`, `import-target.ts`, etc.).
|
|
9
|
+
*
|
|
10
|
+
* See ./index.ts for the per-module rationale and the full list of
|
|
11
|
+
* known limitations. The canonical capture vocabulary is pinned in
|
|
12
|
+
* ./query.ts (TYPESCRIPT_SCOPE_QUERY constant).
|
|
13
|
+
*/
|
|
14
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
15
|
+
import { buildMro, defaultLinearize } from '../../scope-resolution/passes/mro.js';
|
|
16
|
+
import { populateClassOwnedMembers } from '../../scope-resolution/scope/walkers.js';
|
|
17
|
+
import { typescriptProvider } from '../typescript.js';
|
|
18
|
+
import { loadTsconfigPaths } from '../../language-config.js';
|
|
19
|
+
import { typescriptArityCompatibility, typescriptMergeBindings, resolveTsTarget, } from './index.js';
|
|
20
|
+
/**
|
|
21
|
+
* Build a `resolveImportTarget` adapter that memoizes the workspace
|
|
22
|
+
* file list, the lower-cased file list, and the per-pass `resolveCache`
|
|
23
|
+
* across every import lookup in a single workspace pass. The
|
|
24
|
+
* orchestrator passes the same `ReadonlySet` reference for every call
|
|
25
|
+
* within a pass — we use that identity to detect when the workspace
|
|
26
|
+
* changes and recompute the derived state lazily.
|
|
27
|
+
*
|
|
28
|
+
* Without this memoization, `resolveTsTarget` re-derived
|
|
29
|
+
* `allFileList` and `normalizedFileList` (both O(N_files)) and threw
|
|
30
|
+
* away the `resolveCache` on every import — O(N_files × N_imports)
|
|
31
|
+
* total work for what should be O(N_files + N_imports).
|
|
32
|
+
*/
|
|
33
|
+
function makeTsResolveImportTarget() {
|
|
34
|
+
let cached = null;
|
|
35
|
+
return (targetRaw, fromFile, allFilePaths, resolutionConfig) => {
|
|
36
|
+
if (cached === null || cached.key !== allFilePaths) {
|
|
37
|
+
const allFileList = Array.from(allFilePaths);
|
|
38
|
+
cached = {
|
|
39
|
+
key: allFilePaths,
|
|
40
|
+
allFilePaths: new Set(allFilePaths),
|
|
41
|
+
allFileList,
|
|
42
|
+
normalizedFileList: allFileList.map((f) => f.toLowerCase()),
|
|
43
|
+
resolveCache: new Map(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const cfg = resolutionConfig;
|
|
47
|
+
const ws = {
|
|
48
|
+
fromFile,
|
|
49
|
+
allFilePaths: cached.allFilePaths,
|
|
50
|
+
allFileList: cached.allFileList,
|
|
51
|
+
normalizedFileList: cached.normalizedFileList,
|
|
52
|
+
resolveCache: cached.resolveCache,
|
|
53
|
+
tsconfigPaths: cfg?.tsconfigPaths ?? null,
|
|
54
|
+
};
|
|
55
|
+
return resolveTsTarget(targetRaw, ws);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const typescriptScopeResolver = {
|
|
59
|
+
language: SupportedLanguages.TypeScript,
|
|
60
|
+
languageProvider: typescriptProvider,
|
|
61
|
+
importEdgeReason: 'typescript-scope: import',
|
|
62
|
+
resolveImportTarget: makeTsResolveImportTarget(),
|
|
63
|
+
// Threaded into `resolveImportTarget` so tsconfig path aliases
|
|
64
|
+
// (`@/services/user`, `~/x`, …) resolve through the same standard
|
|
65
|
+
// resolver branch the legacy DAG uses. One I/O round-trip per
|
|
66
|
+
// workspace pass; the orchestrator awaits this once.
|
|
67
|
+
loadResolutionConfig: async (repoPath) => ({
|
|
68
|
+
tsconfigPaths: await loadTsconfigPaths(repoPath),
|
|
69
|
+
}),
|
|
70
|
+
// TypeScript declaration merging + LEGB: local > import > wildcard,
|
|
71
|
+
// separated by declaration space (value / type / namespace). The
|
|
72
|
+
// per-scope id is unused (shadowing is computed from origin + def.type),
|
|
73
|
+
// so we don't need to synthesize a Scope here.
|
|
74
|
+
mergeBindings: (existing, incoming) => [...typescriptMergeBindings([...existing, ...incoming])],
|
|
75
|
+
// Adapter: typescriptArityCompatibility uses (def, callsite); the
|
|
76
|
+
// ScopeResolver contract is (callsite, def).
|
|
77
|
+
arityCompatibility: (callsite, def) => typescriptArityCompatibility(def, callsite),
|
|
78
|
+
buildMro: (graph, parsedFiles, nodeLookup) => buildMro(graph, parsedFiles, nodeLookup, defaultLinearize),
|
|
79
|
+
populateOwners: (parsed) => populateClassOwnedMembers(parsed),
|
|
80
|
+
// TypeScript uses `super` for super-class dispatch as a plain
|
|
81
|
+
// identifier or as `super()` in constructors. Match both — `super`
|
|
82
|
+
// on its own (`super.foo`, `super[x]`) and `super(...)` (constructor
|
|
83
|
+
// chain). This also correctly rejects identifiers that merely
|
|
84
|
+
// contain the substring `super` (e.g. `superman`).
|
|
85
|
+
isSuperReceiver: (text) => /^super(\s*\(|\s*\.|\s*\[|\s*$)/.test(text.trim()),
|
|
86
|
+
// TypeScript is statically typed — field-fallback heuristic off
|
|
87
|
+
// (the type-binding layer produces precise owner types). Return-
|
|
88
|
+
// type propagation across imports on (matches the legacy DAG's
|
|
89
|
+
// behavior: explicit return-type annotations flow across `export`
|
|
90
|
+
// boundaries and resolve chained member calls).
|
|
91
|
+
fieldFallbackOnMethodLookup: false,
|
|
92
|
+
propagatesReturnTypesAcrossImports: true,
|
|
93
|
+
// TypeScript uses `.values()` / `.keys()` method-call syntax for
|
|
94
|
+
// collection views — no property-style accessors like C#'s
|
|
95
|
+
// `Dictionary<K,V>.Values`. Leave `unwrapCollectionAccessor`
|
|
96
|
+
// undefined and let the regular member-call branch handle them.
|
|
97
|
+
//
|
|
98
|
+
// `collapseMemberCallsByCallerTarget` left undefined (= false) —
|
|
99
|
+
// TypeScript legacy DAG emits one edge per call site, so
|
|
100
|
+
// per-site dedup is the parity target.
|
|
101
|
+
//
|
|
102
|
+
// `populateNamespaceSiblings` left undefined — TypeScript requires
|
|
103
|
+
// an explicit `import` / namespace augmentation for cross-file
|
|
104
|
+
// visibility; there's no implicit same-namespace sibling rule
|
|
105
|
+
// like C#'s.
|
|
106
|
+
//
|
|
107
|
+
// `hoistTypeBindingsToModule` — `tsBindingScopeFor` DOES hoist
|
|
108
|
+
// method return-type bindings to the enclosing Module scope
|
|
109
|
+
// (mirrors C#), so enable the walk-up that lets the compound-
|
|
110
|
+
// receiver resolver find them.
|
|
111
|
+
hoistTypeBindingsToModule: true,
|
|
112
|
+
};
|
|
113
|
+
export { typescriptScopeResolver };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trivial / no-op-ish hooks for the TypeScript provider. Kept together
|
|
3
|
+
* because each is a few lines and they share a common theme: making
|
|
4
|
+
* the provider's choice explicit rather than relying on "absence ==
|
|
5
|
+
* default" so reviewers don't have to re-derive the analysis.
|
|
6
|
+
*/
|
|
7
|
+
import type { CaptureMatch, ParsedImport, Scope, ScopeId, ScopeTree, TypeRef } from '../../../../_shared/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* TypeScript/JavaScript has block-scoped `let`/`const` (the innermost
|
|
10
|
+
* default covers these) but function-scoped `var` — which hoists to
|
|
11
|
+
* the enclosing **function or module** scope, bypassing intermediate
|
|
12
|
+
* blocks. JS also function-hoists `function_declaration` to the same
|
|
13
|
+
* level.
|
|
14
|
+
*
|
|
15
|
+
* We distinguish var from let/const by sniffing the `@declaration.variable`
|
|
16
|
+
* capture's leading keyword. The capture's text begins with the
|
|
17
|
+
* source-literal keyword (`var ` / `let ` / `const `) because the
|
|
18
|
+
* anchor is the outer `lexical_declaration` / `variable_declaration`
|
|
19
|
+
* node — there's no whitespace before the keyword in any well-formed
|
|
20
|
+
* TS/JS source.
|
|
21
|
+
*
|
|
22
|
+
* Additionally hoists **method return-type bindings**
|
|
23
|
+
* (`@type-binding.return`) all the way to the Module scope, matching
|
|
24
|
+
* C#: the compound-receiver walker and `propagateImportedReturnTypes`
|
|
25
|
+
* both read from module-level typeBindings for cross-file chain
|
|
26
|
+
* propagation.
|
|
27
|
+
*/
|
|
28
|
+
export declare function tsBindingScopeFor(decl: CaptureMatch, innermost: Scope, tree: ScopeTree): ScopeId | null;
|
|
29
|
+
/**
|
|
30
|
+
* TypeScript imports are syntactically top-level: `import_statement` is
|
|
31
|
+
* legal only inside `program` (the module root). `namespace X { … }`
|
|
32
|
+
* bodies CAN contain imports (`internal_module`), in which case the
|
|
33
|
+
* import scopes to the namespace. Dynamic `import()` calls appear
|
|
34
|
+
* inside any scope but their runtime effect is still a module-level
|
|
35
|
+
* resolution — we attach the `ParsedImport` to the innermost Module /
|
|
36
|
+
* Namespace scope so the binding is visible through the full subtree.
|
|
37
|
+
*
|
|
38
|
+
* Returning `null` delegates to the central default, which walks to
|
|
39
|
+
* the nearest enclosing `Module`/`Namespace`. That matches our rule,
|
|
40
|
+
* so we only override when we explicitly need a non-default scope
|
|
41
|
+
* (we don't).
|
|
42
|
+
*/
|
|
43
|
+
export declare function tsImportOwningScope(_imp: ParsedImport, _innermost: Scope, _tree: ScopeTree): ScopeId | null;
|
|
44
|
+
/**
|
|
45
|
+
* Look up `this` on the function scope's type bindings.
|
|
46
|
+
*
|
|
47
|
+
* `this` is synthesized as a type binding on instance-method function
|
|
48
|
+
* scopes during capture emission (`receiver-binding.ts`). Arrow
|
|
49
|
+
* functions and nested functions that reference `this` naturally
|
|
50
|
+
* resolve it via the scope-chain walk — if the arrow function is a
|
|
51
|
+
* class method (`m = () => {}`), it gets a synthesized `this`; if it
|
|
52
|
+
* is nested inside a class method, the scope-chain lookup finds the
|
|
53
|
+
* outer method's `this`. This mirrors TypeScript's lexical-this
|
|
54
|
+
* semantics for arrow functions.
|
|
55
|
+
*
|
|
56
|
+
* Returns `null` for:
|
|
57
|
+
* - static methods (no `this` synthesized)
|
|
58
|
+
* - free functions / module-level code (no enclosing class-like)
|
|
59
|
+
* - non-Function scopes
|
|
60
|
+
*
|
|
61
|
+
* Caveat: a non-arrow `function` declaration nested inside a method
|
|
62
|
+
* DOES see the outer `this` via our scope-chain lookup, even though at
|
|
63
|
+
* runtime its `this` is independently bound (strict-mode `undefined`,
|
|
64
|
+
* sloppy `globalThis`). We accept this false-positive — the real-world
|
|
65
|
+
* pattern that relies on independent `this` inside a nested regular
|
|
66
|
+
* function inside a class method is extremely rare, and catching it
|
|
67
|
+
* would require injecting a `this: undefined` shadow on every non-
|
|
68
|
+
* arrow function scope. Documented as a known limitation in
|
|
69
|
+
* `index.ts`.
|
|
70
|
+
*/
|
|
71
|
+
export declare function tsReceiverBinding(functionScope: Scope): TypeRef | null;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trivial / no-op-ish hooks for the TypeScript provider. Kept together
|
|
3
|
+
* because each is a few lines and they share a common theme: making
|
|
4
|
+
* the provider's choice explicit rather than relying on "absence ==
|
|
5
|
+
* default" so reviewers don't have to re-derive the analysis.
|
|
6
|
+
*/
|
|
7
|
+
// ─── bindingScopeFor ──────────────────────────────────────────────────────
|
|
8
|
+
/**
|
|
9
|
+
* TypeScript/JavaScript has block-scoped `let`/`const` (the innermost
|
|
10
|
+
* default covers these) but function-scoped `var` — which hoists to
|
|
11
|
+
* the enclosing **function or module** scope, bypassing intermediate
|
|
12
|
+
* blocks. JS also function-hoists `function_declaration` to the same
|
|
13
|
+
* level.
|
|
14
|
+
*
|
|
15
|
+
* We distinguish var from let/const by sniffing the `@declaration.variable`
|
|
16
|
+
* capture's leading keyword. The capture's text begins with the
|
|
17
|
+
* source-literal keyword (`var ` / `let ` / `const `) because the
|
|
18
|
+
* anchor is the outer `lexical_declaration` / `variable_declaration`
|
|
19
|
+
* node — there's no whitespace before the keyword in any well-formed
|
|
20
|
+
* TS/JS source.
|
|
21
|
+
*
|
|
22
|
+
* Additionally hoists **method return-type bindings**
|
|
23
|
+
* (`@type-binding.return`) all the way to the Module scope, matching
|
|
24
|
+
* C#: the compound-receiver walker and `propagateImportedReturnTypes`
|
|
25
|
+
* both read from module-level typeBindings for cross-file chain
|
|
26
|
+
* propagation.
|
|
27
|
+
*/
|
|
28
|
+
export function tsBindingScopeFor(decl, innermost, tree) {
|
|
29
|
+
// Method return type: hoist to Module (mirrors csharpBindingScopeFor).
|
|
30
|
+
if (decl['@type-binding.return'] !== undefined) {
|
|
31
|
+
return walkToScope(innermost, tree, 'Module');
|
|
32
|
+
}
|
|
33
|
+
// Parameter property (`constructor(public address: Address)`): hoist
|
|
34
|
+
// to the enclosing Class scope so `user.address` field access
|
|
35
|
+
// resolves through the class's typeBindings. The regular
|
|
36
|
+
// @type-binding.parameter binding still fires for the constructor
|
|
37
|
+
// scope; this one adds a second binding on the class.
|
|
38
|
+
if (decl['@type-binding.parameter-property'] !== undefined) {
|
|
39
|
+
return walkToScope(innermost, tree, 'Class');
|
|
40
|
+
}
|
|
41
|
+
// `var` declarations: hoist to nearest enclosing Function or Module.
|
|
42
|
+
const variable = decl['@declaration.variable'];
|
|
43
|
+
if (variable !== undefined && isVarDeclaration(variable.text)) {
|
|
44
|
+
return walkToScope(innermost, tree, 'Function', 'Module');
|
|
45
|
+
}
|
|
46
|
+
// Function declarations are already anchored at their definition
|
|
47
|
+
// site via `@scope.function`; hoisting is a no-op for them (JS
|
|
48
|
+
// function hoisting is about visibility before the definition, not
|
|
49
|
+
// about placing the binding in a different scope). The scope tree
|
|
50
|
+
// already attaches their name to the enclosing scope. No override
|
|
51
|
+
// needed.
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Walk up the scope chain to find the first scope whose `kind` matches
|
|
56
|
+
* any of `kinds`. Returns the matching scope's id or `null` when no
|
|
57
|
+
* ancestor matches (e.g., a return type binding emitted outside any
|
|
58
|
+
* Module scope — shouldn't happen in well-formed input).
|
|
59
|
+
*/
|
|
60
|
+
function walkToScope(from, tree, ...kinds) {
|
|
61
|
+
let cur = from;
|
|
62
|
+
const kindSet = new Set(kinds);
|
|
63
|
+
while (cur !== undefined) {
|
|
64
|
+
if (kindSet.has(cur.kind))
|
|
65
|
+
return cur.id;
|
|
66
|
+
const parentId = cur.parent ?? null;
|
|
67
|
+
if (parentId === null)
|
|
68
|
+
break;
|
|
69
|
+
cur = tree.getScope(parentId);
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/** `var x = 1;` vs `let x = 1;` / `const x = 1;`. The capture's text
|
|
74
|
+
* starts at the outer declaration's `startIndex` in source, which is
|
|
75
|
+
* the keyword's first character — no leading whitespace possible. */
|
|
76
|
+
function isVarDeclaration(captureText) {
|
|
77
|
+
return (captureText.startsWith('var ') ||
|
|
78
|
+
captureText.startsWith('var\t') ||
|
|
79
|
+
captureText.startsWith('var\n'));
|
|
80
|
+
}
|
|
81
|
+
// ─── importOwningScope ────────────────────────────────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* TypeScript imports are syntactically top-level: `import_statement` is
|
|
84
|
+
* legal only inside `program` (the module root). `namespace X { … }`
|
|
85
|
+
* bodies CAN contain imports (`internal_module`), in which case the
|
|
86
|
+
* import scopes to the namespace. Dynamic `import()` calls appear
|
|
87
|
+
* inside any scope but their runtime effect is still a module-level
|
|
88
|
+
* resolution — we attach the `ParsedImport` to the innermost Module /
|
|
89
|
+
* Namespace scope so the binding is visible through the full subtree.
|
|
90
|
+
*
|
|
91
|
+
* Returning `null` delegates to the central default, which walks to
|
|
92
|
+
* the nearest enclosing `Module`/`Namespace`. That matches our rule,
|
|
93
|
+
* so we only override when we explicitly need a non-default scope
|
|
94
|
+
* (we don't).
|
|
95
|
+
*/
|
|
96
|
+
export function tsImportOwningScope(_imp, _innermost, _tree) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
// ─── receiverBinding ──────────────────────────────────────────────────────
|
|
100
|
+
/**
|
|
101
|
+
* Look up `this` on the function scope's type bindings.
|
|
102
|
+
*
|
|
103
|
+
* `this` is synthesized as a type binding on instance-method function
|
|
104
|
+
* scopes during capture emission (`receiver-binding.ts`). Arrow
|
|
105
|
+
* functions and nested functions that reference `this` naturally
|
|
106
|
+
* resolve it via the scope-chain walk — if the arrow function is a
|
|
107
|
+
* class method (`m = () => {}`), it gets a synthesized `this`; if it
|
|
108
|
+
* is nested inside a class method, the scope-chain lookup finds the
|
|
109
|
+
* outer method's `this`. This mirrors TypeScript's lexical-this
|
|
110
|
+
* semantics for arrow functions.
|
|
111
|
+
*
|
|
112
|
+
* Returns `null` for:
|
|
113
|
+
* - static methods (no `this` synthesized)
|
|
114
|
+
* - free functions / module-level code (no enclosing class-like)
|
|
115
|
+
* - non-Function scopes
|
|
116
|
+
*
|
|
117
|
+
* Caveat: a non-arrow `function` declaration nested inside a method
|
|
118
|
+
* DOES see the outer `this` via our scope-chain lookup, even though at
|
|
119
|
+
* runtime its `this` is independently bound (strict-mode `undefined`,
|
|
120
|
+
* sloppy `globalThis`). We accept this false-positive — the real-world
|
|
121
|
+
* pattern that relies on independent `this` inside a nested regular
|
|
122
|
+
* function inside a class method is extremely rare, and catching it
|
|
123
|
+
* would require injecting a `this: undefined` shadow on every non-
|
|
124
|
+
* arrow function scope. Documented as a known limitation in
|
|
125
|
+
* `index.ts`.
|
|
126
|
+
*/
|
|
127
|
+
export function tsReceiverBinding(functionScope) {
|
|
128
|
+
if (functionScope.kind !== 'Function')
|
|
129
|
+
return null;
|
|
130
|
+
return functionScope.typeBindings.get('this') ?? null;
|
|
131
|
+
}
|
|
@@ -26,6 +26,7 @@ import { typescriptVariableConfig, javascriptVariableConfig, } from '../variable
|
|
|
26
26
|
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
27
27
|
import { typescriptCallConfig, javascriptCallConfig, } from '../call-extractors/configs/typescript-javascript.js';
|
|
28
28
|
import { createHeritageExtractor } from '../heritage-extractors/generic.js';
|
|
29
|
+
import { emitTsScopeCaptures, interpretTsImport, interpretTsTypeBinding, tsBindingScopeFor, tsImportOwningScope, tsReceiverBinding, typescriptMergeBindings, typescriptArityCompatibility, resolveTsImportTarget, } from './typescript/index.js';
|
|
29
30
|
/**
|
|
30
31
|
* TypeScript/JavaScript: arrow_function and function_expression get their name
|
|
31
32
|
* from the parent variable_declarator (e.g. `const foo = () => {}`).
|
|
@@ -162,6 +163,24 @@ export const typescriptProvider = defineLanguage({
|
|
|
162
163
|
classExtractor: createClassExtractor(typescriptClassConfig),
|
|
163
164
|
heritageExtractor: createHeritageExtractor(SupportedLanguages.TypeScript),
|
|
164
165
|
builtInNames: BUILT_INS,
|
|
166
|
+
// ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
|
|
167
|
+
// TypeScript is the third migration after Python and C#. See
|
|
168
|
+
// ./typescript/index.ts for the full per-hook rationale and the
|
|
169
|
+
// canonical capture vocabulary in ./typescript/query.ts
|
|
170
|
+
// (TYPESCRIPT_SCOPE_QUERY constant).
|
|
171
|
+
emitScopeCaptures: emitTsScopeCaptures,
|
|
172
|
+
interpretImport: interpretTsImport,
|
|
173
|
+
interpretTypeBinding: interpretTsTypeBinding,
|
|
174
|
+
bindingScopeFor: tsBindingScopeFor,
|
|
175
|
+
importOwningScope: tsImportOwningScope,
|
|
176
|
+
// Merge precedence is decided from BindingRef origin + declaration
|
|
177
|
+
// space only. The central finalizer already calls this per (scope,
|
|
178
|
+
// name), so the Scope object itself intentionally does not affect
|
|
179
|
+
// TypeScript declaration merging.
|
|
180
|
+
mergeBindings: (_scope, bindings) => typescriptMergeBindings(bindings),
|
|
181
|
+
receiverBinding: tsReceiverBinding,
|
|
182
|
+
arityCompatibility: typescriptArityCompatibility,
|
|
183
|
+
resolveImportTarget: resolveTsImportTarget,
|
|
165
184
|
});
|
|
166
185
|
export const javascriptProvider = defineLanguage({
|
|
167
186
|
id: SupportedLanguages.JavaScript,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// gitnexus/src/core/ingestion/method-extractors/configs/swift.ts
|
|
2
|
-
// Verified against tree-sitter-swift 0.
|
|
2
|
+
// Verified against tree-sitter-swift 0.7.x
|
|
3
3
|
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
4
4
|
import { findVisibility, hasKeyword, hasModifier } from '../../field-extractors/configs/helpers.js';
|
|
5
5
|
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
|
|
@@ -97,7 +97,7 @@ function extractSwiftReturnType(node) {
|
|
|
97
97
|
*/
|
|
98
98
|
function extractSwiftParameters(node) {
|
|
99
99
|
const params = [];
|
|
100
|
-
// In tree-sitter-swift
|
|
100
|
+
// In tree-sitter-swift, parameters are direct children of function_declaration.
|
|
101
101
|
// Default value tokens ('=', literal) are siblings of the parameter node at the
|
|
102
102
|
// function_declaration level, not children of the parameter node.
|
|
103
103
|
for (let i = 0; i < node.childCount; i++) {
|
|
@@ -242,8 +242,7 @@ function extractSwiftAnnotations(node) {
|
|
|
242
242
|
// ---------------------------------------------------------------------------
|
|
243
243
|
export const swiftMethodConfig = {
|
|
244
244
|
language: SupportedLanguages.Swift,
|
|
245
|
-
//
|
|
246
|
-
// and actors — but this cannot be verified until the grammar installs on Node 22+.
|
|
245
|
+
// Keep this conservative until Swift type-shape coverage is expanded.
|
|
247
246
|
// TODO: Verify struct_declaration, enum_declaration, extension_declaration, actor_declaration
|
|
248
247
|
// node types once tree-sitter-swift loads on Node 22, and add them here if they are distinct.
|
|
249
248
|
// protocol_declaration is a separate, confirmed node type.
|
|
@@ -48,8 +48,21 @@ export interface ScopeResolutionIndexes {
|
|
|
48
48
|
readonly methodDispatch: MethodDispatchIndex;
|
|
49
49
|
/** Finalized `ImportEdge[]` per module scope. */
|
|
50
50
|
readonly imports: ReadonlyMap<ScopeId, readonly ImportEdge[]>;
|
|
51
|
-
/**
|
|
51
|
+
/** Finalize-output bindings (local + imports + wildcards) per module scope.
|
|
52
|
+
* Inner `BindingRef[]` arrays are frozen by `materializeBindings`;
|
|
53
|
+
* this channel is permanently immutable post-finalize. Consumers
|
|
54
|
+
* MUST read via `lookupBindingsAt` so the augmentation channel is
|
|
55
|
+
* consulted alongside. See I8 in `contract/scope-resolver.ts`. */
|
|
52
56
|
readonly bindings: ReadonlyMap<ScopeId, ReadonlyMap<string, readonly BindingRef[]>>;
|
|
57
|
+
/** Append-only post-finalize augmentation channel. Populated by
|
|
58
|
+
* language hooks such as `populateNamespaceSiblings` for cross-file
|
|
59
|
+
* bindings synthesized after finalize (e.g. C# same-namespace
|
|
60
|
+
* visibility, `using static` member exposure). Inner arrays are
|
|
61
|
+
* NOT frozen — hooks `push()` directly. Walkers must consult both
|
|
62
|
+
* this map and `bindings` via `lookupBindingsAt`; finalized refs
|
|
63
|
+
* are returned first and win duplicate `def.nodeId` metadata, with
|
|
64
|
+
* unique augmentations appended after. See I8. */
|
|
65
|
+
readonly bindingAugmentations: ReadonlyMap<ScopeId, ReadonlyMap<string, readonly BindingRef[]>>;
|
|
53
66
|
/** Pre-resolution usage facts; consumed by the resolution phase. */
|
|
54
67
|
readonly referenceSites: readonly ReferenceSite[];
|
|
55
68
|
/** SCC condensation of the file-level import graph — callers that want
|