@fictjs/compiler 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +706 -170
- package/dist/index.js +706 -170
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -19942,15 +19942,38 @@ function buildEffectCall(ctx, t4, effectFn, options) {
|
|
|
19942
19942
|
}
|
|
19943
19943
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.useEffect), args);
|
|
19944
19944
|
}
|
|
19945
|
-
function buildMemoCall(ctx, t4, memoFn,
|
|
19945
|
+
function buildMemoCall(ctx, t4, memoFn, options) {
|
|
19946
|
+
const slot = options?.slot;
|
|
19947
|
+
const memoOptionsProperties = [];
|
|
19948
|
+
if (options?.name) {
|
|
19949
|
+
memoOptionsProperties.push(
|
|
19950
|
+
t4.objectProperty(t4.identifier("name"), t4.stringLiteral(options.name))
|
|
19951
|
+
);
|
|
19952
|
+
}
|
|
19953
|
+
if (options?.source) {
|
|
19954
|
+
memoOptionsProperties.push(
|
|
19955
|
+
t4.objectProperty(t4.identifier("devToolsSource"), t4.stringLiteral(options.source))
|
|
19956
|
+
);
|
|
19957
|
+
}
|
|
19958
|
+
if (options?.internal) {
|
|
19959
|
+
memoOptionsProperties.push(t4.objectProperty(t4.identifier("internal"), t4.booleanLiteral(true)));
|
|
19960
|
+
}
|
|
19961
|
+
const memoOptions = memoOptionsProperties.length > 0 ? t4.objectExpression(memoOptionsProperties) : null;
|
|
19946
19962
|
if (ctx.inModule) {
|
|
19947
19963
|
ctx.helpersUsed.add("memo");
|
|
19948
|
-
|
|
19964
|
+
const args2 = [memoFn];
|
|
19965
|
+
if (memoOptions) args2.push(memoOptions);
|
|
19966
|
+
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.memo), args2);
|
|
19949
19967
|
}
|
|
19950
19968
|
ctx.helpersUsed.add("useMemo");
|
|
19951
19969
|
ctx.needsCtx = true;
|
|
19952
19970
|
const args = [t4.identifier("__fictCtx"), memoFn];
|
|
19953
|
-
if (
|
|
19971
|
+
if (memoOptions) {
|
|
19972
|
+
args.push(memoOptions);
|
|
19973
|
+
if (slot !== void 0 && slot >= 0) {
|
|
19974
|
+
args.push(t4.numericLiteral(slot));
|
|
19975
|
+
}
|
|
19976
|
+
} else if (slot !== void 0 && slot >= 0) {
|
|
19954
19977
|
args.push(t4.numericLiteral(slot));
|
|
19955
19978
|
}
|
|
19956
19979
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.useMemo), args);
|
|
@@ -21211,7 +21234,10 @@ function wrapInMemo(region, t4, declaredVars, ctx, bodyStatementsOverride, outpu
|
|
|
21211
21234
|
const returnObj = t4.objectExpression(uniqueOutputNames.map((name) => buildOutputProperty(name)));
|
|
21212
21235
|
const memoBody = t4.blockStatement([...bodyStatements, t4.returnStatement(returnObj)]);
|
|
21213
21236
|
const slot = ctx.inModule ? void 0 : reserveHookSlot(ctx);
|
|
21214
|
-
const memoCall = buildMemoCall(ctx, t4, t4.arrowFunctionExpression([], memoBody),
|
|
21237
|
+
const memoCall = buildMemoCall(ctx, t4, t4.arrowFunctionExpression([], memoBody), {
|
|
21238
|
+
slot,
|
|
21239
|
+
internal: true
|
|
21240
|
+
});
|
|
21215
21241
|
const regionVarName = `__region_${region.id}`;
|
|
21216
21242
|
statements.push(
|
|
21217
21243
|
t4.variableDeclaration("const", [t4.variableDeclarator(t4.identifier(regionVarName), memoCall)])
|
|
@@ -21470,7 +21496,10 @@ function generateLazyConditionalMemo(region, orderedOutputs, bodyStatements, con
|
|
|
21470
21496
|
ctx,
|
|
21471
21497
|
t4,
|
|
21472
21498
|
t4.arrowFunctionExpression([], t4.blockStatement(memoBody)),
|
|
21473
|
-
|
|
21499
|
+
{
|
|
21500
|
+
slot: ctx.inModule ? void 0 : reserveHookSlot(ctx),
|
|
21501
|
+
internal: true
|
|
21502
|
+
}
|
|
21474
21503
|
);
|
|
21475
21504
|
statements.push(
|
|
21476
21505
|
t4.variableDeclaration("const", [t4.variableDeclarator(t4.identifier(regionVarName), memoCall)])
|
|
@@ -21583,7 +21612,12 @@ Context: ${location}`
|
|
|
21583
21612
|
};
|
|
21584
21613
|
const buildDerivedMemoCall = (expr) => {
|
|
21585
21614
|
const slot = !ctx.inModule && inRegionMemo ? reserveHookSlot(ctx) : void 0;
|
|
21586
|
-
|
|
21615
|
+
const source = ctx.options?.dev !== false && instr.loc ? `${ctx.options?.filename ?? ""}:${instr.loc.start.line}:${instr.loc.start.column}` : void 0;
|
|
21616
|
+
return buildMemoCall(ctx, t4, t4.arrowFunctionExpression([], expr), {
|
|
21617
|
+
slot,
|
|
21618
|
+
name: baseName2,
|
|
21619
|
+
source
|
|
21620
|
+
});
|
|
21587
21621
|
};
|
|
21588
21622
|
if (isShadowDeclaration && declKind) {
|
|
21589
21623
|
ctx.trackedVars.delete(baseName2);
|
|
@@ -22945,7 +22979,7 @@ function expressionUsesIdentifier(expr, name, t4) {
|
|
|
22945
22979
|
visit(expr);
|
|
22946
22980
|
return found;
|
|
22947
22981
|
}
|
|
22948
|
-
function extractDelegatedEventData(expr, t4) {
|
|
22982
|
+
function extractDelegatedEventData(expr, t4, options) {
|
|
22949
22983
|
const isSimpleHandler = t4.isIdentifier(expr) || t4.isMemberExpression(expr);
|
|
22950
22984
|
if (isSimpleHandler) {
|
|
22951
22985
|
return { handler: expr };
|
|
@@ -22958,6 +22992,9 @@ function extractDelegatedEventData(expr, t4) {
|
|
|
22958
22992
|
if (!bodyExpr || !t4.isCallExpression(bodyExpr)) return null;
|
|
22959
22993
|
if (paramNames.some((name) => expressionUsesIdentifier(bodyExpr, name, t4))) return null;
|
|
22960
22994
|
if (!t4.isIdentifier(bodyExpr.callee)) return null;
|
|
22995
|
+
if (options?.isKnownHandlerIdentifier && !options.isKnownHandlerIdentifier(bodyExpr.callee.name)) {
|
|
22996
|
+
return null;
|
|
22997
|
+
}
|
|
22961
22998
|
if (bodyExpr.arguments.length === 0) return null;
|
|
22962
22999
|
if (bodyExpr.arguments.length > 1) return null;
|
|
22963
23000
|
const dataArg = bodyExpr.arguments[0];
|
|
@@ -23020,6 +23057,10 @@ function extractDelegatedEventDataFromHIR(expr, ctx) {
|
|
|
23020
23057
|
return null;
|
|
23021
23058
|
}
|
|
23022
23059
|
const handlerName = callee.name;
|
|
23060
|
+
const normalizedHandlerName = deSSAVarName(handlerName);
|
|
23061
|
+
if (!ctx.functionVars?.has(normalizedHandlerName)) {
|
|
23062
|
+
return null;
|
|
23063
|
+
}
|
|
23023
23064
|
if (ctx.signalVars?.has(handlerName) || ctx.memoVars?.has(handlerName) || ctx.aliasVars?.has(handlerName) || ctx.storeVars?.has(handlerName) || ctx.trackedVars.has(handlerName)) {
|
|
23024
23065
|
return null;
|
|
23025
23066
|
}
|
|
@@ -23030,7 +23071,10 @@ function extractDelegatedEventDataFromHIR(expr, ctx) {
|
|
|
23030
23071
|
if (isTrackedAccessor) {
|
|
23031
23072
|
return null;
|
|
23032
23073
|
}
|
|
23033
|
-
const paramNames = new Set(expr.params.map((p) => p.name));
|
|
23074
|
+
const paramNames = new Set(expr.params.map((p) => deSSAVarName(p.name)));
|
|
23075
|
+
if (paramNames.has(deSSAVarName(callee.name))) {
|
|
23076
|
+
return null;
|
|
23077
|
+
}
|
|
23034
23078
|
const dataExpr = bodyExpr.arguments[0];
|
|
23035
23079
|
if (!dataExpr) {
|
|
23036
23080
|
return null;
|
|
@@ -24197,8 +24241,8 @@ function getDependencyPathFromNode(node, t4) {
|
|
|
24197
24241
|
}
|
|
24198
24242
|
return null;
|
|
24199
24243
|
}
|
|
24200
|
-
function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parentKey, skipCurrentNode = false) {
|
|
24201
|
-
const isCallTarget = parentKey === "callee" && (parentKind === "CallExpression" || parentKind === "OptionalCallExpression");
|
|
24244
|
+
function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parentKey, skipCurrentNode = false, allowCallCalleeReplacement = false) {
|
|
24245
|
+
const isCallTarget = !allowCallCalleeReplacement && parentKey === "callee" && (parentKind === "CallExpression" || parentKind === "OptionalCallExpression");
|
|
24202
24246
|
if (parentKind === "VariableDeclarator" && parentKey === "id") {
|
|
24203
24247
|
return;
|
|
24204
24248
|
}
|
|
@@ -24270,9 +24314,25 @@ function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parent
|
|
|
24270
24314
|
}
|
|
24271
24315
|
}
|
|
24272
24316
|
if (t4.isBlockStatement(node.body)) {
|
|
24273
|
-
replaceIdentifiersWithOverrides(
|
|
24317
|
+
replaceIdentifiersWithOverrides(
|
|
24318
|
+
node.body,
|
|
24319
|
+
scopedOverrides,
|
|
24320
|
+
t4,
|
|
24321
|
+
node.type,
|
|
24322
|
+
"body",
|
|
24323
|
+
false,
|
|
24324
|
+
allowCallCalleeReplacement
|
|
24325
|
+
);
|
|
24274
24326
|
} else {
|
|
24275
|
-
replaceIdentifiersWithOverrides(
|
|
24327
|
+
replaceIdentifiersWithOverrides(
|
|
24328
|
+
node.body,
|
|
24329
|
+
scopedOverrides,
|
|
24330
|
+
t4,
|
|
24331
|
+
node.type,
|
|
24332
|
+
"body",
|
|
24333
|
+
false,
|
|
24334
|
+
allowCallCalleeReplacement
|
|
24335
|
+
);
|
|
24276
24336
|
}
|
|
24277
24337
|
return;
|
|
24278
24338
|
}
|
|
@@ -24300,12 +24360,21 @@ function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parent
|
|
|
24300
24360
|
t4,
|
|
24301
24361
|
node.type,
|
|
24302
24362
|
key,
|
|
24303
|
-
false
|
|
24363
|
+
false,
|
|
24364
|
+
allowCallCalleeReplacement
|
|
24304
24365
|
);
|
|
24305
24366
|
}
|
|
24306
24367
|
}
|
|
24307
24368
|
} else if (value && typeof value === "object" && "type" in value) {
|
|
24308
|
-
replaceIdentifiersWithOverrides(
|
|
24369
|
+
replaceIdentifiersWithOverrides(
|
|
24370
|
+
value,
|
|
24371
|
+
overrides,
|
|
24372
|
+
t4,
|
|
24373
|
+
node.type,
|
|
24374
|
+
key,
|
|
24375
|
+
false,
|
|
24376
|
+
allowCallCalleeReplacement
|
|
24377
|
+
);
|
|
24309
24378
|
}
|
|
24310
24379
|
}
|
|
24311
24380
|
}
|
|
@@ -24578,6 +24647,124 @@ function applySelectorHoist(callbackExpr, itemParamName, keyParamName, statement
|
|
|
24578
24647
|
}
|
|
24579
24648
|
|
|
24580
24649
|
// src/ir/codegen-list-child.ts
|
|
24650
|
+
function getCallbackBlocks(callback) {
|
|
24651
|
+
if (callback.kind === "FunctionExpression") {
|
|
24652
|
+
return callback.body;
|
|
24653
|
+
}
|
|
24654
|
+
if (callback.kind === "ArrowFunction" && Array.isArray(callback.body)) {
|
|
24655
|
+
return callback.body;
|
|
24656
|
+
}
|
|
24657
|
+
return [];
|
|
24658
|
+
}
|
|
24659
|
+
function collectMapCallbackAliasDeclarations(callback) {
|
|
24660
|
+
const blocks = getCallbackBlocks(callback);
|
|
24661
|
+
if (blocks.length === 0) {
|
|
24662
|
+
return /* @__PURE__ */ new Map();
|
|
24663
|
+
}
|
|
24664
|
+
const paramNames = callback.kind === "ArrowFunction" || callback.kind === "FunctionExpression" ? new Set(callback.params.map((param) => param.name)) : /* @__PURE__ */ new Set();
|
|
24665
|
+
const declarationState = /* @__PURE__ */ new Map();
|
|
24666
|
+
for (const block of blocks) {
|
|
24667
|
+
for (const instr of block.instructions) {
|
|
24668
|
+
if (instr.kind !== "Assign" || instr.target.kind !== "Identifier") {
|
|
24669
|
+
continue;
|
|
24670
|
+
}
|
|
24671
|
+
const name = instr.target.name;
|
|
24672
|
+
if (paramNames.has(name)) continue;
|
|
24673
|
+
const isDeclaration = !!instr.declarationKind;
|
|
24674
|
+
const previous = declarationState.get(name);
|
|
24675
|
+
if (previous) {
|
|
24676
|
+
declarationState.set(name, {
|
|
24677
|
+
declarationCount: previous.declarationCount + (isDeclaration ? 1 : 0),
|
|
24678
|
+
hasNonDeclarationWrite: previous.hasNonDeclarationWrite || !isDeclaration,
|
|
24679
|
+
declarationValue: previous.declarationValue,
|
|
24680
|
+
lastAssignedValue: instr.value
|
|
24681
|
+
});
|
|
24682
|
+
} else {
|
|
24683
|
+
declarationState.set(name, {
|
|
24684
|
+
declarationCount: isDeclaration ? 1 : 0,
|
|
24685
|
+
hasNonDeclarationWrite: !isDeclaration,
|
|
24686
|
+
declarationValue: isDeclaration ? instr.value : null,
|
|
24687
|
+
lastAssignedValue: instr.value
|
|
24688
|
+
});
|
|
24689
|
+
}
|
|
24690
|
+
}
|
|
24691
|
+
}
|
|
24692
|
+
const aliasMap = /* @__PURE__ */ new Map();
|
|
24693
|
+
const effectiveBlocks = blocks.filter(
|
|
24694
|
+
(block) => block.instructions.length > 0 || block.terminator.kind !== "Unreachable"
|
|
24695
|
+
);
|
|
24696
|
+
const isSingleLinearBlock = effectiveBlocks.length === 1 && effectiveBlocks[0].terminator.kind === "Return";
|
|
24697
|
+
for (const [name, state] of declarationState) {
|
|
24698
|
+
if (isSingleLinearBlock) {
|
|
24699
|
+
if (state.declarationCount <= 1) {
|
|
24700
|
+
aliasMap.set(name, state.lastAssignedValue);
|
|
24701
|
+
}
|
|
24702
|
+
continue;
|
|
24703
|
+
}
|
|
24704
|
+
if (state.declarationCount === 1 && !state.hasNonDeclarationWrite && state.declarationValue) {
|
|
24705
|
+
aliasMap.set(name, state.declarationValue);
|
|
24706
|
+
}
|
|
24707
|
+
}
|
|
24708
|
+
return aliasMap;
|
|
24709
|
+
}
|
|
24710
|
+
function resolveMapCallbackKeyExpression(keyExpr, callback) {
|
|
24711
|
+
if (keyExpr.kind !== "Identifier") {
|
|
24712
|
+
return keyExpr;
|
|
24713
|
+
}
|
|
24714
|
+
const aliasMap = collectMapCallbackAliasDeclarations(callback);
|
|
24715
|
+
if (aliasMap.size === 0) {
|
|
24716
|
+
return keyExpr;
|
|
24717
|
+
}
|
|
24718
|
+
let resolved = keyExpr;
|
|
24719
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24720
|
+
while (resolved.kind === "Identifier") {
|
|
24721
|
+
const next = aliasMap.get(resolved.name);
|
|
24722
|
+
if (!next || seen.has(resolved.name)) break;
|
|
24723
|
+
seen.add(resolved.name);
|
|
24724
|
+
resolved = next;
|
|
24725
|
+
}
|
|
24726
|
+
return resolved;
|
|
24727
|
+
}
|
|
24728
|
+
function collectMapCallbackLocalNames(callback) {
|
|
24729
|
+
const blocks = getCallbackBlocks(callback);
|
|
24730
|
+
if (blocks.length === 0) {
|
|
24731
|
+
return /* @__PURE__ */ new Set();
|
|
24732
|
+
}
|
|
24733
|
+
const paramNames = callback.kind === "ArrowFunction" || callback.kind === "FunctionExpression" ? new Set(callback.params.map((param) => deSSAVarName(param.name))) : /* @__PURE__ */ new Set();
|
|
24734
|
+
const locals = /* @__PURE__ */ new Set();
|
|
24735
|
+
for (const block of blocks) {
|
|
24736
|
+
for (const instr of block.instructions) {
|
|
24737
|
+
if (instr.kind === "Assign" && instr.target.kind === "Identifier") {
|
|
24738
|
+
const name = deSSAVarName(instr.target.name);
|
|
24739
|
+
if (!paramNames.has(name)) locals.add(name);
|
|
24740
|
+
}
|
|
24741
|
+
if (instr.kind === "Phi" && instr.target.kind === "Identifier") {
|
|
24742
|
+
const name = deSSAVarName(instr.target.name);
|
|
24743
|
+
if (!paramNames.has(name)) locals.add(name);
|
|
24744
|
+
}
|
|
24745
|
+
}
|
|
24746
|
+
}
|
|
24747
|
+
return locals;
|
|
24748
|
+
}
|
|
24749
|
+
function hasUnresolvedCallbackLocalKeyDependencies(keyExpr, callback, keyAliasDeclarations) {
|
|
24750
|
+
const callbackLocals = collectMapCallbackLocalNames(callback);
|
|
24751
|
+
if (callbackLocals.size === 0) {
|
|
24752
|
+
return false;
|
|
24753
|
+
}
|
|
24754
|
+
const resolvableAliases = new Set(
|
|
24755
|
+
Array.from(keyAliasDeclarations.keys()).map((name) => deSSAVarName(name))
|
|
24756
|
+
);
|
|
24757
|
+
const deps = /* @__PURE__ */ new Set();
|
|
24758
|
+
collectExpressionDependencies(keyExpr, deps);
|
|
24759
|
+
for (const dep of deps) {
|
|
24760
|
+
const base = dep.split(".")[0] ?? dep;
|
|
24761
|
+
if (!base) continue;
|
|
24762
|
+
if (callbackLocals.has(base) && !resolvableAliases.has(base)) {
|
|
24763
|
+
return true;
|
|
24764
|
+
}
|
|
24765
|
+
}
|
|
24766
|
+
return false;
|
|
24767
|
+
}
|
|
24581
24768
|
function buildListCallExpression(expr, statements, ctx, ops) {
|
|
24582
24769
|
const { t: t4 } = ctx;
|
|
24583
24770
|
if (expr.kind !== "CallExpression" && expr.kind !== "OptionalCallExpression") {
|
|
@@ -24596,7 +24783,8 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24596
24783
|
if (!mapCallback) {
|
|
24597
24784
|
throw new Error("map callback is required");
|
|
24598
24785
|
}
|
|
24599
|
-
const
|
|
24786
|
+
const extractedKeyExpr = extractKeyFromMapCallback(mapCallback);
|
|
24787
|
+
const keyExpr = extractedKeyExpr ? resolveMapCallbackKeyExpression(extractedKeyExpr, mapCallback) : void 0;
|
|
24600
24788
|
const isKeyed = !!keyExpr;
|
|
24601
24789
|
const hasRestParam = (mapCallback.kind === "ArrowFunction" || mapCallback.kind === "FunctionExpression") && Array.isArray(mapCallback.rawParams) && mapCallback.rawParams.some((param) => t4.isRestElement(param));
|
|
24602
24790
|
const canConstifyKey = isKeyed && keyExpr && !hasRestParam;
|
|
@@ -24647,7 +24835,7 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24647
24835
|
if (Object.keys(overrides).length > 0) {
|
|
24648
24836
|
if (t4.isBlockStatement(callbackExpr.body)) {
|
|
24649
24837
|
for (const stmt of callbackExpr.body.body) {
|
|
24650
|
-
if (!t4.isVariableDeclaration(stmt)) continue;
|
|
24838
|
+
if (!t4.isVariableDeclaration(stmt) || stmt.kind !== "const") continue;
|
|
24651
24839
|
for (const decl of stmt.declarations) {
|
|
24652
24840
|
if (!t4.isIdentifier(decl.id) || !decl.init) continue;
|
|
24653
24841
|
const replacement = t4.cloneNode(decl.init, true);
|
|
@@ -24677,7 +24865,32 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24677
24865
|
}
|
|
24678
24866
|
let listCall;
|
|
24679
24867
|
if (isKeyed && keyExpr) {
|
|
24868
|
+
const keyAliasDeclarations = collectMapCallbackAliasDeclarations(mapCallback);
|
|
24869
|
+
const hasUnresolvedLocalKeyDeps = hasUnresolvedCallbackLocalKeyDependencies(
|
|
24870
|
+
keyExpr,
|
|
24871
|
+
mapCallback,
|
|
24872
|
+
keyAliasDeclarations
|
|
24873
|
+
);
|
|
24680
24874
|
let keyExprAst = ops.lowerExpression(keyExpr, ctx);
|
|
24875
|
+
if (keyAliasDeclarations.size > 0) {
|
|
24876
|
+
const keyOverrides = {};
|
|
24877
|
+
for (const [name, value] of keyAliasDeclarations) {
|
|
24878
|
+
const replacement = ops.lowerExpression(value, ctx);
|
|
24879
|
+
replaceIdentifiersWithOverrides(replacement, keyOverrides, t4);
|
|
24880
|
+
keyOverrides[name] = () => t4.cloneNode(replacement, true);
|
|
24881
|
+
}
|
|
24882
|
+
if (Object.keys(keyOverrides).length > 0) {
|
|
24883
|
+
replaceIdentifiersWithOverrides(
|
|
24884
|
+
keyExprAst,
|
|
24885
|
+
keyOverrides,
|
|
24886
|
+
t4,
|
|
24887
|
+
void 0,
|
|
24888
|
+
void 0,
|
|
24889
|
+
false,
|
|
24890
|
+
true
|
|
24891
|
+
);
|
|
24892
|
+
}
|
|
24893
|
+
}
|
|
24681
24894
|
if (t4.isArrowFunctionExpression(callbackExpr) || t4.isFunctionExpression(callbackExpr)) {
|
|
24682
24895
|
const itemParam = callbackExpr.params[0];
|
|
24683
24896
|
const indexParam = callbackExpr.params[1];
|
|
@@ -24691,6 +24904,9 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24691
24904
|
}
|
|
24692
24905
|
const itemParamName = t4.isArrowFunctionExpression(callbackExpr) || t4.isFunctionExpression(callbackExpr) ? callbackExpr.params[0] : null;
|
|
24693
24906
|
const indexParamName = t4.isArrowFunctionExpression(callbackExpr) || t4.isFunctionExpression(callbackExpr) ? callbackExpr.params[1] : null;
|
|
24907
|
+
if (hasUnresolvedLocalKeyDeps) {
|
|
24908
|
+
keyExprAst = t4.identifier(t4.isIdentifier(indexParamName) ? indexParamName.name : "__index");
|
|
24909
|
+
}
|
|
24694
24910
|
const keyFn = t4.arrowFunctionExpression(
|
|
24695
24911
|
[
|
|
24696
24912
|
t4.isIdentifier(itemParamName) ? itemParamName : t4.identifier("__item"),
|
|
@@ -25132,33 +25348,42 @@ function dependencyCoveredByDeclarations(dep, region) {
|
|
|
25132
25348
|
|
|
25133
25349
|
// src/ir/codegen-resumable-utils.ts
|
|
25134
25350
|
var import_node_url2 = require("url");
|
|
25135
|
-
|
|
25136
|
-
|
|
25137
|
-
|
|
25138
|
-
|
|
25139
|
-
|
|
25140
|
-
|
|
25141
|
-
|
|
25142
|
-
|
|
25143
|
-
|
|
25144
|
-
|
|
25145
|
-
|
|
25146
|
-
|
|
25147
|
-
|
|
25148
|
-
|
|
25149
|
-
}
|
|
25150
|
-
const value = n[key];
|
|
25151
|
-
if (Array.isArray(value)) {
|
|
25152
|
-
for (const item of value) {
|
|
25153
|
-
visit(item);
|
|
25154
|
-
}
|
|
25155
|
-
} else if (value && typeof value === "object") {
|
|
25156
|
-
visit(value);
|
|
25351
|
+
var import_traverse2 = __toESM(require("@babel/traverse"), 1);
|
|
25352
|
+
function renameIdentifiersInExpr(expr, renames, t4) {
|
|
25353
|
+
const traverse = import_traverse2.default.default ?? import_traverse2.default;
|
|
25354
|
+
const cloned = t4.cloneNode(expr, true);
|
|
25355
|
+
const file = t4.file(t4.program([t4.expressionStatement(cloned)]));
|
|
25356
|
+
traverse(file, {
|
|
25357
|
+
Identifier(path2) {
|
|
25358
|
+
const oldName = path2.node.name;
|
|
25359
|
+
const nextName = renames.get(oldName);
|
|
25360
|
+
if (!nextName) return;
|
|
25361
|
+
if (path2.parentPath.isObjectProperty() && path2.parentPath.node.shorthand && path2.parentPath.node.value === path2.node && t4.isIdentifier(path2.parentPath.node.key)) {
|
|
25362
|
+
path2.parentPath.node.shorthand = false;
|
|
25363
|
+
path2.parentPath.node.value = t4.identifier(nextName);
|
|
25364
|
+
return;
|
|
25157
25365
|
}
|
|
25366
|
+
if (!path2.isReferencedIdentifier()) return;
|
|
25367
|
+
const binding = path2.scope.getBinding(oldName);
|
|
25368
|
+
if (binding && binding.scope !== path2.scope.getProgramParent()) return;
|
|
25369
|
+
path2.node.name = nextName;
|
|
25158
25370
|
}
|
|
25159
|
-
}
|
|
25160
|
-
|
|
25161
|
-
return cloned;
|
|
25371
|
+
});
|
|
25372
|
+
const first = file.program.body[0];
|
|
25373
|
+
return t4.isExpressionStatement(first) ? first.expression : cloned;
|
|
25374
|
+
}
|
|
25375
|
+
function collectFreeIdentifiersInExpr(expr, t4) {
|
|
25376
|
+
const traverse = import_traverse2.default.default ?? import_traverse2.default;
|
|
25377
|
+
const file = t4.file(t4.program([t4.expressionStatement(t4.cloneNode(expr, true))]));
|
|
25378
|
+
const names = /* @__PURE__ */ new Set();
|
|
25379
|
+
traverse(file, {
|
|
25380
|
+
ReferencedIdentifier(path2) {
|
|
25381
|
+
const name = path2.node.name;
|
|
25382
|
+
if (path2.scope.getBinding(name)) return;
|
|
25383
|
+
names.add(name);
|
|
25384
|
+
}
|
|
25385
|
+
});
|
|
25386
|
+
return names;
|
|
25162
25387
|
}
|
|
25163
25388
|
function genModuleUrlExpr(ctx) {
|
|
25164
25389
|
const { t: t4 } = ctx;
|
|
@@ -25295,10 +25520,10 @@ function registerResumableComponent(componentName, ctx) {
|
|
|
25295
25520
|
}
|
|
25296
25521
|
|
|
25297
25522
|
// src/ir/codegen-resumable-events.ts
|
|
25298
|
-
function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, containingRegion, ops) {
|
|
25523
|
+
function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, containingRegion, ops, options) {
|
|
25299
25524
|
const { t: t4 } = ctx;
|
|
25300
25525
|
if (!ctx.resumableEnabled) {
|
|
25301
|
-
return;
|
|
25526
|
+
return false;
|
|
25302
25527
|
}
|
|
25303
25528
|
const prevWrapTracked = ctx.wrapTrackedExpressions;
|
|
25304
25529
|
ctx.wrapTrackedExpressions = false;
|
|
@@ -25312,53 +25537,88 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25312
25537
|
const scopeParam = t4.identifier("scopeId");
|
|
25313
25538
|
const ensureHandlerParam = (fn) => {
|
|
25314
25539
|
if (t4.isArrowFunctionExpression(fn)) {
|
|
25315
|
-
|
|
25316
|
-
return t4.arrowFunctionExpression([eventParam], fn.body, fn.async);
|
|
25540
|
+
return fn;
|
|
25317
25541
|
}
|
|
25318
25542
|
if (t4.isFunctionExpression(fn)) {
|
|
25319
|
-
|
|
25320
|
-
return t4.functionExpression(fn.id, [eventParam], fn.body, fn.generator, fn.async);
|
|
25543
|
+
return fn;
|
|
25321
25544
|
}
|
|
25322
25545
|
if (t4.isIdentifier(fn) || t4.isMemberExpression(fn)) {
|
|
25323
25546
|
return fn;
|
|
25324
25547
|
}
|
|
25325
|
-
if (t4.isCallExpression(fn) && fn.arguments.length === 0 && (t4.isIdentifier(fn.callee) || t4.isMemberExpression(fn.callee))) {
|
|
25326
|
-
return fn.callee;
|
|
25327
|
-
}
|
|
25328
25548
|
return t4.functionExpression(
|
|
25329
25549
|
null,
|
|
25330
|
-
[
|
|
25331
|
-
t4.blockStatement([
|
|
25332
|
-
t4.returnStatement(
|
|
25333
|
-
t4.callExpression(
|
|
25334
|
-
t4.memberExpression(fn, t4.identifier("call")),
|
|
25335
|
-
[t4.thisExpression(), eventParam]
|
|
25336
|
-
)
|
|
25337
|
-
)
|
|
25338
|
-
])
|
|
25550
|
+
[],
|
|
25551
|
+
t4.blockStatement([t4.returnStatement(fn)])
|
|
25339
25552
|
);
|
|
25340
25553
|
};
|
|
25341
25554
|
const handlerExpr = ensureHandlerParam(valueExpr);
|
|
25342
25555
|
const handlerId = t4.identifier(`__fict_e${ctx.resumableHandlerCounter ?? 0}`);
|
|
25343
25556
|
ctx.resumableHandlerCounter = (ctx.resumableHandlerCounter ?? 0) + 1;
|
|
25344
|
-
const captured =
|
|
25345
|
-
collectExpressionIdentifiersDeep(expr, captured);
|
|
25557
|
+
const captured = collectFreeIdentifiersInExpr(handlerExpr, t4);
|
|
25346
25558
|
const lexicalNames = Array.from(captured).filter((name) => ctx.signalVars?.has(name));
|
|
25347
25559
|
const propsName = ctx.propsParamName && captured.has(ctx.propsParamName) ? ctx.propsParamName : null;
|
|
25560
|
+
const unsupportedLocals = Array.from(captured).filter((name) => {
|
|
25561
|
+
if (ctx.inListRender && ctx.listKeyParamName && name === ctx.listKeyParamName) return true;
|
|
25562
|
+
if (!ctx.localDeclaredNames?.has(name)) return false;
|
|
25563
|
+
if (ctx.signalVars?.has(name)) return false;
|
|
25564
|
+
if (ctx.functionVars?.has(name)) return false;
|
|
25565
|
+
if (propsName && name === propsName) return false;
|
|
25566
|
+
return true;
|
|
25567
|
+
});
|
|
25568
|
+
const loweredFunctionDeps = /* @__PURE__ */ new Map();
|
|
25569
|
+
const unsafeFunctionCaptures = [];
|
|
25570
|
+
for (const name of captured) {
|
|
25571
|
+
if (!ctx.functionVars?.has(name) || ctx.signalVars?.has(name)) continue;
|
|
25572
|
+
if (ctx.hoistedFunctionDepNames?.has(name)) continue;
|
|
25573
|
+
const hirDef = ctx.componentFunctionDefs?.get(name);
|
|
25574
|
+
if (!hirDef) {
|
|
25575
|
+
if (ctx.localDeclaredNames?.has(name)) {
|
|
25576
|
+
unsafeFunctionCaptures.push(`${name} -> <unhoistable>`);
|
|
25577
|
+
}
|
|
25578
|
+
continue;
|
|
25579
|
+
}
|
|
25580
|
+
const loweredFn = ops.lowerDomExpression(hirDef, ctx, null, {
|
|
25581
|
+
skipHookAccessors: true,
|
|
25582
|
+
skipRegionRootOverride: true
|
|
25583
|
+
});
|
|
25584
|
+
const fnCaptured = collectFreeIdentifiersInExpr(loweredFn, t4);
|
|
25585
|
+
const localFnCaptures = Array.from(fnCaptured).filter((dep) => ctx.localDeclaredNames?.has(dep)).sort();
|
|
25586
|
+
if (localFnCaptures.length > 0) {
|
|
25587
|
+
unsafeFunctionCaptures.push(`${name} -> ${localFnCaptures.join(", ")}`);
|
|
25588
|
+
continue;
|
|
25589
|
+
}
|
|
25590
|
+
loweredFunctionDeps.set(name, loweredFn);
|
|
25591
|
+
}
|
|
25592
|
+
if (unsupportedLocals.length > 0 || unsafeFunctionCaptures.length > 0) {
|
|
25593
|
+
const detailParts = [];
|
|
25594
|
+
if (unsupportedLocals.length > 0) {
|
|
25595
|
+
detailParts.push(`direct: ${unsupportedLocals.sort().join(", ")}`);
|
|
25596
|
+
}
|
|
25597
|
+
if (unsafeFunctionCaptures.length > 0) {
|
|
25598
|
+
detailParts.push(`function deps: ${unsafeFunctionCaptures.sort().join("; ")}`);
|
|
25599
|
+
}
|
|
25600
|
+
const detail = `Resumable handlers cannot capture non-serializable local variables (${detailParts.join(" | ")}).`;
|
|
25601
|
+
if (options?.explicit) {
|
|
25602
|
+
const loc = expr.loc?.start;
|
|
25603
|
+
const fileName = ctx.options?.filename ?? "<unknown>";
|
|
25604
|
+
const location = loc ? `${fileName}:${loc.line}:${loc.column + 1}` : fileName;
|
|
25605
|
+
throw new Error(
|
|
25606
|
+
`${detail} Use signals/props/function references or remove '$' suffix.
|
|
25607
|
+
at ${location}`
|
|
25608
|
+
);
|
|
25609
|
+
}
|
|
25610
|
+
return false;
|
|
25611
|
+
}
|
|
25348
25612
|
const functionDepRenames = /* @__PURE__ */ new Map();
|
|
25349
25613
|
for (const name of captured) {
|
|
25350
25614
|
if (ctx.functionVars?.has(name) && !ctx.signalVars?.has(name)) {
|
|
25351
|
-
const hirDef = ctx.componentFunctionDefs?.get(name);
|
|
25352
|
-
if (!hirDef) continue;
|
|
25353
25615
|
let hoistedName = ctx.hoistedFunctionDepNames?.get(name);
|
|
25354
25616
|
if (!hoistedName) {
|
|
25617
|
+
const loweredFn = loweredFunctionDeps.get(name);
|
|
25618
|
+
if (!loweredFn) continue;
|
|
25355
25619
|
hoistedName = `__fict_fn_${name}_${ctx.hoistedFunctionDepCounter ?? 0}`;
|
|
25356
25620
|
ctx.hoistedFunctionDepCounter = (ctx.hoistedFunctionDepCounter ?? 0) + 1;
|
|
25357
25621
|
ctx.hoistedFunctionDepNames?.set(name, hoistedName);
|
|
25358
|
-
const loweredFn = ops.lowerDomExpression(hirDef, ctx, null, {
|
|
25359
|
-
skipHookAccessors: true,
|
|
25360
|
-
skipRegionRootOverride: true
|
|
25361
|
-
});
|
|
25362
25622
|
const hoistedDecl = t4.variableDeclaration("const", [
|
|
25363
25623
|
t4.variableDeclarator(t4.identifier(hoistedName), loweredFn)
|
|
25364
25624
|
]);
|
|
@@ -25370,7 +25630,7 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25370
25630
|
}
|
|
25371
25631
|
let finalHandlerExpr = handlerExpr;
|
|
25372
25632
|
if (functionDepRenames.size > 0) {
|
|
25373
|
-
finalHandlerExpr = renameIdentifiersInExpr(handlerExpr, functionDepRenames);
|
|
25633
|
+
finalHandlerExpr = renameIdentifiersInExpr(handlerExpr, functionDepRenames, t4);
|
|
25374
25634
|
}
|
|
25375
25635
|
const bodyStatements = [];
|
|
25376
25636
|
if (lexicalNames.length > 0) {
|
|
@@ -25403,12 +25663,97 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25403
25663
|
);
|
|
25404
25664
|
}
|
|
25405
25665
|
const handlerVar = t4.identifier("__handler");
|
|
25666
|
+
const resultVar = t4.identifier("__result");
|
|
25406
25667
|
bodyStatements.push(
|
|
25407
25668
|
t4.variableDeclaration("const", [t4.variableDeclarator(handlerVar, finalHandlerExpr)])
|
|
25408
25669
|
);
|
|
25409
25670
|
bodyStatements.push(
|
|
25410
|
-
t4.
|
|
25411
|
-
t4.
|
|
25671
|
+
t4.ifStatement(
|
|
25672
|
+
t4.binaryExpression(
|
|
25673
|
+
"===",
|
|
25674
|
+
t4.unaryExpression("typeof", handlerVar),
|
|
25675
|
+
t4.stringLiteral("function")
|
|
25676
|
+
),
|
|
25677
|
+
t4.blockStatement([
|
|
25678
|
+
t4.variableDeclaration("const", [
|
|
25679
|
+
t4.variableDeclarator(
|
|
25680
|
+
resultVar,
|
|
25681
|
+
t4.callExpression(t4.memberExpression(handlerVar, t4.identifier("call")), [
|
|
25682
|
+
elParam,
|
|
25683
|
+
eventParam
|
|
25684
|
+
])
|
|
25685
|
+
)
|
|
25686
|
+
]),
|
|
25687
|
+
t4.ifStatement(
|
|
25688
|
+
t4.logicalExpression(
|
|
25689
|
+
"&&",
|
|
25690
|
+
t4.binaryExpression(
|
|
25691
|
+
"===",
|
|
25692
|
+
t4.unaryExpression("typeof", resultVar),
|
|
25693
|
+
t4.stringLiteral("function")
|
|
25694
|
+
),
|
|
25695
|
+
t4.binaryExpression("!==", resultVar, handlerVar)
|
|
25696
|
+
),
|
|
25697
|
+
t4.blockStatement([
|
|
25698
|
+
t4.returnStatement(
|
|
25699
|
+
t4.callExpression(t4.memberExpression(resultVar, t4.identifier("call")), [
|
|
25700
|
+
elParam,
|
|
25701
|
+
eventParam
|
|
25702
|
+
])
|
|
25703
|
+
)
|
|
25704
|
+
])
|
|
25705
|
+
),
|
|
25706
|
+
t4.ifStatement(
|
|
25707
|
+
t4.logicalExpression(
|
|
25708
|
+
"&&",
|
|
25709
|
+
resultVar,
|
|
25710
|
+
t4.binaryExpression(
|
|
25711
|
+
"===",
|
|
25712
|
+
t4.unaryExpression(
|
|
25713
|
+
"typeof",
|
|
25714
|
+
t4.memberExpression(resultVar, t4.identifier("handleEvent"))
|
|
25715
|
+
),
|
|
25716
|
+
t4.stringLiteral("function")
|
|
25717
|
+
)
|
|
25718
|
+
),
|
|
25719
|
+
t4.blockStatement([
|
|
25720
|
+
t4.returnStatement(
|
|
25721
|
+
t4.callExpression(
|
|
25722
|
+
t4.memberExpression(
|
|
25723
|
+
t4.memberExpression(resultVar, t4.identifier("handleEvent")),
|
|
25724
|
+
t4.identifier("call")
|
|
25725
|
+
),
|
|
25726
|
+
[resultVar, eventParam]
|
|
25727
|
+
)
|
|
25728
|
+
)
|
|
25729
|
+
])
|
|
25730
|
+
),
|
|
25731
|
+
t4.returnStatement(resultVar)
|
|
25732
|
+
])
|
|
25733
|
+
)
|
|
25734
|
+
);
|
|
25735
|
+
bodyStatements.push(
|
|
25736
|
+
t4.ifStatement(
|
|
25737
|
+
t4.logicalExpression(
|
|
25738
|
+
"&&",
|
|
25739
|
+
handlerVar,
|
|
25740
|
+
t4.binaryExpression(
|
|
25741
|
+
"===",
|
|
25742
|
+
t4.unaryExpression("typeof", t4.memberExpression(handlerVar, t4.identifier("handleEvent"))),
|
|
25743
|
+
t4.stringLiteral("function")
|
|
25744
|
+
)
|
|
25745
|
+
),
|
|
25746
|
+
t4.blockStatement([
|
|
25747
|
+
t4.returnStatement(
|
|
25748
|
+
t4.callExpression(
|
|
25749
|
+
t4.memberExpression(
|
|
25750
|
+
t4.memberExpression(handlerVar, t4.identifier("handleEvent")),
|
|
25751
|
+
t4.identifier("call")
|
|
25752
|
+
),
|
|
25753
|
+
[handlerVar, eventParam]
|
|
25754
|
+
)
|
|
25755
|
+
)
|
|
25756
|
+
])
|
|
25412
25757
|
)
|
|
25413
25758
|
);
|
|
25414
25759
|
const exportedHandler = t4.exportNamedDeclaration(
|
|
@@ -25437,6 +25782,7 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25437
25782
|
])
|
|
25438
25783
|
)
|
|
25439
25784
|
);
|
|
25785
|
+
return true;
|
|
25440
25786
|
}
|
|
25441
25787
|
|
|
25442
25788
|
// src/ir/codegen-runtime-imports.ts
|
|
@@ -25821,7 +26167,8 @@ function extractHIRStaticHtml(jsx, ctx, ops, parentPath = [], namespace = null)
|
|
|
25821
26167
|
name: eventName.toLowerCase(),
|
|
25822
26168
|
expr: attr.value ?? void 0,
|
|
25823
26169
|
eventOptions: { capture, passive, once },
|
|
25824
|
-
resumable: shouldBeResumable
|
|
26170
|
+
resumable: shouldBeResumable,
|
|
26171
|
+
resumableExplicit: isResumableEvent
|
|
25825
26172
|
});
|
|
25826
26173
|
continue;
|
|
25827
26174
|
}
|
|
@@ -26394,7 +26741,7 @@ function buildOutputParams(fn, t4) {
|
|
|
26394
26741
|
}
|
|
26395
26742
|
return fn.params.map((p) => t4.identifier(deSSAVarName(p.name)));
|
|
26396
26743
|
}
|
|
26397
|
-
function lowerTrackedExpression(expr, ctx) {
|
|
26744
|
+
function lowerTrackedExpression(expr, ctx, valueUsed = true) {
|
|
26398
26745
|
const regionOverride = ctx.inReturn && ctx.currentFnIsHook ? null : ctx.currentRegion ?? (ctx.trackedVars.size ? {
|
|
26399
26746
|
id: -1,
|
|
26400
26747
|
dependencies: new Set(ctx.trackedVars),
|
|
@@ -26402,7 +26749,7 @@ function lowerTrackedExpression(expr, ctx) {
|
|
|
26402
26749
|
hasControlFlow: false,
|
|
26403
26750
|
hasReactiveWrites: false
|
|
26404
26751
|
} : null);
|
|
26405
|
-
const lowered = lowerExpression2(expr, ctx);
|
|
26752
|
+
const lowered = lowerExpression2(expr, ctx, valueUsed);
|
|
26406
26753
|
if (ctx.t.isAssignmentExpression(lowered)) {
|
|
26407
26754
|
const right = applyRegionMetadataToExpression2(lowered.right, ctx, regionOverride ?? void 0);
|
|
26408
26755
|
return ctx.t.assignmentExpression(lowered.operator, lowered.left, right);
|
|
@@ -26524,7 +26871,7 @@ function lowerInstruction(instr, ctx) {
|
|
|
26524
26871
|
);
|
|
26525
26872
|
}
|
|
26526
26873
|
if (instr.kind === "Expression") {
|
|
26527
|
-
return applyLoc(t4.expressionStatement(lowerTrackedExpression(instr.value, ctx)));
|
|
26874
|
+
return applyLoc(t4.expressionStatement(lowerTrackedExpression(instr.value, ctx, false)));
|
|
26528
26875
|
}
|
|
26529
26876
|
if (instr.kind === "Phi") {
|
|
26530
26877
|
return null;
|
|
@@ -26688,7 +27035,7 @@ function collectLocalDeclaredNames(params, blocks, t4) {
|
|
|
26688
27035
|
}
|
|
26689
27036
|
return declared;
|
|
26690
27037
|
}
|
|
26691
|
-
function lowerExpression2(expr, ctx,
|
|
27038
|
+
function lowerExpression2(expr, ctx, valueUsed = true) {
|
|
26692
27039
|
const depth = (ctx.expressionDepth ?? 0) + 1;
|
|
26693
27040
|
const maxDepth = ctx.maxExpressionDepth ?? 500;
|
|
26694
27041
|
if (depth > maxDepth) {
|
|
@@ -26699,12 +27046,12 @@ function lowerExpression2(expr, ctx, isAssigned = false) {
|
|
|
26699
27046
|
}
|
|
26700
27047
|
ctx.expressionDepth = depth;
|
|
26701
27048
|
try {
|
|
26702
|
-
return setNodeLoc(lowerExpressionImpl(expr, ctx,
|
|
27049
|
+
return setNodeLoc(lowerExpressionImpl(expr, ctx, valueUsed), expr.loc);
|
|
26703
27050
|
} finally {
|
|
26704
27051
|
ctx.expressionDepth = depth - 1;
|
|
26705
27052
|
}
|
|
26706
27053
|
}
|
|
26707
|
-
function lowerExpressionImpl(expr, ctx,
|
|
27054
|
+
function lowerExpressionImpl(expr, ctx, valueUsed = true) {
|
|
26708
27055
|
const { t: t4 } = ctx;
|
|
26709
27056
|
const mapParams = (params) => params.map((p) => t4.identifier(deSSAVarName(p.name)));
|
|
26710
27057
|
const lowerArgsAsExpressions = (args) => args.map(
|
|
@@ -26745,6 +27092,152 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
26745
27092
|
ctx.localDeclaredNames = prevLocalDeclared;
|
|
26746
27093
|
return result;
|
|
26747
27094
|
};
|
|
27095
|
+
const lowerTrackedWriteCall = (callee, nextValue) => {
|
|
27096
|
+
if (!valueUsed) {
|
|
27097
|
+
return t4.callExpression(t4.cloneNode(callee, true), [nextValue]);
|
|
27098
|
+
}
|
|
27099
|
+
const nextId = genTemp3(ctx, "next");
|
|
27100
|
+
const nextRef = t4.identifier(nextId.name);
|
|
27101
|
+
return t4.callExpression(
|
|
27102
|
+
t4.arrowFunctionExpression(
|
|
27103
|
+
[t4.cloneNode(nextId, true)],
|
|
27104
|
+
t4.sequenceExpression([
|
|
27105
|
+
t4.callExpression(t4.cloneNode(callee, true), [nextRef]),
|
|
27106
|
+
t4.identifier(nextId.name)
|
|
27107
|
+
])
|
|
27108
|
+
),
|
|
27109
|
+
[nextValue]
|
|
27110
|
+
);
|
|
27111
|
+
};
|
|
27112
|
+
const buildTrackedAssignmentNext = (operator, current, right) => {
|
|
27113
|
+
switch (operator) {
|
|
27114
|
+
case "=":
|
|
27115
|
+
return right;
|
|
27116
|
+
case "+=":
|
|
27117
|
+
return t4.binaryExpression("+", current, right);
|
|
27118
|
+
case "-=":
|
|
27119
|
+
return t4.binaryExpression("-", current, right);
|
|
27120
|
+
case "*=":
|
|
27121
|
+
return t4.binaryExpression("*", current, right);
|
|
27122
|
+
case "/=":
|
|
27123
|
+
return t4.binaryExpression("/", current, right);
|
|
27124
|
+
case "%=":
|
|
27125
|
+
return t4.binaryExpression("%", current, right);
|
|
27126
|
+
case "**=":
|
|
27127
|
+
return t4.binaryExpression("**", current, right);
|
|
27128
|
+
case "<<=":
|
|
27129
|
+
return t4.binaryExpression("<<", current, right);
|
|
27130
|
+
case ">>=":
|
|
27131
|
+
return t4.binaryExpression(">>", current, right);
|
|
27132
|
+
case ">>>=":
|
|
27133
|
+
return t4.binaryExpression(">>>", current, right);
|
|
27134
|
+
case "|=":
|
|
27135
|
+
return t4.binaryExpression("|", current, right);
|
|
27136
|
+
case "^=":
|
|
27137
|
+
return t4.binaryExpression("^", current, right);
|
|
27138
|
+
case "&=":
|
|
27139
|
+
return t4.binaryExpression("&", current, right);
|
|
27140
|
+
case "&&=":
|
|
27141
|
+
return t4.logicalExpression("&&", current, right);
|
|
27142
|
+
case "||=":
|
|
27143
|
+
return t4.logicalExpression("||", current, right);
|
|
27144
|
+
case "??=":
|
|
27145
|
+
return t4.logicalExpression("??", current, right);
|
|
27146
|
+
default:
|
|
27147
|
+
return right;
|
|
27148
|
+
}
|
|
27149
|
+
};
|
|
27150
|
+
const buildStaticSignalKeyTest = (keyRef, keys) => {
|
|
27151
|
+
if (keys.length === 0) return null;
|
|
27152
|
+
let test = null;
|
|
27153
|
+
for (const key of keys) {
|
|
27154
|
+
const literal = typeof key === "number" ? t4.numericLiteral(key) : t4.stringLiteral(String(key));
|
|
27155
|
+
const eq = t4.binaryExpression("===", t4.cloneNode(keyRef, true), literal);
|
|
27156
|
+
test = test ? t4.logicalExpression("||", test, eq) : eq;
|
|
27157
|
+
}
|
|
27158
|
+
return test;
|
|
27159
|
+
};
|
|
27160
|
+
const lowerComputedHookSignalAssignment = (objectName, keyExpr, signalKeys, operator, rightExpr) => {
|
|
27161
|
+
const keyTestKeys = signalKeys.filter(
|
|
27162
|
+
(key) => typeof key === "number" && Number.isFinite(key) || typeof key === "string"
|
|
27163
|
+
);
|
|
27164
|
+
if (keyTestKeys.length === 0) return null;
|
|
27165
|
+
const keyId = genTemp3(ctx, "key");
|
|
27166
|
+
const keyRef = t4.identifier(keyId.name);
|
|
27167
|
+
const memberForAccessor = t4.memberExpression(
|
|
27168
|
+
t4.identifier(objectName),
|
|
27169
|
+
t4.identifier(keyId.name),
|
|
27170
|
+
true
|
|
27171
|
+
);
|
|
27172
|
+
const current = t4.callExpression(t4.cloneNode(memberForAccessor, true), []);
|
|
27173
|
+
const right = lowerExpression2(rightExpr, ctx);
|
|
27174
|
+
const signalWrite = lowerTrackedWriteCall(
|
|
27175
|
+
memberForAccessor,
|
|
27176
|
+
buildTrackedAssignmentNext(operator, current, t4.cloneNode(right, true))
|
|
27177
|
+
);
|
|
27178
|
+
const fallback = t4.assignmentExpression(
|
|
27179
|
+
operator,
|
|
27180
|
+
t4.memberExpression(t4.identifier(objectName), t4.identifier(keyId.name), true),
|
|
27181
|
+
right
|
|
27182
|
+
);
|
|
27183
|
+
const keyTest = buildStaticSignalKeyTest(keyRef, keyTestKeys);
|
|
27184
|
+
if (!keyTest) return null;
|
|
27185
|
+
return t4.callExpression(
|
|
27186
|
+
t4.arrowFunctionExpression(
|
|
27187
|
+
[t4.cloneNode(keyId, true)],
|
|
27188
|
+
t4.conditionalExpression(keyTest, signalWrite, fallback)
|
|
27189
|
+
),
|
|
27190
|
+
[lowerExpression2(keyExpr, ctx)]
|
|
27191
|
+
);
|
|
27192
|
+
};
|
|
27193
|
+
const lowerComputedHookSignalUpdate = (objectName, keyExpr, signalKeys, operator, prefix) => {
|
|
27194
|
+
const keyTestKeys = signalKeys.filter(
|
|
27195
|
+
(key) => typeof key === "number" && Number.isFinite(key) || typeof key === "string"
|
|
27196
|
+
);
|
|
27197
|
+
if (keyTestKeys.length === 0) return null;
|
|
27198
|
+
const keyId = genTemp3(ctx, "key");
|
|
27199
|
+
const keyRef = t4.identifier(keyId.name);
|
|
27200
|
+
const signalUpdate = lowerTrackedUpdateCall(
|
|
27201
|
+
t4.memberExpression(t4.identifier(objectName), t4.identifier(keyId.name), true),
|
|
27202
|
+
operator,
|
|
27203
|
+
prefix
|
|
27204
|
+
);
|
|
27205
|
+
const fallback = t4.updateExpression(
|
|
27206
|
+
operator,
|
|
27207
|
+
t4.memberExpression(t4.identifier(objectName), t4.identifier(keyId.name), true),
|
|
27208
|
+
prefix
|
|
27209
|
+
);
|
|
27210
|
+
const keyTest = buildStaticSignalKeyTest(keyRef, keyTestKeys);
|
|
27211
|
+
if (!keyTest) return null;
|
|
27212
|
+
return t4.callExpression(
|
|
27213
|
+
t4.arrowFunctionExpression(
|
|
27214
|
+
[t4.cloneNode(keyId, true)],
|
|
27215
|
+
t4.conditionalExpression(keyTest, signalUpdate, fallback)
|
|
27216
|
+
),
|
|
27217
|
+
[lowerExpression2(keyExpr, ctx)]
|
|
27218
|
+
);
|
|
27219
|
+
};
|
|
27220
|
+
const lowerTrackedUpdateCall = (callee, operator, prefix) => {
|
|
27221
|
+
const op = operator === "++" ? "+" : "-";
|
|
27222
|
+
const delta = t4.numericLiteral(1);
|
|
27223
|
+
const current = t4.callExpression(t4.cloneNode(callee, true), []);
|
|
27224
|
+
if (!valueUsed) {
|
|
27225
|
+
return t4.callExpression(t4.cloneNode(callee, true), [t4.binaryExpression(op, current, delta)]);
|
|
27226
|
+
}
|
|
27227
|
+
const prevId = genTemp3(ctx, "prev");
|
|
27228
|
+
const prevForSet = t4.identifier(prevId.name);
|
|
27229
|
+
const prevForResult = t4.identifier(prevId.name);
|
|
27230
|
+
return t4.callExpression(
|
|
27231
|
+
t4.arrowFunctionExpression(
|
|
27232
|
+
[t4.cloneNode(prevId, true)],
|
|
27233
|
+
t4.sequenceExpression([
|
|
27234
|
+
t4.callExpression(t4.cloneNode(callee, true), [t4.binaryExpression(op, prevForSet, delta)]),
|
|
27235
|
+
prefix ? t4.binaryExpression(op, prevForResult, t4.numericLiteral(1)) : prevForResult
|
|
27236
|
+
])
|
|
27237
|
+
),
|
|
27238
|
+
[current]
|
|
27239
|
+
);
|
|
27240
|
+
};
|
|
26748
27241
|
const lowerBlocksToStatements = (blocks) => {
|
|
26749
27242
|
const stmts = [];
|
|
26750
27243
|
for (const block of blocks) {
|
|
@@ -26914,6 +27407,24 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
26914
27407
|
expr.arguments,
|
|
26915
27408
|
(arg) => arg.kind === "ArrowFunction" || arg.kind === "FunctionExpression" ? withNonReactiveScope(ctx, () => lowerExpression2(arg, ctx)) : lowerExpression2(arg, ctx)
|
|
26916
27409
|
);
|
|
27410
|
+
const includeDevtools = ctx.options?.dev !== false;
|
|
27411
|
+
if (includeDevtools && expr.loc) {
|
|
27412
|
+
const source = `${ctx.options?.filename ?? ""}:${expr.loc.start.line}:${expr.loc.start.column}`;
|
|
27413
|
+
const sourceProp = t4.objectProperty(
|
|
27414
|
+
t4.identifier("devToolsSource"),
|
|
27415
|
+
t4.stringLiteral(source)
|
|
27416
|
+
);
|
|
27417
|
+
if (args.length === 1) {
|
|
27418
|
+
args.push(t4.objectExpression([sourceProp]));
|
|
27419
|
+
} else if (args.length > 1 && t4.isObjectExpression(args[1])) {
|
|
27420
|
+
const hasSourceProp = args[1].properties.some(
|
|
27421
|
+
(prop) => t4.isObjectProperty(prop) && t4.isIdentifier(prop.key) && prop.key.name === "devToolsSource"
|
|
27422
|
+
);
|
|
27423
|
+
if (!hasSourceProp) {
|
|
27424
|
+
args[1].properties.push(sourceProp);
|
|
27425
|
+
}
|
|
27426
|
+
}
|
|
27427
|
+
}
|
|
26917
27428
|
if (ctx.inModule) {
|
|
26918
27429
|
ctx.helpersUsed.add("effect");
|
|
26919
27430
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.effect), args);
|
|
@@ -27221,59 +27732,42 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
27221
27732
|
expr.left.computed,
|
|
27222
27733
|
expr.left.optional
|
|
27223
27734
|
);
|
|
27224
|
-
const current = t4.callExpression(member, []);
|
|
27735
|
+
const current = t4.callExpression(t4.cloneNode(member, true), []);
|
|
27225
27736
|
const right = lowerExpression2(expr.right, ctx);
|
|
27226
|
-
|
|
27227
|
-
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
|
|
27232
|
-
|
|
27233
|
-
|
|
27234
|
-
|
|
27235
|
-
next = t4.binaryExpression("-", current, right);
|
|
27236
|
-
break;
|
|
27237
|
-
case "*=":
|
|
27238
|
-
next = t4.binaryExpression("*", current, right);
|
|
27239
|
-
break;
|
|
27240
|
-
case "/=":
|
|
27241
|
-
next = t4.binaryExpression("/", current, right);
|
|
27242
|
-
break;
|
|
27243
|
-
default:
|
|
27244
|
-
next = right;
|
|
27737
|
+
const next = buildTrackedAssignmentNext(expr.operator, current, right);
|
|
27738
|
+
return lowerTrackedWriteCall(member, next);
|
|
27739
|
+
}
|
|
27740
|
+
if (expr.left.computed) {
|
|
27741
|
+
const signalKeys = [];
|
|
27742
|
+
if (info?.objectProps) {
|
|
27743
|
+
for (const [key, accessorKind] of info.objectProps.entries()) {
|
|
27744
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27745
|
+
}
|
|
27245
27746
|
}
|
|
27246
|
-
|
|
27747
|
+
if (info?.arrayProps) {
|
|
27748
|
+
for (const [key, accessorKind] of info.arrayProps.entries()) {
|
|
27749
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27750
|
+
}
|
|
27751
|
+
}
|
|
27752
|
+
const lowered = lowerComputedHookSignalAssignment(
|
|
27753
|
+
deSSAVarName(expr.left.object.name),
|
|
27754
|
+
expr.left.property,
|
|
27755
|
+
signalKeys,
|
|
27756
|
+
expr.operator,
|
|
27757
|
+
expr.right
|
|
27758
|
+
);
|
|
27759
|
+
if (lowered) return lowered;
|
|
27247
27760
|
}
|
|
27248
27761
|
}
|
|
27249
27762
|
}
|
|
27250
27763
|
if (expr.left.kind === "Identifier") {
|
|
27251
27764
|
const baseName2 = deSSAVarName(expr.left.name);
|
|
27252
27765
|
if (ctx.trackedVars.has(baseName2)) {
|
|
27253
|
-
const
|
|
27766
|
+
const callee = t4.identifier(baseName2);
|
|
27254
27767
|
const current = t4.callExpression(t4.identifier(baseName2), []);
|
|
27255
27768
|
const right = lowerExpression2(expr.right, ctx);
|
|
27256
|
-
|
|
27257
|
-
|
|
27258
|
-
case "=":
|
|
27259
|
-
next = right;
|
|
27260
|
-
break;
|
|
27261
|
-
case "+=":
|
|
27262
|
-
next = t4.binaryExpression("+", current, right);
|
|
27263
|
-
break;
|
|
27264
|
-
case "-=":
|
|
27265
|
-
next = t4.binaryExpression("-", current, right);
|
|
27266
|
-
break;
|
|
27267
|
-
case "*=":
|
|
27268
|
-
next = t4.binaryExpression("*", current, right);
|
|
27269
|
-
break;
|
|
27270
|
-
case "/=":
|
|
27271
|
-
next = t4.binaryExpression("/", current, right);
|
|
27272
|
-
break;
|
|
27273
|
-
default:
|
|
27274
|
-
next = right;
|
|
27275
|
-
}
|
|
27276
|
-
return t4.callExpression(id, [next]);
|
|
27769
|
+
const next = buildTrackedAssignmentNext(expr.operator, current, right);
|
|
27770
|
+
return lowerTrackedWriteCall(callee, next);
|
|
27277
27771
|
}
|
|
27278
27772
|
}
|
|
27279
27773
|
return t4.assignmentExpression(
|
|
@@ -27305,21 +27799,35 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
27305
27799
|
expr.argument.computed,
|
|
27306
27800
|
expr.argument.optional
|
|
27307
27801
|
);
|
|
27308
|
-
|
|
27309
|
-
|
|
27310
|
-
|
|
27311
|
-
|
|
27802
|
+
return lowerTrackedUpdateCall(member, expr.operator, expr.prefix);
|
|
27803
|
+
}
|
|
27804
|
+
if (expr.argument.computed) {
|
|
27805
|
+
const signalKeys = [];
|
|
27806
|
+
if (info?.objectProps) {
|
|
27807
|
+
for (const [key, accessorKind] of info.objectProps.entries()) {
|
|
27808
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27809
|
+
}
|
|
27810
|
+
}
|
|
27811
|
+
if (info?.arrayProps) {
|
|
27812
|
+
for (const [key, accessorKind] of info.arrayProps.entries()) {
|
|
27813
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27814
|
+
}
|
|
27815
|
+
}
|
|
27816
|
+
const lowered = lowerComputedHookSignalUpdate(
|
|
27817
|
+
deSSAVarName(expr.argument.object.name),
|
|
27818
|
+
expr.argument.property,
|
|
27819
|
+
signalKeys,
|
|
27820
|
+
expr.operator,
|
|
27821
|
+
expr.prefix
|
|
27822
|
+
);
|
|
27823
|
+
if (lowered) return lowered;
|
|
27312
27824
|
}
|
|
27313
27825
|
}
|
|
27314
27826
|
}
|
|
27315
27827
|
if (expr.argument.kind === "Identifier") {
|
|
27316
27828
|
const baseName2 = deSSAVarName(expr.argument.name);
|
|
27317
27829
|
if (ctx.trackedVars.has(baseName2)) {
|
|
27318
|
-
|
|
27319
|
-
const current = t4.callExpression(t4.identifier(baseName2), []);
|
|
27320
|
-
const delta = t4.numericLiteral(1);
|
|
27321
|
-
const next = expr.operator === "++" ? t4.binaryExpression("+", current, delta) : t4.binaryExpression("-", current, delta);
|
|
27322
|
-
return t4.callExpression(id, [next]);
|
|
27830
|
+
return lowerTrackedUpdateCall(t4.identifier(baseName2), expr.operator, expr.prefix);
|
|
27323
27831
|
}
|
|
27324
27832
|
}
|
|
27325
27833
|
return t4.updateExpression(
|
|
@@ -27341,7 +27849,11 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
27341
27849
|
case "NewExpression":
|
|
27342
27850
|
return t4.newExpression(lowerExpression2(expr.callee, ctx), lowerCallArguments(expr.arguments));
|
|
27343
27851
|
case "SequenceExpression":
|
|
27344
|
-
return t4.sequenceExpression(
|
|
27852
|
+
return t4.sequenceExpression(
|
|
27853
|
+
expr.expressions.map(
|
|
27854
|
+
(e, index) => lowerExpression2(e, ctx, index === expr.expressions.length - 1 ? valueUsed : false)
|
|
27855
|
+
)
|
|
27856
|
+
);
|
|
27345
27857
|
case "YieldExpression":
|
|
27346
27858
|
return t4.yieldExpression(
|
|
27347
27859
|
expr.argument ? lowerExpression2(expr.argument, ctx) : null,
|
|
@@ -27799,16 +28311,17 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27799
28311
|
const hasEventOptions = binding.eventOptions && (binding.eventOptions.capture || binding.eventOptions.passive || binding.eventOptions.once);
|
|
27800
28312
|
const isDelegated = DelegatedEvents.has(eventName) && !hasEventOptions;
|
|
27801
28313
|
if (binding.resumable && !hasEventOptions) {
|
|
27802
|
-
emitResumableEventBinding(
|
|
28314
|
+
const emitted = emitResumableEventBinding(
|
|
27803
28315
|
targetId,
|
|
27804
28316
|
eventName,
|
|
27805
28317
|
binding.expr,
|
|
27806
28318
|
statements,
|
|
27807
28319
|
ctx,
|
|
27808
28320
|
containingRegion,
|
|
27809
|
-
createResumableEventBindingOps()
|
|
28321
|
+
createResumableEventBindingOps(),
|
|
28322
|
+
{ explicit: binding.resumableExplicit === true }
|
|
27810
28323
|
);
|
|
27811
|
-
continue;
|
|
28324
|
+
if (emitted) continue;
|
|
27812
28325
|
}
|
|
27813
28326
|
const hirDataBinding = isDelegated && binding.expr ? extractDelegatedEventDataFromHIR(binding.expr, ctx) : null;
|
|
27814
28327
|
if (hirDataBinding) {
|
|
@@ -27850,34 +28363,24 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27850
28363
|
const isFn = t4.isArrowFunctionExpression(valueExpr) || t4.isFunctionExpression(valueExpr);
|
|
27851
28364
|
const ensureHandlerParam = (fn) => {
|
|
27852
28365
|
if (t4.isArrowFunctionExpression(fn)) {
|
|
27853
|
-
|
|
27854
|
-
return t4.arrowFunctionExpression([eventParam], fn.body, fn.async);
|
|
28366
|
+
return fn;
|
|
27855
28367
|
}
|
|
27856
28368
|
if (t4.isFunctionExpression(fn)) {
|
|
27857
|
-
|
|
27858
|
-
return t4.functionExpression(fn.id, [eventParam], fn.body, fn.generator, fn.async);
|
|
28369
|
+
return fn;
|
|
27859
28370
|
}
|
|
27860
28371
|
if (t4.isIdentifier(fn) || t4.isMemberExpression(fn)) {
|
|
27861
28372
|
return fn;
|
|
27862
28373
|
}
|
|
27863
|
-
if (t4.isCallExpression(fn) && fn.arguments.length === 0 && (t4.isIdentifier(fn.callee) || t4.isMemberExpression(fn.callee))) {
|
|
27864
|
-
return fn.callee;
|
|
27865
|
-
}
|
|
27866
28374
|
return t4.functionExpression(
|
|
27867
28375
|
null,
|
|
27868
|
-
[
|
|
27869
|
-
t4.blockStatement([
|
|
27870
|
-
t4.returnStatement(
|
|
27871
|
-
t4.callExpression(
|
|
27872
|
-
t4.memberExpression(fn, t4.identifier("call")),
|
|
27873
|
-
[t4.thisExpression(), eventParam]
|
|
27874
|
-
)
|
|
27875
|
-
)
|
|
27876
|
-
])
|
|
28376
|
+
[],
|
|
28377
|
+
t4.blockStatement([t4.returnStatement(fn)])
|
|
27877
28378
|
);
|
|
27878
28379
|
};
|
|
27879
28380
|
const handlerExpr = !isFn && shouldWrapHandler ? t4.arrowFunctionExpression([], valueExpr) : ensureHandlerParam(valueExpr);
|
|
27880
|
-
let dataBinding = isDelegated && !shouldWrapHandler ? extractDelegatedEventData(valueExpr, t4
|
|
28381
|
+
let dataBinding = isDelegated && !shouldWrapHandler ? extractDelegatedEventData(valueExpr, t4, {
|
|
28382
|
+
isKnownHandlerIdentifier: (name) => ctx.functionVars?.has(deSSAVarName(name)) ?? false
|
|
28383
|
+
}) : null;
|
|
27881
28384
|
if (dataBinding && t4.isIdentifier(dataBinding.handler)) {
|
|
27882
28385
|
const handlerName = dataBinding.handler.name;
|
|
27883
28386
|
if (ctx.signalVars?.has(handlerName) || ctx.memoVars?.has(handlerName) || ctx.aliasVars?.has(handlerName) || ctx.storeVars?.has(handlerName) || ctx.trackedVars.has(handlerName)) {
|
|
@@ -27889,8 +28392,6 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27889
28392
|
let handlerName = null;
|
|
27890
28393
|
if (t4.isIdentifier(valueExpr)) {
|
|
27891
28394
|
handlerName = valueExpr.name;
|
|
27892
|
-
} else if (t4.isCallExpression(valueExpr) && valueExpr.arguments.length === 0 && t4.isIdentifier(valueExpr.callee)) {
|
|
27893
|
-
handlerName = valueExpr.callee.name;
|
|
27894
28395
|
}
|
|
27895
28396
|
const handlerForCall = handlerName ? t4.identifier(handlerName) : t4.cloneNode(valueExpr, true);
|
|
27896
28397
|
const finalHandler = !isFn && shouldWrapHandler ? t4.functionExpression(
|
|
@@ -27906,9 +28407,6 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27906
28407
|
])
|
|
27907
28408
|
) : handlerExpr;
|
|
27908
28409
|
const normalizeHandler = (expr) => {
|
|
27909
|
-
if (t4.isCallExpression(expr) && (t4.isIdentifier(expr.callee) || t4.isMemberExpression(expr.callee))) {
|
|
27910
|
-
return expr.callee;
|
|
27911
|
-
}
|
|
27912
28410
|
return expr;
|
|
27913
28411
|
};
|
|
27914
28412
|
const normalizedDataHandler = dataBinding !== null ? normalizeHandler(
|
|
@@ -30359,11 +30857,27 @@ function optimizeReactiveBlock(block, reactive, purity, options) {
|
|
|
30359
30857
|
const constArrays = /* @__PURE__ */ new Map();
|
|
30360
30858
|
const cseMap = /* @__PURE__ */ new Map();
|
|
30361
30859
|
const instructions = [];
|
|
30860
|
+
const deleteByBase = (map, name) => {
|
|
30861
|
+
const base = getSSABaseName(name);
|
|
30862
|
+
for (const key of Array.from(map.keys())) {
|
|
30863
|
+
if (getSSABaseName(key) === base) {
|
|
30864
|
+
map.delete(key);
|
|
30865
|
+
}
|
|
30866
|
+
}
|
|
30867
|
+
};
|
|
30362
30868
|
const invalidateCSE = (name) => {
|
|
30869
|
+
const base = getSSABaseName(name);
|
|
30363
30870
|
const toDelete = [];
|
|
30364
30871
|
for (const [hash, entry] of cseMap.entries()) {
|
|
30365
|
-
if (entry.name ===
|
|
30872
|
+
if (getSSABaseName(entry.name) === base) {
|
|
30366
30873
|
toDelete.push(hash);
|
|
30874
|
+
continue;
|
|
30875
|
+
}
|
|
30876
|
+
for (const dep of entry.deps) {
|
|
30877
|
+
if (getSSABaseName(dep) === base) {
|
|
30878
|
+
toDelete.push(hash);
|
|
30879
|
+
break;
|
|
30880
|
+
}
|
|
30367
30881
|
}
|
|
30368
30882
|
}
|
|
30369
30883
|
toDelete.forEach((hash) => cseMap.delete(hash));
|
|
@@ -30373,22 +30887,22 @@ function optimizeReactiveBlock(block, reactive, purity, options) {
|
|
|
30373
30887
|
const target = instr.target.name;
|
|
30374
30888
|
const declKind = instr.declarationKind;
|
|
30375
30889
|
invalidateCSE(target);
|
|
30376
|
-
constants
|
|
30377
|
-
constObjects
|
|
30378
|
-
constArrays
|
|
30890
|
+
deleteByBase(constants, target);
|
|
30891
|
+
deleteByBase(constObjects, target);
|
|
30892
|
+
deleteByBase(constArrays, target);
|
|
30379
30893
|
const sideWrites = collectWriteTargets(instr.value);
|
|
30380
30894
|
for (const name of sideWrites) {
|
|
30381
30895
|
if (name !== target) {
|
|
30382
|
-
constants
|
|
30896
|
+
deleteByBase(constants, name);
|
|
30383
30897
|
invalidateCSE(name);
|
|
30384
30898
|
}
|
|
30385
|
-
constObjects
|
|
30386
|
-
constArrays
|
|
30899
|
+
deleteByBase(constObjects, name);
|
|
30900
|
+
deleteByBase(constArrays, name);
|
|
30387
30901
|
}
|
|
30388
30902
|
const memberCalls = collectMemberCallTargets(instr.value);
|
|
30389
30903
|
for (const name of memberCalls) {
|
|
30390
|
-
constObjects
|
|
30391
|
-
constArrays
|
|
30904
|
+
deleteByBase(constObjects, name);
|
|
30905
|
+
deleteByBase(constArrays, name);
|
|
30392
30906
|
}
|
|
30393
30907
|
const dependsOnReactiveValue = expressionDependsOnReactive(instr.value, reactive);
|
|
30394
30908
|
let value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, options, constObjects, constArrays);
|
|
@@ -30428,15 +30942,15 @@ function optimizeReactiveBlock(block, reactive, purity, options) {
|
|
|
30428
30942
|
if (instr.kind === "Expression") {
|
|
30429
30943
|
const writes = collectWriteTargets(instr.value);
|
|
30430
30944
|
for (const name of writes) {
|
|
30431
|
-
constants
|
|
30945
|
+
deleteByBase(constants, name);
|
|
30432
30946
|
invalidateCSE(name);
|
|
30433
|
-
constObjects
|
|
30434
|
-
constArrays
|
|
30947
|
+
deleteByBase(constObjects, name);
|
|
30948
|
+
deleteByBase(constArrays, name);
|
|
30435
30949
|
}
|
|
30436
30950
|
const memberCalls = collectMemberCallTargets(instr.value);
|
|
30437
30951
|
for (const name of memberCalls) {
|
|
30438
|
-
constObjects
|
|
30439
|
-
constArrays
|
|
30952
|
+
deleteByBase(constObjects, name);
|
|
30953
|
+
deleteByBase(constArrays, name);
|
|
30440
30954
|
}
|
|
30441
30955
|
const dependsOnReactiveValue = expressionDependsOnReactive(instr.value, reactive);
|
|
30442
30956
|
const value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, options, constObjects, constArrays);
|
|
@@ -31086,6 +31600,8 @@ function collectWriteTargets(expr) {
|
|
|
31086
31600
|
} else if (left.kind === "MemberExpression" || left.kind === "OptionalMemberExpression") {
|
|
31087
31601
|
const base = getMemberBaseIdentifier(left);
|
|
31088
31602
|
if (base) writes.add(base.name);
|
|
31603
|
+
visit(left.object);
|
|
31604
|
+
if (left.computed) visit(left.property);
|
|
31089
31605
|
} else {
|
|
31090
31606
|
visit(left);
|
|
31091
31607
|
}
|
|
@@ -31102,8 +31618,10 @@ function collectWriteTargets(expr) {
|
|
|
31102
31618
|
const base = getMemberBaseIdentifier(arg);
|
|
31103
31619
|
if (base) {
|
|
31104
31620
|
writes.add(base.name);
|
|
31105
|
-
return;
|
|
31106
31621
|
}
|
|
31622
|
+
visit(arg.object);
|
|
31623
|
+
if (arg.computed) visit(arg.property);
|
|
31624
|
+
return;
|
|
31107
31625
|
}
|
|
31108
31626
|
visit(arg);
|
|
31109
31627
|
return;
|
|
@@ -31409,6 +31927,16 @@ function propagateConstants(fn, options) {
|
|
|
31409
31927
|
}
|
|
31410
31928
|
function computeConstantMap(fn) {
|
|
31411
31929
|
const constants = /* @__PURE__ */ new Map();
|
|
31930
|
+
const invalidateWrittenName = (writtenName) => {
|
|
31931
|
+
const writtenBase = getSSABaseName(writtenName);
|
|
31932
|
+
let removed = false;
|
|
31933
|
+
for (const constantName of Array.from(constants.keys())) {
|
|
31934
|
+
if (constantName === writtenName || getSSABaseName(constantName) === writtenBase) {
|
|
31935
|
+
removed = constants.delete(constantName) || removed;
|
|
31936
|
+
}
|
|
31937
|
+
}
|
|
31938
|
+
return removed;
|
|
31939
|
+
};
|
|
31412
31940
|
let changed = true;
|
|
31413
31941
|
let iterations = 0;
|
|
31414
31942
|
const maxIterations = 10;
|
|
@@ -31417,6 +31945,14 @@ function computeConstantMap(fn) {
|
|
|
31417
31945
|
changed = false;
|
|
31418
31946
|
for (const block of fn.blocks) {
|
|
31419
31947
|
for (const instr of block.instructions) {
|
|
31948
|
+
if (instr.kind === "Assign" || instr.kind === "Expression") {
|
|
31949
|
+
const writes = collectWriteTargets(instr.value);
|
|
31950
|
+
for (const writtenName of writes) {
|
|
31951
|
+
if (invalidateWrittenName(writtenName)) {
|
|
31952
|
+
changed = true;
|
|
31953
|
+
}
|
|
31954
|
+
}
|
|
31955
|
+
}
|
|
31420
31956
|
if (instr.kind === "Assign") {
|
|
31421
31957
|
const value = evaluateConstant(instr.value, constants);
|
|
31422
31958
|
if (value !== UNKNOWN_CONST) {
|