@component-compass/reference-graph 0.1.23 → 0.1.24
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/argument-map.d.ts +7 -0
- package/dist/engine/argument-map.js +7 -0
- package/dist/engine/argument-map.js.map +1 -1
- package/dist/engine/component-shape.js +2 -2
- package/dist/engine/component-shape.js.map +1 -1
- package/dist/engine/denotation.d.ts +83 -0
- package/dist/engine/denotation.js +40 -0
- package/dist/engine/denotation.js.map +1 -0
- package/dist/engine/host-element.d.ts +7 -3
- package/dist/engine/host-element.js +7 -3
- package/dist/engine/host-element.js.map +1 -1
- package/dist/engine/index.js +58 -52
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/library-stubs.d.ts +36 -0
- package/dist/engine/library-stubs.js +26 -29
- package/dist/engine/library-stubs.js.map +1 -1
- package/dist/engine/registry.d.ts +13 -2
- package/dist/engine/registry.js +68 -32
- package/dist/engine/registry.js.map +1 -1
- package/dist/engine/resolve-type.d.ts +1 -1
- package/dist/engine/resolve-type.js +3 -2
- package/dist/engine/resolve-type.js.map +1 -1
- package/dist/engine/wrapper-folding.d.ts +3 -13
- package/dist/engine/wrapper-folding.js +283 -54
- package/dist/engine/wrapper-folding.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -11,6 +11,13 @@ export interface ArgumentMap {
|
|
|
11
11
|
unbind(fn: Reference): void;
|
|
12
12
|
lookup(fn: Reference, index: number): InferredType | undefined;
|
|
13
13
|
}
|
|
14
|
+
/** THE question "did the call the walk is inside bind this parameter", and the
|
|
15
|
+
* argument it bound, asked once. Every reader of a `ParameterOf` — the
|
|
16
|
+
* algebra's substitution, the component-shape predicate, the walker's
|
|
17
|
+
* late-bound naming — calls this rather than keying the map itself. */
|
|
18
|
+
export declare function boundArgument(argMap: ArgumentMap, param: Extract<InferredType, {
|
|
19
|
+
kind: "ParameterOf";
|
|
20
|
+
}>): InferredType | undefined;
|
|
14
21
|
/** Key an ArgumentMap frame by. Exported so wrapper-folding's structural
|
|
15
22
|
* pass-through check compares `ParameterOf.fn` against a callee's
|
|
16
23
|
* `bindingRef` exactly the way `lookup` would. */
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/** THE question "did the call the walk is inside bind this parameter", and the
|
|
2
|
+
* argument it bound, asked once. Every reader of a `ParameterOf` — the
|
|
3
|
+
* algebra's substitution, the component-shape predicate, the walker's
|
|
4
|
+
* late-bound naming — calls this rather than keying the map itself. */
|
|
5
|
+
export function boundArgument(argMap, param) {
|
|
6
|
+
return argMap.lookup(param.fn, param.index);
|
|
7
|
+
}
|
|
1
8
|
/** Key an ArgumentMap frame by. Exported so wrapper-folding's structural
|
|
2
9
|
* pass-through check compares `ParameterOf.fn` against a callee's
|
|
3
10
|
* `bindingRef` exactly the way `lookup` would. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"argument-map.js","sourceRoot":"","sources":["../../src/engine/argument-map.ts"],"names":[],"mappings":"AAeA;;mDAEmD;AACnD,MAAM,UAAU,cAAc,CAAC,GAAc;IAC3C,OAAO,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAiD,EAAE,CAAC;IAC/D,OAAO;QACL,IAAI,CAAC,EAAE,EAAE,IAAI;YACX,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,CAAC,EAAE;YACP,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG,EAAE,CAAC;oBAC1B,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACnB,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,CAAC,EAAE,EAAE,KAAK;YACd,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvB,IAAI,KAAK,EAAE,GAAG,KAAK,GAAG;oBAAE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"argument-map.js","sourceRoot":"","sources":["../../src/engine/argument-map.ts"],"names":[],"mappings":"AAeA;;;wEAGwE;AACxE,MAAM,UAAU,aAAa,CAC3B,MAAmB,EACnB,KAAqD;IAErD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED;;mDAEmD;AACnD,MAAM,UAAU,cAAc,CAAC,GAAc;IAC3C,OAAO,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAiD,EAAE,CAAC;IAC/D,OAAO;QACL,IAAI,CAAC,EAAE,EAAE,IAAI;YACX,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,CAAC,EAAE;YACP,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG,EAAE,CAAC;oBAC1B,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACnB,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,CAAC,EAAE,EAAE,KAAK;YACd,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvB,IAAI,KAAK,EAAE,GAAG,KAAK,GAAG;oBAAE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createArgumentMap } from "./argument-map.js";
|
|
1
|
+
import { boundArgument, createArgumentMap } from "./argument-map.js";
|
|
2
2
|
import { createCycleGuard } from "./cycle-detection.js";
|
|
3
3
|
import { fileGraphForRef, resolveReference } from "./resolve-reference.js";
|
|
4
4
|
import { resolveToFunctions, resolveType, DYNAMIC_MEMBER_KEY } from "./resolve-type.js";
|
|
@@ -31,7 +31,7 @@ function evalInner(t, ctx) {
|
|
|
31
31
|
case "Union":
|
|
32
32
|
return merge(t.types.map((u) => evalInner(u, ctx)));
|
|
33
33
|
case "ParameterOf": {
|
|
34
|
-
const bound = ctx.argMap
|
|
34
|
+
const bound = boundArgument(ctx.argMap, t);
|
|
35
35
|
return bound ? evalInner(bound, ctx) : "other";
|
|
36
36
|
}
|
|
37
37
|
case "TypeOf": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-shape.js","sourceRoot":"","sources":["../../src/engine/component-shape.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"component-shape.js","sourceRoot":"","sources":["../../src/engine/component-shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { OccurrenceVia } from "@component-compass/plugin-core";
|
|
2
|
+
import type { TerminalIdentity } from "./wrapper-folding.js";
|
|
3
|
+
/**
|
|
4
|
+
* THE closed set of things a value can denote when something asks "what is
|
|
5
|
+
* this tag". One variant per outcome a caller can act on differently. Adding a
|
|
6
|
+
* variant is a compile error at every `matchDenotation` call and in
|
|
7
|
+
* `RENDER_VERDICT`.
|
|
8
|
+
*/
|
|
9
|
+
export type Denotation =
|
|
10
|
+
/** An element value: a render body, or an already-rendered `const br = <br/>`. */
|
|
11
|
+
{
|
|
12
|
+
kind: "element";
|
|
13
|
+
}
|
|
14
|
+
/** A string the walk reached through value hops only — a reference, a union
|
|
15
|
+
* branch, a member of an object or array literal — so the TAG itself is the
|
|
16
|
+
* string: an intrinsic host element. */
|
|
17
|
+
| {
|
|
18
|
+
kind: "host-string";
|
|
19
|
+
value: string | null;
|
|
20
|
+
}
|
|
21
|
+
/** A framework value that is provably not a component (a context object). */
|
|
22
|
+
| {
|
|
23
|
+
kind: "opaque";
|
|
24
|
+
semantics: OpaqueSemantics;
|
|
25
|
+
}
|
|
26
|
+
/** A value supplied somewhere else: an unsubstituted parameter, a prop read
|
|
27
|
+
* off one, a hook result. */
|
|
28
|
+
| {
|
|
29
|
+
kind: "late-bound";
|
|
30
|
+
source: LateBoundSource;
|
|
31
|
+
}
|
|
32
|
+
/** An import the graph cannot see. Identity known, shape unknowable. */
|
|
33
|
+
| {
|
|
34
|
+
kind: "foreign";
|
|
35
|
+
}
|
|
36
|
+
/** Data: a value that reached tag position without being one — an object or
|
|
37
|
+
* array literal, or a string a function body or a call returned. */
|
|
38
|
+
| {
|
|
39
|
+
kind: "data";
|
|
40
|
+
shape: "object" | "array" | "string";
|
|
41
|
+
}
|
|
42
|
+
/** Nothing known. */
|
|
43
|
+
| {
|
|
44
|
+
kind: "indeterminate";
|
|
45
|
+
};
|
|
46
|
+
export type OpaqueSemantics = "context";
|
|
47
|
+
export type LateBoundSource = "parameter" | "parameter-member" | "hook-result";
|
|
48
|
+
/**
|
|
49
|
+
* One branch of an evaluation. `identity` is the binding this branch credits
|
|
50
|
+
* (null = "the caller's own fallback names this render"); `viaTrail` is the
|
|
51
|
+
* fold's hops, outermost-first, excluding the caller's outer via.
|
|
52
|
+
*/
|
|
53
|
+
export type Terminal = {
|
|
54
|
+
denotation: Denotation;
|
|
55
|
+
identity: TerminalIdentity;
|
|
56
|
+
viaTrail: OccurrenceVia[];
|
|
57
|
+
};
|
|
58
|
+
/** The result of evaluating one value. Never empty. */
|
|
59
|
+
export type Evaluation = readonly [Terminal, ...Terminal[]];
|
|
60
|
+
/** One handler per denotation kind. A missing key is a type error; there is
|
|
61
|
+
* deliberately no default case and no `Partial`. */
|
|
62
|
+
export type DenotationCases<R> = {
|
|
63
|
+
[K in Denotation["kind"]]: (d: Extract<Denotation, {
|
|
64
|
+
kind: K;
|
|
65
|
+
}>, t: Terminal) => R;
|
|
66
|
+
};
|
|
67
|
+
/** The only sanctioned reader of `Denotation["kind"]` outside this module. */
|
|
68
|
+
export declare function matchDenotation<R>(t: Terminal, cases: DenotationCases<R>): R;
|
|
69
|
+
export type RenderOutcome = {
|
|
70
|
+
kind: "credit";
|
|
71
|
+
terminals: readonly [Terminal, ...Terminal[]];
|
|
72
|
+
} | {
|
|
73
|
+
kind: "silent";
|
|
74
|
+
because: "host-string" | "opaque";
|
|
75
|
+
} | {
|
|
76
|
+
kind: "diagnose";
|
|
77
|
+
code: "late-bound-render" | "unresolved-reference";
|
|
78
|
+
};
|
|
79
|
+
/** The terminals a render of this value credits — rule 1 of the table, shared
|
|
80
|
+
* with the holder fold and argument-site seeding so there is not one
|
|
81
|
+
* classification per arm. Empty when nothing is credited. */
|
|
82
|
+
export declare function creditedTerminals(e: readonly Terminal[]): Terminal[];
|
|
83
|
+
export declare function renderOutcome(e: Evaluation): RenderOutcome;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** The only sanctioned reader of `Denotation["kind"]` outside this module. */
|
|
2
|
+
export function matchDenotation(t, cases) {
|
|
3
|
+
const handler = cases[t.denotation.kind];
|
|
4
|
+
return handler(t.denotation, t);
|
|
5
|
+
}
|
|
6
|
+
/** THE table: what one denotation means for a tag position. Stated once. */
|
|
7
|
+
const RENDER_VERDICT = {
|
|
8
|
+
element: () => "credit",
|
|
9
|
+
foreign: () => "credit",
|
|
10
|
+
"host-string": () => "silent",
|
|
11
|
+
opaque: () => "silent",
|
|
12
|
+
"late-bound": () => "late-bound",
|
|
13
|
+
data: () => "unresolved",
|
|
14
|
+
indeterminate: () => "unresolved",
|
|
15
|
+
};
|
|
16
|
+
/** THE fan-out precedence: a Union / dynamic-map evaluation has several
|
|
17
|
+
* terminals with different verdicts. Highest wins, once, here. */
|
|
18
|
+
const VERDICT_ORDER = ["credit", "silent", "late-bound", "unresolved"];
|
|
19
|
+
/** The terminals a render of this value credits — rule 1 of the table, shared
|
|
20
|
+
* with the holder fold and argument-site seeding so there is not one
|
|
21
|
+
* classification per arm. Empty when nothing is credited. */
|
|
22
|
+
export function creditedTerminals(e) {
|
|
23
|
+
return e.filter((t) => matchDenotation(t, RENDER_VERDICT) === "credit");
|
|
24
|
+
}
|
|
25
|
+
export function renderOutcome(e) {
|
|
26
|
+
const verdicts = e.map((t) => matchDenotation(t, RENDER_VERDICT));
|
|
27
|
+
const winner = VERDICT_ORDER.find((v) => verdicts.includes(v)) ?? "unresolved";
|
|
28
|
+
const first = e[verdicts.indexOf(winner)] ?? e[0];
|
|
29
|
+
switch (winner) {
|
|
30
|
+
case "credit":
|
|
31
|
+
return { kind: "credit", terminals: creditedTerminals(e) };
|
|
32
|
+
case "silent":
|
|
33
|
+
return { kind: "silent", because: first.denotation.kind === "opaque" ? "opaque" : "host-string" };
|
|
34
|
+
case "late-bound":
|
|
35
|
+
return { kind: "diagnose", code: "late-bound-render" };
|
|
36
|
+
case "unresolved":
|
|
37
|
+
return { kind: "diagnose", code: "unresolved-reference" };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=denotation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"denotation.js","sourceRoot":"","sources":["../../src/engine/denotation.ts"],"names":[],"mappings":"AAoDA,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAAI,CAAW,EAAE,KAAyB;IACvE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAsC,CAAC;IAC9E,OAAO,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAClC,CAAC;AAID,4EAA4E;AAC5E,MAAM,cAAc,GAAmC;IACrD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ;IACvB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ;IACvB,aAAa,EAAE,GAAG,EAAE,CAAC,QAAQ;IAC7B,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ;IACtB,YAAY,EAAE,GAAG,EAAE,CAAC,YAAY;IAChC,IAAI,EAAE,GAAG,EAAE,CAAC,YAAY;IACxB,aAAa,EAAE,GAAG,EAAE,CAAC,YAAY;CAClC,CAAC;AAEF;mEACmE;AACnE,MAAM,aAAa,GAA6B,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;AAOjG;;8DAE8D;AAC9D,MAAM,UAAU,iBAAiB,CAAC,CAAsB;IACtD,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,cAAc,CAAC,KAAK,QAAQ,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAa;IACzC,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC;IAC/E,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAA8B,EAAE,CAAC;QAC1F,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACpG,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;QACzD,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { FileGraph } from "../index.js";
|
|
2
|
+
/**
|
|
3
|
+
* React's own hook predicate (`isHookName` in rules-of-hooks and the
|
|
4
|
+
* compiler).
|
|
5
|
+
*/
|
|
6
|
+
export declare const HOOK_NAME: RegExp;
|
|
2
7
|
/**
|
|
3
8
|
* THE JSX host-element naming rule. JSX compiles a bare,
|
|
4
9
|
* lowercase-initial element name to a string — `div`, `svg`, `web-button` —
|
|
@@ -9,9 +14,8 @@ import type { FileGraph } from "../index.js";
|
|
|
9
14
|
* intrinsic, so a caller holding a reference checks `memberChain.length === 0`
|
|
10
15
|
* first (`isHostElementRoot`, `engine/index.ts`).
|
|
11
16
|
*
|
|
12
|
-
* `isPascalCase` in `ast-utils/src/find-owner.ts`
|
|
13
|
-
*
|
|
14
|
-
* which rejects `_Foo`). Do not fold them into this one.
|
|
17
|
+
* `isPascalCase` in `ast-utils/src/find-owner.ts` is a DIFFERENT predicate
|
|
18
|
+
* (`/^[A-Z]/`, which rejects `_Foo`). Do not fold it into this one.
|
|
15
19
|
*/
|
|
16
20
|
export declare function isHostElementName(name: string): boolean;
|
|
17
21
|
/**
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React's own hook predicate (`isHookName` in rules-of-hooks and the
|
|
3
|
+
* compiler).
|
|
4
|
+
*/
|
|
5
|
+
export const HOOK_NAME = /^use[A-Z0-9]/;
|
|
1
6
|
/**
|
|
2
7
|
* THE JSX host-element naming rule. JSX compiles a bare,
|
|
3
8
|
* lowercase-initial element name to a string — `div`, `svg`, `web-button` —
|
|
@@ -8,9 +13,8 @@
|
|
|
8
13
|
* intrinsic, so a caller holding a reference checks `memberChain.length === 0`
|
|
9
14
|
* first (`isHostElementRoot`, `engine/index.ts`).
|
|
10
15
|
*
|
|
11
|
-
* `isPascalCase` in `ast-utils/src/find-owner.ts`
|
|
12
|
-
*
|
|
13
|
-
* which rejects `_Foo`). Do not fold them into this one.
|
|
16
|
+
* `isPascalCase` in `ast-utils/src/find-owner.ts` is a DIFFERENT predicate
|
|
17
|
+
* (`/^[A-Z]/`, which rejects `_Foo`). Do not fold it into this one.
|
|
14
18
|
*/
|
|
15
19
|
export function isHostElementName(name) {
|
|
16
20
|
return /^[a-z]/.test(name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-element.js","sourceRoot":"","sources":["../../src/engine/host-element.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"host-element.js","sourceRoot":"","sources":["../../src/engine/host-element.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,cAAc,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,SAAgC;IACtF,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM;YAAE,SAAS;QACxD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/engine/index.js
CHANGED
|
@@ -10,8 +10,9 @@ import { resolveOwnerChain } from "./owner-resolution.js";
|
|
|
10
10
|
import { createCycleGuard } from "./cycle-detection.js";
|
|
11
11
|
import { unparsedMemberDefinition, effectiveExportName, residualMemberChain, compoundExportName } from "./member-identity.js";
|
|
12
12
|
import { buildComponentRegistry, excludeFoldedHolders, excludeHostElementNames, entryKey } from "./registry.js";
|
|
13
|
-
import { hasOnlyHostElementNames, isHostElementName } from "./host-element.js";
|
|
13
|
+
import { hasOnlyHostElementNames, isHostElementName, HOOK_NAME } from "./host-element.js";
|
|
14
14
|
import { firstDynamicImport } from "./component-shape.js";
|
|
15
|
+
import { creditedTerminals, renderOutcome } from "./denotation.js";
|
|
15
16
|
/**
|
|
16
17
|
* JSX treats a bare, lowercase-initial element name as a host element
|
|
17
18
|
* (`div`, `svg`, `web-button`) — it never names a binding, so it is not an
|
|
@@ -134,8 +135,8 @@ export function resolve(graph, opts) {
|
|
|
134
135
|
if (!decl)
|
|
135
136
|
return { kind: "unbound" };
|
|
136
137
|
return {
|
|
137
|
-
kind: "
|
|
138
|
-
|
|
138
|
+
kind: "evaluated",
|
|
139
|
+
...pushLocalOccurrence(occurrences, filePath, usage, decl, graph, fileGraph, argMap, ownerRef, helperIndex, opts, viaOverride),
|
|
139
140
|
};
|
|
140
141
|
}
|
|
141
142
|
const packageName = packageNameFromSpecifier(matchedImport.specifier);
|
|
@@ -166,10 +167,10 @@ export function resolve(graph, opts) {
|
|
|
166
167
|
// Resolve the type to confirm it's a JSX component. Cross-file resolution
|
|
167
168
|
// works when resolveToGraphKey is present (graph keys are repo-relative).
|
|
168
169
|
const refType = resolveReference(graph, fileGraph, usage.ref);
|
|
169
|
-
const
|
|
170
|
-
const jsxTerminals =
|
|
170
|
+
const evaluation = walkWithFolding(graph, fileGraph, refType, argMap);
|
|
171
|
+
const jsxTerminals = creditedTerminals(evaluation);
|
|
171
172
|
if (jsxTerminals.length === 0)
|
|
172
|
-
return { kind: "
|
|
173
|
+
return { kind: "evaluated", evaluation, value: refType };
|
|
173
174
|
// Determine the canonical source file + local export name. When the
|
|
174
175
|
// target is a re-export barrel (`export { X } from './source'`),
|
|
175
176
|
// follow the chain to the actual definition file so JSX edges
|
|
@@ -217,7 +218,7 @@ export function resolve(graph, opts) {
|
|
|
217
218
|
});
|
|
218
219
|
emitOccurrence(occurrences, site, rawComponentId, owners, viaOverride !== undefined ? [viaOverride] : [outerVia, ...ft.viaTrail], ft.identity === null ? definition : undefined);
|
|
219
220
|
}
|
|
220
|
-
return { kind: "
|
|
221
|
+
return { kind: "evaluated", evaluation, value: refType };
|
|
221
222
|
}
|
|
222
223
|
// Check whether the import resolves to a local file that IS in the graph.
|
|
223
224
|
// If it does, resolve properly to avoid false positives (e.g. importing a
|
|
@@ -237,10 +238,10 @@ export function resolve(graph, opts) {
|
|
|
237
238
|
// than a phantom external stub. Terminal identities from deriveIdentity
|
|
238
239
|
// are already local when applicable (workspaceSiblingIdentity fires).
|
|
239
240
|
const refType = resolveReference(graph, fileGraph, usage.ref);
|
|
240
|
-
const
|
|
241
|
-
const jsxTerminals =
|
|
241
|
+
const evaluation = walkWithFolding(graph, fileGraph, refType, argMap);
|
|
242
|
+
const jsxTerminals = creditedTerminals(evaluation);
|
|
242
243
|
if (jsxTerminals.length === 0)
|
|
243
|
-
return { kind: "
|
|
244
|
+
return { kind: "evaluated", evaluation, value: refType };
|
|
244
245
|
const siblingFallback = workspaceSiblingFallback(graph, resolvedNormTarget, matchedImport, effectiveImported, fileGraph.dialect);
|
|
245
246
|
const localFallback = siblingFallback !== undefined && siblingFallback.kind !== "custom-element"
|
|
246
247
|
? { ...siblingFallback, export: compoundExportName(siblingFallback.export, residual) }
|
|
@@ -251,7 +252,7 @@ export function resolve(graph, opts) {
|
|
|
251
252
|
for (const ft of jsxTerminals) {
|
|
252
253
|
pushOccurrence(occurrences, filePath, usage, matchedImport, compoundExportName(effectiveImported, residual), packageName, graph, fileGraph, ft, ownerRef, helperIndex, opts, localFallback, viaOverride, ft.identity === null ? definition : undefined);
|
|
253
254
|
}
|
|
254
|
-
return { kind: "
|
|
255
|
+
return { kind: "evaluated", evaluation, value: refType };
|
|
255
256
|
}
|
|
256
257
|
// Target not in graph. Workspace membership: a
|
|
257
258
|
// resolved target owned by a workspace member is first-party — emit
|
|
@@ -263,7 +264,7 @@ export function resolve(graph, opts) {
|
|
|
263
264
|
const member = resolvedAbsTarget !== null
|
|
264
265
|
? unparsedMemberDefinition(graph, resolvedAbsTarget, effectiveImported)
|
|
265
266
|
: null;
|
|
266
|
-
const sentinelFt = {
|
|
267
|
+
const sentinelFt = { denotation: { kind: "foreign" }, viaTrail: [], identity: null };
|
|
267
268
|
if (member !== null) {
|
|
268
269
|
const localFallback = {
|
|
269
270
|
kind: componentKindFor(fileGraph.dialect),
|
|
@@ -275,7 +276,7 @@ export function resolve(graph, opts) {
|
|
|
275
276
|
else {
|
|
276
277
|
pushOccurrence(occurrences, filePath, usage, matchedImport, compoundExportName(effectiveImported, residual), packageName, graph, fileGraph, sentinelFt, ownerRef, helperIndex, opts, undefined, viaOverride);
|
|
277
278
|
}
|
|
278
|
-
return { kind: "
|
|
279
|
+
return { kind: "evaluated", evaluation: [sentinelFt], value: null };
|
|
279
280
|
};
|
|
280
281
|
for (const [filePath, fileGraph] of graph.files) {
|
|
281
282
|
for (let usageIdx = 0; usageIdx < fileGraph.jsxUsages.length; usageIdx++) {
|
|
@@ -371,7 +372,7 @@ export function resolve(graph, opts) {
|
|
|
371
372
|
continue;
|
|
372
373
|
if (!registry.hasLocal(filePath, decl.symbol))
|
|
373
374
|
continue;
|
|
374
|
-
const holderJsx = walkWithFolding(graph, fileGraph, decl.value, argMap)
|
|
375
|
+
const holderJsx = creditedTerminals(walkWithFolding(graph, fileGraph, decl.value, argMap));
|
|
375
376
|
const foldedAway = foldedHolder(holderJsx, filePath);
|
|
376
377
|
if (foldedAway !== null)
|
|
377
378
|
folded.set(entryKey(filePath, decl.symbol), foldedAway);
|
|
@@ -709,10 +710,16 @@ effectiveImported, packageName, graph, fileGraph, ft, ownerRef, helperIndex, opt
|
|
|
709
710
|
}
|
|
710
711
|
/**
|
|
711
712
|
* The one reporter for a JSX usage that produced no occurrence. A host-element
|
|
712
|
-
* root reports nothing. A failed import is `unresolved-import
|
|
713
|
-
* holding an `import()` is
|
|
714
|
-
* `import()` is declared in when
|
|
715
|
-
*
|
|
713
|
+
* root reports nothing. A failed import is `unresolved-import`, an unbound root
|
|
714
|
+
* `unresolved-reference`. A walked value holding an `import()` is
|
|
715
|
+
* `lazy-import-unsupported`, naming the file the `import()` is declared in when
|
|
716
|
+
* that is not the render file; the `import()` in the walked value is checked
|
|
717
|
+
* before the evaluation. Everything the evaluation itself decides
|
|
718
|
+
* is `renderOutcome`'s: a value that is not a component reports nothing, a
|
|
719
|
+
* value supplied elsewhere reports `late-bound-render`, and anything else —
|
|
720
|
+
* including a credit whose occurrences admission rejected (#544: one occurrence
|
|
721
|
+
* or one diagnostic) — reports `unresolved-reference`. A non-react dialect
|
|
722
|
+
* reports only the import codes (#621).
|
|
716
723
|
*/
|
|
717
724
|
function reportDroppedRender(opts, filePath, dialect, usage, outcome) {
|
|
718
725
|
const collector = opts?.collector;
|
|
@@ -721,35 +728,36 @@ function reportDroppedRender(opts, filePath, dialect, usage, outcome) {
|
|
|
721
728
|
if (isHostElementRoot(usage.ref))
|
|
722
729
|
return;
|
|
723
730
|
const at = { filePath, line: usage.loc.line, column: usage.loc.column };
|
|
731
|
+
const positional = { ...at, symbol: usage.ref.symbol, memberChain: [...usage.ref.memberChain] };
|
|
724
732
|
if (outcome.kind === "import-failed") {
|
|
725
733
|
collector.emit({ code: "unresolved-import", severity: "warning", ...at, specifier: outcome.specifier });
|
|
726
734
|
return;
|
|
727
735
|
}
|
|
728
|
-
if (outcome.kind === "
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
// property, or a target whose component shape could not be confirmed.
|
|
732
|
-
const di = outcome.value === null ? null : firstDynamicImport(outcome.value);
|
|
733
|
-
if (di) {
|
|
734
|
-
collector.emit({
|
|
735
|
-
code: "lazy-import-unsupported",
|
|
736
|
-
severity: "warning",
|
|
737
|
-
...at,
|
|
738
|
-
specifier: di.specifier,
|
|
739
|
-
detail: `the import() target could not be resolved to a component${di.originFile === filePath ? "" : ` (declared in ${di.originFile})`}`,
|
|
740
|
-
});
|
|
741
|
-
return;
|
|
742
|
-
}
|
|
743
|
-
if (dialect !== "react")
|
|
744
|
-
return;
|
|
736
|
+
if (outcome.kind === "unbound") {
|
|
737
|
+
collector.emit({ code: "unresolved-reference", severity: "info", ...positional });
|
|
738
|
+
return;
|
|
745
739
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
740
|
+
const di = outcome.value === null ? null : firstDynamicImport(outcome.value);
|
|
741
|
+
if (di) {
|
|
742
|
+
collector.emit({
|
|
743
|
+
code: "lazy-import-unsupported",
|
|
744
|
+
severity: "warning",
|
|
745
|
+
...at,
|
|
746
|
+
specifier: di.specifier,
|
|
747
|
+
detail: `the import() target could not be resolved to a component${di.originFile === filePath ? "" : ` (declared in ${di.originFile})`}`,
|
|
748
|
+
});
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
const decided = renderOutcome(outcome.evaluation);
|
|
752
|
+
if (decided.kind === "silent")
|
|
753
|
+
return;
|
|
754
|
+
if (dialect !== "react")
|
|
755
|
+
return;
|
|
756
|
+
if (decided.kind === "credit") {
|
|
757
|
+
collector.emit({ code: "unresolved-reference", severity: "info", ...positional });
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
collector.emit({ code: decided.code, severity: "info", ...positional });
|
|
753
761
|
}
|
|
754
762
|
/**
|
|
755
763
|
* Push local-scope occurrences for a symbol declared in the same file (no import).
|
|
@@ -762,10 +770,10 @@ function pushLocalOccurrence(occurrences, filePath, usage, decl, graph, fileGrap
|
|
|
762
770
|
// static-MemberOf arm). A bare reference is unchanged:
|
|
763
771
|
// `decl.value` is what `resolveReference` returns for an empty chain.
|
|
764
772
|
const value = usage.ref.memberChain.length > 0 ? resolveReference(graph, fileGraph, usage.ref) : decl.value;
|
|
765
|
-
const
|
|
766
|
-
const jsxTerminals =
|
|
773
|
+
const evaluation = walkWithFolding(graph, fileGraph, value, argMap);
|
|
774
|
+
const jsxTerminals = creditedTerminals(evaluation);
|
|
767
775
|
if (jsxTerminals.length === 0)
|
|
768
|
-
return value;
|
|
776
|
+
return { evaluation, value };
|
|
769
777
|
const outerVia = viaOverride ?? { kind: "local-component" };
|
|
770
778
|
const site = usageSite(filePath, usage);
|
|
771
779
|
const owners = usageOwners(graph, helperIndex, ownerRef, viaOverride, fileGraph.filePath);
|
|
@@ -782,7 +790,7 @@ function pushLocalOccurrence(occurrences, filePath, usage, decl, graph, fileGrap
|
|
|
782
790
|
});
|
|
783
791
|
emitOccurrence(occurrences, site, rawComponentId, owners, viaOverride !== undefined ? [viaOverride] : [outerVia, ...ft.viaTrail], ft.identity === null ? definition : undefined);
|
|
784
792
|
}
|
|
785
|
-
return value;
|
|
793
|
+
return { evaluation, value };
|
|
786
794
|
}
|
|
787
795
|
/**
|
|
788
796
|
* A holder is folded away iff its fold reaches JSX and EVERY JSX
|
|
@@ -829,7 +837,7 @@ function pushArgumentSiteOccurrences(occurrences, filePath, holder, call, holder
|
|
|
829
837
|
const folded = foldedArgument(graph, fileGraph, call, holderJsx, argMap);
|
|
830
838
|
if (folded?.arg.kind !== "ReturnTypeOf")
|
|
831
839
|
return;
|
|
832
|
-
const innerJsx = walkWithFolding(graph, fileGraph, folded.arg, argMap)
|
|
840
|
+
const innerJsx = creditedTerminals(walkWithFolding(graph, fileGraph, folded.arg, argMap));
|
|
833
841
|
pushArgumentSiteOccurrences(occurrences, filePath, holder, folded.arg, innerJsx, graph, fileGraph, argMap, opts, depth + 1);
|
|
834
842
|
return;
|
|
835
843
|
}
|
|
@@ -868,8 +876,6 @@ function callFoldShape(jsx) {
|
|
|
868
876
|
return "product";
|
|
869
877
|
return credited === jsx.length ? "wrapper" : null;
|
|
870
878
|
}
|
|
871
|
-
/** React's own hook predicate (`isHookName` in rules-of-hooks and the compiler). */
|
|
872
|
-
const HOOK_NAME = /^use[A-Z0-9]/;
|
|
873
879
|
/**
|
|
874
880
|
* THE argument-site push seam: one `passed-as-argument` occurrence per
|
|
875
881
|
* (identifier argument that resolves to a component) × (owner). The
|
|
@@ -911,8 +917,8 @@ function pushCallArgumentOccurrences(occurrences, filePath, call, owners, graph,
|
|
|
911
917
|
// and `buildComponentId` returns the fallback only for a null one. The
|
|
912
918
|
// relabel seam's signature requires a fallback all the same.
|
|
913
919
|
const unusedFallback = makeLocalComponentId(filePath, arg.ref.symbol, fileGraph.dialect);
|
|
914
|
-
for (const ft of walkWithFolding(graph, fileGraph, arg, argMap)) {
|
|
915
|
-
if (ft.
|
|
920
|
+
for (const ft of creditedTerminals(walkWithFolding(graph, fileGraph, arg, argMap))) {
|
|
921
|
+
if (ft.identity === null)
|
|
916
922
|
continue;
|
|
917
923
|
const rawComponentId = componentIdFromIdentity(ft.identity, unusedFallback, fileGraph.dialect, {
|
|
918
924
|
filePath,
|
|
@@ -932,7 +938,7 @@ function pushCallArgumentOccurrences(occurrences, filePath, call, owners, graph,
|
|
|
932
938
|
}
|
|
933
939
|
if (arg.kind !== "ReturnTypeOf" || callDepth >= MAX_ARGUMENT_CALL_DEPTH)
|
|
934
940
|
return;
|
|
935
|
-
const argJsx = walkWithFolding(graph, fileGraph, arg, argMap)
|
|
941
|
+
const argJsx = creditedTerminals(walkWithFolding(graph, fileGraph, arg, argMap));
|
|
936
942
|
const shape = callFoldShape(argJsx);
|
|
937
943
|
if (shape === "product") {
|
|
938
944
|
seedArguments(arg, callDepth + 1);
|