mirror of
https://github.com/morluto/rea.git
synced 2026-11-13 10:12:50 +00:00
refactor(javascript): break the semantic analysis import cycle (#8063)
* 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>
This commit is contained in:
1 parent
940d71a45a
commit
249b90c5e3
33 files changed
+1043
-772
No files matched your search
@@ -1,31 +1,20 @@
|
||||
import * as t from "@babel/types";
|
||||
import { javaScriptProgramStrictness } from "./javascriptSourceParser.js";
|
||||
import { unwrapJavaScriptExpression } from "./javascriptAstValues.js";
|
||||
import { createAmbientPathResolver } from "./javascriptSemanticAmbientWrites.js";
|
||||
import { createSemanticModuleInterop } from "./javascriptModuleInterop.js";
|
||||
import {
|
||||
isUnshadowedGlobal,
|
||||
semanticEffectTiming,
|
||||
semanticBindingEffectFollowsCapture,
|
||||
semanticBindingEffectFollowsRead,
|
||||
semanticReadPrecedesEffectWithinActivation,
|
||||
} from "./javascriptSemanticMutationInitializers.js";
|
||||
import {
|
||||
isUnshadowedGlobal,
|
||||
resolveSemanticBindingState,
|
||||
type JavaScriptSemanticAnalysisState,
|
||||
type JavaScriptSemanticBindingState,
|
||||
} from "./javascriptSemanticState.js";
|
||||
|
||||
/** One source owns sites and the minimal scope tree reaching them; O(AST) storage. */
|
||||
export interface JavaScriptOpaqueScopeEffects {
|
||||
/** Cheap source evidence collected with declarations, before alias queries. */
|
||||
mayReferenceGlobalEval: boolean;
|
||||
readonly sites: WeakSet<t.Node>;
|
||||
readonly sloppySites: WeakSet<t.Node>;
|
||||
readonly byScope: Map<string, t.CallExpression[]>;
|
||||
readonly children: Map<string, Set<string>>;
|
||||
readonly globalSites: (t.CallExpression | t.OptionalCallExpression)[];
|
||||
}
|
||||
export type { JavaScriptOpaqueScopeEffects } from "./javascriptSemanticState.js";
|
||||
|
||||
export const indexSemanticOpaqueEffects = (
|
||||
candidates: readonly {
|
||||
@@ -59,11 +48,30 @@ export const indexSemanticOpaqueEffects = (
|
||||
* neither retain a second call list nor create another alias resolver. */
|
||||
export const createSemanticOpaqueGlobalObserver = (
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
dependencies: {
|
||||
createAmbientPathResolver: (
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
observeGlobals: boolean,
|
||||
) => (
|
||||
node: t.Node,
|
||||
site: t.Node | undefined,
|
||||
) => { paths: readonly (readonly (string | null)[])[] };
|
||||
createSemanticModuleInterop: (
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
options?: {
|
||||
intrinsicPath: (node: t.Node) => readonly string[] | undefined;
|
||||
},
|
||||
) => {
|
||||
intrinsicInvocation: (
|
||||
node: t.CallExpression | t.OptionalCallExpression,
|
||||
) => { readonly path: readonly string[] } | undefined;
|
||||
};
|
||||
},
|
||||
): ((node: t.Node) => void) | undefined => {
|
||||
if (!state.opaqueEffects.mayReferenceGlobalEval) return undefined;
|
||||
const ambientPaths = createAmbientPathResolver(state, true);
|
||||
const ambientPaths = dependencies.createAmbientPathResolver(state, true);
|
||||
let invocationSite: t.Node | undefined;
|
||||
const interop = createSemanticModuleInterop(state, {
|
||||
const interop = dependencies.createSemanticModuleInterop(state, {
|
||||
intrinsicPath: (node) => {
|
||||
const paths = ambientPaths(node, invocationSite).paths;
|
||||
const path = paths.find((path) => path[1] === "eval") ?? paths[0];
|
||||
|
||||
Reference in new issue
Block a user