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,451 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `emitScopeCaptures` for TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Drives the TypeScript scope query against tree-sitter-typescript and groups
|
|
5
|
+
* raw matches into `CaptureMatch[]` for the central extractor. Layers
|
|
6
|
+
* synthesized streams on top:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Import decomposition** — each `import_statement` / re-export is
|
|
9
|
+
* re-emitted with `@import.kind/source/name/alias/typeOnly` markers so
|
|
10
|
+
* `interpretTsImport` can recover the `ParsedImport` shape without
|
|
11
|
+
* re-parsing raw text (see `import-decomposer.ts`). Unit 2 adds this;
|
|
12
|
+
* until then, raw `@import.statement` matches flow through as-is.
|
|
13
|
+
* 2. **Dynamic imports** — `import('./m')` is re-emitted as a
|
|
14
|
+
* decomposed `@import.statement` with `@import.kind=dynamic` so the
|
|
15
|
+
* central extractor treats it uniformly with static imports.
|
|
16
|
+
* 3. **Function-decl arity metadata** (Unit 5) — `@declaration.parameter-count`
|
|
17
|
+
* / `@declaration.required-parameter-count` / `@declaration.parameter-types`
|
|
18
|
+
* synthesized onto function-like declarations so the registry can narrow
|
|
19
|
+
* overloads.
|
|
20
|
+
* 4. **Callsite arity metadata** (Unit 5) — `@reference.arity` /
|
|
21
|
+
* `@reference.parameter-types` on every callsite.
|
|
22
|
+
* 5. **Receiver-binding synthesis** (Unit 3) — `this` type anchors on
|
|
23
|
+
* instance methods, with arrow-function lexical-this walk-up.
|
|
24
|
+
*
|
|
25
|
+
* Pure given the input source text. No I/O, no globals consulted.
|
|
26
|
+
*/
|
|
27
|
+
import { findNodeAtRange, nodeToCapture, syntheticCapture, } from '../../utils/ast-helpers.js';
|
|
28
|
+
import { splitImportStatement } from './import-decomposer.js';
|
|
29
|
+
import { getTsParser, getTsScopeQuery, tsCachedTreeMatchesGrammar } from './query.js';
|
|
30
|
+
import { recordCacheHit, recordCacheMiss } from './cache-stats.js';
|
|
31
|
+
import { synthesizeTsReceiverBinding } from './receiver-binding.js';
|
|
32
|
+
import { computeTsArityMetadata } from './arity-metadata.js';
|
|
33
|
+
import { getTreeSitterBufferSize } from '../../constants.js';
|
|
34
|
+
/** tree-sitter-typescript node types for function-like scopes that may
|
|
35
|
+
* carry a synthesized `this` binding. Kept in sync with the
|
|
36
|
+
* `@scope.function` patterns in `query.ts`. */
|
|
37
|
+
const FUNCTION_NODE_TYPES = [
|
|
38
|
+
'method_definition',
|
|
39
|
+
'method_signature',
|
|
40
|
+
'abstract_method_signature',
|
|
41
|
+
'arrow_function',
|
|
42
|
+
'function_expression',
|
|
43
|
+
'function_declaration',
|
|
44
|
+
'generator_function_declaration',
|
|
45
|
+
'function_signature',
|
|
46
|
+
];
|
|
47
|
+
/** Declaration anchors that carry function-like arity metadata. */
|
|
48
|
+
const FUNCTION_DECL_TAGS = ['@declaration.method', '@declaration.function'];
|
|
49
|
+
/** Callsite anchors that should carry `@reference.arity` + param types. */
|
|
50
|
+
const CALL_TAGS = [
|
|
51
|
+
'@reference.call.free',
|
|
52
|
+
'@reference.call.member',
|
|
53
|
+
'@reference.call.constructor',
|
|
54
|
+
];
|
|
55
|
+
function pickFirstDefined(grouped, tags) {
|
|
56
|
+
for (const tag of tags) {
|
|
57
|
+
const cap = grouped[tag];
|
|
58
|
+
if (cap !== undefined)
|
|
59
|
+
return cap;
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Drop `@reference.read.member` matches whose underlying `member_expression`
|
|
65
|
+
* is NOT actually a read context:
|
|
66
|
+
*
|
|
67
|
+
* 1. The member_expression is the `function:` of a `call_expression`
|
|
68
|
+
* (it's a call, already captured as `@reference.call.member`).
|
|
69
|
+
* 2. The member_expression is the `constructor:` of a `new_expression`
|
|
70
|
+
* (already captured as `@reference.call.constructor.qualified`).
|
|
71
|
+
* 3. The member_expression is the `left:` of an `assignment_expression` /
|
|
72
|
+
* `augmented_assignment_expression` (it's a write, already captured
|
|
73
|
+
* as `@reference.write.member`).
|
|
74
|
+
* 4. The member_expression is the `function:` of an `await_expression`
|
|
75
|
+
* being called (handled by the member-call capture).
|
|
76
|
+
*
|
|
77
|
+
* Returns `true` when the capture should be kept as a read reference,
|
|
78
|
+
* `false` when it should be dropped.
|
|
79
|
+
*/
|
|
80
|
+
function shouldEmitReadMember(memberNode) {
|
|
81
|
+
const parent = memberNode.parent;
|
|
82
|
+
if (parent === null)
|
|
83
|
+
return true;
|
|
84
|
+
switch (parent.type) {
|
|
85
|
+
case 'call_expression':
|
|
86
|
+
return parent.childForFieldName('function')?.id !== memberNode.id;
|
|
87
|
+
case 'new_expression':
|
|
88
|
+
return parent.childForFieldName('constructor')?.id !== memberNode.id;
|
|
89
|
+
case 'assignment_expression':
|
|
90
|
+
case 'augmented_assignment_expression':
|
|
91
|
+
return parent.childForFieldName('left')?.id !== memberNode.id;
|
|
92
|
+
default:
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export function emitTsScopeCaptures(sourceText, filePath, cachedTree) {
|
|
97
|
+
// Skip the parse when the caller (parse phase's scopeTreeCache) already
|
|
98
|
+
// produced a Tree for this source. Cache miss = re-parse, same as before.
|
|
99
|
+
// The cachedTree parameter is typed as `unknown` at the LanguageProvider
|
|
100
|
+
// contract layer; cast here at the use site.
|
|
101
|
+
//
|
|
102
|
+
// Grammar selection: `.tsx` files are parsed with the TSX grammar,
|
|
103
|
+
// `.ts` files with the TypeScript grammar. The two grammars have
|
|
104
|
+
// separate node-type id spaces, so a Query compiled against one
|
|
105
|
+
// cannot match a Tree produced by the other. We validate the cached
|
|
106
|
+
// tree's grammar against the file extension and fall back to a
|
|
107
|
+
// fresh parse if they disagree (e.g. a worker-mode parse landed
|
|
108
|
+
// with the wrong grammar pinned).
|
|
109
|
+
let tree = cachedTree;
|
|
110
|
+
if (tree !== undefined && !tsCachedTreeMatchesGrammar(tree, filePath)) {
|
|
111
|
+
tree = undefined;
|
|
112
|
+
}
|
|
113
|
+
if (tree === undefined) {
|
|
114
|
+
tree = getTsParser(filePath).parse(sourceText, undefined, {
|
|
115
|
+
bufferSize: getTreeSitterBufferSize(sourceText),
|
|
116
|
+
});
|
|
117
|
+
recordCacheMiss();
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
recordCacheHit();
|
|
121
|
+
}
|
|
122
|
+
const rawMatches = getTsScopeQuery(filePath).matches(tree.rootNode);
|
|
123
|
+
const out = [];
|
|
124
|
+
for (const m of rawMatches) {
|
|
125
|
+
// Group captures by their tag name. Tree-sitter strips the leading
|
|
126
|
+
// `@`; we put it back so the central extractor's prefix lookups
|
|
127
|
+
// (`@scope.`, `@declaration.`, …) work.
|
|
128
|
+
const grouped = {};
|
|
129
|
+
for (const c of m.captures) {
|
|
130
|
+
const tag = '@' + c.name;
|
|
131
|
+
grouped[tag] = nodeToCapture(tag, c.node);
|
|
132
|
+
}
|
|
133
|
+
if (Object.keys(grouped).length === 0)
|
|
134
|
+
continue;
|
|
135
|
+
// Decompose each `import_statement` / re-export `export_statement`
|
|
136
|
+
// so `interpretTsImport` sees the kind/source/name/alias markers
|
|
137
|
+
// it consumes. The raw query anchor carries only @import.statement.
|
|
138
|
+
// Side-effect imports emit a non-binding marker so finalize can keep
|
|
139
|
+
// the file-level dependency.
|
|
140
|
+
if (grouped['@import.statement'] !== undefined) {
|
|
141
|
+
const stmtCapture = grouped['@import.statement'];
|
|
142
|
+
const stmtNode = findNodeAtRange(tree.rootNode, stmtCapture.range, 'import_statement') ??
|
|
143
|
+
findNodeAtRange(tree.rootNode, stmtCapture.range, 'export_statement');
|
|
144
|
+
if (stmtNode !== null) {
|
|
145
|
+
const decomposed = splitImportStatement(stmtNode);
|
|
146
|
+
for (const d of decomposed)
|
|
147
|
+
out.push(d);
|
|
148
|
+
}
|
|
149
|
+
// If decomposition yielded nothing (malformed/bare anchor), drop
|
|
150
|
+
// the match. Emitting a bare
|
|
151
|
+
// @import.statement without kind/source would confuse the
|
|
152
|
+
// central extractor.
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
// Dynamic imports — decompose via the same path. `@import.dynamic`
|
|
156
|
+
// is anchored on a `call_expression`, which the decomposer's
|
|
157
|
+
// `splitDynamicImport` branch consumes.
|
|
158
|
+
if (grouped['@import.dynamic'] !== undefined) {
|
|
159
|
+
const dynCapture = grouped['@import.dynamic'];
|
|
160
|
+
const callNode = findNodeAtRange(tree.rootNode, dynCapture.range, 'call_expression');
|
|
161
|
+
if (callNode !== null) {
|
|
162
|
+
const decomposed = splitImportStatement(callNode);
|
|
163
|
+
for (const d of decomposed)
|
|
164
|
+
out.push(d);
|
|
165
|
+
}
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
// Filter out `@reference.read.member` matches whose AST parent tells
|
|
169
|
+
// us they are actually calls / writes / constructor invocations. The
|
|
170
|
+
// tree-sitter pattern is context-free and matches every member_expression;
|
|
171
|
+
// we rely on this emit-side filter so the query stays simple.
|
|
172
|
+
if (grouped['@reference.read.member'] !== undefined) {
|
|
173
|
+
const anchor = grouped['@reference.read.member'];
|
|
174
|
+
const memberNode = findNodeAtRange(tree.rootNode, anchor.range, 'member_expression');
|
|
175
|
+
if (memberNode === null || !shouldEmitReadMember(memberNode)) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Synthesize arity metadata on function-like declaration anchors
|
|
180
|
+
// before pushing the match. The registry uses these to narrow
|
|
181
|
+
// overloads — TypeScript supports overload signatures via
|
|
182
|
+
// function_signature, so `parameterTypes` is populated when
|
|
183
|
+
// available.
|
|
184
|
+
const declAnchor = pickFirstDefined(grouped, FUNCTION_DECL_TAGS);
|
|
185
|
+
if (declAnchor !== undefined) {
|
|
186
|
+
const fnNode = findFunctionNode(tree.rootNode, declAnchor.range);
|
|
187
|
+
if (fnNode !== null) {
|
|
188
|
+
const arity = computeTsArityMetadata(fnNode);
|
|
189
|
+
if (arity.parameterCount !== undefined) {
|
|
190
|
+
grouped['@declaration.parameter-count'] = syntheticCapture('@declaration.parameter-count', fnNode, String(arity.parameterCount));
|
|
191
|
+
}
|
|
192
|
+
if (arity.requiredParameterCount !== undefined) {
|
|
193
|
+
grouped['@declaration.required-parameter-count'] = syntheticCapture('@declaration.required-parameter-count', fnNode, String(arity.requiredParameterCount));
|
|
194
|
+
}
|
|
195
|
+
if (arity.parameterTypes !== undefined) {
|
|
196
|
+
grouped['@declaration.parameter-types'] = syntheticCapture('@declaration.parameter-types', fnNode, JSON.stringify(arity.parameterTypes));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Synthesize `@reference.arity` on every callsite so the registry's
|
|
201
|
+
// arity filter can narrow overloads. Count the `argument` named
|
|
202
|
+
// children of the backing `arguments` node. TypeScript constructor
|
|
203
|
+
// calls use `new_expression`; regular calls use `call_expression`.
|
|
204
|
+
const callAnchor = pickFirstDefined(grouped, CALL_TAGS);
|
|
205
|
+
if (callAnchor !== undefined && grouped['@reference.arity'] === undefined) {
|
|
206
|
+
const callNode = findNodeAtRange(tree.rootNode, callAnchor.range, 'call_expression') ??
|
|
207
|
+
findNodeAtRange(tree.rootNode, callAnchor.range, 'new_expression');
|
|
208
|
+
if (callNode !== null) {
|
|
209
|
+
const argList = callNode.childForFieldName('arguments');
|
|
210
|
+
const args = argList === null
|
|
211
|
+
? []
|
|
212
|
+
: argList.namedChildren.filter((c) => c !== null && c.type !== 'comment');
|
|
213
|
+
grouped['@reference.arity'] = syntheticCapture('@reference.arity', callNode, String(args.length));
|
|
214
|
+
const argTypes = args.map((arg) => inferArgType(arg));
|
|
215
|
+
grouped['@reference.parameter-types'] = syntheticCapture('@reference.parameter-types', callNode, JSON.stringify(argTypes));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
out.push(grouped);
|
|
219
|
+
// Synthesize `this` receiver type-bindings on every function-like
|
|
220
|
+
// scope that is structurally a class member. `receiver-binding.ts`
|
|
221
|
+
// handles the walk-up (method, method_signature, abstract
|
|
222
|
+
// signature, arrow/function-expression assigned to a class field).
|
|
223
|
+
// Arrow functions nested inside method bodies rely on scope-chain
|
|
224
|
+
// lookup instead of synthesis — covered by `tsReceiverBinding`.
|
|
225
|
+
const scopeFnAnchor = grouped['@scope.function'];
|
|
226
|
+
if (scopeFnAnchor !== undefined) {
|
|
227
|
+
const fnNode = findFunctionNode(tree.rootNode, scopeFnAnchor.range);
|
|
228
|
+
if (fnNode !== null) {
|
|
229
|
+
const synth = synthesizeTsReceiverBinding(fnNode);
|
|
230
|
+
if (synth !== null)
|
|
231
|
+
out.push(synth);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Synthesize object-destructuring type bindings. The tree-sitter query
|
|
236
|
+
// alone can't express "give me the field NAME and the RHS identifier
|
|
237
|
+
// together" in a way that produces usable @type-binding.name /
|
|
238
|
+
// @type-binding.type captures, so we walk `variable_declarator` nodes
|
|
239
|
+
// whose `name:` is an `object_pattern` and synthesize per-field
|
|
240
|
+
// bindings keyed to the receiver-path `rhsName.fieldName`. The
|
|
241
|
+
// compound-receiver resolver's Case 3b then walks that path when the
|
|
242
|
+
// destructured local is used as a receiver (e.g. `address.save()`).
|
|
243
|
+
synthesizeDestructuringBindings(tree.rootNode, out);
|
|
244
|
+
synthesizeForOfMapTupleBindings(tree.rootNode, out);
|
|
245
|
+
synthesizeInstanceofNarrowings(tree.rootNode, out);
|
|
246
|
+
return out;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Walk the AST and synthesize type-binding captures for object
|
|
250
|
+
* destructuring of the form `const { field } = rhs` or
|
|
251
|
+
* `const { field: alias } = rhs`. Pushes one synthetic CaptureMatch
|
|
252
|
+
* per destructured identifier with:
|
|
253
|
+
*
|
|
254
|
+
* - `@type-binding.name` → the local identifier
|
|
255
|
+
* - `@type-binding.type` → the compound path `rhs.field`
|
|
256
|
+
* - `@type-binding.destructured` anchor
|
|
257
|
+
*
|
|
258
|
+
* Only fires when the RHS is a bare identifier — more complex RHS
|
|
259
|
+
* shapes (call_expression, member_expression) resolve via the normal
|
|
260
|
+
* type-alias + chain-follow paths on the RHS first, then the field
|
|
261
|
+
* walk catches the destructured identifier on a second fixpoint pass.
|
|
262
|
+
* Left as a follow-up optimization.
|
|
263
|
+
*/
|
|
264
|
+
function synthesizeDestructuringBindings(root, out) {
|
|
265
|
+
const stack = [root];
|
|
266
|
+
for (;;) {
|
|
267
|
+
const node = stack.pop();
|
|
268
|
+
if (node === undefined)
|
|
269
|
+
break;
|
|
270
|
+
for (const child of node.namedChildren) {
|
|
271
|
+
if (child !== null)
|
|
272
|
+
stack.push(child);
|
|
273
|
+
}
|
|
274
|
+
if (node.type !== 'variable_declarator')
|
|
275
|
+
continue;
|
|
276
|
+
const nameNode = node.childForFieldName('name');
|
|
277
|
+
const valueNode = node.childForFieldName('value');
|
|
278
|
+
if (nameNode === null || valueNode === null)
|
|
279
|
+
continue;
|
|
280
|
+
if (nameNode.type !== 'object_pattern')
|
|
281
|
+
continue;
|
|
282
|
+
if (valueNode.type !== 'identifier')
|
|
283
|
+
continue;
|
|
284
|
+
const rhsName = valueNode.text;
|
|
285
|
+
for (const fieldNode of nameNode.namedChildren) {
|
|
286
|
+
if (fieldNode === null)
|
|
287
|
+
continue;
|
|
288
|
+
if (fieldNode.type === 'shorthand_property_identifier_pattern') {
|
|
289
|
+
// `const { address } = user`
|
|
290
|
+
const localName = fieldNode.text;
|
|
291
|
+
out.push({
|
|
292
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', fieldNode, localName),
|
|
293
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', fieldNode, `${rhsName}.${localName}`),
|
|
294
|
+
'@type-binding.destructured': syntheticCapture('@type-binding.destructured', fieldNode, fieldNode.text),
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
else if (fieldNode.type === 'pair_pattern') {
|
|
298
|
+
// `const { address: addr } = user`
|
|
299
|
+
const key = fieldNode.childForFieldName('key');
|
|
300
|
+
const value = fieldNode.childForFieldName('value');
|
|
301
|
+
if (key === null || value === null)
|
|
302
|
+
continue;
|
|
303
|
+
if (value.type !== 'identifier')
|
|
304
|
+
continue;
|
|
305
|
+
const fieldName = key.text;
|
|
306
|
+
const localName = value.text;
|
|
307
|
+
out.push({
|
|
308
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', value, localName),
|
|
309
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', fieldNode, `${rhsName}.${fieldName}`),
|
|
310
|
+
'@type-binding.destructured': syntheticCapture('@type-binding.destructured', fieldNode, fieldNode.text),
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* `for (const [k, v] of mapId)` over a `Map<K,V>` — synthesize per-slot
|
|
318
|
+
* type bindings so `v` resolves like a `Map` iterator tuple element.
|
|
319
|
+
* Uses sentinel `__MAP_TUPLE_i__:rhs` consumed by compound-receiver.
|
|
320
|
+
*/
|
|
321
|
+
function synthesizeForOfMapTupleBindings(root, out) {
|
|
322
|
+
const stack = [root];
|
|
323
|
+
for (;;) {
|
|
324
|
+
const node = stack.pop();
|
|
325
|
+
if (node === undefined)
|
|
326
|
+
break;
|
|
327
|
+
for (const child of node.namedChildren) {
|
|
328
|
+
if (child !== null)
|
|
329
|
+
stack.push(child);
|
|
330
|
+
}
|
|
331
|
+
if (node.type !== 'for_in_statement')
|
|
332
|
+
continue;
|
|
333
|
+
const left = node.childForFieldName('left');
|
|
334
|
+
const right = node.childForFieldName('right');
|
|
335
|
+
if (left === null || right === null)
|
|
336
|
+
continue;
|
|
337
|
+
if (left.type !== 'array_pattern' || right.type !== 'identifier')
|
|
338
|
+
continue;
|
|
339
|
+
const rhs = right.text;
|
|
340
|
+
let slot = 0;
|
|
341
|
+
for (const child of left.namedChildren) {
|
|
342
|
+
if (child === null || child.type !== 'identifier')
|
|
343
|
+
continue;
|
|
344
|
+
const localName = child.text;
|
|
345
|
+
out.push({
|
|
346
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', child, localName),
|
|
347
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', child, `__MAP_TUPLE_${slot}__:${rhs}`),
|
|
348
|
+
'@type-binding.map-tuple-entry': syntheticCapture('@type-binding.map-tuple-entry', child, String(slot)),
|
|
349
|
+
});
|
|
350
|
+
slot++;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* `if (x instanceof User) { x.save() }` — synthesize a `User` type binding
|
|
356
|
+
* for `x` anchored in the consequence block so scope-chain lookup inside
|
|
357
|
+
* the then-branch sees the narrowed type.
|
|
358
|
+
*
|
|
359
|
+
* **Known limitation:** the LHS must be a bare `identifier` and the RHS
|
|
360
|
+
* an `identifier`/`type_identifier`. Member-expression LHS such as
|
|
361
|
+
* `if (user.address instanceof Address)` is intentionally NOT synthesized
|
|
362
|
+
* — narrowing a property-access target requires a stable storage key
|
|
363
|
+
* the binding layer can hold, which member chains don't supply. Field-
|
|
364
|
+
* type resolution covers the common case for those receivers via
|
|
365
|
+
* declared types instead.
|
|
366
|
+
*/
|
|
367
|
+
function synthesizeInstanceofNarrowings(root, out) {
|
|
368
|
+
const stack = [root];
|
|
369
|
+
for (;;) {
|
|
370
|
+
const node = stack.pop();
|
|
371
|
+
if (node === undefined)
|
|
372
|
+
break;
|
|
373
|
+
for (const child of node.namedChildren) {
|
|
374
|
+
if (child !== null)
|
|
375
|
+
stack.push(child);
|
|
376
|
+
}
|
|
377
|
+
if (node.type !== 'if_statement')
|
|
378
|
+
continue;
|
|
379
|
+
const cond = node.childForFieldName('condition');
|
|
380
|
+
if (cond === null)
|
|
381
|
+
continue;
|
|
382
|
+
const inner = cond.type === 'parenthesized_expression' ? cond.namedChildren[0] : cond;
|
|
383
|
+
if (inner === null || inner.type !== 'binary_expression')
|
|
384
|
+
continue;
|
|
385
|
+
const op = inner.childForFieldName('operator');
|
|
386
|
+
const left = inner.childForFieldName('left');
|
|
387
|
+
const right = inner.childForFieldName('right');
|
|
388
|
+
if (op === null || left === null || right === null)
|
|
389
|
+
continue;
|
|
390
|
+
if (op.type !== 'instanceof')
|
|
391
|
+
continue;
|
|
392
|
+
if (left.type !== 'identifier')
|
|
393
|
+
continue;
|
|
394
|
+
if (right.type !== 'identifier' && right.type !== 'type_identifier')
|
|
395
|
+
continue;
|
|
396
|
+
const varName = left.text;
|
|
397
|
+
const typeName = right.text;
|
|
398
|
+
const cons = node.childForFieldName('consequence');
|
|
399
|
+
if (cons === null)
|
|
400
|
+
continue;
|
|
401
|
+
out.push({
|
|
402
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', cons, varName),
|
|
403
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', right, typeName),
|
|
404
|
+
'@type-binding.instanceof-narrow': syntheticCapture('@type-binding.instanceof-narrow', cons, '1'),
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/** Infer a TypeScript argument expression's static type from literal
|
|
409
|
+
* shapes. Returns `''` when the arg has no statically-derivable type
|
|
410
|
+
* (identifiers, member accesses, etc.) — consumers treat unknown as
|
|
411
|
+
* any-match during overload narrowing. */
|
|
412
|
+
function inferArgType(argNode) {
|
|
413
|
+
switch (argNode.type) {
|
|
414
|
+
case 'number':
|
|
415
|
+
return 'number';
|
|
416
|
+
case 'string':
|
|
417
|
+
case 'template_string':
|
|
418
|
+
return 'string';
|
|
419
|
+
case 'true':
|
|
420
|
+
case 'false':
|
|
421
|
+
return 'boolean';
|
|
422
|
+
case 'null':
|
|
423
|
+
return 'null';
|
|
424
|
+
case 'undefined':
|
|
425
|
+
return 'undefined';
|
|
426
|
+
case 'array':
|
|
427
|
+
return 'Array';
|
|
428
|
+
case 'object':
|
|
429
|
+
return 'object';
|
|
430
|
+
case 'regex':
|
|
431
|
+
return 'RegExp';
|
|
432
|
+
case 'new_expression': {
|
|
433
|
+
const ctor = argNode.childForFieldName('constructor');
|
|
434
|
+
return ctor?.text ?? '';
|
|
435
|
+
}
|
|
436
|
+
default:
|
|
437
|
+
return '';
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/** Find the first TypeScript function-like node at the given range.
|
|
441
|
+
* The `@scope.function` anchor range covers the whole node, but the
|
|
442
|
+
* tag alone doesn't identify which node type among the many TS
|
|
443
|
+
* function-likes. */
|
|
444
|
+
function findFunctionNode(rootNode, range) {
|
|
445
|
+
for (const nodeType of FUNCTION_NODE_TYPES) {
|
|
446
|
+
const n = findNodeAtRange(rootNode, range, nodeType);
|
|
447
|
+
if (n !== null)
|
|
448
|
+
return n;
|
|
449
|
+
}
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decompose a TypeScript `import_statement` / re-export `export_statement` /
|
|
3
|
+
* dynamic `call_expression(import)` into one `CaptureMatch` per imported
|
|
4
|
+
* name.
|
|
5
|
+
*
|
|
6
|
+
* Why split here? The `LanguageProvider.interpretImport` contract is
|
|
7
|
+
* one `ParsedImport` per call. Tree-sitter delivers
|
|
8
|
+
*
|
|
9
|
+
* import D, { X as Y, type Z } from './m'
|
|
10
|
+
*
|
|
11
|
+
* as a single `import_statement` match, so without decomposition we'd
|
|
12
|
+
* lose names. The synthesized markers (`@import.kind` / `@import.name`
|
|
13
|
+
* / `@import.alias` / `@import.source`) carry everything
|
|
14
|
+
* `interpretTsImport` needs to recover the `ParsedImport` shape —
|
|
15
|
+
* see `interpret.ts`.
|
|
16
|
+
*
|
|
17
|
+
* Kinds we emit and how `interpret.ts` maps them to `ParsedImport`:
|
|
18
|
+
*
|
|
19
|
+
* - `default` : `import D from './m'` → alias (importedName=default)
|
|
20
|
+
* - `named` : `import { X } from './m'` → named
|
|
21
|
+
* - `named-alias` : `import { X as Y } from './m'` → alias
|
|
22
|
+
* - `namespace` : `import * as N from './m'` → namespace
|
|
23
|
+
* - `reexport` : `export { X } from './m'` → reexport
|
|
24
|
+
* - `reexport-alias` : `export { X as Y } from './m'` → reexport (with alias)
|
|
25
|
+
* - `reexport-wildcard` : `export * from './m'` → wildcard
|
|
26
|
+
* - `reexport-namespace` : `export * as ns from './m'` → namespace (local=ns,imported=source)
|
|
27
|
+
* - `dynamic` : `import('./m')` / `import(x)` → dynamic-resolved or dynamic-unresolved
|
|
28
|
+
*
|
|
29
|
+
* Type-only constructs (`import type { X }`, `import { type X }`,
|
|
30
|
+
* `export type { X }`) emit the same kinds as runtime forms — at the
|
|
31
|
+
* TypeScript scope-resolution layer, types and values share the same
|
|
32
|
+
* lookup; runtime-emission is a downstream concern.
|
|
33
|
+
*
|
|
34
|
+
* Side-effect imports (`import './polyfill'`) produce a single match
|
|
35
|
+
* with `kind: 'side-effect'`. The shared finalize algorithm resolves
|
|
36
|
+
* the target file and emits a file-level IMPORTS edge, but
|
|
37
|
+
* materializes no `BindingRef` (matching the legacy DAG, which counts
|
|
38
|
+
* `import './polyfill'` as a module-reachability dependency only).
|
|
39
|
+
*/
|
|
40
|
+
import type { CaptureMatch } from '../../../../_shared/index.js';
|
|
41
|
+
import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
42
|
+
/**
|
|
43
|
+
* Decompose an import anchor. Handles three node types:
|
|
44
|
+
*
|
|
45
|
+
* - `import_statement` : all static import forms (incl. side-effect)
|
|
46
|
+
* - `export_statement` (w/ source) : re-exports
|
|
47
|
+
* - `call_expression` (import fn) : dynamic `import()`
|
|
48
|
+
*/
|
|
49
|
+
export declare function splitImportStatement(stmtNode: SyntaxNode): CaptureMatch[];
|