fix(javascript): resolve module-level Electron options in functions (#8960)

* fix(javascript): resolve module-level Electron options in functions

* fix(javascript): limit module option ancestry walk

* fix(javascript): preserve uncertain captured argument ordering

* fix(javascript): retain hoisted activation uncertainty

* fix(javascript): retain function ownership through loops

* fix(javascript): account for classic global activations

* fix(javascript): bind first activations to lexical identities

* fix(javascript): retain uncertain global activation timing

* fix(javascript): isolate receiver facts and share computed reads

* fix(javascript): retain projected and opaque global activations

* fix(javascript): refresh activation bounds as opaque effects grow

* fix(ci): format website watch directories without changing configuration

* fix(javascript): share source reads across opaque-effect updates

* fix(javascript): retain constructed-code global activation bounds

* fix(javascript): share runtime activation and receiver facts

* fix(javascript): reuse pattern reads and function positions

* fix(javascript): isolate copied paths and preserve runtime reads

* style(javascript): format migrated reference imports

* fix(javascript): normalize constructor activation and receiver effects

* fix(javascript): retain aliased receiver timing and lexical global this

* fix(javascript): preserve effect-free receiver identity across activations

* fix(javascript): retain outer activation and prototype effects

* fix(javascript): index implicit reads without deep path rescans

* fix(javascript): retain aliased prototype and parameter read uncertainty

* fix(javascript): index reflected reads through intrinsic invocation facts

* fix(javascript): retain unresolved global activation reads

* chore: refresh PR branch after review fix publication

* fix(javascript): retain projected receiver reads and cache method facts

* fix(javascript): retain inherited and implicit activation reads

* fix(javascript): retain caller-owned this uncertainty

* fix(javascript): retain reflected reads with unresolved spread arguments

* fix(javascript): preserve enclosing activation for decorators

* fix(javascript): track intrinsic literal prototype effects

* fix(javascript): retain catch activation from implicit reads

* perf(javascript): reuse effective keys for projected reads

* fix(javascript): retain possible caller-owned ambient effects
This commit is contained in:
ShuaixinHuang authored and GitHub committed 2026-11-05 16:52:19 +08:00
1 parent ce07d358cd
commit a2134b3a74
40 files changed
+2585 -191

No files matched your search

@@ -1,3 +1,4 @@
import { javaScriptThisOwner } from "./javascriptSourceParser.js";
import * as t from "@babel/types";
import {
@@ -38,10 +39,10 @@ import {
} from "./javascriptSemanticGlobalReference.js";
import { readSemanticRequireLoader } from "./javascriptSemanticRequireOriginSlot.js";
import {
semanticCopiedReferencePath,
semanticReferenceIterationUnknown,
semanticReferenceSourcesInactive,
} from "./javascriptSemanticReferenceSources.js";
import { semanticCopiedReferencePath } from "./javascriptSemanticCopiedReferencePaths.js";
export {
isUnmodifiedGlobalReference,
@@ -144,6 +145,7 @@ type AmbientIdentityUnknownReason =
interface AmbientResolution {
readonly paths: readonly AmbientPath[];
readonly callerPaths: readonly AmbientPath[];
readonly ownership: "local" | "ambient" | "unknown";
readonly unknownReasons: readonly AmbientIdentityUnknownReason[];
}
@@ -179,6 +181,7 @@ export const createAmbientPathResolver = (
const prior = possibleWrites ? undefined : cached.get(node);
if (prior !== undefined) return prior;
const result = new Map<string, AmbientPath>();
const callerPaths = new Map<string, AmbientPath>();
let hasLocalIdentity = false;
const unknownReasons = new Set<AmbientIdentityUnknownReason>();
// The caller's write site selects initializers for the written target.
@@ -254,6 +257,7 @@ export const createAmbientPathResolver = (
if (!possibleWrites) {
const unresolved: AmbientResolution = {
paths: [],
callerPaths: [...callerPaths.values()],
ownership: "unknown",
unknownReasons: ["widened-projection"],
};
@@ -319,6 +323,22 @@ export const createAmbientPathResolver = (
resolvedIdentity = true;
continue;
}
if (t.isThisExpression(root)) {
const owner = javaScriptThisOwner(
root,
state.program,
state.parentsByNode,
);
if (owner === "global") {
retain(["global", ...(suffix ?? [])]);
resolvedIdentity = true;
continue;
}
if (owner === "caller" && suffix !== undefined) {
const path = canonicalAmbientPath(["global", ...suffix]);
callerPaths.set(JSON.stringify(path), path);
}
}
if (t.isIdentifier(root)) {
// The wrapper module object is distinct from globalThis.module. Keep
// its identity through the same alias/projection owner used for writes.
@@ -345,7 +365,7 @@ export const createAmbientPathResolver = (
const readAt = current.readsAtSelf ? root : capture;
const atRead =
possibleWrites && readAt !== undefined
? semanticBindingAtRead(binding, readAt, state.parentsByNode)
? semanticBindingAtRead(binding, readAt, state)
: undefined;
const selected = atRead?.binding ?? binding;
if (possibleWrites && atRead?.hasDefiniteInitializer === false)
@@ -552,6 +572,7 @@ export const createAmbientPathResolver = (
unknownReasons.add("mixed-identities");
const resolution: AmbientResolution = {
paths,
callerPaths: [...callerPaths.values()],
ownership:
unknownReasons.size > 0
? "unknown"