@component-compass/reference-graph 0.1.24 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/binding.d.ts +96 -0
- package/dist/engine/binding.js +405 -0
- package/dist/engine/binding.js.map +1 -0
- package/dist/engine/component-shape.d.ts +26 -2
- package/dist/engine/component-shape.js +74 -11
- package/dist/engine/component-shape.js.map +1 -1
- package/dist/engine/denotation.d.ts +7 -0
- package/dist/engine/denotation.js +15 -0
- package/dist/engine/denotation.js.map +1 -1
- package/dist/engine/helper-callers.d.ts +0 -7
- package/dist/engine/helper-callers.js +2 -23
- package/dist/engine/helper-callers.js.map +1 -1
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.js +259 -308
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/member-identity.d.ts +7 -19
- package/dist/engine/member-identity.js +13 -19
- package/dist/engine/member-identity.js.map +1 -1
- package/dist/engine/re-export-chain.d.ts +1 -1
- package/dist/engine/re-export-chain.js +6 -6
- package/dist/engine/re-export-chain.js.map +1 -1
- package/dist/engine/registry.d.ts +52 -13
- package/dist/engine/registry.js +73 -58
- package/dist/engine/registry.js.map +1 -1
- package/dist/engine/resolve-reference.d.ts +2 -21
- package/dist/engine/resolve-reference.js +4 -178
- package/dist/engine/resolve-reference.js.map +1 -1
- package/dist/engine/resolve-type.d.ts +7 -7
- package/dist/engine/resolve-type.js +23 -29
- package/dist/engine/resolve-type.js.map +1 -1
- package/dist/engine/wrapper-folding.d.ts +18 -22
- package/dist/engine/wrapper-folding.js +147 -282
- package/dist/engine/wrapper-folding.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/engine/registry.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { MODULE_SCOPE } from "../index.js";
|
|
2
2
|
import { parseCompoundExport } from "@component-compass/plugin-core";
|
|
3
|
-
import { resolveRefToDecl
|
|
3
|
+
import { resolveRefToDecl } from "./helper-callers.js";
|
|
4
|
+
import { findLocalDeclaration } from "./binding.js";
|
|
4
5
|
import { evalKind } from "./component-shape.js";
|
|
5
6
|
import { hasOnlyHostElementNames } from "./host-element.js";
|
|
7
|
+
import { memberOfObjectPath } from "./member-identity.js";
|
|
6
8
|
/** The registry's key shape, shared with the engine's folded-holder map. */
|
|
7
9
|
export function entryKey(filePath, name) {
|
|
8
10
|
return `${filePath}::${name}`;
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* A narrowed view over an existing registry: `localEntries()` and `hasLocal`
|
|
12
|
-
* answer for `entries` only; `
|
|
13
|
-
* `
|
|
14
|
-
* still declared where it was. Both roster narrowings — folded holders and
|
|
15
|
-
* host-element names — construct their result here rather than
|
|
16
|
-
*
|
|
14
|
+
* answer for `entries` only; `isComponent`, `declarationOf`,
|
|
15
|
+
* `isRenderedAsTag` and `isTagged` are always delegated untouched — a narrowed-away member
|
|
16
|
+
* is still declared where it was. Both roster narrowings — folded holders and
|
|
17
|
+
* host-element names — construct their result here rather than each
|
|
18
|
+
* rebuilding the name index.
|
|
17
19
|
*/
|
|
18
20
|
function narrowTo(registry, entries) {
|
|
19
21
|
const survivingNames = new Set();
|
|
@@ -23,12 +25,17 @@ function narrowTo(registry, entries) {
|
|
|
23
25
|
}
|
|
24
26
|
return {
|
|
25
27
|
hasLocal: (filePath, exportName) => survivingNames.has(entryKey(filePath, exportName)),
|
|
26
|
-
|
|
28
|
+
isComponent: (filePath, name, declaration) => registry.isComponent(filePath, name, declaration),
|
|
27
29
|
declarationOf: (filePath, exportName) => registry.declarationOf(filePath, exportName),
|
|
30
|
+
isRenderedAsTag: (entry) => registry.isRenderedAsTag(entry),
|
|
31
|
+
isTagged: (declaration) => registry.isTagged(declaration),
|
|
28
32
|
localEntries: () => entries,
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
|
-
|
|
35
|
+
/** `tagged`: every declaration a tag's walk landed on as a function
|
|
36
|
+
* (`callable`), as the render site or the identity's tag-position stamp
|
|
37
|
+
* resolved it in scope. */
|
|
38
|
+
export function buildComponentRegistry(graph, tagged = []) {
|
|
32
39
|
const consumed = new Set(); // `${file}::${symbol}`
|
|
33
40
|
// 1. Consumption: exports, JSX references, held values.
|
|
34
41
|
for (const [file, fg] of graph.files) {
|
|
@@ -51,19 +58,22 @@ export function buildComponentRegistry(graph) {
|
|
|
51
58
|
consumed.add(entryKey(target.file, target.symbol));
|
|
52
59
|
}
|
|
53
60
|
}
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
// Each tagged declaration is marked; `isTagged` reads the marks.
|
|
62
|
+
const renderedAsTag = new Set(tagged);
|
|
63
|
+
const isTagged = (declaration) => declaration !== undefined && renderedAsTag.has(declaration);
|
|
64
|
+
// 2. Membership: consumed AND component-shaped, or rendered as a tag. Among
|
|
65
|
+
// members sharing a name, the one `findDeclaration` resolves the name to
|
|
66
|
+
// takes the first one's entry, in its list position.
|
|
57
67
|
const byKey = new Map();
|
|
58
68
|
const entryIndex = new Map();
|
|
59
69
|
const entries = [];
|
|
70
|
+
const taggedEntries = new Set();
|
|
60
71
|
for (const [file, fg] of graph.files) {
|
|
61
72
|
if (fg.dialect === "vue")
|
|
62
73
|
continue;
|
|
63
74
|
for (const decl of fg.declarations.values()) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (!isAdmittedShape(decl.value, graph, fg))
|
|
75
|
+
const symbolKey = entryKey(file, decl.symbol);
|
|
76
|
+
if (!renderedAsTag.has(decl) && !(consumed.has(symbolKey) && isAdmittedShape(decl.value, graph, fg)))
|
|
67
77
|
continue;
|
|
68
78
|
const exportName = decl.exportedAs ?? decl.symbol;
|
|
69
79
|
const entry = {
|
|
@@ -74,6 +84,8 @@ export function buildComponentRegistry(graph) {
|
|
|
74
84
|
loc: decl.loc,
|
|
75
85
|
isDefault: decl.symbol === "default" || fg.exports.some((e) => e.kind === "default" && "local" in e && e.local === decl.symbol),
|
|
76
86
|
};
|
|
87
|
+
if (renderedAsTag.has(decl))
|
|
88
|
+
taggedEntries.add(declarationKey(entry));
|
|
77
89
|
const key = entryKey(file, exportName);
|
|
78
90
|
if (!byKey.has(key)) {
|
|
79
91
|
entryIndex.set(key, entries.length);
|
|
@@ -88,31 +100,33 @@ export function buildComponentRegistry(graph) {
|
|
|
88
100
|
byKey.set(key, entry);
|
|
89
101
|
}
|
|
90
102
|
}
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
// A compound name (`NS.Inline`) names a member of a holder declaration: the
|
|
104
|
+
// holder is looked up by its root and the residual path walked through its
|
|
105
|
+
// Object props. `parseCompoundExport` is the one reader of the dotted form;
|
|
106
|
+
// `compoundExportName` the one writer.
|
|
107
|
+
const judge = (fg, name, declaration) => {
|
|
108
|
+
const { root, path } = parseCompoundExport(name);
|
|
109
|
+
const decl = declaration ?? findDeclaration(fg, root);
|
|
110
|
+
if (decl === undefined)
|
|
111
|
+
return false;
|
|
112
|
+
if (path.length > 0)
|
|
113
|
+
return isAdmittedMember(decl.value, path, graph, fg);
|
|
114
|
+
return isAdmittedShape(decl.value, graph, fg) || renderedAsTag.has(decl);
|
|
115
|
+
};
|
|
116
|
+
// Cached per (file, name) for name-only calls.
|
|
117
|
+
const judgedByName = new Map();
|
|
118
|
+
const isComponent = (filePath, name, declaration) => {
|
|
119
|
+
const fg = graph.files.get(filePath);
|
|
120
|
+
if (fg === undefined || fg.dialect === "vue")
|
|
121
|
+
return false;
|
|
122
|
+
if (declaration !== undefined)
|
|
123
|
+
return judge(fg, name, declaration);
|
|
124
|
+
const cacheKey = entryKey(filePath, name);
|
|
125
|
+
const cached = judgedByName.get(cacheKey);
|
|
100
126
|
if (cached !== undefined)
|
|
101
127
|
return cached;
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
if (fg && fg.dialect !== "vue") {
|
|
105
|
-
// A compound export (`NS.Inline`) names a member of a holder
|
|
106
|
-
// declaration: look the HOLDER up by its root, then walk the residual
|
|
107
|
-
// path through its Object props. `parseCompoundExport` is the one
|
|
108
|
-
// reader of the dotted form; `compoundExportName` the one writer.
|
|
109
|
-
const { root, path } = parseCompoundExport(exportName);
|
|
110
|
-
const decl = findDeclaration(fg, root);
|
|
111
|
-
result =
|
|
112
|
-
decl !== undefined &&
|
|
113
|
-
(path.length === 0 ? isAdmittedShape(decl.value, graph, fg) : isAdmittedMember(decl.value, path, graph, fg));
|
|
114
|
-
}
|
|
115
|
-
shapeCache.set(cacheKey, result);
|
|
128
|
+
const result = judge(fg, name, undefined);
|
|
129
|
+
judgedByName.set(cacheKey, result);
|
|
116
130
|
return result;
|
|
117
131
|
};
|
|
118
132
|
const declarationOf = (filePath, exportName) => {
|
|
@@ -129,18 +143,26 @@ export function buildComponentRegistry(graph) {
|
|
|
129
143
|
};
|
|
130
144
|
return {
|
|
131
145
|
hasLocal: (filePath, exportName) => byKey.has(entryKey(filePath, exportName)),
|
|
132
|
-
|
|
146
|
+
isComponent,
|
|
133
147
|
declarationOf,
|
|
148
|
+
isRenderedAsTag: (entry) => taggedEntries.has(declarationKey(entry)),
|
|
149
|
+
isTagged,
|
|
134
150
|
localEntries: () => entries,
|
|
135
151
|
};
|
|
136
152
|
}
|
|
153
|
+
/** One declaration's key: its file, symbol and position. */
|
|
154
|
+
function declarationKey(entry) {
|
|
155
|
+
return `${entryKey(entry.filePath, entry.symbol)}@${entry.loc.line}:${entry.loc.column}`;
|
|
156
|
+
}
|
|
137
157
|
/**
|
|
138
158
|
* THE narrowing seam: the roster registry after folded holders are
|
|
139
159
|
* removed. `resolve()` computes `folded` from the ONE fold it already runs
|
|
140
|
-
* per call-valued member; this function never folds. A
|
|
160
|
+
* per call-valued member; this function never folds. A folded holder a tag
|
|
161
|
+
* rendered as a function (`isRenderedAsTag`) is kept: the tag credits the
|
|
162
|
+
* holder itself, and it hands nothing to its target. Any other
|
|
141
163
|
* folded holder is absent from `localEntries()` and `hasLocal` says no for
|
|
142
|
-
* its symbol and its export name; `
|
|
143
|
-
*
|
|
164
|
+
* its symbol and its export name; `isComponent` (the component judge) is
|
|
165
|
+
* untouched.
|
|
144
166
|
* A folded DEFAULT holder hands `isDefault` to its same-file target.
|
|
145
167
|
* The narrowed `hasLocal` answers only for names of surviving entries, so a
|
|
146
168
|
* name the base registry knew only through its de-duplicated `byKey` (never
|
|
@@ -155,7 +177,7 @@ export function excludeFoldedHolders(registry, folded) {
|
|
|
155
177
|
const survivors = [];
|
|
156
178
|
for (const entry of registry.localEntries()) {
|
|
157
179
|
const holder = folded.get(entryKey(entry.filePath, entry.symbol));
|
|
158
|
-
if (holder === undefined) {
|
|
180
|
+
if (holder === undefined || registry.isRenderedAsTag(entry)) {
|
|
159
181
|
survivors.push(entry);
|
|
160
182
|
continue;
|
|
161
183
|
}
|
|
@@ -185,7 +207,7 @@ export function excludeFoldedHolders(registry, folded) {
|
|
|
185
207
|
* is exempt, and that inheritance happens in the fold narrowing.
|
|
186
208
|
*
|
|
187
209
|
* The naming rule and its exemptions live in `hasOnlyHostElementNames`,
|
|
188
|
-
* shared with owner classification. `
|
|
210
|
+
* shared with owner classification. `isComponent` is untouched: JSX
|
|
189
211
|
* cannot render a bare lowercase name, and a diagnostic is the residual
|
|
190
212
|
* guard for any other path that lands an occurrence on one.
|
|
191
213
|
*/
|
|
@@ -203,7 +225,7 @@ export function excludeHostElementNames(registry, graph) {
|
|
|
203
225
|
* `export const Sidebar = { Root, Branch, Leaf }` rendered as
|
|
204
226
|
* `<Sidebar.Root/>`. `evalKind` itself stays pure (an `Object` is always
|
|
205
227
|
* "other" there); this widening lives ONLY at the registry boundary — the
|
|
206
|
-
* one place shape gets turned into
|
|
228
|
+
* one place shape gets turned into the judge's and membership's decision.
|
|
207
229
|
*/
|
|
208
230
|
function isAdmittedShape(value, graph, fg) {
|
|
209
231
|
if (evalKind(value, graph, fg) === "component")
|
|
@@ -214,21 +236,14 @@ function isAdmittedShape(value, graph, fg) {
|
|
|
214
236
|
}
|
|
215
237
|
/**
|
|
216
238
|
* The member a compound export names. Walk `path` through nested
|
|
217
|
-
* `Object` props from the holder's value; the terminal
|
|
218
|
-
* admitted-shaped (a component, or itself a component
|
|
219
|
-
* that is not an `Object` prop, or a missing prop, is
|
|
239
|
+
* `Object` props from the holder's value (`memberOfObjectPath`); the terminal
|
|
240
|
+
* value must be admitted-shaped (a component, or itself a component
|
|
241
|
+
* namespace). Any step that is not an `Object` prop, or a missing prop, is
|
|
242
|
+
* not a member.
|
|
220
243
|
*/
|
|
221
244
|
function isAdmittedMember(holder, path, graph, fg) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (cur.kind !== "Object")
|
|
225
|
-
return false;
|
|
226
|
-
const next = cur.props[segment];
|
|
227
|
-
if (next === undefined)
|
|
228
|
-
return false;
|
|
229
|
-
cur = next;
|
|
230
|
-
}
|
|
231
|
-
return isAdmittedShape(cur, graph, fg);
|
|
245
|
+
const member = memberOfObjectPath(holder, path);
|
|
246
|
+
return member !== undefined && isAdmittedShape(member, graph, fg);
|
|
232
247
|
}
|
|
233
248
|
/**
|
|
234
249
|
* THE identity-name → declaration lookup, in order: a module-scope declaration
|
|
@@ -249,7 +264,7 @@ function isAdmittedMember(holder, path, graph, fg) {
|
|
|
249
264
|
* `ComponentId.export` has no scope field to disambiguate with; threading
|
|
250
265
|
* scope through `ComponentId` is the real fix.
|
|
251
266
|
*/
|
|
252
|
-
function findDeclaration(fg, name) {
|
|
267
|
+
export function findDeclaration(fg, name) {
|
|
253
268
|
const atModuleScope = fg.declarations.get(`${MODULE_SCOPE}::${name}`);
|
|
254
269
|
if (atModuleScope)
|
|
255
270
|
return atModuleScope;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/engine/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/engine/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +1,5 @@
|
|
|
1
1
|
import type { FileGraph, Graph, InferredType, Reference } from "../index.js";
|
|
2
2
|
import { type CycleGuard } from "./cycle-detection.js";
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* its FileGraph, falling through to imports at module scope, and following
|
|
6
|
-
* cross-file resolution through exports. Returns InferredType::Unknown for
|
|
7
|
-
* unresolved symbols and cycles.
|
|
8
|
-
*
|
|
9
|
-
* When `ref.originFile` is set, the lookup switches to that file's FileGraph.
|
|
10
|
-
* `scope` is opaque per-FileGraph, so any TypeOf travelling across module
|
|
11
|
-
* boundaries (e.g. via cross-module function returns) must be resolved in
|
|
12
|
-
* its origin context. Refs without `originFile` fall back to the passed
|
|
13
|
-
* FileGraph (synthetic test refs, parsers that haven't adopted the
|
|
14
|
-
* annotation).
|
|
15
|
-
*/
|
|
3
|
+
/** The value a reference names: `bindingValue` of its binding. `Unknown` for
|
|
4
|
+
* unresolved symbols and cycles. */
|
|
16
5
|
export declare function resolveReference(graph: Graph, fileGraph: FileGraph, ref: Reference, guard?: CycleGuard): InferredType;
|
|
17
|
-
/**
|
|
18
|
-
* Pick the FileGraph a Reference should be resolved against. When
|
|
19
|
-
* `ref.originFile` is set, prefer that file's graph; this is how refs that
|
|
20
|
-
* have travelled across a module boundary get looked up in their authoring
|
|
21
|
-
* context. Falls back to the caller's `fileGraph` when no annotation is
|
|
22
|
-
* present (synthetic refs / parsers without ref-origin tagging).
|
|
23
|
-
*/
|
|
24
|
-
export declare function fileGraphForRef(graph: Graph, ref: Reference, fallback: FileGraph): FileGraph;
|
|
@@ -1,182 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bindingValue, resolveBinding } from "./binding.js";
|
|
2
2
|
import { createCycleGuard } from "./cycle-detection.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Resolve a Reference to an InferredType by walking the scope chain in
|
|
6
|
-
* its FileGraph, falling through to imports at module scope, and following
|
|
7
|
-
* cross-file resolution through exports. Returns InferredType::Unknown for
|
|
8
|
-
* unresolved symbols and cycles.
|
|
9
|
-
*
|
|
10
|
-
* When `ref.originFile` is set, the lookup switches to that file's FileGraph.
|
|
11
|
-
* `scope` is opaque per-FileGraph, so any TypeOf travelling across module
|
|
12
|
-
* boundaries (e.g. via cross-module function returns) must be resolved in
|
|
13
|
-
* its origin context. Refs without `originFile` fall back to the passed
|
|
14
|
-
* FileGraph (synthetic test refs, parsers that haven't adopted the
|
|
15
|
-
* annotation).
|
|
16
|
-
*/
|
|
3
|
+
/** The value a reference names: `bindingValue` of its binding. `Unknown` for
|
|
4
|
+
* unresolved symbols and cycles. */
|
|
17
5
|
export function resolveReference(graph, fileGraph, ref, guard = createCycleGuard()) {
|
|
18
|
-
|
|
19
|
-
// Walk up the scope chain.
|
|
20
|
-
let scope = ref.scope;
|
|
21
|
-
while (true) {
|
|
22
|
-
const decl = lookupGraph.declarations.get(`${scope}::${ref.symbol}`);
|
|
23
|
-
if (decl) {
|
|
24
|
-
// Apply member chain via MemberOf wrap.
|
|
25
|
-
return wrapWithMemberChain(decl.value, ref.memberChain);
|
|
26
|
-
}
|
|
27
|
-
if (scope === MODULE_SCOPE)
|
|
28
|
-
break;
|
|
29
|
-
const parent = lookupGraph.scopes.get(scope)?.parent;
|
|
30
|
-
if (parent === null || parent === undefined)
|
|
31
|
-
break;
|
|
32
|
-
scope = parent;
|
|
33
|
-
}
|
|
34
|
-
// At module scope — check imports.
|
|
35
|
-
const imp = lookupGraph.importsByLocal.get(ref.symbol);
|
|
36
|
-
if (!imp)
|
|
37
|
-
return { kind: "Unknown" };
|
|
38
|
-
// Library stub table: a known framework export gets a structural
|
|
39
|
-
// type instead of walking node_modules it can never parse. Checked before
|
|
40
|
-
// module resolution because these packages are never in the graph.
|
|
41
|
-
const stub = libraryStubFor(imp, ref);
|
|
42
|
-
if (stub)
|
|
43
|
-
return stub;
|
|
44
|
-
const resolvedFile = graph.moduleResolver(lookupGraph.filePath, imp.specifier);
|
|
45
|
-
if (!resolvedFile)
|
|
46
|
-
return { kind: "Unknown" };
|
|
47
|
-
// Normalize the resolved path to the graph key format (repo-relative POSIX).
|
|
48
|
-
// `moduleResolver` may return absolute paths; `resolveToGraphKey` maps them
|
|
49
|
-
// to relative keys matching `graph.files`.
|
|
50
|
-
const targetFile = graph.resolveToGraphKey
|
|
51
|
-
? (graph.resolveToGraphKey(resolvedFile) ?? resolvedFile)
|
|
52
|
-
: resolvedFile;
|
|
53
|
-
// Look up the export with the imported name in the target file, following
|
|
54
|
-
// star re-exports when needed.
|
|
55
|
-
const found = findExport(graph, targetFile, imp.imported, new Set());
|
|
56
|
-
if (!found)
|
|
57
|
-
return { kind: "Unknown" };
|
|
58
|
-
const { record: exp, fileGraph: expFileGraph } = found;
|
|
59
|
-
return resolveExport(graph, expFileGraph, exp, ref.memberChain, guard);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Find an ExportRecord matching `imported` starting from `file`, following
|
|
63
|
-
* `{kind: "star"}` re-exports when the named/default export isn't in the
|
|
64
|
-
* file's own export list. Returns the matched record together with the
|
|
65
|
-
* FileGraph it belongs to — callers need the owning FileGraph to drive
|
|
66
|
-
* `resolveExport` correctly when the match is in a transitive star source.
|
|
67
|
-
*
|
|
68
|
-
* Uses a cycle guard keyed by `${file}::${imported}` to avoid infinite
|
|
69
|
-
* loops through mutual `export *` chains.
|
|
70
|
-
*/
|
|
71
|
-
function findExport(graph, file, imported, seen) {
|
|
72
|
-
const seenKey = `${file}::${imported}`;
|
|
73
|
-
if (seen.has(seenKey))
|
|
74
|
-
return null;
|
|
75
|
-
seen.add(seenKey);
|
|
76
|
-
const target = graph.files.get(file);
|
|
77
|
-
if (!target)
|
|
78
|
-
return null;
|
|
79
|
-
// Step 1 — named/default hit in this file.
|
|
80
|
-
for (const exp of target.exports) {
|
|
81
|
-
if (exp.kind === "named" && exp.exportedAs === imported)
|
|
82
|
-
return { record: exp, fileGraph: target };
|
|
83
|
-
if (exp.kind === "default" && imported === "default")
|
|
84
|
-
return { record: exp, fileGraph: target };
|
|
85
|
-
}
|
|
86
|
-
// Step 2 — star fallback: walk {kind: "star"} entries in source order.
|
|
87
|
-
// seen is shared across sibling branches to prevent revisiting files already tried at this level — matches followReExportChain.
|
|
88
|
-
for (const exp of target.exports) {
|
|
89
|
-
if (exp.kind !== "star")
|
|
90
|
-
continue;
|
|
91
|
-
const resolvedFrom = graph.moduleResolver(file, exp.from);
|
|
92
|
-
if (!resolvedFrom)
|
|
93
|
-
continue;
|
|
94
|
-
const nextFile = graph.resolveToGraphKey
|
|
95
|
-
? (graph.resolveToGraphKey(resolvedFrom) ?? resolvedFrom)
|
|
96
|
-
: resolvedFrom;
|
|
97
|
-
const result = findExport(graph, nextFile, imported, seen);
|
|
98
|
-
if (result)
|
|
99
|
-
return result;
|
|
100
|
-
}
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
function resolveExport(graph, fileGraph, exp, memberChain, guard) {
|
|
104
|
-
if (exp.kind === "named" && "local" in exp) {
|
|
105
|
-
const guardResult = guard.push(fileGraph.filePath, exp.local);
|
|
106
|
-
if (guardResult !== "ok")
|
|
107
|
-
return { kind: "Unknown" };
|
|
108
|
-
try {
|
|
109
|
-
const localRef = {
|
|
110
|
-
symbol: exp.local,
|
|
111
|
-
scope: MODULE_SCOPE,
|
|
112
|
-
memberChain,
|
|
113
|
-
loc: { line: 0, column: 0 },
|
|
114
|
-
};
|
|
115
|
-
return resolveReference(graph, fileGraph, localRef, guard);
|
|
116
|
-
}
|
|
117
|
-
finally {
|
|
118
|
-
guard.pop(fileGraph.filePath, exp.local);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
if (exp.kind === "named" && "from" in exp) {
|
|
122
|
-
// Re-export: resolve to the source module's binding.
|
|
123
|
-
const resolvedFrom = graph.moduleResolver(fileGraph.filePath, exp.from);
|
|
124
|
-
if (!resolvedFrom)
|
|
125
|
-
return { kind: "Unknown" };
|
|
126
|
-
const targetFile = graph.resolveToGraphKey
|
|
127
|
-
? (graph.resolveToGraphKey(resolvedFrom) ?? resolvedFrom)
|
|
128
|
-
: resolvedFrom;
|
|
129
|
-
const innerFound = findExport(graph, targetFile, exp.fromImported, new Set());
|
|
130
|
-
if (!innerFound)
|
|
131
|
-
return { kind: "Unknown" };
|
|
132
|
-
const guardResult = guard.push(fileGraph.filePath, exp.exportedAs);
|
|
133
|
-
if (guardResult !== "ok")
|
|
134
|
-
return { kind: "Unknown" };
|
|
135
|
-
try {
|
|
136
|
-
return resolveExport(graph, innerFound.fileGraph, innerFound.record, memberChain, guard);
|
|
137
|
-
}
|
|
138
|
-
finally {
|
|
139
|
-
guard.pop(fileGraph.filePath, exp.exportedAs);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (exp.kind === "default" && "local" in exp) {
|
|
143
|
-
const guardResult = guard.push(fileGraph.filePath, exp.local);
|
|
144
|
-
if (guardResult !== "ok")
|
|
145
|
-
return { kind: "Unknown" };
|
|
146
|
-
try {
|
|
147
|
-
const localRef = {
|
|
148
|
-
symbol: exp.local,
|
|
149
|
-
scope: MODULE_SCOPE,
|
|
150
|
-
memberChain,
|
|
151
|
-
loc: { line: 0, column: 0 },
|
|
152
|
-
};
|
|
153
|
-
return resolveReference(graph, fileGraph, localRef, guard);
|
|
154
|
-
}
|
|
155
|
-
finally {
|
|
156
|
-
guard.pop(fileGraph.filePath, exp.local);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return { kind: "Unknown" };
|
|
160
|
-
}
|
|
161
|
-
function wrapWithMemberChain(t, chain) {
|
|
162
|
-
let result = t;
|
|
163
|
-
for (const member of chain) {
|
|
164
|
-
result = { kind: "MemberOf", obj: result, member };
|
|
165
|
-
}
|
|
166
|
-
return result;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Pick the FileGraph a Reference should be resolved against. When
|
|
170
|
-
* `ref.originFile` is set, prefer that file's graph; this is how refs that
|
|
171
|
-
* have travelled across a module boundary get looked up in their authoring
|
|
172
|
-
* context. Falls back to the caller's `fileGraph` when no annotation is
|
|
173
|
-
* present (synthetic refs / parsers without ref-origin tagging).
|
|
174
|
-
*/
|
|
175
|
-
export function fileGraphForRef(graph, ref, fallback) {
|
|
176
|
-
if (!ref.originFile)
|
|
177
|
-
return fallback;
|
|
178
|
-
if (ref.originFile === fallback.filePath)
|
|
179
|
-
return fallback;
|
|
180
|
-
return graph.files.get(ref.originFile) ?? fallback;
|
|
6
|
+
return bindingValue(resolveBinding(graph, fileGraph, ref, guard));
|
|
181
7
|
}
|
|
182
8
|
//# sourceMappingURL=resolve-reference.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-reference.js","sourceRoot":"","sources":["../../src/engine/resolve-reference.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-reference.js","sourceRoot":"","sources":["../../src/engine/resolve-reference.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAmB,MAAM,sBAAsB,CAAC;AAEzE;qCACqC;AACrC,MAAM,UAAU,gBAAgB,CAC9B,KAAY,EACZ,SAAoB,EACpB,GAAc,EACd,QAAoB,gBAAgB,EAAE;IAEtC,OAAO,YAAY,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -22,16 +22,16 @@ export type ResolvedTerminal = {
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function resolveType(graph: Graph, fileGraph: FileGraph, type: InferredType, argMap: ArgumentMap, guard?: CycleGuard): ResolvedTerminal[];
|
|
24
24
|
/**
|
|
25
|
-
* A DynamicImport's target: the
|
|
26
|
-
* the file that contains the import()
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
25
|
+
* A DynamicImport's target: the binding its specifier's projected export
|
|
26
|
+
* names from the file that contains the `import()`. For a declaration, the
|
|
27
|
+
* declaring file and its value; for an unparsed binding reached through a
|
|
28
|
+
* parsed file's imported local, that file and `Unknown`. Any remaining
|
|
29
|
+
* projection is applied as member walks. Null otherwise, so a package export
|
|
30
|
+
* stays the `DynamicImport`. Resolved on its own cycle guard, not the walk's.
|
|
31
31
|
*/
|
|
32
32
|
export declare function resolveDynamicImportTarget(graph: Graph, fileGraph: FileGraph, di: Extract<InferredType, {
|
|
33
33
|
kind: "DynamicImport";
|
|
34
|
-
}
|
|
34
|
+
}>): {
|
|
35
35
|
targetFileGraph: FileGraph;
|
|
36
36
|
value: InferredType;
|
|
37
37
|
} | null;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { MODULE_SCOPE } from "../index.js";
|
|
2
1
|
import { boundArgument } from "./argument-map.js";
|
|
3
|
-
import { resolveReference
|
|
2
|
+
import { resolveReference } from "./resolve-reference.js";
|
|
3
|
+
import { bindingValue, fileGraphForRef, resolveModuleExport } from "./binding.js";
|
|
4
4
|
import { fileGraphForDynamicImport } from "./wrapper-folding.js";
|
|
5
5
|
import { createCycleGuard } from "./cycle-detection.js";
|
|
6
6
|
import { libraryStubFor } from "./library-stubs.js";
|
|
7
7
|
import { assertNever } from "./assert-never.js";
|
|
8
|
-
import { followReExportChain } from "./re-export-chain.js";
|
|
9
8
|
/** Sentinel for dynamic member access (`obj[expr]` where expr isn't a literal). */
|
|
10
9
|
export const DYNAMIC_MEMBER_KEY = "";
|
|
11
10
|
/**
|
|
@@ -142,7 +141,7 @@ function resolveTypeInner(graph, fileGraph, type, argMap, guard) {
|
|
|
142
141
|
// terminal (specifier + projection) rather than collapsing to Unknown —
|
|
143
142
|
// the foldTerminals seam (wrapper-folding.ts) synthesizes occurrence
|
|
144
143
|
// identity from it.
|
|
145
|
-
const target = resolveDynamicImportTarget(graph, fileGraph, type
|
|
144
|
+
const target = resolveDynamicImportTarget(graph, fileGraph, type);
|
|
146
145
|
if (!target)
|
|
147
146
|
return [{ type, source: type }];
|
|
148
147
|
return resolveType(graph, target.targetFileGraph, target.value, argMap, guard);
|
|
@@ -152,36 +151,31 @@ function resolveTypeInner(graph, fileGraph, type, argMap, guard) {
|
|
|
152
151
|
}
|
|
153
152
|
}
|
|
154
153
|
/**
|
|
155
|
-
* A DynamicImport's target: the
|
|
156
|
-
* the file that contains the import()
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
154
|
+
* A DynamicImport's target: the binding its specifier's projected export
|
|
155
|
+
* names from the file that contains the `import()`. For a declaration, the
|
|
156
|
+
* declaring file and its value; for an unparsed binding reached through a
|
|
157
|
+
* parsed file's imported local, that file and `Unknown`. Any remaining
|
|
158
|
+
* projection is applied as member walks. Null otherwise, so a package export
|
|
159
|
+
* stays the `DynamicImport`. Resolved on its own cycle guard, not the walk's.
|
|
161
160
|
*/
|
|
162
|
-
export function resolveDynamicImportTarget(graph, fileGraph, di
|
|
161
|
+
export function resolveDynamicImportTarget(graph, fileGraph, di) {
|
|
163
162
|
const origin = fileGraphForDynamicImport(graph, di, fileGraph);
|
|
164
|
-
const
|
|
165
|
-
|
|
163
|
+
const b = resolveModuleExport(graph, origin.filePath, di.specifier, di.projection[0] ?? "default", []);
|
|
164
|
+
// Transitional: an unparsed binding reached through a parsed barrel's
|
|
165
|
+
// imported local keeps that barrel as the lazy target, as before the
|
|
166
|
+
// resolver; removed when it is pinned (#628).
|
|
167
|
+
const targetFile = b.kind === "declaration"
|
|
168
|
+
? b.file
|
|
169
|
+
: b.kind === "unparsed" && b.mainGap !== undefined
|
|
170
|
+
? b.mainGap.barrel
|
|
171
|
+
: null;
|
|
172
|
+
const targetFileGraph = targetFile === null ? undefined : graph.files.get(targetFile);
|
|
173
|
+
if (!targetFileGraph)
|
|
166
174
|
return null;
|
|
167
|
-
|
|
168
|
-
const chained = followReExportChain(graph, key, di.projection[0] ?? "default");
|
|
169
|
-
const targetFile = chained ? graph.files.get(chained.file) : undefined;
|
|
170
|
-
if (!chained || !targetFile)
|
|
171
|
-
return null;
|
|
172
|
-
const local = chained.localExport;
|
|
173
|
-
if (!targetFile.declarations.has(`${MODULE_SCOPE}::${local}`) && !targetFile.importsByLocal.has(local))
|
|
174
|
-
return null;
|
|
175
|
-
const localRef = {
|
|
176
|
-
symbol: local,
|
|
177
|
-
scope: MODULE_SCOPE,
|
|
178
|
-
memberChain: [],
|
|
179
|
-
loc: { line: 0, column: 0 },
|
|
180
|
-
};
|
|
181
|
-
let value = resolveReference(graph, targetFile, localRef, guard);
|
|
175
|
+
let value = bindingValue(b);
|
|
182
176
|
for (const member of di.projection.slice(1))
|
|
183
177
|
value = { kind: "MemberOf", obj: value, member };
|
|
184
|
-
return { targetFileGraph
|
|
178
|
+
return { targetFileGraph, value };
|
|
185
179
|
}
|
|
186
180
|
/**
|
|
187
181
|
* Resolve a type down to its bare Function node(s) without expanding their
|