mirror of
https://github.com/morluto/rea
synced 2026-10-26 14:25:49 -04:00
dea770d5d9
* fix(javascript): retain getter receivers through local aliases * fix(javascript): resolve projected private getter receivers --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
import type * as t from "@babel/types";
|
|
import type { JavaScriptSemanticAnalysisState } from "./javascriptSemanticState.js";
|
|
import type { JavaScriptSemanticPropertyPath as PropertyPath } from "./javascriptSemanticPropertyPaths.js";
|
|
import { evaluateSemanticExpression } from "./javascriptSemanticValues.js";
|
|
import { semanticSlotAtPath } from "./javascriptSemanticSlots.js";
|
|
|
|
interface ReferenceSource {
|
|
readonly node: t.Node;
|
|
readonly projection: PropertyPath;
|
|
}
|
|
|
|
/** Exclude references whose source slot or destructuring fallback is absent. */
|
|
export const semanticReferenceSourcesInactive = (
|
|
reference: {
|
|
readonly requiredSources?: readonly ReferenceSource[];
|
|
readonly fallbackSources?: readonly ReferenceSource[];
|
|
},
|
|
state: JavaScriptSemanticAnalysisState,
|
|
): boolean =>
|
|
reference.requiredSources?.some(
|
|
(source) =>
|
|
semanticSelectedReferenceSlot(source, state, source.node)?.presence ===
|
|
"absent",
|
|
) === true ||
|
|
reference.fallbackSources?.some((source) => {
|
|
// Selection precedes effects through the chosen reference. A later escape
|
|
// cannot make a fallback that was excluded at destructuring reachable.
|
|
const slot = semanticSelectedReferenceSlot(source, state, source.node);
|
|
return (
|
|
slot?.presence === "present" &&
|
|
(slot.value.status === "literal" ||
|
|
slot.value.status === "union" ||
|
|
slot.value.status === "object" ||
|
|
slot.value.status === "array")
|
|
);
|
|
}) === true;
|
|
|
|
/** Select a retained source slot at its capture, before later effects. */
|
|
export const semanticSelectedReferenceSlot = (
|
|
source: ReferenceSource,
|
|
state: JavaScriptSemanticAnalysisState,
|
|
capturePoint?: t.Node,
|
|
) => {
|
|
const path: string[] = [];
|
|
for (const key of source.projection) {
|
|
if (key === null || typeof key === "object") return undefined;
|
|
path.push(String(key));
|
|
}
|
|
return semanticSlotAtPath(
|
|
evaluateSemanticExpression(source.node, state, capturePoint),
|
|
path,
|
|
);
|
|
};
|