mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(javascript): preserve runtime path bytes and Electron ownership (#4941)
* fix(javascript): preserve literal percent runtime paths * fix(javascript): ignore resolve prefixes before the final anchor * fix(electron): retain application roots for loadFile declarations * fix(electron): resolve loadFile from enclosing application package * fix(electron): retain outer application root across package scopes * fix(electron): derive application ownership from inventoried packages * fix(electron): retain resolved package entrypoint ownership * fix(electron): preserve competing application ownership * fix(electron): retain invalid and omitted runtime ownership * fix(electron): preserve omitted module ownership and runtime paths * fix(electron): preserve proven roots before confining page paths * fix(electron): retain possible owners behind missing imports * fix(electron): distinguish absent imports and owned page candidates * fix(electron): keep unavailable JSON out of owner gaps * fix(electron): retain exact loader formats and default entry status * fix(electron): retain unavailable entrypoint ownership candidates * test(ghidra): preserve Windows Node probe prerequisites * test(ghidra): assert cancellation during profile shutdown * fix(electron): separate examined imports from frontend ownership * fix(electron): retain unavailable directory entrypoint owners * test(jeb): retain Linux ownership prerequisite in isolation * fix(javascript): retain unchecked loader ownership and literal main paths * fix(javascript): preserve runtime paths and call-site module aliases * fix(javascript): bound module alias traversal and preserve projections * fix(javascript): retain host module and nested artifact path boundaries * fix(javascript): preserve ESM and archive module loader provenance * test(javascript): distinguish unmapped containers from missing exports * fix: retain default module aliases and Electron builtin imports * fix: preserve host file URL and inward ASAR ownership * fix: preserve CommonJS file URL classification in CI fixtures * fix: retain bound module loaders and Windows entrypoint uncertainty * fix: retain ASAR uncertainty and invalidate changed Electron app roots * fix(javascript): retain ownership uncertainty across loader boundaries * fix(javascript): preserve loader sources and bound alias queries * fix(javascript): retain destructured loader sources * fix(javascript): preserve loader uncertainty at resolution boundaries * fix(javascript): preserve callable and package launch ownership * fix(javascript): preserve captured values across member reads * test(process): assert tagged filesystem cancellation failures * fix(javascript): preserve inventory bases and invocation read timing * fix(javascript): preserve ownership across indirect and unread loads * test(javascript): order fixture directory creation on Windows * test(javascript): share ordered filesystem fixture writer * fix(javascript): unify loader provenance and package validation * fix(javascript): preserve captured Node require loader values * fix(javascript): preserve loader invocation authority * fix(javascript): verify generic loader invocation authority * fix(javascript): preserve conditional loader method alternatives * fix(javascript): require proven factories for source association * fix(javascript): honor replaced Electron app path setters * fix(javascript): prove path and assignment source ownership * fix(javascript): retain native delegate eligibility through shared writes * fix(process): settle stale baseline errors after confirmed absence * fix(javascript): preserve assignment and path boundary evidence * fix(javascript): prove source-directory resolve anchors * fix: preserve application path provenance and portable schemas * fix(javascript): retain CommonJS exported setter effects * fix: isolate Linux identity observations and retain native module exports * fix(javascript): preserve published app and helper provenance * fix(javascript): normalize typed stores and native path fixtures
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
import type { JavaScriptOpaqueScopeEffects } from "./javascriptSemanticOpaqueEffects.js";
|
||||
import type { SemanticIterationSource } from "./javascriptSemanticIterationSources.js";
|
||||
import * as t from "@babel/types";
|
||||
import {
|
||||
semanticStaticPropertyKey,
|
||||
unwrapJavaScriptExpression,
|
||||
} from "./javascriptAstValues.js";
|
||||
import {
|
||||
semanticBindingAtRead,
|
||||
semanticEffectTiming,
|
||||
} from "./javascriptSemanticMutationInitializers.js";
|
||||
|
||||
import type {
|
||||
JavaScriptSemanticPropertyPath,
|
||||
@@ -29,10 +34,16 @@ export interface JavaScriptSemanticInitializer {
|
||||
readonly node: t.Node;
|
||||
readonly projection: readonly (string | number | null)[];
|
||||
readonly entryBody?: t.BlockStatement;
|
||||
readonly iterationSources?: readonly {
|
||||
readonly node: t.Node;
|
||||
readonly projection: JavaScriptSemanticPropertyPath;
|
||||
}[];
|
||||
}
|
||||
|
||||
/** Additional references from destructuring copies and possible defaults. */
|
||||
interface JavaScriptSemanticReferenceInitializer extends JavaScriptSemanticInitializer {
|
||||
/** This source is a value replacement, rather than a declaration fallback. */
|
||||
readonly assignment?: true;
|
||||
readonly copyKind?: "object-rest" | "array-rest";
|
||||
readonly copyProjectionOffset?: number;
|
||||
readonly copyExcludedKeys?: readonly string[];
|
||||
@@ -45,6 +56,12 @@ interface JavaScriptSemanticReferenceInitializer extends JavaScriptSemanticIniti
|
||||
export interface JavaScriptSemanticMemberEffect {
|
||||
readonly path: JavaScriptSemanticPropertyPath;
|
||||
readonly node: t.Node | undefined;
|
||||
/** Selected RHS values retained by the shared pattern-store owner. */
|
||||
readonly assignedSources?: readonly SemanticIterationSource[];
|
||||
/** Binding values whose receiver identities were selected for this effect. */
|
||||
readonly receiverInitializers?: readonly JavaScriptSemanticInitializer[];
|
||||
/** Capture of this binding used while following an aliased effect receiver. */
|
||||
readonly receiverAt?: t.Node;
|
||||
}
|
||||
|
||||
export type JavaScriptSemanticEffectTiming = "before" | "after" | "unknown";
|
||||
@@ -101,6 +118,7 @@ export interface JavaScriptSemanticScopeState {
|
||||
|
||||
/** Shared state for semantic collection and evaluation. */
|
||||
export interface JavaScriptSemanticAnalysisState {
|
||||
arrayIterationUnknown: boolean;
|
||||
readonly program: t.Program;
|
||||
readonly opaqueEffects: JavaScriptOpaqueScopeEffects;
|
||||
/** Effective loader for static imports in this source artifact. */
|
||||
@@ -150,6 +168,8 @@ export interface JavaScriptSemanticAnalysisState {
|
||||
readonly ambientWrites: SemanticPropertyPathCoverage;
|
||||
/** Ambient object identities passed to calls whose effects are not evaluated. */
|
||||
readonly ambientEscapes: SemanticPropertyPathCoverage;
|
||||
/** Capture sites keep later opaque effects from changing earlier copies. */
|
||||
readonly ambientEscapeEffects: JavaScriptSemanticMemberEffect[];
|
||||
/** Source sites distinguish replacement before an ambient identity capture from later writes. */
|
||||
readonly ambientWriteEffects: JavaScriptSemanticMemberEffect[];
|
||||
}
|
||||
@@ -537,7 +557,52 @@ export const isUnmodifiedCommonJsWrapperBinding = (
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): boolean => {
|
||||
const binding = commonJsWrapperBindingDeclaration(node, name, state);
|
||||
return binding !== undefined && binding.initializers.length === 0;
|
||||
return (
|
||||
binding !== undefined &&
|
||||
!semanticBindingHasPriorValueWrite(node, binding, state)
|
||||
);
|
||||
};
|
||||
|
||||
/** Retained value and pattern stores share one source-ordered write boundary. */
|
||||
export const semanticBindingHasPriorValueWrite = (
|
||||
site: t.Node,
|
||||
binding: JavaScriptSemanticBindingState,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
): boolean => {
|
||||
if (binding.definitions.some(({ kind }) => kind === "function")) return true;
|
||||
const writes = state.bindingWrites.get(binding.bindingId) ?? [];
|
||||
const read = semanticBindingAtRead(binding, site, state.parentsByNode);
|
||||
const retained =
|
||||
read.status === "ordered"
|
||||
? new Set([
|
||||
...read.binding.initializers,
|
||||
...read.binding.referenceInitializers,
|
||||
])
|
||||
: undefined;
|
||||
const representedWrites = new Set<t.Node>();
|
||||
const retainedWrites = new Set<t.Node>();
|
||||
for (const source of [
|
||||
...binding.initializers,
|
||||
...binding.referenceInitializers,
|
||||
]) {
|
||||
let owner: t.Node | undefined = source.node;
|
||||
while (owner !== undefined && !writes.includes(owner))
|
||||
owner = state.parentsByNode.get(owner);
|
||||
if (owner !== undefined) {
|
||||
representedWrites.add(owner);
|
||||
if (retained === undefined || retained.has(source))
|
||||
retainedWrites.add(owner);
|
||||
} else if (
|
||||
(retained === undefined || retained.has(source)) &&
|
||||
semanticEffectTiming(site, source.node, state) !== "after"
|
||||
)
|
||||
return true;
|
||||
}
|
||||
return writes.some(
|
||||
(write) =>
|
||||
(!representedWrites.has(write) || retainedWrites.has(write)) &&
|
||||
semanticEffectTiming(site, write, state) !== "after",
|
||||
);
|
||||
};
|
||||
|
||||
/** Program `var` redeclarations retain wrapper identity until a source write. */
|
||||
@@ -550,7 +615,9 @@ export const commonJsWrapperBindingDeclaration = (
|
||||
// specifier resolution mode does not establish that distinction.
|
||||
if (
|
||||
state.program.sourceType !== "script" ||
|
||||
!["module", "exports", "require"].includes(name) ||
|
||||
!["module", "exports", "require", "__dirname", "__filename"].includes(
|
||||
name,
|
||||
) ||
|
||||
!t.isIdentifier(node, { name })
|
||||
)
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user