@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.js
CHANGED
|
@@ -19927,15 +19927,38 @@ function buildEffectCall(ctx, t4, effectFn, options) {
|
|
|
19927
19927
|
}
|
|
19928
19928
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.useEffect), args);
|
|
19929
19929
|
}
|
|
19930
|
-
function buildMemoCall(ctx, t4, memoFn,
|
|
19930
|
+
function buildMemoCall(ctx, t4, memoFn, options) {
|
|
19931
|
+
const slot = options?.slot;
|
|
19932
|
+
const memoOptionsProperties = [];
|
|
19933
|
+
if (options?.name) {
|
|
19934
|
+
memoOptionsProperties.push(
|
|
19935
|
+
t4.objectProperty(t4.identifier("name"), t4.stringLiteral(options.name))
|
|
19936
|
+
);
|
|
19937
|
+
}
|
|
19938
|
+
if (options?.source) {
|
|
19939
|
+
memoOptionsProperties.push(
|
|
19940
|
+
t4.objectProperty(t4.identifier("devToolsSource"), t4.stringLiteral(options.source))
|
|
19941
|
+
);
|
|
19942
|
+
}
|
|
19943
|
+
if (options?.internal) {
|
|
19944
|
+
memoOptionsProperties.push(t4.objectProperty(t4.identifier("internal"), t4.booleanLiteral(true)));
|
|
19945
|
+
}
|
|
19946
|
+
const memoOptions = memoOptionsProperties.length > 0 ? t4.objectExpression(memoOptionsProperties) : null;
|
|
19931
19947
|
if (ctx.inModule) {
|
|
19932
19948
|
ctx.helpersUsed.add("memo");
|
|
19933
|
-
|
|
19949
|
+
const args2 = [memoFn];
|
|
19950
|
+
if (memoOptions) args2.push(memoOptions);
|
|
19951
|
+
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.memo), args2);
|
|
19934
19952
|
}
|
|
19935
19953
|
ctx.helpersUsed.add("useMemo");
|
|
19936
19954
|
ctx.needsCtx = true;
|
|
19937
19955
|
const args = [t4.identifier("__fictCtx"), memoFn];
|
|
19938
|
-
if (
|
|
19956
|
+
if (memoOptions) {
|
|
19957
|
+
args.push(memoOptions);
|
|
19958
|
+
if (slot !== void 0 && slot >= 0) {
|
|
19959
|
+
args.push(t4.numericLiteral(slot));
|
|
19960
|
+
}
|
|
19961
|
+
} else if (slot !== void 0 && slot >= 0) {
|
|
19939
19962
|
args.push(t4.numericLiteral(slot));
|
|
19940
19963
|
}
|
|
19941
19964
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.useMemo), args);
|
|
@@ -21196,7 +21219,10 @@ function wrapInMemo(region, t4, declaredVars, ctx, bodyStatementsOverride, outpu
|
|
|
21196
21219
|
const returnObj = t4.objectExpression(uniqueOutputNames.map((name) => buildOutputProperty(name)));
|
|
21197
21220
|
const memoBody = t4.blockStatement([...bodyStatements, t4.returnStatement(returnObj)]);
|
|
21198
21221
|
const slot = ctx.inModule ? void 0 : reserveHookSlot(ctx);
|
|
21199
|
-
const memoCall = buildMemoCall(ctx, t4, t4.arrowFunctionExpression([], memoBody),
|
|
21222
|
+
const memoCall = buildMemoCall(ctx, t4, t4.arrowFunctionExpression([], memoBody), {
|
|
21223
|
+
slot,
|
|
21224
|
+
internal: true
|
|
21225
|
+
});
|
|
21200
21226
|
const regionVarName = `__region_${region.id}`;
|
|
21201
21227
|
statements.push(
|
|
21202
21228
|
t4.variableDeclaration("const", [t4.variableDeclarator(t4.identifier(regionVarName), memoCall)])
|
|
@@ -21455,7 +21481,10 @@ function generateLazyConditionalMemo(region, orderedOutputs, bodyStatements, con
|
|
|
21455
21481
|
ctx,
|
|
21456
21482
|
t4,
|
|
21457
21483
|
t4.arrowFunctionExpression([], t4.blockStatement(memoBody)),
|
|
21458
|
-
|
|
21484
|
+
{
|
|
21485
|
+
slot: ctx.inModule ? void 0 : reserveHookSlot(ctx),
|
|
21486
|
+
internal: true
|
|
21487
|
+
}
|
|
21459
21488
|
);
|
|
21460
21489
|
statements.push(
|
|
21461
21490
|
t4.variableDeclaration("const", [t4.variableDeclarator(t4.identifier(regionVarName), memoCall)])
|
|
@@ -21568,7 +21597,12 @@ Context: ${location}`
|
|
|
21568
21597
|
};
|
|
21569
21598
|
const buildDerivedMemoCall = (expr) => {
|
|
21570
21599
|
const slot = !ctx.inModule && inRegionMemo ? reserveHookSlot(ctx) : void 0;
|
|
21571
|
-
|
|
21600
|
+
const source = ctx.options?.dev !== false && instr.loc ? `${ctx.options?.filename ?? ""}:${instr.loc.start.line}:${instr.loc.start.column}` : void 0;
|
|
21601
|
+
return buildMemoCall(ctx, t4, t4.arrowFunctionExpression([], expr), {
|
|
21602
|
+
slot,
|
|
21603
|
+
name: baseName2,
|
|
21604
|
+
source
|
|
21605
|
+
});
|
|
21572
21606
|
};
|
|
21573
21607
|
if (isShadowDeclaration && declKind) {
|
|
21574
21608
|
ctx.trackedVars.delete(baseName2);
|
|
@@ -22930,7 +22964,7 @@ function expressionUsesIdentifier(expr, name, t4) {
|
|
|
22930
22964
|
visit(expr);
|
|
22931
22965
|
return found;
|
|
22932
22966
|
}
|
|
22933
|
-
function extractDelegatedEventData(expr, t4) {
|
|
22967
|
+
function extractDelegatedEventData(expr, t4, options) {
|
|
22934
22968
|
const isSimpleHandler = t4.isIdentifier(expr) || t4.isMemberExpression(expr);
|
|
22935
22969
|
if (isSimpleHandler) {
|
|
22936
22970
|
return { handler: expr };
|
|
@@ -22943,6 +22977,9 @@ function extractDelegatedEventData(expr, t4) {
|
|
|
22943
22977
|
if (!bodyExpr || !t4.isCallExpression(bodyExpr)) return null;
|
|
22944
22978
|
if (paramNames.some((name) => expressionUsesIdentifier(bodyExpr, name, t4))) return null;
|
|
22945
22979
|
if (!t4.isIdentifier(bodyExpr.callee)) return null;
|
|
22980
|
+
if (options?.isKnownHandlerIdentifier && !options.isKnownHandlerIdentifier(bodyExpr.callee.name)) {
|
|
22981
|
+
return null;
|
|
22982
|
+
}
|
|
22946
22983
|
if (bodyExpr.arguments.length === 0) return null;
|
|
22947
22984
|
if (bodyExpr.arguments.length > 1) return null;
|
|
22948
22985
|
const dataArg = bodyExpr.arguments[0];
|
|
@@ -23005,6 +23042,10 @@ function extractDelegatedEventDataFromHIR(expr, ctx) {
|
|
|
23005
23042
|
return null;
|
|
23006
23043
|
}
|
|
23007
23044
|
const handlerName = callee.name;
|
|
23045
|
+
const normalizedHandlerName = deSSAVarName(handlerName);
|
|
23046
|
+
if (!ctx.functionVars?.has(normalizedHandlerName)) {
|
|
23047
|
+
return null;
|
|
23048
|
+
}
|
|
23008
23049
|
if (ctx.signalVars?.has(handlerName) || ctx.memoVars?.has(handlerName) || ctx.aliasVars?.has(handlerName) || ctx.storeVars?.has(handlerName) || ctx.trackedVars.has(handlerName)) {
|
|
23009
23050
|
return null;
|
|
23010
23051
|
}
|
|
@@ -23015,7 +23056,10 @@ function extractDelegatedEventDataFromHIR(expr, ctx) {
|
|
|
23015
23056
|
if (isTrackedAccessor) {
|
|
23016
23057
|
return null;
|
|
23017
23058
|
}
|
|
23018
|
-
const paramNames = new Set(expr.params.map((p) => p.name));
|
|
23059
|
+
const paramNames = new Set(expr.params.map((p) => deSSAVarName(p.name)));
|
|
23060
|
+
if (paramNames.has(deSSAVarName(callee.name))) {
|
|
23061
|
+
return null;
|
|
23062
|
+
}
|
|
23019
23063
|
const dataExpr = bodyExpr.arguments[0];
|
|
23020
23064
|
if (!dataExpr) {
|
|
23021
23065
|
return null;
|
|
@@ -24182,8 +24226,8 @@ function getDependencyPathFromNode(node, t4) {
|
|
|
24182
24226
|
}
|
|
24183
24227
|
return null;
|
|
24184
24228
|
}
|
|
24185
|
-
function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parentKey, skipCurrentNode = false) {
|
|
24186
|
-
const isCallTarget = parentKey === "callee" && (parentKind === "CallExpression" || parentKind === "OptionalCallExpression");
|
|
24229
|
+
function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parentKey, skipCurrentNode = false, allowCallCalleeReplacement = false) {
|
|
24230
|
+
const isCallTarget = !allowCallCalleeReplacement && parentKey === "callee" && (parentKind === "CallExpression" || parentKind === "OptionalCallExpression");
|
|
24187
24231
|
if (parentKind === "VariableDeclarator" && parentKey === "id") {
|
|
24188
24232
|
return;
|
|
24189
24233
|
}
|
|
@@ -24255,9 +24299,25 @@ function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parent
|
|
|
24255
24299
|
}
|
|
24256
24300
|
}
|
|
24257
24301
|
if (t4.isBlockStatement(node.body)) {
|
|
24258
|
-
replaceIdentifiersWithOverrides(
|
|
24302
|
+
replaceIdentifiersWithOverrides(
|
|
24303
|
+
node.body,
|
|
24304
|
+
scopedOverrides,
|
|
24305
|
+
t4,
|
|
24306
|
+
node.type,
|
|
24307
|
+
"body",
|
|
24308
|
+
false,
|
|
24309
|
+
allowCallCalleeReplacement
|
|
24310
|
+
);
|
|
24259
24311
|
} else {
|
|
24260
|
-
replaceIdentifiersWithOverrides(
|
|
24312
|
+
replaceIdentifiersWithOverrides(
|
|
24313
|
+
node.body,
|
|
24314
|
+
scopedOverrides,
|
|
24315
|
+
t4,
|
|
24316
|
+
node.type,
|
|
24317
|
+
"body",
|
|
24318
|
+
false,
|
|
24319
|
+
allowCallCalleeReplacement
|
|
24320
|
+
);
|
|
24261
24321
|
}
|
|
24262
24322
|
return;
|
|
24263
24323
|
}
|
|
@@ -24285,12 +24345,21 @@ function replaceIdentifiersWithOverrides(node, overrides, t4, parentKind, parent
|
|
|
24285
24345
|
t4,
|
|
24286
24346
|
node.type,
|
|
24287
24347
|
key,
|
|
24288
|
-
false
|
|
24348
|
+
false,
|
|
24349
|
+
allowCallCalleeReplacement
|
|
24289
24350
|
);
|
|
24290
24351
|
}
|
|
24291
24352
|
}
|
|
24292
24353
|
} else if (value && typeof value === "object" && "type" in value) {
|
|
24293
|
-
replaceIdentifiersWithOverrides(
|
|
24354
|
+
replaceIdentifiersWithOverrides(
|
|
24355
|
+
value,
|
|
24356
|
+
overrides,
|
|
24357
|
+
t4,
|
|
24358
|
+
node.type,
|
|
24359
|
+
key,
|
|
24360
|
+
false,
|
|
24361
|
+
allowCallCalleeReplacement
|
|
24362
|
+
);
|
|
24294
24363
|
}
|
|
24295
24364
|
}
|
|
24296
24365
|
}
|
|
@@ -24563,6 +24632,124 @@ function applySelectorHoist(callbackExpr, itemParamName, keyParamName, statement
|
|
|
24563
24632
|
}
|
|
24564
24633
|
|
|
24565
24634
|
// src/ir/codegen-list-child.ts
|
|
24635
|
+
function getCallbackBlocks(callback) {
|
|
24636
|
+
if (callback.kind === "FunctionExpression") {
|
|
24637
|
+
return callback.body;
|
|
24638
|
+
}
|
|
24639
|
+
if (callback.kind === "ArrowFunction" && Array.isArray(callback.body)) {
|
|
24640
|
+
return callback.body;
|
|
24641
|
+
}
|
|
24642
|
+
return [];
|
|
24643
|
+
}
|
|
24644
|
+
function collectMapCallbackAliasDeclarations(callback) {
|
|
24645
|
+
const blocks = getCallbackBlocks(callback);
|
|
24646
|
+
if (blocks.length === 0) {
|
|
24647
|
+
return /* @__PURE__ */ new Map();
|
|
24648
|
+
}
|
|
24649
|
+
const paramNames = callback.kind === "ArrowFunction" || callback.kind === "FunctionExpression" ? new Set(callback.params.map((param) => param.name)) : /* @__PURE__ */ new Set();
|
|
24650
|
+
const declarationState = /* @__PURE__ */ new Map();
|
|
24651
|
+
for (const block of blocks) {
|
|
24652
|
+
for (const instr of block.instructions) {
|
|
24653
|
+
if (instr.kind !== "Assign" || instr.target.kind !== "Identifier") {
|
|
24654
|
+
continue;
|
|
24655
|
+
}
|
|
24656
|
+
const name = instr.target.name;
|
|
24657
|
+
if (paramNames.has(name)) continue;
|
|
24658
|
+
const isDeclaration = !!instr.declarationKind;
|
|
24659
|
+
const previous = declarationState.get(name);
|
|
24660
|
+
if (previous) {
|
|
24661
|
+
declarationState.set(name, {
|
|
24662
|
+
declarationCount: previous.declarationCount + (isDeclaration ? 1 : 0),
|
|
24663
|
+
hasNonDeclarationWrite: previous.hasNonDeclarationWrite || !isDeclaration,
|
|
24664
|
+
declarationValue: previous.declarationValue,
|
|
24665
|
+
lastAssignedValue: instr.value
|
|
24666
|
+
});
|
|
24667
|
+
} else {
|
|
24668
|
+
declarationState.set(name, {
|
|
24669
|
+
declarationCount: isDeclaration ? 1 : 0,
|
|
24670
|
+
hasNonDeclarationWrite: !isDeclaration,
|
|
24671
|
+
declarationValue: isDeclaration ? instr.value : null,
|
|
24672
|
+
lastAssignedValue: instr.value
|
|
24673
|
+
});
|
|
24674
|
+
}
|
|
24675
|
+
}
|
|
24676
|
+
}
|
|
24677
|
+
const aliasMap = /* @__PURE__ */ new Map();
|
|
24678
|
+
const effectiveBlocks = blocks.filter(
|
|
24679
|
+
(block) => block.instructions.length > 0 || block.terminator.kind !== "Unreachable"
|
|
24680
|
+
);
|
|
24681
|
+
const isSingleLinearBlock = effectiveBlocks.length === 1 && effectiveBlocks[0].terminator.kind === "Return";
|
|
24682
|
+
for (const [name, state] of declarationState) {
|
|
24683
|
+
if (isSingleLinearBlock) {
|
|
24684
|
+
if (state.declarationCount <= 1) {
|
|
24685
|
+
aliasMap.set(name, state.lastAssignedValue);
|
|
24686
|
+
}
|
|
24687
|
+
continue;
|
|
24688
|
+
}
|
|
24689
|
+
if (state.declarationCount === 1 && !state.hasNonDeclarationWrite && state.declarationValue) {
|
|
24690
|
+
aliasMap.set(name, state.declarationValue);
|
|
24691
|
+
}
|
|
24692
|
+
}
|
|
24693
|
+
return aliasMap;
|
|
24694
|
+
}
|
|
24695
|
+
function resolveMapCallbackKeyExpression(keyExpr, callback) {
|
|
24696
|
+
if (keyExpr.kind !== "Identifier") {
|
|
24697
|
+
return keyExpr;
|
|
24698
|
+
}
|
|
24699
|
+
const aliasMap = collectMapCallbackAliasDeclarations(callback);
|
|
24700
|
+
if (aliasMap.size === 0) {
|
|
24701
|
+
return keyExpr;
|
|
24702
|
+
}
|
|
24703
|
+
let resolved = keyExpr;
|
|
24704
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24705
|
+
while (resolved.kind === "Identifier") {
|
|
24706
|
+
const next = aliasMap.get(resolved.name);
|
|
24707
|
+
if (!next || seen.has(resolved.name)) break;
|
|
24708
|
+
seen.add(resolved.name);
|
|
24709
|
+
resolved = next;
|
|
24710
|
+
}
|
|
24711
|
+
return resolved;
|
|
24712
|
+
}
|
|
24713
|
+
function collectMapCallbackLocalNames(callback) {
|
|
24714
|
+
const blocks = getCallbackBlocks(callback);
|
|
24715
|
+
if (blocks.length === 0) {
|
|
24716
|
+
return /* @__PURE__ */ new Set();
|
|
24717
|
+
}
|
|
24718
|
+
const paramNames = callback.kind === "ArrowFunction" || callback.kind === "FunctionExpression" ? new Set(callback.params.map((param) => deSSAVarName(param.name))) : /* @__PURE__ */ new Set();
|
|
24719
|
+
const locals = /* @__PURE__ */ new Set();
|
|
24720
|
+
for (const block of blocks) {
|
|
24721
|
+
for (const instr of block.instructions) {
|
|
24722
|
+
if (instr.kind === "Assign" && instr.target.kind === "Identifier") {
|
|
24723
|
+
const name = deSSAVarName(instr.target.name);
|
|
24724
|
+
if (!paramNames.has(name)) locals.add(name);
|
|
24725
|
+
}
|
|
24726
|
+
if (instr.kind === "Phi" && instr.target.kind === "Identifier") {
|
|
24727
|
+
const name = deSSAVarName(instr.target.name);
|
|
24728
|
+
if (!paramNames.has(name)) locals.add(name);
|
|
24729
|
+
}
|
|
24730
|
+
}
|
|
24731
|
+
}
|
|
24732
|
+
return locals;
|
|
24733
|
+
}
|
|
24734
|
+
function hasUnresolvedCallbackLocalKeyDependencies(keyExpr, callback, keyAliasDeclarations) {
|
|
24735
|
+
const callbackLocals = collectMapCallbackLocalNames(callback);
|
|
24736
|
+
if (callbackLocals.size === 0) {
|
|
24737
|
+
return false;
|
|
24738
|
+
}
|
|
24739
|
+
const resolvableAliases = new Set(
|
|
24740
|
+
Array.from(keyAliasDeclarations.keys()).map((name) => deSSAVarName(name))
|
|
24741
|
+
);
|
|
24742
|
+
const deps = /* @__PURE__ */ new Set();
|
|
24743
|
+
collectExpressionDependencies(keyExpr, deps);
|
|
24744
|
+
for (const dep of deps) {
|
|
24745
|
+
const base = dep.split(".")[0] ?? dep;
|
|
24746
|
+
if (!base) continue;
|
|
24747
|
+
if (callbackLocals.has(base) && !resolvableAliases.has(base)) {
|
|
24748
|
+
return true;
|
|
24749
|
+
}
|
|
24750
|
+
}
|
|
24751
|
+
return false;
|
|
24752
|
+
}
|
|
24566
24753
|
function buildListCallExpression(expr, statements, ctx, ops) {
|
|
24567
24754
|
const { t: t4 } = ctx;
|
|
24568
24755
|
if (expr.kind !== "CallExpression" && expr.kind !== "OptionalCallExpression") {
|
|
@@ -24581,7 +24768,8 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24581
24768
|
if (!mapCallback) {
|
|
24582
24769
|
throw new Error("map callback is required");
|
|
24583
24770
|
}
|
|
24584
|
-
const
|
|
24771
|
+
const extractedKeyExpr = extractKeyFromMapCallback(mapCallback);
|
|
24772
|
+
const keyExpr = extractedKeyExpr ? resolveMapCallbackKeyExpression(extractedKeyExpr, mapCallback) : void 0;
|
|
24585
24773
|
const isKeyed = !!keyExpr;
|
|
24586
24774
|
const hasRestParam = (mapCallback.kind === "ArrowFunction" || mapCallback.kind === "FunctionExpression") && Array.isArray(mapCallback.rawParams) && mapCallback.rawParams.some((param) => t4.isRestElement(param));
|
|
24587
24775
|
const canConstifyKey = isKeyed && keyExpr && !hasRestParam;
|
|
@@ -24632,7 +24820,7 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24632
24820
|
if (Object.keys(overrides).length > 0) {
|
|
24633
24821
|
if (t4.isBlockStatement(callbackExpr.body)) {
|
|
24634
24822
|
for (const stmt of callbackExpr.body.body) {
|
|
24635
|
-
if (!t4.isVariableDeclaration(stmt)) continue;
|
|
24823
|
+
if (!t4.isVariableDeclaration(stmt) || stmt.kind !== "const") continue;
|
|
24636
24824
|
for (const decl of stmt.declarations) {
|
|
24637
24825
|
if (!t4.isIdentifier(decl.id) || !decl.init) continue;
|
|
24638
24826
|
const replacement = t4.cloneNode(decl.init, true);
|
|
@@ -24662,7 +24850,32 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24662
24850
|
}
|
|
24663
24851
|
let listCall;
|
|
24664
24852
|
if (isKeyed && keyExpr) {
|
|
24853
|
+
const keyAliasDeclarations = collectMapCallbackAliasDeclarations(mapCallback);
|
|
24854
|
+
const hasUnresolvedLocalKeyDeps = hasUnresolvedCallbackLocalKeyDependencies(
|
|
24855
|
+
keyExpr,
|
|
24856
|
+
mapCallback,
|
|
24857
|
+
keyAliasDeclarations
|
|
24858
|
+
);
|
|
24665
24859
|
let keyExprAst = ops.lowerExpression(keyExpr, ctx);
|
|
24860
|
+
if (keyAliasDeclarations.size > 0) {
|
|
24861
|
+
const keyOverrides = {};
|
|
24862
|
+
for (const [name, value] of keyAliasDeclarations) {
|
|
24863
|
+
const replacement = ops.lowerExpression(value, ctx);
|
|
24864
|
+
replaceIdentifiersWithOverrides(replacement, keyOverrides, t4);
|
|
24865
|
+
keyOverrides[name] = () => t4.cloneNode(replacement, true);
|
|
24866
|
+
}
|
|
24867
|
+
if (Object.keys(keyOverrides).length > 0) {
|
|
24868
|
+
replaceIdentifiersWithOverrides(
|
|
24869
|
+
keyExprAst,
|
|
24870
|
+
keyOverrides,
|
|
24871
|
+
t4,
|
|
24872
|
+
void 0,
|
|
24873
|
+
void 0,
|
|
24874
|
+
false,
|
|
24875
|
+
true
|
|
24876
|
+
);
|
|
24877
|
+
}
|
|
24878
|
+
}
|
|
24666
24879
|
if (t4.isArrowFunctionExpression(callbackExpr) || t4.isFunctionExpression(callbackExpr)) {
|
|
24667
24880
|
const itemParam = callbackExpr.params[0];
|
|
24668
24881
|
const indexParam = callbackExpr.params[1];
|
|
@@ -24676,6 +24889,9 @@ function buildListCallExpression(expr, statements, ctx, ops) {
|
|
|
24676
24889
|
}
|
|
24677
24890
|
const itemParamName = t4.isArrowFunctionExpression(callbackExpr) || t4.isFunctionExpression(callbackExpr) ? callbackExpr.params[0] : null;
|
|
24678
24891
|
const indexParamName = t4.isArrowFunctionExpression(callbackExpr) || t4.isFunctionExpression(callbackExpr) ? callbackExpr.params[1] : null;
|
|
24892
|
+
if (hasUnresolvedLocalKeyDeps) {
|
|
24893
|
+
keyExprAst = t4.identifier(t4.isIdentifier(indexParamName) ? indexParamName.name : "__index");
|
|
24894
|
+
}
|
|
24679
24895
|
const keyFn = t4.arrowFunctionExpression(
|
|
24680
24896
|
[
|
|
24681
24897
|
t4.isIdentifier(itemParamName) ? itemParamName : t4.identifier("__item"),
|
|
@@ -25117,33 +25333,42 @@ function dependencyCoveredByDeclarations(dep, region) {
|
|
|
25117
25333
|
|
|
25118
25334
|
// src/ir/codegen-resumable-utils.ts
|
|
25119
25335
|
import { pathToFileURL } from "url";
|
|
25120
|
-
|
|
25121
|
-
|
|
25122
|
-
|
|
25123
|
-
|
|
25124
|
-
|
|
25125
|
-
|
|
25126
|
-
|
|
25127
|
-
|
|
25128
|
-
|
|
25129
|
-
|
|
25130
|
-
|
|
25131
|
-
|
|
25132
|
-
|
|
25133
|
-
|
|
25134
|
-
}
|
|
25135
|
-
const value = n[key];
|
|
25136
|
-
if (Array.isArray(value)) {
|
|
25137
|
-
for (const item of value) {
|
|
25138
|
-
visit(item);
|
|
25139
|
-
}
|
|
25140
|
-
} else if (value && typeof value === "object") {
|
|
25141
|
-
visit(value);
|
|
25336
|
+
import traverseModule2 from "@babel/traverse";
|
|
25337
|
+
function renameIdentifiersInExpr(expr, renames, t4) {
|
|
25338
|
+
const traverse = traverseModule2.default ?? traverseModule2;
|
|
25339
|
+
const cloned = t4.cloneNode(expr, true);
|
|
25340
|
+
const file = t4.file(t4.program([t4.expressionStatement(cloned)]));
|
|
25341
|
+
traverse(file, {
|
|
25342
|
+
Identifier(path2) {
|
|
25343
|
+
const oldName = path2.node.name;
|
|
25344
|
+
const nextName = renames.get(oldName);
|
|
25345
|
+
if (!nextName) return;
|
|
25346
|
+
if (path2.parentPath.isObjectProperty() && path2.parentPath.node.shorthand && path2.parentPath.node.value === path2.node && t4.isIdentifier(path2.parentPath.node.key)) {
|
|
25347
|
+
path2.parentPath.node.shorthand = false;
|
|
25348
|
+
path2.parentPath.node.value = t4.identifier(nextName);
|
|
25349
|
+
return;
|
|
25142
25350
|
}
|
|
25351
|
+
if (!path2.isReferencedIdentifier()) return;
|
|
25352
|
+
const binding = path2.scope.getBinding(oldName);
|
|
25353
|
+
if (binding && binding.scope !== path2.scope.getProgramParent()) return;
|
|
25354
|
+
path2.node.name = nextName;
|
|
25143
25355
|
}
|
|
25144
|
-
}
|
|
25145
|
-
|
|
25146
|
-
return cloned;
|
|
25356
|
+
});
|
|
25357
|
+
const first = file.program.body[0];
|
|
25358
|
+
return t4.isExpressionStatement(first) ? first.expression : cloned;
|
|
25359
|
+
}
|
|
25360
|
+
function collectFreeIdentifiersInExpr(expr, t4) {
|
|
25361
|
+
const traverse = traverseModule2.default ?? traverseModule2;
|
|
25362
|
+
const file = t4.file(t4.program([t4.expressionStatement(t4.cloneNode(expr, true))]));
|
|
25363
|
+
const names = /* @__PURE__ */ new Set();
|
|
25364
|
+
traverse(file, {
|
|
25365
|
+
ReferencedIdentifier(path2) {
|
|
25366
|
+
const name = path2.node.name;
|
|
25367
|
+
if (path2.scope.getBinding(name)) return;
|
|
25368
|
+
names.add(name);
|
|
25369
|
+
}
|
|
25370
|
+
});
|
|
25371
|
+
return names;
|
|
25147
25372
|
}
|
|
25148
25373
|
function genModuleUrlExpr(ctx) {
|
|
25149
25374
|
const { t: t4 } = ctx;
|
|
@@ -25280,10 +25505,10 @@ function registerResumableComponent(componentName, ctx) {
|
|
|
25280
25505
|
}
|
|
25281
25506
|
|
|
25282
25507
|
// src/ir/codegen-resumable-events.ts
|
|
25283
|
-
function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, containingRegion, ops) {
|
|
25508
|
+
function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, containingRegion, ops, options) {
|
|
25284
25509
|
const { t: t4 } = ctx;
|
|
25285
25510
|
if (!ctx.resumableEnabled) {
|
|
25286
|
-
return;
|
|
25511
|
+
return false;
|
|
25287
25512
|
}
|
|
25288
25513
|
const prevWrapTracked = ctx.wrapTrackedExpressions;
|
|
25289
25514
|
ctx.wrapTrackedExpressions = false;
|
|
@@ -25297,53 +25522,88 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25297
25522
|
const scopeParam = t4.identifier("scopeId");
|
|
25298
25523
|
const ensureHandlerParam = (fn) => {
|
|
25299
25524
|
if (t4.isArrowFunctionExpression(fn)) {
|
|
25300
|
-
|
|
25301
|
-
return t4.arrowFunctionExpression([eventParam], fn.body, fn.async);
|
|
25525
|
+
return fn;
|
|
25302
25526
|
}
|
|
25303
25527
|
if (t4.isFunctionExpression(fn)) {
|
|
25304
|
-
|
|
25305
|
-
return t4.functionExpression(fn.id, [eventParam], fn.body, fn.generator, fn.async);
|
|
25528
|
+
return fn;
|
|
25306
25529
|
}
|
|
25307
25530
|
if (t4.isIdentifier(fn) || t4.isMemberExpression(fn)) {
|
|
25308
25531
|
return fn;
|
|
25309
25532
|
}
|
|
25310
|
-
if (t4.isCallExpression(fn) && fn.arguments.length === 0 && (t4.isIdentifier(fn.callee) || t4.isMemberExpression(fn.callee))) {
|
|
25311
|
-
return fn.callee;
|
|
25312
|
-
}
|
|
25313
25533
|
return t4.functionExpression(
|
|
25314
25534
|
null,
|
|
25315
|
-
[
|
|
25316
|
-
t4.blockStatement([
|
|
25317
|
-
t4.returnStatement(
|
|
25318
|
-
t4.callExpression(
|
|
25319
|
-
t4.memberExpression(fn, t4.identifier("call")),
|
|
25320
|
-
[t4.thisExpression(), eventParam]
|
|
25321
|
-
)
|
|
25322
|
-
)
|
|
25323
|
-
])
|
|
25535
|
+
[],
|
|
25536
|
+
t4.blockStatement([t4.returnStatement(fn)])
|
|
25324
25537
|
);
|
|
25325
25538
|
};
|
|
25326
25539
|
const handlerExpr = ensureHandlerParam(valueExpr);
|
|
25327
25540
|
const handlerId = t4.identifier(`__fict_e${ctx.resumableHandlerCounter ?? 0}`);
|
|
25328
25541
|
ctx.resumableHandlerCounter = (ctx.resumableHandlerCounter ?? 0) + 1;
|
|
25329
|
-
const captured =
|
|
25330
|
-
collectExpressionIdentifiersDeep(expr, captured);
|
|
25542
|
+
const captured = collectFreeIdentifiersInExpr(handlerExpr, t4);
|
|
25331
25543
|
const lexicalNames = Array.from(captured).filter((name) => ctx.signalVars?.has(name));
|
|
25332
25544
|
const propsName = ctx.propsParamName && captured.has(ctx.propsParamName) ? ctx.propsParamName : null;
|
|
25545
|
+
const unsupportedLocals = Array.from(captured).filter((name) => {
|
|
25546
|
+
if (ctx.inListRender && ctx.listKeyParamName && name === ctx.listKeyParamName) return true;
|
|
25547
|
+
if (!ctx.localDeclaredNames?.has(name)) return false;
|
|
25548
|
+
if (ctx.signalVars?.has(name)) return false;
|
|
25549
|
+
if (ctx.functionVars?.has(name)) return false;
|
|
25550
|
+
if (propsName && name === propsName) return false;
|
|
25551
|
+
return true;
|
|
25552
|
+
});
|
|
25553
|
+
const loweredFunctionDeps = /* @__PURE__ */ new Map();
|
|
25554
|
+
const unsafeFunctionCaptures = [];
|
|
25555
|
+
for (const name of captured) {
|
|
25556
|
+
if (!ctx.functionVars?.has(name) || ctx.signalVars?.has(name)) continue;
|
|
25557
|
+
if (ctx.hoistedFunctionDepNames?.has(name)) continue;
|
|
25558
|
+
const hirDef = ctx.componentFunctionDefs?.get(name);
|
|
25559
|
+
if (!hirDef) {
|
|
25560
|
+
if (ctx.localDeclaredNames?.has(name)) {
|
|
25561
|
+
unsafeFunctionCaptures.push(`${name} -> <unhoistable>`);
|
|
25562
|
+
}
|
|
25563
|
+
continue;
|
|
25564
|
+
}
|
|
25565
|
+
const loweredFn = ops.lowerDomExpression(hirDef, ctx, null, {
|
|
25566
|
+
skipHookAccessors: true,
|
|
25567
|
+
skipRegionRootOverride: true
|
|
25568
|
+
});
|
|
25569
|
+
const fnCaptured = collectFreeIdentifiersInExpr(loweredFn, t4);
|
|
25570
|
+
const localFnCaptures = Array.from(fnCaptured).filter((dep) => ctx.localDeclaredNames?.has(dep)).sort();
|
|
25571
|
+
if (localFnCaptures.length > 0) {
|
|
25572
|
+
unsafeFunctionCaptures.push(`${name} -> ${localFnCaptures.join(", ")}`);
|
|
25573
|
+
continue;
|
|
25574
|
+
}
|
|
25575
|
+
loweredFunctionDeps.set(name, loweredFn);
|
|
25576
|
+
}
|
|
25577
|
+
if (unsupportedLocals.length > 0 || unsafeFunctionCaptures.length > 0) {
|
|
25578
|
+
const detailParts = [];
|
|
25579
|
+
if (unsupportedLocals.length > 0) {
|
|
25580
|
+
detailParts.push(`direct: ${unsupportedLocals.sort().join(", ")}`);
|
|
25581
|
+
}
|
|
25582
|
+
if (unsafeFunctionCaptures.length > 0) {
|
|
25583
|
+
detailParts.push(`function deps: ${unsafeFunctionCaptures.sort().join("; ")}`);
|
|
25584
|
+
}
|
|
25585
|
+
const detail = `Resumable handlers cannot capture non-serializable local variables (${detailParts.join(" | ")}).`;
|
|
25586
|
+
if (options?.explicit) {
|
|
25587
|
+
const loc = expr.loc?.start;
|
|
25588
|
+
const fileName = ctx.options?.filename ?? "<unknown>";
|
|
25589
|
+
const location = loc ? `${fileName}:${loc.line}:${loc.column + 1}` : fileName;
|
|
25590
|
+
throw new Error(
|
|
25591
|
+
`${detail} Use signals/props/function references or remove '$' suffix.
|
|
25592
|
+
at ${location}`
|
|
25593
|
+
);
|
|
25594
|
+
}
|
|
25595
|
+
return false;
|
|
25596
|
+
}
|
|
25333
25597
|
const functionDepRenames = /* @__PURE__ */ new Map();
|
|
25334
25598
|
for (const name of captured) {
|
|
25335
25599
|
if (ctx.functionVars?.has(name) && !ctx.signalVars?.has(name)) {
|
|
25336
|
-
const hirDef = ctx.componentFunctionDefs?.get(name);
|
|
25337
|
-
if (!hirDef) continue;
|
|
25338
25600
|
let hoistedName = ctx.hoistedFunctionDepNames?.get(name);
|
|
25339
25601
|
if (!hoistedName) {
|
|
25602
|
+
const loweredFn = loweredFunctionDeps.get(name);
|
|
25603
|
+
if (!loweredFn) continue;
|
|
25340
25604
|
hoistedName = `__fict_fn_${name}_${ctx.hoistedFunctionDepCounter ?? 0}`;
|
|
25341
25605
|
ctx.hoistedFunctionDepCounter = (ctx.hoistedFunctionDepCounter ?? 0) + 1;
|
|
25342
25606
|
ctx.hoistedFunctionDepNames?.set(name, hoistedName);
|
|
25343
|
-
const loweredFn = ops.lowerDomExpression(hirDef, ctx, null, {
|
|
25344
|
-
skipHookAccessors: true,
|
|
25345
|
-
skipRegionRootOverride: true
|
|
25346
|
-
});
|
|
25347
25607
|
const hoistedDecl = t4.variableDeclaration("const", [
|
|
25348
25608
|
t4.variableDeclarator(t4.identifier(hoistedName), loweredFn)
|
|
25349
25609
|
]);
|
|
@@ -25355,7 +25615,7 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25355
25615
|
}
|
|
25356
25616
|
let finalHandlerExpr = handlerExpr;
|
|
25357
25617
|
if (functionDepRenames.size > 0) {
|
|
25358
|
-
finalHandlerExpr = renameIdentifiersInExpr(handlerExpr, functionDepRenames);
|
|
25618
|
+
finalHandlerExpr = renameIdentifiersInExpr(handlerExpr, functionDepRenames, t4);
|
|
25359
25619
|
}
|
|
25360
25620
|
const bodyStatements = [];
|
|
25361
25621
|
if (lexicalNames.length > 0) {
|
|
@@ -25388,12 +25648,97 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25388
25648
|
);
|
|
25389
25649
|
}
|
|
25390
25650
|
const handlerVar = t4.identifier("__handler");
|
|
25651
|
+
const resultVar = t4.identifier("__result");
|
|
25391
25652
|
bodyStatements.push(
|
|
25392
25653
|
t4.variableDeclaration("const", [t4.variableDeclarator(handlerVar, finalHandlerExpr)])
|
|
25393
25654
|
);
|
|
25394
25655
|
bodyStatements.push(
|
|
25395
|
-
t4.
|
|
25396
|
-
t4.
|
|
25656
|
+
t4.ifStatement(
|
|
25657
|
+
t4.binaryExpression(
|
|
25658
|
+
"===",
|
|
25659
|
+
t4.unaryExpression("typeof", handlerVar),
|
|
25660
|
+
t4.stringLiteral("function")
|
|
25661
|
+
),
|
|
25662
|
+
t4.blockStatement([
|
|
25663
|
+
t4.variableDeclaration("const", [
|
|
25664
|
+
t4.variableDeclarator(
|
|
25665
|
+
resultVar,
|
|
25666
|
+
t4.callExpression(t4.memberExpression(handlerVar, t4.identifier("call")), [
|
|
25667
|
+
elParam,
|
|
25668
|
+
eventParam
|
|
25669
|
+
])
|
|
25670
|
+
)
|
|
25671
|
+
]),
|
|
25672
|
+
t4.ifStatement(
|
|
25673
|
+
t4.logicalExpression(
|
|
25674
|
+
"&&",
|
|
25675
|
+
t4.binaryExpression(
|
|
25676
|
+
"===",
|
|
25677
|
+
t4.unaryExpression("typeof", resultVar),
|
|
25678
|
+
t4.stringLiteral("function")
|
|
25679
|
+
),
|
|
25680
|
+
t4.binaryExpression("!==", resultVar, handlerVar)
|
|
25681
|
+
),
|
|
25682
|
+
t4.blockStatement([
|
|
25683
|
+
t4.returnStatement(
|
|
25684
|
+
t4.callExpression(t4.memberExpression(resultVar, t4.identifier("call")), [
|
|
25685
|
+
elParam,
|
|
25686
|
+
eventParam
|
|
25687
|
+
])
|
|
25688
|
+
)
|
|
25689
|
+
])
|
|
25690
|
+
),
|
|
25691
|
+
t4.ifStatement(
|
|
25692
|
+
t4.logicalExpression(
|
|
25693
|
+
"&&",
|
|
25694
|
+
resultVar,
|
|
25695
|
+
t4.binaryExpression(
|
|
25696
|
+
"===",
|
|
25697
|
+
t4.unaryExpression(
|
|
25698
|
+
"typeof",
|
|
25699
|
+
t4.memberExpression(resultVar, t4.identifier("handleEvent"))
|
|
25700
|
+
),
|
|
25701
|
+
t4.stringLiteral("function")
|
|
25702
|
+
)
|
|
25703
|
+
),
|
|
25704
|
+
t4.blockStatement([
|
|
25705
|
+
t4.returnStatement(
|
|
25706
|
+
t4.callExpression(
|
|
25707
|
+
t4.memberExpression(
|
|
25708
|
+
t4.memberExpression(resultVar, t4.identifier("handleEvent")),
|
|
25709
|
+
t4.identifier("call")
|
|
25710
|
+
),
|
|
25711
|
+
[resultVar, eventParam]
|
|
25712
|
+
)
|
|
25713
|
+
)
|
|
25714
|
+
])
|
|
25715
|
+
),
|
|
25716
|
+
t4.returnStatement(resultVar)
|
|
25717
|
+
])
|
|
25718
|
+
)
|
|
25719
|
+
);
|
|
25720
|
+
bodyStatements.push(
|
|
25721
|
+
t4.ifStatement(
|
|
25722
|
+
t4.logicalExpression(
|
|
25723
|
+
"&&",
|
|
25724
|
+
handlerVar,
|
|
25725
|
+
t4.binaryExpression(
|
|
25726
|
+
"===",
|
|
25727
|
+
t4.unaryExpression("typeof", t4.memberExpression(handlerVar, t4.identifier("handleEvent"))),
|
|
25728
|
+
t4.stringLiteral("function")
|
|
25729
|
+
)
|
|
25730
|
+
),
|
|
25731
|
+
t4.blockStatement([
|
|
25732
|
+
t4.returnStatement(
|
|
25733
|
+
t4.callExpression(
|
|
25734
|
+
t4.memberExpression(
|
|
25735
|
+
t4.memberExpression(handlerVar, t4.identifier("handleEvent")),
|
|
25736
|
+
t4.identifier("call")
|
|
25737
|
+
),
|
|
25738
|
+
[handlerVar, eventParam]
|
|
25739
|
+
)
|
|
25740
|
+
)
|
|
25741
|
+
])
|
|
25397
25742
|
)
|
|
25398
25743
|
);
|
|
25399
25744
|
const exportedHandler = t4.exportNamedDeclaration(
|
|
@@ -25422,6 +25767,7 @@ function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, c
|
|
|
25422
25767
|
])
|
|
25423
25768
|
)
|
|
25424
25769
|
);
|
|
25770
|
+
return true;
|
|
25425
25771
|
}
|
|
25426
25772
|
|
|
25427
25773
|
// src/ir/codegen-runtime-imports.ts
|
|
@@ -25806,7 +26152,8 @@ function extractHIRStaticHtml(jsx, ctx, ops, parentPath = [], namespace = null)
|
|
|
25806
26152
|
name: eventName.toLowerCase(),
|
|
25807
26153
|
expr: attr.value ?? void 0,
|
|
25808
26154
|
eventOptions: { capture, passive, once },
|
|
25809
|
-
resumable: shouldBeResumable
|
|
26155
|
+
resumable: shouldBeResumable,
|
|
26156
|
+
resumableExplicit: isResumableEvent
|
|
25810
26157
|
});
|
|
25811
26158
|
continue;
|
|
25812
26159
|
}
|
|
@@ -26379,7 +26726,7 @@ function buildOutputParams(fn, t4) {
|
|
|
26379
26726
|
}
|
|
26380
26727
|
return fn.params.map((p) => t4.identifier(deSSAVarName(p.name)));
|
|
26381
26728
|
}
|
|
26382
|
-
function lowerTrackedExpression(expr, ctx) {
|
|
26729
|
+
function lowerTrackedExpression(expr, ctx, valueUsed = true) {
|
|
26383
26730
|
const regionOverride = ctx.inReturn && ctx.currentFnIsHook ? null : ctx.currentRegion ?? (ctx.trackedVars.size ? {
|
|
26384
26731
|
id: -1,
|
|
26385
26732
|
dependencies: new Set(ctx.trackedVars),
|
|
@@ -26387,7 +26734,7 @@ function lowerTrackedExpression(expr, ctx) {
|
|
|
26387
26734
|
hasControlFlow: false,
|
|
26388
26735
|
hasReactiveWrites: false
|
|
26389
26736
|
} : null);
|
|
26390
|
-
const lowered = lowerExpression2(expr, ctx);
|
|
26737
|
+
const lowered = lowerExpression2(expr, ctx, valueUsed);
|
|
26391
26738
|
if (ctx.t.isAssignmentExpression(lowered)) {
|
|
26392
26739
|
const right = applyRegionMetadataToExpression2(lowered.right, ctx, regionOverride ?? void 0);
|
|
26393
26740
|
return ctx.t.assignmentExpression(lowered.operator, lowered.left, right);
|
|
@@ -26509,7 +26856,7 @@ function lowerInstruction(instr, ctx) {
|
|
|
26509
26856
|
);
|
|
26510
26857
|
}
|
|
26511
26858
|
if (instr.kind === "Expression") {
|
|
26512
|
-
return applyLoc(t4.expressionStatement(lowerTrackedExpression(instr.value, ctx)));
|
|
26859
|
+
return applyLoc(t4.expressionStatement(lowerTrackedExpression(instr.value, ctx, false)));
|
|
26513
26860
|
}
|
|
26514
26861
|
if (instr.kind === "Phi") {
|
|
26515
26862
|
return null;
|
|
@@ -26673,7 +27020,7 @@ function collectLocalDeclaredNames(params, blocks, t4) {
|
|
|
26673
27020
|
}
|
|
26674
27021
|
return declared;
|
|
26675
27022
|
}
|
|
26676
|
-
function lowerExpression2(expr, ctx,
|
|
27023
|
+
function lowerExpression2(expr, ctx, valueUsed = true) {
|
|
26677
27024
|
const depth = (ctx.expressionDepth ?? 0) + 1;
|
|
26678
27025
|
const maxDepth = ctx.maxExpressionDepth ?? 500;
|
|
26679
27026
|
if (depth > maxDepth) {
|
|
@@ -26684,12 +27031,12 @@ function lowerExpression2(expr, ctx, isAssigned = false) {
|
|
|
26684
27031
|
}
|
|
26685
27032
|
ctx.expressionDepth = depth;
|
|
26686
27033
|
try {
|
|
26687
|
-
return setNodeLoc(lowerExpressionImpl(expr, ctx,
|
|
27034
|
+
return setNodeLoc(lowerExpressionImpl(expr, ctx, valueUsed), expr.loc);
|
|
26688
27035
|
} finally {
|
|
26689
27036
|
ctx.expressionDepth = depth - 1;
|
|
26690
27037
|
}
|
|
26691
27038
|
}
|
|
26692
|
-
function lowerExpressionImpl(expr, ctx,
|
|
27039
|
+
function lowerExpressionImpl(expr, ctx, valueUsed = true) {
|
|
26693
27040
|
const { t: t4 } = ctx;
|
|
26694
27041
|
const mapParams = (params) => params.map((p) => t4.identifier(deSSAVarName(p.name)));
|
|
26695
27042
|
const lowerArgsAsExpressions = (args) => args.map(
|
|
@@ -26730,6 +27077,152 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
26730
27077
|
ctx.localDeclaredNames = prevLocalDeclared;
|
|
26731
27078
|
return result;
|
|
26732
27079
|
};
|
|
27080
|
+
const lowerTrackedWriteCall = (callee, nextValue) => {
|
|
27081
|
+
if (!valueUsed) {
|
|
27082
|
+
return t4.callExpression(t4.cloneNode(callee, true), [nextValue]);
|
|
27083
|
+
}
|
|
27084
|
+
const nextId = genTemp3(ctx, "next");
|
|
27085
|
+
const nextRef = t4.identifier(nextId.name);
|
|
27086
|
+
return t4.callExpression(
|
|
27087
|
+
t4.arrowFunctionExpression(
|
|
27088
|
+
[t4.cloneNode(nextId, true)],
|
|
27089
|
+
t4.sequenceExpression([
|
|
27090
|
+
t4.callExpression(t4.cloneNode(callee, true), [nextRef]),
|
|
27091
|
+
t4.identifier(nextId.name)
|
|
27092
|
+
])
|
|
27093
|
+
),
|
|
27094
|
+
[nextValue]
|
|
27095
|
+
);
|
|
27096
|
+
};
|
|
27097
|
+
const buildTrackedAssignmentNext = (operator, current, right) => {
|
|
27098
|
+
switch (operator) {
|
|
27099
|
+
case "=":
|
|
27100
|
+
return right;
|
|
27101
|
+
case "+=":
|
|
27102
|
+
return t4.binaryExpression("+", current, right);
|
|
27103
|
+
case "-=":
|
|
27104
|
+
return t4.binaryExpression("-", current, right);
|
|
27105
|
+
case "*=":
|
|
27106
|
+
return t4.binaryExpression("*", current, right);
|
|
27107
|
+
case "/=":
|
|
27108
|
+
return t4.binaryExpression("/", current, right);
|
|
27109
|
+
case "%=":
|
|
27110
|
+
return t4.binaryExpression("%", current, right);
|
|
27111
|
+
case "**=":
|
|
27112
|
+
return t4.binaryExpression("**", current, right);
|
|
27113
|
+
case "<<=":
|
|
27114
|
+
return t4.binaryExpression("<<", current, right);
|
|
27115
|
+
case ">>=":
|
|
27116
|
+
return t4.binaryExpression(">>", current, right);
|
|
27117
|
+
case ">>>=":
|
|
27118
|
+
return t4.binaryExpression(">>>", current, right);
|
|
27119
|
+
case "|=":
|
|
27120
|
+
return t4.binaryExpression("|", current, right);
|
|
27121
|
+
case "^=":
|
|
27122
|
+
return t4.binaryExpression("^", current, right);
|
|
27123
|
+
case "&=":
|
|
27124
|
+
return t4.binaryExpression("&", current, right);
|
|
27125
|
+
case "&&=":
|
|
27126
|
+
return t4.logicalExpression("&&", current, right);
|
|
27127
|
+
case "||=":
|
|
27128
|
+
return t4.logicalExpression("||", current, right);
|
|
27129
|
+
case "??=":
|
|
27130
|
+
return t4.logicalExpression("??", current, right);
|
|
27131
|
+
default:
|
|
27132
|
+
return right;
|
|
27133
|
+
}
|
|
27134
|
+
};
|
|
27135
|
+
const buildStaticSignalKeyTest = (keyRef, keys) => {
|
|
27136
|
+
if (keys.length === 0) return null;
|
|
27137
|
+
let test = null;
|
|
27138
|
+
for (const key of keys) {
|
|
27139
|
+
const literal = typeof key === "number" ? t4.numericLiteral(key) : t4.stringLiteral(String(key));
|
|
27140
|
+
const eq = t4.binaryExpression("===", t4.cloneNode(keyRef, true), literal);
|
|
27141
|
+
test = test ? t4.logicalExpression("||", test, eq) : eq;
|
|
27142
|
+
}
|
|
27143
|
+
return test;
|
|
27144
|
+
};
|
|
27145
|
+
const lowerComputedHookSignalAssignment = (objectName, keyExpr, signalKeys, operator, rightExpr) => {
|
|
27146
|
+
const keyTestKeys = signalKeys.filter(
|
|
27147
|
+
(key) => typeof key === "number" && Number.isFinite(key) || typeof key === "string"
|
|
27148
|
+
);
|
|
27149
|
+
if (keyTestKeys.length === 0) return null;
|
|
27150
|
+
const keyId = genTemp3(ctx, "key");
|
|
27151
|
+
const keyRef = t4.identifier(keyId.name);
|
|
27152
|
+
const memberForAccessor = t4.memberExpression(
|
|
27153
|
+
t4.identifier(objectName),
|
|
27154
|
+
t4.identifier(keyId.name),
|
|
27155
|
+
true
|
|
27156
|
+
);
|
|
27157
|
+
const current = t4.callExpression(t4.cloneNode(memberForAccessor, true), []);
|
|
27158
|
+
const right = lowerExpression2(rightExpr, ctx);
|
|
27159
|
+
const signalWrite = lowerTrackedWriteCall(
|
|
27160
|
+
memberForAccessor,
|
|
27161
|
+
buildTrackedAssignmentNext(operator, current, t4.cloneNode(right, true))
|
|
27162
|
+
);
|
|
27163
|
+
const fallback = t4.assignmentExpression(
|
|
27164
|
+
operator,
|
|
27165
|
+
t4.memberExpression(t4.identifier(objectName), t4.identifier(keyId.name), true),
|
|
27166
|
+
right
|
|
27167
|
+
);
|
|
27168
|
+
const keyTest = buildStaticSignalKeyTest(keyRef, keyTestKeys);
|
|
27169
|
+
if (!keyTest) return null;
|
|
27170
|
+
return t4.callExpression(
|
|
27171
|
+
t4.arrowFunctionExpression(
|
|
27172
|
+
[t4.cloneNode(keyId, true)],
|
|
27173
|
+
t4.conditionalExpression(keyTest, signalWrite, fallback)
|
|
27174
|
+
),
|
|
27175
|
+
[lowerExpression2(keyExpr, ctx)]
|
|
27176
|
+
);
|
|
27177
|
+
};
|
|
27178
|
+
const lowerComputedHookSignalUpdate = (objectName, keyExpr, signalKeys, operator, prefix) => {
|
|
27179
|
+
const keyTestKeys = signalKeys.filter(
|
|
27180
|
+
(key) => typeof key === "number" && Number.isFinite(key) || typeof key === "string"
|
|
27181
|
+
);
|
|
27182
|
+
if (keyTestKeys.length === 0) return null;
|
|
27183
|
+
const keyId = genTemp3(ctx, "key");
|
|
27184
|
+
const keyRef = t4.identifier(keyId.name);
|
|
27185
|
+
const signalUpdate = lowerTrackedUpdateCall(
|
|
27186
|
+
t4.memberExpression(t4.identifier(objectName), t4.identifier(keyId.name), true),
|
|
27187
|
+
operator,
|
|
27188
|
+
prefix
|
|
27189
|
+
);
|
|
27190
|
+
const fallback = t4.updateExpression(
|
|
27191
|
+
operator,
|
|
27192
|
+
t4.memberExpression(t4.identifier(objectName), t4.identifier(keyId.name), true),
|
|
27193
|
+
prefix
|
|
27194
|
+
);
|
|
27195
|
+
const keyTest = buildStaticSignalKeyTest(keyRef, keyTestKeys);
|
|
27196
|
+
if (!keyTest) return null;
|
|
27197
|
+
return t4.callExpression(
|
|
27198
|
+
t4.arrowFunctionExpression(
|
|
27199
|
+
[t4.cloneNode(keyId, true)],
|
|
27200
|
+
t4.conditionalExpression(keyTest, signalUpdate, fallback)
|
|
27201
|
+
),
|
|
27202
|
+
[lowerExpression2(keyExpr, ctx)]
|
|
27203
|
+
);
|
|
27204
|
+
};
|
|
27205
|
+
const lowerTrackedUpdateCall = (callee, operator, prefix) => {
|
|
27206
|
+
const op = operator === "++" ? "+" : "-";
|
|
27207
|
+
const delta = t4.numericLiteral(1);
|
|
27208
|
+
const current = t4.callExpression(t4.cloneNode(callee, true), []);
|
|
27209
|
+
if (!valueUsed) {
|
|
27210
|
+
return t4.callExpression(t4.cloneNode(callee, true), [t4.binaryExpression(op, current, delta)]);
|
|
27211
|
+
}
|
|
27212
|
+
const prevId = genTemp3(ctx, "prev");
|
|
27213
|
+
const prevForSet = t4.identifier(prevId.name);
|
|
27214
|
+
const prevForResult = t4.identifier(prevId.name);
|
|
27215
|
+
return t4.callExpression(
|
|
27216
|
+
t4.arrowFunctionExpression(
|
|
27217
|
+
[t4.cloneNode(prevId, true)],
|
|
27218
|
+
t4.sequenceExpression([
|
|
27219
|
+
t4.callExpression(t4.cloneNode(callee, true), [t4.binaryExpression(op, prevForSet, delta)]),
|
|
27220
|
+
prefix ? t4.binaryExpression(op, prevForResult, t4.numericLiteral(1)) : prevForResult
|
|
27221
|
+
])
|
|
27222
|
+
),
|
|
27223
|
+
[current]
|
|
27224
|
+
);
|
|
27225
|
+
};
|
|
26733
27226
|
const lowerBlocksToStatements = (blocks) => {
|
|
26734
27227
|
const stmts = [];
|
|
26735
27228
|
for (const block of blocks) {
|
|
@@ -26899,6 +27392,24 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
26899
27392
|
expr.arguments,
|
|
26900
27393
|
(arg) => arg.kind === "ArrowFunction" || arg.kind === "FunctionExpression" ? withNonReactiveScope(ctx, () => lowerExpression2(arg, ctx)) : lowerExpression2(arg, ctx)
|
|
26901
27394
|
);
|
|
27395
|
+
const includeDevtools = ctx.options?.dev !== false;
|
|
27396
|
+
if (includeDevtools && expr.loc) {
|
|
27397
|
+
const source = `${ctx.options?.filename ?? ""}:${expr.loc.start.line}:${expr.loc.start.column}`;
|
|
27398
|
+
const sourceProp = t4.objectProperty(
|
|
27399
|
+
t4.identifier("devToolsSource"),
|
|
27400
|
+
t4.stringLiteral(source)
|
|
27401
|
+
);
|
|
27402
|
+
if (args.length === 1) {
|
|
27403
|
+
args.push(t4.objectExpression([sourceProp]));
|
|
27404
|
+
} else if (args.length > 1 && t4.isObjectExpression(args[1])) {
|
|
27405
|
+
const hasSourceProp = args[1].properties.some(
|
|
27406
|
+
(prop) => t4.isObjectProperty(prop) && t4.isIdentifier(prop.key) && prop.key.name === "devToolsSource"
|
|
27407
|
+
);
|
|
27408
|
+
if (!hasSourceProp) {
|
|
27409
|
+
args[1].properties.push(sourceProp);
|
|
27410
|
+
}
|
|
27411
|
+
}
|
|
27412
|
+
}
|
|
26902
27413
|
if (ctx.inModule) {
|
|
26903
27414
|
ctx.helpersUsed.add("effect");
|
|
26904
27415
|
return t4.callExpression(t4.identifier(RUNTIME_ALIASES.effect), args);
|
|
@@ -27206,59 +27717,42 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
27206
27717
|
expr.left.computed,
|
|
27207
27718
|
expr.left.optional
|
|
27208
27719
|
);
|
|
27209
|
-
const current = t4.callExpression(member, []);
|
|
27720
|
+
const current = t4.callExpression(t4.cloneNode(member, true), []);
|
|
27210
27721
|
const right = lowerExpression2(expr.right, ctx);
|
|
27211
|
-
|
|
27212
|
-
|
|
27213
|
-
|
|
27214
|
-
|
|
27215
|
-
|
|
27216
|
-
|
|
27217
|
-
|
|
27218
|
-
|
|
27219
|
-
|
|
27220
|
-
next = t4.binaryExpression("-", current, right);
|
|
27221
|
-
break;
|
|
27222
|
-
case "*=":
|
|
27223
|
-
next = t4.binaryExpression("*", current, right);
|
|
27224
|
-
break;
|
|
27225
|
-
case "/=":
|
|
27226
|
-
next = t4.binaryExpression("/", current, right);
|
|
27227
|
-
break;
|
|
27228
|
-
default:
|
|
27229
|
-
next = right;
|
|
27722
|
+
const next = buildTrackedAssignmentNext(expr.operator, current, right);
|
|
27723
|
+
return lowerTrackedWriteCall(member, next);
|
|
27724
|
+
}
|
|
27725
|
+
if (expr.left.computed) {
|
|
27726
|
+
const signalKeys = [];
|
|
27727
|
+
if (info?.objectProps) {
|
|
27728
|
+
for (const [key, accessorKind] of info.objectProps.entries()) {
|
|
27729
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27730
|
+
}
|
|
27230
27731
|
}
|
|
27231
|
-
|
|
27732
|
+
if (info?.arrayProps) {
|
|
27733
|
+
for (const [key, accessorKind] of info.arrayProps.entries()) {
|
|
27734
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27735
|
+
}
|
|
27736
|
+
}
|
|
27737
|
+
const lowered = lowerComputedHookSignalAssignment(
|
|
27738
|
+
deSSAVarName(expr.left.object.name),
|
|
27739
|
+
expr.left.property,
|
|
27740
|
+
signalKeys,
|
|
27741
|
+
expr.operator,
|
|
27742
|
+
expr.right
|
|
27743
|
+
);
|
|
27744
|
+
if (lowered) return lowered;
|
|
27232
27745
|
}
|
|
27233
27746
|
}
|
|
27234
27747
|
}
|
|
27235
27748
|
if (expr.left.kind === "Identifier") {
|
|
27236
27749
|
const baseName2 = deSSAVarName(expr.left.name);
|
|
27237
27750
|
if (ctx.trackedVars.has(baseName2)) {
|
|
27238
|
-
const
|
|
27751
|
+
const callee = t4.identifier(baseName2);
|
|
27239
27752
|
const current = t4.callExpression(t4.identifier(baseName2), []);
|
|
27240
27753
|
const right = lowerExpression2(expr.right, ctx);
|
|
27241
|
-
|
|
27242
|
-
|
|
27243
|
-
case "=":
|
|
27244
|
-
next = right;
|
|
27245
|
-
break;
|
|
27246
|
-
case "+=":
|
|
27247
|
-
next = t4.binaryExpression("+", current, right);
|
|
27248
|
-
break;
|
|
27249
|
-
case "-=":
|
|
27250
|
-
next = t4.binaryExpression("-", current, right);
|
|
27251
|
-
break;
|
|
27252
|
-
case "*=":
|
|
27253
|
-
next = t4.binaryExpression("*", current, right);
|
|
27254
|
-
break;
|
|
27255
|
-
case "/=":
|
|
27256
|
-
next = t4.binaryExpression("/", current, right);
|
|
27257
|
-
break;
|
|
27258
|
-
default:
|
|
27259
|
-
next = right;
|
|
27260
|
-
}
|
|
27261
|
-
return t4.callExpression(id, [next]);
|
|
27754
|
+
const next = buildTrackedAssignmentNext(expr.operator, current, right);
|
|
27755
|
+
return lowerTrackedWriteCall(callee, next);
|
|
27262
27756
|
}
|
|
27263
27757
|
}
|
|
27264
27758
|
return t4.assignmentExpression(
|
|
@@ -27290,21 +27784,35 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
27290
27784
|
expr.argument.computed,
|
|
27291
27785
|
expr.argument.optional
|
|
27292
27786
|
);
|
|
27293
|
-
|
|
27294
|
-
|
|
27295
|
-
|
|
27296
|
-
|
|
27787
|
+
return lowerTrackedUpdateCall(member, expr.operator, expr.prefix);
|
|
27788
|
+
}
|
|
27789
|
+
if (expr.argument.computed) {
|
|
27790
|
+
const signalKeys = [];
|
|
27791
|
+
if (info?.objectProps) {
|
|
27792
|
+
for (const [key, accessorKind] of info.objectProps.entries()) {
|
|
27793
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27794
|
+
}
|
|
27795
|
+
}
|
|
27796
|
+
if (info?.arrayProps) {
|
|
27797
|
+
for (const [key, accessorKind] of info.arrayProps.entries()) {
|
|
27798
|
+
if (accessorKind === "signal") signalKeys.push(key);
|
|
27799
|
+
}
|
|
27800
|
+
}
|
|
27801
|
+
const lowered = lowerComputedHookSignalUpdate(
|
|
27802
|
+
deSSAVarName(expr.argument.object.name),
|
|
27803
|
+
expr.argument.property,
|
|
27804
|
+
signalKeys,
|
|
27805
|
+
expr.operator,
|
|
27806
|
+
expr.prefix
|
|
27807
|
+
);
|
|
27808
|
+
if (lowered) return lowered;
|
|
27297
27809
|
}
|
|
27298
27810
|
}
|
|
27299
27811
|
}
|
|
27300
27812
|
if (expr.argument.kind === "Identifier") {
|
|
27301
27813
|
const baseName2 = deSSAVarName(expr.argument.name);
|
|
27302
27814
|
if (ctx.trackedVars.has(baseName2)) {
|
|
27303
|
-
|
|
27304
|
-
const current = t4.callExpression(t4.identifier(baseName2), []);
|
|
27305
|
-
const delta = t4.numericLiteral(1);
|
|
27306
|
-
const next = expr.operator === "++" ? t4.binaryExpression("+", current, delta) : t4.binaryExpression("-", current, delta);
|
|
27307
|
-
return t4.callExpression(id, [next]);
|
|
27815
|
+
return lowerTrackedUpdateCall(t4.identifier(baseName2), expr.operator, expr.prefix);
|
|
27308
27816
|
}
|
|
27309
27817
|
}
|
|
27310
27818
|
return t4.updateExpression(
|
|
@@ -27326,7 +27834,11 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
27326
27834
|
case "NewExpression":
|
|
27327
27835
|
return t4.newExpression(lowerExpression2(expr.callee, ctx), lowerCallArguments(expr.arguments));
|
|
27328
27836
|
case "SequenceExpression":
|
|
27329
|
-
return t4.sequenceExpression(
|
|
27837
|
+
return t4.sequenceExpression(
|
|
27838
|
+
expr.expressions.map(
|
|
27839
|
+
(e, index) => lowerExpression2(e, ctx, index === expr.expressions.length - 1 ? valueUsed : false)
|
|
27840
|
+
)
|
|
27841
|
+
);
|
|
27330
27842
|
case "YieldExpression":
|
|
27331
27843
|
return t4.yieldExpression(
|
|
27332
27844
|
expr.argument ? lowerExpression2(expr.argument, ctx) : null,
|
|
@@ -27784,16 +28296,17 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27784
28296
|
const hasEventOptions = binding.eventOptions && (binding.eventOptions.capture || binding.eventOptions.passive || binding.eventOptions.once);
|
|
27785
28297
|
const isDelegated = DelegatedEvents.has(eventName) && !hasEventOptions;
|
|
27786
28298
|
if (binding.resumable && !hasEventOptions) {
|
|
27787
|
-
emitResumableEventBinding(
|
|
28299
|
+
const emitted = emitResumableEventBinding(
|
|
27788
28300
|
targetId,
|
|
27789
28301
|
eventName,
|
|
27790
28302
|
binding.expr,
|
|
27791
28303
|
statements,
|
|
27792
28304
|
ctx,
|
|
27793
28305
|
containingRegion,
|
|
27794
|
-
createResumableEventBindingOps()
|
|
28306
|
+
createResumableEventBindingOps(),
|
|
28307
|
+
{ explicit: binding.resumableExplicit === true }
|
|
27795
28308
|
);
|
|
27796
|
-
continue;
|
|
28309
|
+
if (emitted) continue;
|
|
27797
28310
|
}
|
|
27798
28311
|
const hirDataBinding = isDelegated && binding.expr ? extractDelegatedEventDataFromHIR(binding.expr, ctx) : null;
|
|
27799
28312
|
if (hirDataBinding) {
|
|
@@ -27835,34 +28348,24 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27835
28348
|
const isFn = t4.isArrowFunctionExpression(valueExpr) || t4.isFunctionExpression(valueExpr);
|
|
27836
28349
|
const ensureHandlerParam = (fn) => {
|
|
27837
28350
|
if (t4.isArrowFunctionExpression(fn)) {
|
|
27838
|
-
|
|
27839
|
-
return t4.arrowFunctionExpression([eventParam], fn.body, fn.async);
|
|
28351
|
+
return fn;
|
|
27840
28352
|
}
|
|
27841
28353
|
if (t4.isFunctionExpression(fn)) {
|
|
27842
|
-
|
|
27843
|
-
return t4.functionExpression(fn.id, [eventParam], fn.body, fn.generator, fn.async);
|
|
28354
|
+
return fn;
|
|
27844
28355
|
}
|
|
27845
28356
|
if (t4.isIdentifier(fn) || t4.isMemberExpression(fn)) {
|
|
27846
28357
|
return fn;
|
|
27847
28358
|
}
|
|
27848
|
-
if (t4.isCallExpression(fn) && fn.arguments.length === 0 && (t4.isIdentifier(fn.callee) || t4.isMemberExpression(fn.callee))) {
|
|
27849
|
-
return fn.callee;
|
|
27850
|
-
}
|
|
27851
28359
|
return t4.functionExpression(
|
|
27852
28360
|
null,
|
|
27853
|
-
[
|
|
27854
|
-
t4.blockStatement([
|
|
27855
|
-
t4.returnStatement(
|
|
27856
|
-
t4.callExpression(
|
|
27857
|
-
t4.memberExpression(fn, t4.identifier("call")),
|
|
27858
|
-
[t4.thisExpression(), eventParam]
|
|
27859
|
-
)
|
|
27860
|
-
)
|
|
27861
|
-
])
|
|
28361
|
+
[],
|
|
28362
|
+
t4.blockStatement([t4.returnStatement(fn)])
|
|
27862
28363
|
);
|
|
27863
28364
|
};
|
|
27864
28365
|
const handlerExpr = !isFn && shouldWrapHandler ? t4.arrowFunctionExpression([], valueExpr) : ensureHandlerParam(valueExpr);
|
|
27865
|
-
let dataBinding = isDelegated && !shouldWrapHandler ? extractDelegatedEventData(valueExpr, t4
|
|
28366
|
+
let dataBinding = isDelegated && !shouldWrapHandler ? extractDelegatedEventData(valueExpr, t4, {
|
|
28367
|
+
isKnownHandlerIdentifier: (name) => ctx.functionVars?.has(deSSAVarName(name)) ?? false
|
|
28368
|
+
}) : null;
|
|
27866
28369
|
if (dataBinding && t4.isIdentifier(dataBinding.handler)) {
|
|
27867
28370
|
const handlerName = dataBinding.handler.name;
|
|
27868
28371
|
if (ctx.signalVars?.has(handlerName) || ctx.memoVars?.has(handlerName) || ctx.aliasVars?.has(handlerName) || ctx.storeVars?.has(handlerName) || ctx.trackedVars.has(handlerName)) {
|
|
@@ -27874,8 +28377,6 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27874
28377
|
let handlerName = null;
|
|
27875
28378
|
if (t4.isIdentifier(valueExpr)) {
|
|
27876
28379
|
handlerName = valueExpr.name;
|
|
27877
|
-
} else if (t4.isCallExpression(valueExpr) && valueExpr.arguments.length === 0 && t4.isIdentifier(valueExpr.callee)) {
|
|
27878
|
-
handlerName = valueExpr.callee.name;
|
|
27879
28380
|
}
|
|
27880
28381
|
const handlerForCall = handlerName ? t4.identifier(handlerName) : t4.cloneNode(valueExpr, true);
|
|
27881
28382
|
const finalHandler = !isFn && shouldWrapHandler ? t4.functionExpression(
|
|
@@ -27891,9 +28392,6 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
27891
28392
|
])
|
|
27892
28393
|
) : handlerExpr;
|
|
27893
28394
|
const normalizeHandler = (expr) => {
|
|
27894
|
-
if (t4.isCallExpression(expr) && (t4.isIdentifier(expr.callee) || t4.isMemberExpression(expr.callee))) {
|
|
27895
|
-
return expr.callee;
|
|
27896
|
-
}
|
|
27897
28395
|
return expr;
|
|
27898
28396
|
};
|
|
27899
28397
|
const normalizedDataHandler = dataBinding !== null ? normalizeHandler(
|
|
@@ -30344,11 +30842,27 @@ function optimizeReactiveBlock(block, reactive, purity, options) {
|
|
|
30344
30842
|
const constArrays = /* @__PURE__ */ new Map();
|
|
30345
30843
|
const cseMap = /* @__PURE__ */ new Map();
|
|
30346
30844
|
const instructions = [];
|
|
30845
|
+
const deleteByBase = (map, name) => {
|
|
30846
|
+
const base = getSSABaseName(name);
|
|
30847
|
+
for (const key of Array.from(map.keys())) {
|
|
30848
|
+
if (getSSABaseName(key) === base) {
|
|
30849
|
+
map.delete(key);
|
|
30850
|
+
}
|
|
30851
|
+
}
|
|
30852
|
+
};
|
|
30347
30853
|
const invalidateCSE = (name) => {
|
|
30854
|
+
const base = getSSABaseName(name);
|
|
30348
30855
|
const toDelete = [];
|
|
30349
30856
|
for (const [hash, entry] of cseMap.entries()) {
|
|
30350
|
-
if (entry.name ===
|
|
30857
|
+
if (getSSABaseName(entry.name) === base) {
|
|
30351
30858
|
toDelete.push(hash);
|
|
30859
|
+
continue;
|
|
30860
|
+
}
|
|
30861
|
+
for (const dep of entry.deps) {
|
|
30862
|
+
if (getSSABaseName(dep) === base) {
|
|
30863
|
+
toDelete.push(hash);
|
|
30864
|
+
break;
|
|
30865
|
+
}
|
|
30352
30866
|
}
|
|
30353
30867
|
}
|
|
30354
30868
|
toDelete.forEach((hash) => cseMap.delete(hash));
|
|
@@ -30358,22 +30872,22 @@ function optimizeReactiveBlock(block, reactive, purity, options) {
|
|
|
30358
30872
|
const target = instr.target.name;
|
|
30359
30873
|
const declKind = instr.declarationKind;
|
|
30360
30874
|
invalidateCSE(target);
|
|
30361
|
-
constants
|
|
30362
|
-
constObjects
|
|
30363
|
-
constArrays
|
|
30875
|
+
deleteByBase(constants, target);
|
|
30876
|
+
deleteByBase(constObjects, target);
|
|
30877
|
+
deleteByBase(constArrays, target);
|
|
30364
30878
|
const sideWrites = collectWriteTargets(instr.value);
|
|
30365
30879
|
for (const name of sideWrites) {
|
|
30366
30880
|
if (name !== target) {
|
|
30367
|
-
constants
|
|
30881
|
+
deleteByBase(constants, name);
|
|
30368
30882
|
invalidateCSE(name);
|
|
30369
30883
|
}
|
|
30370
|
-
constObjects
|
|
30371
|
-
constArrays
|
|
30884
|
+
deleteByBase(constObjects, name);
|
|
30885
|
+
deleteByBase(constArrays, name);
|
|
30372
30886
|
}
|
|
30373
30887
|
const memberCalls = collectMemberCallTargets(instr.value);
|
|
30374
30888
|
for (const name of memberCalls) {
|
|
30375
|
-
constObjects
|
|
30376
|
-
constArrays
|
|
30889
|
+
deleteByBase(constObjects, name);
|
|
30890
|
+
deleteByBase(constArrays, name);
|
|
30377
30891
|
}
|
|
30378
30892
|
const dependsOnReactiveValue = expressionDependsOnReactive(instr.value, reactive);
|
|
30379
30893
|
let value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, options, constObjects, constArrays);
|
|
@@ -30413,15 +30927,15 @@ function optimizeReactiveBlock(block, reactive, purity, options) {
|
|
|
30413
30927
|
if (instr.kind === "Expression") {
|
|
30414
30928
|
const writes = collectWriteTargets(instr.value);
|
|
30415
30929
|
for (const name of writes) {
|
|
30416
|
-
constants
|
|
30930
|
+
deleteByBase(constants, name);
|
|
30417
30931
|
invalidateCSE(name);
|
|
30418
|
-
constObjects
|
|
30419
|
-
constArrays
|
|
30932
|
+
deleteByBase(constObjects, name);
|
|
30933
|
+
deleteByBase(constArrays, name);
|
|
30420
30934
|
}
|
|
30421
30935
|
const memberCalls = collectMemberCallTargets(instr.value);
|
|
30422
30936
|
for (const name of memberCalls) {
|
|
30423
|
-
constObjects
|
|
30424
|
-
constArrays
|
|
30937
|
+
deleteByBase(constObjects, name);
|
|
30938
|
+
deleteByBase(constArrays, name);
|
|
30425
30939
|
}
|
|
30426
30940
|
const dependsOnReactiveValue = expressionDependsOnReactive(instr.value, reactive);
|
|
30427
30941
|
const value = dependsOnReactiveValue ? instr.value : foldExpressionWithConstants(instr.value, constants, options, constObjects, constArrays);
|
|
@@ -31071,6 +31585,8 @@ function collectWriteTargets(expr) {
|
|
|
31071
31585
|
} else if (left.kind === "MemberExpression" || left.kind === "OptionalMemberExpression") {
|
|
31072
31586
|
const base = getMemberBaseIdentifier(left);
|
|
31073
31587
|
if (base) writes.add(base.name);
|
|
31588
|
+
visit(left.object);
|
|
31589
|
+
if (left.computed) visit(left.property);
|
|
31074
31590
|
} else {
|
|
31075
31591
|
visit(left);
|
|
31076
31592
|
}
|
|
@@ -31087,8 +31603,10 @@ function collectWriteTargets(expr) {
|
|
|
31087
31603
|
const base = getMemberBaseIdentifier(arg);
|
|
31088
31604
|
if (base) {
|
|
31089
31605
|
writes.add(base.name);
|
|
31090
|
-
return;
|
|
31091
31606
|
}
|
|
31607
|
+
visit(arg.object);
|
|
31608
|
+
if (arg.computed) visit(arg.property);
|
|
31609
|
+
return;
|
|
31092
31610
|
}
|
|
31093
31611
|
visit(arg);
|
|
31094
31612
|
return;
|
|
@@ -31394,6 +31912,16 @@ function propagateConstants(fn, options) {
|
|
|
31394
31912
|
}
|
|
31395
31913
|
function computeConstantMap(fn) {
|
|
31396
31914
|
const constants = /* @__PURE__ */ new Map();
|
|
31915
|
+
const invalidateWrittenName = (writtenName) => {
|
|
31916
|
+
const writtenBase = getSSABaseName(writtenName);
|
|
31917
|
+
let removed = false;
|
|
31918
|
+
for (const constantName of Array.from(constants.keys())) {
|
|
31919
|
+
if (constantName === writtenName || getSSABaseName(constantName) === writtenBase) {
|
|
31920
|
+
removed = constants.delete(constantName) || removed;
|
|
31921
|
+
}
|
|
31922
|
+
}
|
|
31923
|
+
return removed;
|
|
31924
|
+
};
|
|
31397
31925
|
let changed = true;
|
|
31398
31926
|
let iterations = 0;
|
|
31399
31927
|
const maxIterations = 10;
|
|
@@ -31402,6 +31930,14 @@ function computeConstantMap(fn) {
|
|
|
31402
31930
|
changed = false;
|
|
31403
31931
|
for (const block of fn.blocks) {
|
|
31404
31932
|
for (const instr of block.instructions) {
|
|
31933
|
+
if (instr.kind === "Assign" || instr.kind === "Expression") {
|
|
31934
|
+
const writes = collectWriteTargets(instr.value);
|
|
31935
|
+
for (const writtenName of writes) {
|
|
31936
|
+
if (invalidateWrittenName(writtenName)) {
|
|
31937
|
+
changed = true;
|
|
31938
|
+
}
|
|
31939
|
+
}
|
|
31940
|
+
}
|
|
31405
31941
|
if (instr.kind === "Assign") {
|
|
31406
31942
|
const value = evaluateConstant(instr.value, constants);
|
|
31407
31943
|
if (value !== UNKNOWN_CONST) {
|