chore: merge main into audited lifecycle fixes

This commit is contained in:
morluto
2026-10-20 19:28:09 +08:00
286 changed files with 30304 additions and 1706 deletions
@@ -6,7 +6,10 @@ import type {
} from "./javascriptSemanticIr.js";
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
import { semanticCallableIdForNode } from "./javascriptSemanticProjection.js";
import { semanticBindingAtRead } from "./javascriptSemanticMutationInitializers.js";
import {
semanticBindingAtRead,
semanticEffectTiming,
} from "./javascriptSemanticMutationInitializers.js";
import {
unwrapJavaScriptExpression,
runtimeFunctionParameters,
@@ -118,6 +121,7 @@ const resolveIdentifier = (
};
const candidates = resolveBindingCallables(
read.binding,
node,
selectsAll
? {
...context,
@@ -165,6 +169,7 @@ const resolveAlternatives = (
const resolveBindingCallables = (
binding: JavaScriptSemanticBindingState,
site: t.Identifier,
context: CallResolutionContext,
): LocalCallableResolution => {
if (binding.initializers.length === 0)
@@ -196,11 +201,21 @@ const resolveBindingCallables = (
const callableIds = uniqueCallableIds(
candidates.flatMap((candidate) => candidate.callableIds),
);
// Pattern writes are owned reference facts, not ordinary initializers. A
// read may retain both an earlier callable and a conditional projected
// replacement. Until projected callable resolution is supported here,
// preserve known candidates without claiming they cover every target.
const complete =
!binding.referenceInitializers.some(
(initializer) =>
initializer.assignment &&
semanticEffectTiming(site, initializer.node, context.state) !== "after",
) && candidates.every(({ complete }) => complete);
const resolution = {
callableIds,
complete: candidates.every(({ complete }) => complete),
complete,
reason:
callableIds.length === 1 && candidates.every(({ complete }) => complete)
callableIds.length === 1 && complete
? "Unique local callable target."
: `Call target ${binding.name} has ambiguous or unsupported assignments.`,
...(candidates.some((candidate) => candidate.cycleDependent)