mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 01:41:21 +00:00
* refactor(javascript): break the semantic analysis import cycle Split shared semantic facts out of the analysis hub so projectors of effects, evaluation, and identity no longer import one another in a cycle. * refactor(javascript): share the import specifier reader Read static imports in one module used by the boundary checker and both cycle guards, so those rules cannot drift apart. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import * as t from "@babel/types";
|
|
import {
|
|
semanticObjectPropertyReferences,
|
|
semanticArrayPropertyReferences,
|
|
type JavaScriptSemanticObjectReference as Reference,
|
|
} from "./javascriptSemanticObjectReferences.js";
|
|
import type { JavaScriptSemanticAnalysisState } from "./javascriptSemanticState.js";
|
|
import { SemanticGetterQuery } from "./javascriptSemanticGetterQueries.js";
|
|
import { GetterResultWalker } from "./javascriptSemanticGetterResultWalker.js";
|
|
|
|
/** Project an effect operand through the same local aliases and `this` owner as getter results. */
|
|
export const semanticGetterReceiverReferences = (
|
|
getter: t.ObjectMethod | t.ClassMethod,
|
|
operand: t.Node,
|
|
state: JavaScriptSemanticAnalysisState,
|
|
): readonly Reference[] => {
|
|
const parent = state.parentsByNode.get(getter);
|
|
const owner = t.isClassBody(parent)
|
|
? state.parentsByNode.get(parent)
|
|
: parent;
|
|
if (!t.isObjectExpression(owner) && !t.isClass(owner)) return [];
|
|
const query = new SemanticGetterQuery(state);
|
|
let privateReceiver = false;
|
|
const references = query.run(
|
|
() => {
|
|
query.schedule({ getter, owner }, []);
|
|
return [];
|
|
},
|
|
(job) =>
|
|
new GetterResultWalker(
|
|
job,
|
|
query,
|
|
{
|
|
objectReferences: (_receiver, path) => [{ node: getter, path }],
|
|
classReferences: (_lookup, path) => [{ node: getter, path }],
|
|
privateReceiver: () => {
|
|
// Keep private-field initializer identity from the existing
|
|
// getter owner; private slots are not public property paths.
|
|
privateReceiver = true;
|
|
return true;
|
|
},
|
|
bases: () => [],
|
|
containerReferences: (node, path) =>
|
|
t.isObjectExpression(node)
|
|
? semanticObjectPropertyReferences(node, path, state)
|
|
: semanticArrayPropertyReferences(node, path),
|
|
},
|
|
[{ node: operand }],
|
|
).run(),
|
|
);
|
|
return references.filter(({ node }) => node === getter || privateReceiver);
|
|
};
|