@fictjs/compiler 0.0.14 → 0.1.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 +515 -193
- package/dist/index.js +515 -193
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -15547,6 +15547,17 @@ function processStatement(stmt, bb, jumpTarget, ctx) {
|
|
|
15547
15547
|
}
|
|
15548
15548
|
function convertExpression(node) {
|
|
15549
15549
|
const loc = getLoc(node);
|
|
15550
|
+
const convertCallArguments = (args) => args.map((arg) => {
|
|
15551
|
+
if (t.isSpreadElement(arg)) {
|
|
15552
|
+
return {
|
|
15553
|
+
kind: "SpreadElement",
|
|
15554
|
+
argument: convertExpression(arg.argument),
|
|
15555
|
+
loc: getLoc(arg)
|
|
15556
|
+
};
|
|
15557
|
+
}
|
|
15558
|
+
if (t.isExpression(arg)) return convertExpression(arg);
|
|
15559
|
+
return void 0;
|
|
15560
|
+
}).filter(Boolean);
|
|
15550
15561
|
if (t.isIdentifier(node)) return { kind: "Identifier", name: node.name, loc };
|
|
15551
15562
|
if (t.isStringLiteral(node) || t.isNumericLiteral(node) || t.isBooleanLiteral(node) || t.isNullLiteral(node))
|
|
15552
15563
|
return { kind: "Literal", value: node.value ?? null, loc };
|
|
@@ -15554,7 +15565,7 @@ function convertExpression(node) {
|
|
|
15554
15565
|
const call = {
|
|
15555
15566
|
kind: "CallExpression",
|
|
15556
15567
|
callee: convertExpression(node.callee),
|
|
15557
|
-
arguments: node.arguments
|
|
15568
|
+
arguments: convertCallArguments(node.arguments),
|
|
15558
15569
|
loc
|
|
15559
15570
|
};
|
|
15560
15571
|
return call;
|
|
@@ -15834,7 +15845,7 @@ function convertExpression(node) {
|
|
|
15834
15845
|
return {
|
|
15835
15846
|
kind: "NewExpression",
|
|
15836
15847
|
callee: convertExpression(node.callee),
|
|
15837
|
-
arguments: node.arguments
|
|
15848
|
+
arguments: convertCallArguments(node.arguments),
|
|
15838
15849
|
loc
|
|
15839
15850
|
};
|
|
15840
15851
|
}
|
|
@@ -15857,7 +15868,7 @@ function convertExpression(node) {
|
|
|
15857
15868
|
return {
|
|
15858
15869
|
kind: "OptionalCallExpression",
|
|
15859
15870
|
callee: convertExpression(node.callee),
|
|
15860
|
-
arguments: node.arguments
|
|
15871
|
+
arguments: convertCallArguments(node.arguments),
|
|
15861
15872
|
optional: node.optional,
|
|
15862
15873
|
loc
|
|
15863
15874
|
};
|
|
@@ -16067,6 +16078,7 @@ var DiagnosticMessages = {
|
|
|
16067
16078
|
["FICT-P002" /* FICT_P002 */]: "Array rest in props destructuring falls back to non-reactive binding.",
|
|
16068
16079
|
["FICT-P003" /* FICT_P003 */]: "Computed property in props pattern cannot be made reactive.",
|
|
16069
16080
|
["FICT-P004" /* FICT_P004 */]: "Nested props destructuring falls back to non-reactive binding; access props directly or use prop.",
|
|
16081
|
+
["FICT-P005" /* FICT_P005 */]: "Dynamic props spread may not stay reactive; consider explicit props or mergeProps(() => source).",
|
|
16070
16082
|
["FICT-S001" /* FICT_S001 */]: "State variable mutation detected outside component scope.",
|
|
16071
16083
|
["FICT-S002" /* FICT_S002 */]: "State variable escaped to external scope, may cause memory leaks.",
|
|
16072
16084
|
["FICT-E001" /* FICT_E001 */]: "Effect without reactive dependencies will run only once; consider adding state reads or removing the effect.",
|
|
@@ -16096,6 +16108,7 @@ var DiagnosticSeverities = {
|
|
|
16096
16108
|
["FICT-P002" /* FICT_P002 */]: "warning" /* Warning */,
|
|
16097
16109
|
["FICT-P003" /* FICT_P003 */]: "warning" /* Warning */,
|
|
16098
16110
|
["FICT-P004" /* FICT_P004 */]: "warning" /* Warning */,
|
|
16111
|
+
["FICT-P005" /* FICT_P005 */]: "warning" /* Warning */,
|
|
16099
16112
|
["FICT-S001" /* FICT_S001 */]: "error" /* Error */,
|
|
16100
16113
|
["FICT-S002" /* FICT_S002 */]: "warning" /* Warning */,
|
|
16101
16114
|
["FICT-E001" /* FICT_E001 */]: "warning" /* Warning */,
|
|
@@ -16148,6 +16161,215 @@ function reportDiagnostic(ctx, code, node, context) {
|
|
|
16148
16161
|
}
|
|
16149
16162
|
}
|
|
16150
16163
|
|
|
16164
|
+
// src/ir/props-plan.ts
|
|
16165
|
+
function buildPropsPlan(attributes, children, ctx, helpers) {
|
|
16166
|
+
const { t: t2 } = ctx;
|
|
16167
|
+
const prevPropsContext = ctx.inPropsContext;
|
|
16168
|
+
ctx.inPropsContext = true;
|
|
16169
|
+
try {
|
|
16170
|
+
if (attributes.length === 0 && children.length === 0) return null;
|
|
16171
|
+
const segments = [];
|
|
16172
|
+
const flags = {
|
|
16173
|
+
needsMergeProps: false,
|
|
16174
|
+
hasLazySource: false
|
|
16175
|
+
};
|
|
16176
|
+
let bucket = [];
|
|
16177
|
+
const toPropKey = (name) => /^[a-zA-Z_$][\w$]*$/.test(name) ? t2.identifier(name) : t2.stringLiteral(name);
|
|
16178
|
+
const isAccessorName = (name) => (ctx.memoVars?.has(name) ?? false) || (ctx.signalVars?.has(name) ?? false) || (ctx.aliasVars?.has(name) ?? false);
|
|
16179
|
+
const isZeroArgFunction = (expr) => (t2.isArrowFunctionExpression(expr) || t2.isFunctionExpression(expr)) && expr.params.length === 0;
|
|
16180
|
+
const wrapAccessorSource = (node) => {
|
|
16181
|
+
if (t2.isCallExpression(node) && t2.isIdentifier(node.callee) && node.arguments.length === 0) {
|
|
16182
|
+
const baseName2 = helpers.deSSAVarName(node.callee.name);
|
|
16183
|
+
if (isAccessorName(baseName2)) {
|
|
16184
|
+
return t2.arrowFunctionExpression([], node);
|
|
16185
|
+
}
|
|
16186
|
+
}
|
|
16187
|
+
if (t2.isIdentifier(node)) {
|
|
16188
|
+
const baseName2 = helpers.deSSAVarName(node.name);
|
|
16189
|
+
if (isAccessorName(baseName2)) {
|
|
16190
|
+
return t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseName2), []));
|
|
16191
|
+
}
|
|
16192
|
+
}
|
|
16193
|
+
return node;
|
|
16194
|
+
};
|
|
16195
|
+
const isAccessorSource = (expr) => {
|
|
16196
|
+
if (expr.kind === "Identifier") {
|
|
16197
|
+
return isAccessorName(helpers.deSSAVarName(expr.name));
|
|
16198
|
+
}
|
|
16199
|
+
if (expr.kind === "CallExpression" || expr.kind === "OptionalCallExpression") {
|
|
16200
|
+
if (expr.callee.kind === "Identifier" && expr.arguments.length === 0) {
|
|
16201
|
+
return isAccessorName(helpers.deSSAVarName(expr.callee.name));
|
|
16202
|
+
}
|
|
16203
|
+
}
|
|
16204
|
+
return false;
|
|
16205
|
+
};
|
|
16206
|
+
const isRuntimeMergeProps = () => !ctx.shadowedNames?.has(RUNTIME_ALIASES.mergeProps) && !ctx.localDeclaredNames?.has(RUNTIME_ALIASES.mergeProps) && (!ctx.moduleDeclaredNames?.has(RUNTIME_ALIASES.mergeProps) || (ctx.moduleRuntimeNames?.has(RUNTIME_ALIASES.mergeProps) ?? false));
|
|
16207
|
+
const isMergePropsCall = (expr) => expr.kind === "CallExpression" && expr.callee.kind === "Identifier" && expr.callee.name === RUNTIME_ALIASES.mergeProps && isRuntimeMergeProps();
|
|
16208
|
+
const isDynamicMemberSpread = (expr) => {
|
|
16209
|
+
if (expr.kind !== "MemberExpression" && expr.kind !== "OptionalMemberExpression") return false;
|
|
16210
|
+
if (expr.computed) return true;
|
|
16211
|
+
if (expr.kind === "OptionalMemberExpression" && expr.optional) return true;
|
|
16212
|
+
let current = expr;
|
|
16213
|
+
while (current.kind === "MemberExpression" || current.kind === "OptionalMemberExpression") {
|
|
16214
|
+
const obj = current.object;
|
|
16215
|
+
if (obj.kind === "CallExpression" || obj.kind === "OptionalCallExpression" || obj.kind === "ConditionalExpression" || obj.kind === "LogicalExpression" || obj.kind === "SequenceExpression" || obj.kind === "AssignmentExpression" || obj.kind === "UpdateExpression" || obj.kind === "AwaitExpression" || obj.kind === "NewExpression" || obj.kind === "YieldExpression") {
|
|
16216
|
+
return true;
|
|
16217
|
+
}
|
|
16218
|
+
if (obj.kind === "OptionalMemberExpression" && obj.optional) {
|
|
16219
|
+
return true;
|
|
16220
|
+
}
|
|
16221
|
+
if (obj.kind !== "MemberExpression" && obj.kind !== "OptionalMemberExpression") {
|
|
16222
|
+
return obj.kind !== "Identifier";
|
|
16223
|
+
}
|
|
16224
|
+
current = obj;
|
|
16225
|
+
}
|
|
16226
|
+
return false;
|
|
16227
|
+
};
|
|
16228
|
+
const isDynamicPropsSpread = (expr) => {
|
|
16229
|
+
if (isAccessorSource(expr) || isMergePropsCall(expr)) return false;
|
|
16230
|
+
if (expr.kind === "CallExpression" || expr.kind === "OptionalCallExpression" || expr.kind === "ConditionalExpression" || expr.kind === "LogicalExpression" || expr.kind === "SequenceExpression" || expr.kind === "AssignmentExpression" || expr.kind === "UpdateExpression" || expr.kind === "AwaitExpression" || expr.kind === "NewExpression" || expr.kind === "YieldExpression") {
|
|
16231
|
+
return true;
|
|
16232
|
+
}
|
|
16233
|
+
if (expr.kind === "MemberExpression" || expr.kind === "OptionalMemberExpression") {
|
|
16234
|
+
return isDynamicMemberSpread(expr);
|
|
16235
|
+
}
|
|
16236
|
+
if (expr.kind === "ObjectExpression") {
|
|
16237
|
+
return expr.properties.some((p) => p.kind === "SpreadElement");
|
|
16238
|
+
}
|
|
16239
|
+
return false;
|
|
16240
|
+
};
|
|
16241
|
+
const flushBucket = () => {
|
|
16242
|
+
if (bucket.length === 0) return;
|
|
16243
|
+
segments.push({ kind: "object", properties: bucket });
|
|
16244
|
+
bucket = [];
|
|
16245
|
+
};
|
|
16246
|
+
const pushSpread = (expr) => {
|
|
16247
|
+
flags.needsMergeProps = true;
|
|
16248
|
+
if (isZeroArgFunction(expr)) {
|
|
16249
|
+
flags.hasLazySource = true;
|
|
16250
|
+
}
|
|
16251
|
+
segments.push({ kind: "spread", expr });
|
|
16252
|
+
};
|
|
16253
|
+
for (const attr of attributes) {
|
|
16254
|
+
if (attr.isSpread && attr.spreadExpr) {
|
|
16255
|
+
flushBucket();
|
|
16256
|
+
if (isDynamicPropsSpread(attr.spreadExpr)) {
|
|
16257
|
+
reportDiagnostic(ctx, "FICT-P005" /* FICT_P005 */, attr.spreadExpr);
|
|
16258
|
+
}
|
|
16259
|
+
let spreadExpr = helpers.lowerDomExpression(attr.spreadExpr, ctx);
|
|
16260
|
+
if (t2.isCallExpression(spreadExpr) && t2.isIdentifier(spreadExpr.callee) && spreadExpr.callee.name === RUNTIME_ALIASES.mergeProps && isRuntimeMergeProps()) {
|
|
16261
|
+
const callExpr = spreadExpr;
|
|
16262
|
+
const rewrittenArgs = callExpr.arguments.map(
|
|
16263
|
+
(arg) => t2.isExpression(arg) ? wrapAccessorSource(arg) : arg
|
|
16264
|
+
);
|
|
16265
|
+
if (rewrittenArgs.some((arg, idx) => arg !== callExpr.arguments[idx])) {
|
|
16266
|
+
spreadExpr = t2.callExpression(
|
|
16267
|
+
callExpr.callee,
|
|
16268
|
+
rewrittenArgs
|
|
16269
|
+
);
|
|
16270
|
+
}
|
|
16271
|
+
const flattenArgs = [];
|
|
16272
|
+
let canFlatten = true;
|
|
16273
|
+
for (const arg of rewrittenArgs) {
|
|
16274
|
+
if (t2.isExpression(arg)) {
|
|
16275
|
+
flattenArgs.push(arg);
|
|
16276
|
+
} else {
|
|
16277
|
+
canFlatten = false;
|
|
16278
|
+
break;
|
|
16279
|
+
}
|
|
16280
|
+
}
|
|
16281
|
+
if (canFlatten) {
|
|
16282
|
+
for (const arg of flattenArgs) {
|
|
16283
|
+
pushSpread(arg);
|
|
16284
|
+
}
|
|
16285
|
+
continue;
|
|
16286
|
+
}
|
|
16287
|
+
}
|
|
16288
|
+
spreadExpr = wrapAccessorSource(spreadExpr);
|
|
16289
|
+
pushSpread(spreadExpr);
|
|
16290
|
+
continue;
|
|
16291
|
+
}
|
|
16292
|
+
if (attr.value) {
|
|
16293
|
+
const isFunctionLike = attr.value.kind === "ArrowFunction" || attr.value.kind === "FunctionExpression";
|
|
16294
|
+
const prevPropsCtx = ctx.inPropsContext;
|
|
16295
|
+
if (isFunctionLike) {
|
|
16296
|
+
ctx.inPropsContext = false;
|
|
16297
|
+
}
|
|
16298
|
+
const lowered = helpers.lowerDomExpression(attr.value, ctx);
|
|
16299
|
+
if (isFunctionLike) {
|
|
16300
|
+
ctx.inPropsContext = prevPropsCtx;
|
|
16301
|
+
}
|
|
16302
|
+
const baseIdent = attr.value.kind === "Identifier" ? helpers.deSSAVarName(attr.value.name) : void 0;
|
|
16303
|
+
const isAccessorBase = baseIdent && ((ctx.memoVars?.has(baseIdent) ?? false) || (ctx.signalVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false));
|
|
16304
|
+
const isStoreBase = baseIdent ? ctx.storeVars?.has(baseIdent) ?? false : false;
|
|
16305
|
+
const alreadyGetter = isFunctionLike || (baseIdent ? isStoreBase || (ctx.memoVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false) : false);
|
|
16306
|
+
const usesTracked = (!ctx.nonReactiveScopeDepth || ctx.nonReactiveScopeDepth === 0) && helpers.expressionUsesTracked(attr.value, ctx) && !alreadyGetter;
|
|
16307
|
+
const trackedExpr = usesTracked ? helpers.lowerTrackedExpression(
|
|
16308
|
+
attr.value,
|
|
16309
|
+
ctx
|
|
16310
|
+
) : null;
|
|
16311
|
+
const useMemoProp = usesTracked && trackedExpr && t2.isExpression(trackedExpr) && !t2.isIdentifier(trackedExpr) && !t2.isMemberExpression(trackedExpr) && !t2.isLiteral(trackedExpr);
|
|
16312
|
+
const valueExpr = !isFunctionLike && isAccessorBase && baseIdent ? (() => {
|
|
16313
|
+
ctx.helpersUsed.add("propGetter");
|
|
16314
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
16315
|
+
t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseIdent), []))
|
|
16316
|
+
]);
|
|
16317
|
+
})() : usesTracked && t2.isExpression(lowered) ? (() => {
|
|
16318
|
+
if (useMemoProp) {
|
|
16319
|
+
ctx.helpersUsed.add("prop");
|
|
16320
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
16321
|
+
t2.arrowFunctionExpression([], trackedExpr ?? lowered)
|
|
16322
|
+
]);
|
|
16323
|
+
}
|
|
16324
|
+
ctx.helpersUsed.add("propGetter");
|
|
16325
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
16326
|
+
t2.arrowFunctionExpression([], trackedExpr ?? lowered)
|
|
16327
|
+
]);
|
|
16328
|
+
})() : lowered;
|
|
16329
|
+
bucket.push(t2.objectProperty(toPropKey(attr.name), valueExpr));
|
|
16330
|
+
continue;
|
|
16331
|
+
}
|
|
16332
|
+
bucket.push(t2.objectProperty(toPropKey(attr.name), t2.booleanLiteral(true)));
|
|
16333
|
+
}
|
|
16334
|
+
if (children.length === 1 && children[0]) {
|
|
16335
|
+
bucket.push(t2.objectProperty(t2.identifier("children"), children[0]));
|
|
16336
|
+
} else if (children.length > 1) {
|
|
16337
|
+
bucket.push(t2.objectProperty(t2.identifier("children"), t2.arrayExpression(children)));
|
|
16338
|
+
}
|
|
16339
|
+
flushBucket();
|
|
16340
|
+
if (segments.length === 0) return null;
|
|
16341
|
+
return { segments, flags };
|
|
16342
|
+
} finally {
|
|
16343
|
+
ctx.inPropsContext = prevPropsContext;
|
|
16344
|
+
}
|
|
16345
|
+
}
|
|
16346
|
+
function lowerPropsPlan(plan, ctx) {
|
|
16347
|
+
const { t: t2 } = ctx;
|
|
16348
|
+
const args = [];
|
|
16349
|
+
for (const segment of plan.segments) {
|
|
16350
|
+
if (segment.kind === "object") {
|
|
16351
|
+
if (segment.properties.length === 0) continue;
|
|
16352
|
+
args.push(t2.objectExpression(segment.properties));
|
|
16353
|
+
continue;
|
|
16354
|
+
}
|
|
16355
|
+
args.push(segment.expr);
|
|
16356
|
+
}
|
|
16357
|
+
if (args.length === 0) return null;
|
|
16358
|
+
if (!plan.flags.needsMergeProps) {
|
|
16359
|
+
return args[0] ?? null;
|
|
16360
|
+
}
|
|
16361
|
+
if (args.length === 1 && !plan.flags.hasLazySource) {
|
|
16362
|
+
return args[0];
|
|
16363
|
+
}
|
|
16364
|
+
ctx.helpersUsed.add("mergeProps");
|
|
16365
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.mergeProps), args);
|
|
16366
|
+
}
|
|
16367
|
+
function buildPropsExpression(attributes, children, ctx, helpers) {
|
|
16368
|
+
const plan = buildPropsPlan(attributes, children, ctx, helpers);
|
|
16369
|
+
if (!plan) return null;
|
|
16370
|
+
return lowerPropsPlan(plan, ctx);
|
|
16371
|
+
}
|
|
16372
|
+
|
|
16151
16373
|
// src/ir/ssa.ts
|
|
16152
16374
|
function analyzeCFG(blocks) {
|
|
16153
16375
|
const predecessors = computePredecessors(blocks);
|
|
@@ -16645,6 +16867,9 @@ function collectExprReads(expr, into, paths, bound = /* @__PURE__ */ new Set(),
|
|
|
16645
16867
|
expr.arguments?.forEach((a) => collectExprReads(a, into, paths, bound));
|
|
16646
16868
|
return;
|
|
16647
16869
|
}
|
|
16870
|
+
case "SpreadElement":
|
|
16871
|
+
collectExprReads(expr.argument, into, paths, bound);
|
|
16872
|
+
return;
|
|
16648
16873
|
case "MemberExpression":
|
|
16649
16874
|
case "OptionalMemberExpression": {
|
|
16650
16875
|
const depPath = extractDependencyPath(expr);
|
|
@@ -18139,11 +18364,15 @@ function containsJSXExpr(expr) {
|
|
|
18139
18364
|
case "ArrayExpression":
|
|
18140
18365
|
return expr.elements?.some((el) => containsJSXExpr(el)) ?? false;
|
|
18141
18366
|
case "ObjectExpression":
|
|
18142
|
-
return expr.properties?.some(
|
|
18367
|
+
return expr.properties?.some(
|
|
18368
|
+
(p) => p.kind === "SpreadElement" ? containsJSXExpr(p.argument) : containsJSXExpr(p.value)
|
|
18369
|
+
) ?? false;
|
|
18143
18370
|
case "ConditionalExpression":
|
|
18144
18371
|
return containsJSXExpr(expr.consequent) || containsJSXExpr(expr.alternate);
|
|
18145
18372
|
case "ArrowFunction":
|
|
18146
18373
|
return containsJSXExpr(expr.body);
|
|
18374
|
+
case "SpreadElement":
|
|
18375
|
+
return containsJSXExpr(expr.argument);
|
|
18147
18376
|
default:
|
|
18148
18377
|
return false;
|
|
18149
18378
|
}
|
|
@@ -18173,6 +18402,8 @@ function expressionUsesTracked(expr, ctx) {
|
|
|
18173
18402
|
});
|
|
18174
18403
|
case "TemplateLiteral":
|
|
18175
18404
|
return expr.expressions.some((e) => expressionUsesTracked(e, ctx));
|
|
18405
|
+
case "SpreadElement":
|
|
18406
|
+
return expressionUsesTracked(expr.argument, ctx);
|
|
18176
18407
|
default:
|
|
18177
18408
|
return false;
|
|
18178
18409
|
}
|
|
@@ -20219,6 +20450,9 @@ function collectCalledIdentifiers(fn) {
|
|
|
20219
20450
|
function createCodegenContext(t2) {
|
|
20220
20451
|
return {
|
|
20221
20452
|
t: t2,
|
|
20453
|
+
moduleDeclaredNames: /* @__PURE__ */ new Set(),
|
|
20454
|
+
moduleRuntimeNames: /* @__PURE__ */ new Set(),
|
|
20455
|
+
localDeclaredNames: /* @__PURE__ */ new Set(),
|
|
20222
20456
|
helpersUsed: /* @__PURE__ */ new Set(),
|
|
20223
20457
|
tempCounter: 0,
|
|
20224
20458
|
trackedVars: /* @__PURE__ */ new Set(),
|
|
@@ -21363,8 +21597,7 @@ function lowerTerminator(block, ctx) {
|
|
|
21363
21597
|
return applyLoc([]);
|
|
21364
21598
|
}
|
|
21365
21599
|
}
|
|
21366
|
-
function
|
|
21367
|
-
if (ctx.helpersUsed.size === 0) return body;
|
|
21600
|
+
function collectDeclaredNames(body, t2) {
|
|
21368
21601
|
const declared = /* @__PURE__ */ new Set();
|
|
21369
21602
|
const addPatternNames = (pattern) => {
|
|
21370
21603
|
if (t2.isIdentifier(pattern)) {
|
|
@@ -21438,6 +21671,78 @@ function attachHelperImports(ctx, body, t2) {
|
|
|
21438
21671
|
declared.add(stmt.declaration.name);
|
|
21439
21672
|
}
|
|
21440
21673
|
}
|
|
21674
|
+
return declared;
|
|
21675
|
+
}
|
|
21676
|
+
function collectRuntimeImportNames(body, t2) {
|
|
21677
|
+
const runtimeModules = /* @__PURE__ */ new Set([RUNTIME_MODULE, "@fictjs/runtime", "fict"]);
|
|
21678
|
+
const imported = /* @__PURE__ */ new Set();
|
|
21679
|
+
for (const stmt of body) {
|
|
21680
|
+
if (!t2.isImportDeclaration(stmt)) continue;
|
|
21681
|
+
if (!runtimeModules.has(stmt.source.value)) continue;
|
|
21682
|
+
for (const spec of stmt.specifiers) {
|
|
21683
|
+
imported.add(spec.local.name);
|
|
21684
|
+
}
|
|
21685
|
+
}
|
|
21686
|
+
return imported;
|
|
21687
|
+
}
|
|
21688
|
+
function collectLocalDeclaredNames(params, blocks, t2) {
|
|
21689
|
+
const declared = /* @__PURE__ */ new Set();
|
|
21690
|
+
const addPatternNames = (pattern) => {
|
|
21691
|
+
if (t2.isIdentifier(pattern)) {
|
|
21692
|
+
declared.add(deSSAVarName(pattern.name));
|
|
21693
|
+
return;
|
|
21694
|
+
}
|
|
21695
|
+
if (t2.isAssignmentPattern(pattern)) {
|
|
21696
|
+
addPatternNames(pattern.left);
|
|
21697
|
+
return;
|
|
21698
|
+
}
|
|
21699
|
+
if (t2.isRestElement(pattern)) {
|
|
21700
|
+
addPatternNames(pattern.argument);
|
|
21701
|
+
return;
|
|
21702
|
+
}
|
|
21703
|
+
if (t2.isObjectPattern(pattern)) {
|
|
21704
|
+
for (const prop of pattern.properties) {
|
|
21705
|
+
if (t2.isRestElement(prop)) {
|
|
21706
|
+
addPatternNames(prop.argument);
|
|
21707
|
+
} else if (t2.isObjectProperty(prop)) {
|
|
21708
|
+
addPatternNames(prop.value);
|
|
21709
|
+
}
|
|
21710
|
+
}
|
|
21711
|
+
return;
|
|
21712
|
+
}
|
|
21713
|
+
if (t2.isArrayPattern(pattern)) {
|
|
21714
|
+
for (const el of pattern.elements) {
|
|
21715
|
+
if (!el) continue;
|
|
21716
|
+
if (t2.isPatternLike(el)) addPatternNames(el);
|
|
21717
|
+
}
|
|
21718
|
+
}
|
|
21719
|
+
};
|
|
21720
|
+
params.forEach((param) => declared.add(deSSAVarName(param.name)));
|
|
21721
|
+
if (!blocks) return declared;
|
|
21722
|
+
for (const block of blocks) {
|
|
21723
|
+
for (const instr of block.instructions) {
|
|
21724
|
+
if (instr.kind !== "Assign") continue;
|
|
21725
|
+
const target = deSSAVarName(instr.target.name);
|
|
21726
|
+
const isFunctionDecl = instr.value.kind === "FunctionExpression" && !!instr.value.name && deSSAVarName(instr.value.name) === target;
|
|
21727
|
+
if (instr.declarationKind || isFunctionDecl) {
|
|
21728
|
+
declared.add(target);
|
|
21729
|
+
}
|
|
21730
|
+
}
|
|
21731
|
+
const term = block.terminator;
|
|
21732
|
+
if (term.kind === "ForOf" || term.kind === "ForIn") {
|
|
21733
|
+
declared.add(deSSAVarName(term.variable));
|
|
21734
|
+
if (term.pattern) {
|
|
21735
|
+
addPatternNames(term.pattern);
|
|
21736
|
+
}
|
|
21737
|
+
} else if (term.kind === "Try" && term.catchParam) {
|
|
21738
|
+
declared.add(deSSAVarName(term.catchParam));
|
|
21739
|
+
}
|
|
21740
|
+
}
|
|
21741
|
+
return declared;
|
|
21742
|
+
}
|
|
21743
|
+
function attachHelperImports(ctx, body, t2) {
|
|
21744
|
+
if (ctx.helpersUsed.size === 0) return body;
|
|
21745
|
+
const declared = collectDeclaredNames(body, t2);
|
|
21441
21746
|
const specifiers = [];
|
|
21442
21747
|
for (const name of ctx.helpersUsed) {
|
|
21443
21748
|
const alias = RUNTIME_ALIASES[name];
|
|
@@ -21507,11 +21812,21 @@ function lowerExpression(expr, ctx, isAssigned = false) {
|
|
|
21507
21812
|
function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
21508
21813
|
const { t: t2 } = ctx;
|
|
21509
21814
|
const mapParams = (params) => params.map((p) => t2.identifier(deSSAVarName(p.name)));
|
|
21510
|
-
const
|
|
21815
|
+
const lowerArgsAsExpressions = (args) => args.map(
|
|
21816
|
+
(arg) => arg.kind === "SpreadElement" ? lowerExpression(arg.argument, ctx) : lowerExpression(arg, ctx)
|
|
21817
|
+
);
|
|
21818
|
+
const lowerCallArguments = (args, mapArg) => args.map((arg, idx) => {
|
|
21819
|
+
if (arg.kind === "SpreadElement") {
|
|
21820
|
+
return t2.spreadElement(lowerExpression(arg.argument, ctx));
|
|
21821
|
+
}
|
|
21822
|
+
return mapArg ? mapArg(arg, idx) : lowerExpression(arg, ctx);
|
|
21823
|
+
});
|
|
21824
|
+
const withFunctionScope = (paramNames, fn, localDeclared) => {
|
|
21511
21825
|
const prevTracked = ctx.trackedVars;
|
|
21512
21826
|
const prevAlias = ctx.aliasVars;
|
|
21513
21827
|
const prevExternal = ctx.externalTracked;
|
|
21514
21828
|
const prevShadowed = ctx.shadowedNames;
|
|
21829
|
+
const prevLocalDeclared = ctx.localDeclaredNames;
|
|
21515
21830
|
const scoped = new Set(ctx.trackedVars);
|
|
21516
21831
|
paramNames.forEach((n) => scoped.delete(deSSAVarName(n)));
|
|
21517
21832
|
ctx.trackedVars = scoped;
|
|
@@ -21520,11 +21835,19 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21520
21835
|
const shadowed = new Set(prevShadowed ?? []);
|
|
21521
21836
|
paramNames.forEach((n) => shadowed.add(deSSAVarName(n)));
|
|
21522
21837
|
ctx.shadowedNames = shadowed;
|
|
21838
|
+
const localNames = new Set(prevLocalDeclared ?? []);
|
|
21839
|
+
if (localDeclared) {
|
|
21840
|
+
for (const name of localDeclared) {
|
|
21841
|
+
localNames.add(deSSAVarName(name));
|
|
21842
|
+
}
|
|
21843
|
+
}
|
|
21844
|
+
ctx.localDeclaredNames = localNames;
|
|
21523
21845
|
const result = fn();
|
|
21524
21846
|
ctx.trackedVars = prevTracked;
|
|
21525
21847
|
ctx.aliasVars = prevAlias;
|
|
21526
21848
|
ctx.externalTracked = prevExternal;
|
|
21527
21849
|
ctx.shadowedNames = prevShadowed;
|
|
21850
|
+
ctx.localDeclaredNames = prevLocalDeclared;
|
|
21528
21851
|
return result;
|
|
21529
21852
|
};
|
|
21530
21853
|
const lowerBlocksToStatements = (blocks) => {
|
|
@@ -21586,7 +21909,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21586
21909
|
ctx.needsCtx = true;
|
|
21587
21910
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useSignal), [
|
|
21588
21911
|
t2.identifier("__fictCtx"),
|
|
21589
|
-
...expr.arguments
|
|
21912
|
+
...lowerCallArguments(expr.arguments)
|
|
21590
21913
|
]);
|
|
21591
21914
|
}
|
|
21592
21915
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "$effect") {
|
|
@@ -21594,14 +21917,15 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21594
21917
|
ctx.needsCtx = true;
|
|
21595
21918
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useEffect), [
|
|
21596
21919
|
t2.identifier("__fictCtx"),
|
|
21597
|
-
...
|
|
21920
|
+
...lowerCallArguments(
|
|
21921
|
+
expr.arguments,
|
|
21598
21922
|
(arg) => arg.kind === "ArrowFunction" || arg.kind === "FunctionExpression" ? withNonReactiveScope(ctx, () => lowerExpression(arg, ctx)) : lowerExpression(arg, ctx)
|
|
21599
21923
|
)
|
|
21600
21924
|
]);
|
|
21601
21925
|
}
|
|
21602
21926
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "__forOf") {
|
|
21603
21927
|
ctx.needsForOfHelper = true;
|
|
21604
|
-
const [iterable, cb] = expr.arguments
|
|
21928
|
+
const [iterable, cb] = lowerArgsAsExpressions(expr.arguments);
|
|
21605
21929
|
return t2.callExpression(t2.identifier("__fictForOf"), [
|
|
21606
21930
|
iterable ?? t2.identifier("undefined"),
|
|
21607
21931
|
cb ?? t2.arrowFunctionExpression([], t2.identifier("undefined"))
|
|
@@ -21609,7 +21933,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21609
21933
|
}
|
|
21610
21934
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "__forIn") {
|
|
21611
21935
|
ctx.needsForInHelper = true;
|
|
21612
|
-
const [obj, cb] = expr.arguments
|
|
21936
|
+
const [obj, cb] = lowerArgsAsExpressions(expr.arguments);
|
|
21613
21937
|
return t2.callExpression(t2.identifier("__fictForIn"), [
|
|
21614
21938
|
obj ?? t2.identifier("undefined"),
|
|
21615
21939
|
cb ?? t2.arrowFunctionExpression([], t2.identifier("undefined"))
|
|
@@ -21617,12 +21941,12 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21617
21941
|
}
|
|
21618
21942
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "__fictPropsRest") {
|
|
21619
21943
|
ctx.helpersUsed.add("propsRest");
|
|
21620
|
-
const args = expr.arguments
|
|
21944
|
+
const args = lowerCallArguments(expr.arguments);
|
|
21621
21945
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propsRest), args);
|
|
21622
21946
|
}
|
|
21623
21947
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "mergeProps") {
|
|
21624
21948
|
ctx.helpersUsed.add("mergeProps");
|
|
21625
|
-
const args = expr.arguments
|
|
21949
|
+
const args = lowerCallArguments(expr.arguments);
|
|
21626
21950
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.mergeProps), args);
|
|
21627
21951
|
}
|
|
21628
21952
|
const isIIFE = (expr.callee.kind === "ArrowFunction" || expr.callee.kind === "FunctionExpression") && expr.arguments.length === 0 && expr.callee.params.length === 0;
|
|
@@ -21630,7 +21954,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21630
21954
|
const calleeIsMemoAccessor = !!calleeName && ctx.memoVars?.has(calleeName);
|
|
21631
21955
|
const calleeIsSignalLike = !!calleeName && (ctx.signalVars?.has(calleeName) || ctx.storeVars?.has(calleeName));
|
|
21632
21956
|
if (calleeIsMemoAccessor && !calleeIsSignalLike && expr.arguments.length > 0) {
|
|
21633
|
-
const loweredArgs2 = expr.arguments
|
|
21957
|
+
const loweredArgs2 = lowerCallArguments(expr.arguments);
|
|
21634
21958
|
return t2.callExpression(t2.callExpression(t2.identifier(calleeName), []), loweredArgs2);
|
|
21635
21959
|
}
|
|
21636
21960
|
const lowerCallee = () => isIIFE ? withNonReactiveScope(ctx, () => lowerExpression(expr.callee, ctx)) : lowerExpression(expr.callee, ctx);
|
|
@@ -21639,7 +21963,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21639
21963
|
) || expr.callee.property.kind === "Literal" && ["map", "reduce", "forEach", "filter", "flatMap", "some", "every", "find"].includes(
|
|
21640
21964
|
String(expr.callee.property.value)
|
|
21641
21965
|
));
|
|
21642
|
-
const loweredArgs = expr.arguments
|
|
21966
|
+
const loweredArgs = lowerCallArguments(expr.arguments, (a, idx) => {
|
|
21643
21967
|
if (idx === 0 && isIteratingMethod && (a.kind === "ArrowFunction" || a.kind === "FunctionExpression")) {
|
|
21644
21968
|
return withNoMemoAndDynamicHooks(ctx, () => lowerExpression(a, ctx));
|
|
21645
21969
|
}
|
|
@@ -21745,67 +22069,81 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21745
22069
|
case "ArrowFunction": {
|
|
21746
22070
|
const paramIds = mapParams(expr.params);
|
|
21747
22071
|
const shadowed = new Set(expr.params.map((p) => deSSAVarName(p.name)));
|
|
22072
|
+
const localDeclared = collectLocalDeclaredNames(
|
|
22073
|
+
expr.params,
|
|
22074
|
+
Array.isArray(expr.body) ? expr.body : null,
|
|
22075
|
+
t2
|
|
22076
|
+
);
|
|
21748
22077
|
return withNonReactiveScope(
|
|
21749
22078
|
ctx,
|
|
21750
|
-
() => withFunctionScope(
|
|
21751
|
-
|
|
21752
|
-
|
|
21753
|
-
|
|
21754
|
-
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
22079
|
+
() => withFunctionScope(
|
|
22080
|
+
shadowed,
|
|
22081
|
+
() => {
|
|
22082
|
+
let fn;
|
|
22083
|
+
if (expr.isExpression && !Array.isArray(expr.body)) {
|
|
22084
|
+
const { result: bodyExpr, cacheDeclarations } = withGetterCache(
|
|
22085
|
+
ctx,
|
|
22086
|
+
() => lowerTrackedExpression(expr.body, ctx)
|
|
22087
|
+
);
|
|
22088
|
+
if (cacheDeclarations.length > 0) {
|
|
22089
|
+
fn = t2.arrowFunctionExpression(
|
|
22090
|
+
paramIds,
|
|
22091
|
+
t2.blockStatement([...cacheDeclarations, t2.returnStatement(bodyExpr)])
|
|
22092
|
+
);
|
|
22093
|
+
} else {
|
|
22094
|
+
fn = t2.arrowFunctionExpression(paramIds, bodyExpr);
|
|
22095
|
+
}
|
|
22096
|
+
} else if (Array.isArray(expr.body)) {
|
|
22097
|
+
const { result: stmts, cacheDeclarations } = withGetterCache(
|
|
22098
|
+
ctx,
|
|
22099
|
+
() => lowerStructuredBlocks(expr.body, expr.params, paramIds)
|
|
22100
|
+
);
|
|
21758
22101
|
fn = t2.arrowFunctionExpression(
|
|
21759
22102
|
paramIds,
|
|
21760
|
-
t2.blockStatement([...cacheDeclarations,
|
|
22103
|
+
t2.blockStatement([...cacheDeclarations, ...stmts])
|
|
21761
22104
|
);
|
|
21762
22105
|
} else {
|
|
21763
|
-
fn = t2.arrowFunctionExpression(paramIds,
|
|
22106
|
+
fn = t2.arrowFunctionExpression(paramIds, t2.blockStatement([]));
|
|
21764
22107
|
}
|
|
21765
|
-
|
|
21766
|
-
|
|
21767
|
-
|
|
21768
|
-
|
|
21769
|
-
|
|
21770
|
-
fn = t2.arrowFunctionExpression(
|
|
21771
|
-
paramIds,
|
|
21772
|
-
t2.blockStatement([...cacheDeclarations, ...stmts])
|
|
21773
|
-
);
|
|
21774
|
-
} else {
|
|
21775
|
-
fn = t2.arrowFunctionExpression(paramIds, t2.blockStatement([]));
|
|
21776
|
-
}
|
|
21777
|
-
fn.async = expr.isAsync ?? false;
|
|
21778
|
-
return fn;
|
|
21779
|
-
})
|
|
22108
|
+
fn.async = expr.isAsync ?? false;
|
|
22109
|
+
return fn;
|
|
22110
|
+
},
|
|
22111
|
+
localDeclared
|
|
22112
|
+
)
|
|
21780
22113
|
);
|
|
21781
22114
|
}
|
|
21782
22115
|
case "FunctionExpression": {
|
|
21783
22116
|
const paramIds = mapParams(expr.params);
|
|
21784
22117
|
const shadowed = new Set(expr.params.map((p) => deSSAVarName(p.name)));
|
|
22118
|
+
const localDeclared = collectLocalDeclaredNames(expr.params, expr.body, t2);
|
|
21785
22119
|
return withNonReactiveScope(
|
|
21786
22120
|
ctx,
|
|
21787
|
-
() => withFunctionScope(
|
|
21788
|
-
|
|
21789
|
-
|
|
21790
|
-
|
|
21791
|
-
|
|
21792
|
-
|
|
21793
|
-
|
|
21794
|
-
|
|
21795
|
-
|
|
21796
|
-
|
|
21797
|
-
|
|
21798
|
-
|
|
21799
|
-
|
|
21800
|
-
|
|
21801
|
-
|
|
21802
|
-
|
|
21803
|
-
|
|
21804
|
-
|
|
21805
|
-
|
|
21806
|
-
|
|
21807
|
-
|
|
21808
|
-
|
|
22121
|
+
() => withFunctionScope(
|
|
22122
|
+
shadowed,
|
|
22123
|
+
() => {
|
|
22124
|
+
let fn;
|
|
22125
|
+
if (Array.isArray(expr.body)) {
|
|
22126
|
+
const { result: stmts, cacheDeclarations } = withGetterCache(
|
|
22127
|
+
ctx,
|
|
22128
|
+
() => lowerStructuredBlocks(expr.body, expr.params, paramIds)
|
|
22129
|
+
);
|
|
22130
|
+
fn = t2.functionExpression(
|
|
22131
|
+
expr.name ? t2.identifier(deSSAVarName(expr.name)) : null,
|
|
22132
|
+
paramIds,
|
|
22133
|
+
t2.blockStatement([...cacheDeclarations, ...stmts])
|
|
22134
|
+
);
|
|
22135
|
+
} else {
|
|
22136
|
+
fn = t2.functionExpression(
|
|
22137
|
+
expr.name ? t2.identifier(deSSAVarName(expr.name)) : null,
|
|
22138
|
+
paramIds,
|
|
22139
|
+
t2.blockStatement([])
|
|
22140
|
+
);
|
|
22141
|
+
}
|
|
22142
|
+
fn.async = expr.isAsync ?? false;
|
|
22143
|
+
return fn;
|
|
22144
|
+
},
|
|
22145
|
+
localDeclared
|
|
22146
|
+
)
|
|
21809
22147
|
);
|
|
21810
22148
|
}
|
|
21811
22149
|
case "AssignmentExpression":
|
|
@@ -21939,10 +22277,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21939
22277
|
case "AwaitExpression":
|
|
21940
22278
|
return t2.awaitExpression(lowerExpression(expr.argument, ctx));
|
|
21941
22279
|
case "NewExpression":
|
|
21942
|
-
return t2.newExpression(
|
|
21943
|
-
lowerExpression(expr.callee, ctx),
|
|
21944
|
-
expr.arguments.map((a) => lowerExpression(a, ctx))
|
|
21945
|
-
);
|
|
22280
|
+
return t2.newExpression(lowerExpression(expr.callee, ctx), lowerCallArguments(expr.arguments));
|
|
21946
22281
|
case "SequenceExpression":
|
|
21947
22282
|
return t2.sequenceExpression(expr.expressions.map((e) => lowerExpression(e, ctx)));
|
|
21948
22283
|
case "YieldExpression":
|
|
@@ -21953,7 +22288,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21953
22288
|
case "OptionalCallExpression":
|
|
21954
22289
|
return t2.optionalCallExpression(
|
|
21955
22290
|
lowerExpression(expr.callee, ctx),
|
|
21956
|
-
expr.arguments
|
|
22291
|
+
lowerCallArguments(expr.arguments),
|
|
21957
22292
|
expr.optional
|
|
21958
22293
|
);
|
|
21959
22294
|
case "TaggedTemplateExpression":
|
|
@@ -22085,26 +22420,17 @@ function lowerJSXElement(jsx, ctx) {
|
|
|
22085
22420
|
]);
|
|
22086
22421
|
}
|
|
22087
22422
|
ctx.helpersUsed.add("createElement");
|
|
22088
|
-
const propsObj = buildPropsObject(jsx.attributes, ctx);
|
|
22089
22423
|
const children = jsx.children.map((c) => lowerJSXChild(c, ctx));
|
|
22424
|
+
const propsExpr = buildPropsExpression(jsx.attributes, children, ctx, {
|
|
22425
|
+
lowerDomExpression,
|
|
22426
|
+
lowerTrackedExpression,
|
|
22427
|
+
expressionUsesTracked,
|
|
22428
|
+
deSSAVarName
|
|
22429
|
+
});
|
|
22090
22430
|
const componentRef = typeof jsx.tagName === "string" ? t2.identifier(jsx.tagName) : lowerExpression(jsx.tagName, ctx);
|
|
22091
|
-
const propsWithChildren = [];
|
|
22092
|
-
if (propsObj && t2.isObjectExpression(propsObj)) {
|
|
22093
|
-
propsWithChildren.push(...propsObj.properties);
|
|
22094
|
-
}
|
|
22095
|
-
if (children.length === 1 && children[0]) {
|
|
22096
|
-
propsWithChildren.push(t2.objectProperty(t2.identifier("children"), children[0]));
|
|
22097
|
-
} else if (children.length > 1) {
|
|
22098
|
-
propsWithChildren.push(
|
|
22099
|
-
t2.objectProperty(t2.identifier("children"), t2.arrayExpression(children))
|
|
22100
|
-
);
|
|
22101
|
-
}
|
|
22102
22431
|
return t2.objectExpression([
|
|
22103
22432
|
t2.objectProperty(t2.identifier("type"), componentRef),
|
|
22104
|
-
t2.objectProperty(
|
|
22105
|
-
t2.identifier("props"),
|
|
22106
|
-
propsWithChildren.length > 0 ? t2.objectExpression(propsWithChildren) : t2.nullLiteral()
|
|
22107
|
-
)
|
|
22433
|
+
t2.objectProperty(t2.identifier("props"), propsExpr ?? t2.nullLiteral())
|
|
22108
22434
|
]);
|
|
22109
22435
|
}
|
|
22110
22436
|
const useFineGrainedDom = !ctx.noMemo;
|
|
@@ -23857,98 +24183,6 @@ function lowerJSXChild(child, ctx) {
|
|
|
23857
24183
|
return applyRegionMetadataToExpression(lowerExpression(child.value, ctx), ctx);
|
|
23858
24184
|
}
|
|
23859
24185
|
}
|
|
23860
|
-
function buildPropsObject(attributes, ctx) {
|
|
23861
|
-
const { t: t2 } = ctx;
|
|
23862
|
-
const prevPropsContext = ctx.inPropsContext;
|
|
23863
|
-
ctx.inPropsContext = true;
|
|
23864
|
-
try {
|
|
23865
|
-
if (attributes.length === 0) return null;
|
|
23866
|
-
const properties = [];
|
|
23867
|
-
const spreads = [];
|
|
23868
|
-
const toPropKey = (name) => /^[a-zA-Z_$][\w$]*$/.test(name) ? t2.identifier(name) : t2.stringLiteral(name);
|
|
23869
|
-
const isAccessorName = (name) => (ctx.memoVars?.has(name) ?? false) || (ctx.signalVars?.has(name) ?? false) || (ctx.aliasVars?.has(name) ?? false);
|
|
23870
|
-
const wrapAccessorSource = (node) => {
|
|
23871
|
-
if (t2.isCallExpression(node) && t2.isIdentifier(node.callee) && node.arguments.length === 0) {
|
|
23872
|
-
const baseName2 = deSSAVarName(node.callee.name);
|
|
23873
|
-
if (isAccessorName(baseName2)) {
|
|
23874
|
-
return t2.arrowFunctionExpression([], node);
|
|
23875
|
-
}
|
|
23876
|
-
}
|
|
23877
|
-
if (t2.isIdentifier(node)) {
|
|
23878
|
-
const baseName2 = deSSAVarName(node.name);
|
|
23879
|
-
if (isAccessorName(baseName2)) {
|
|
23880
|
-
return t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseName2), []));
|
|
23881
|
-
}
|
|
23882
|
-
}
|
|
23883
|
-
return node;
|
|
23884
|
-
};
|
|
23885
|
-
for (const attr of attributes) {
|
|
23886
|
-
if (attr.isSpread && attr.spreadExpr) {
|
|
23887
|
-
let spreadExpr = lowerDomExpression(attr.spreadExpr, ctx);
|
|
23888
|
-
if (t2.isCallExpression(spreadExpr)) {
|
|
23889
|
-
const callExpr = spreadExpr;
|
|
23890
|
-
const rewrittenArgs = callExpr.arguments.map(
|
|
23891
|
-
(arg) => t2.isExpression(arg) ? wrapAccessorSource(arg) : arg
|
|
23892
|
-
);
|
|
23893
|
-
if (rewrittenArgs.some((arg, idx) => arg !== callExpr.arguments[idx])) {
|
|
23894
|
-
spreadExpr = t2.callExpression(callExpr.callee, rewrittenArgs);
|
|
23895
|
-
}
|
|
23896
|
-
}
|
|
23897
|
-
spreadExpr = wrapAccessorSource(spreadExpr);
|
|
23898
|
-
spreads.push(t2.spreadElement(spreadExpr));
|
|
23899
|
-
} else if (attr.value) {
|
|
23900
|
-
const isFunctionLike = attr.value.kind === "ArrowFunction" || attr.value.kind === "FunctionExpression";
|
|
23901
|
-
const prevPropsCtx = ctx.inPropsContext;
|
|
23902
|
-
if (isFunctionLike) {
|
|
23903
|
-
ctx.inPropsContext = false;
|
|
23904
|
-
}
|
|
23905
|
-
const lowered = lowerDomExpression(attr.value, ctx);
|
|
23906
|
-
if (isFunctionLike) {
|
|
23907
|
-
ctx.inPropsContext = prevPropsCtx;
|
|
23908
|
-
}
|
|
23909
|
-
const baseIdent = attr.value.kind === "Identifier" ? deSSAVarName(attr.value.name) : void 0;
|
|
23910
|
-
const isAccessorBase = baseIdent && ((ctx.memoVars?.has(baseIdent) ?? false) || (ctx.signalVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false));
|
|
23911
|
-
const isStoreBase = baseIdent ? ctx.storeVars?.has(baseIdent) ?? false : false;
|
|
23912
|
-
const alreadyGetter = isFunctionLike || (baseIdent ? isStoreBase || (ctx.memoVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false) : false);
|
|
23913
|
-
const usesTracked = (!ctx.nonReactiveScopeDepth || ctx.nonReactiveScopeDepth === 0) && expressionUsesTracked(attr.value, ctx) && !alreadyGetter;
|
|
23914
|
-
const trackedExpr = usesTracked ? lowerTrackedExpression(attr.value, ctx) : null;
|
|
23915
|
-
const useMemoProp = usesTracked && trackedExpr && t2.isExpression(trackedExpr) && !t2.isIdentifier(trackedExpr) && !t2.isMemberExpression(trackedExpr) && !t2.isLiteral(trackedExpr);
|
|
23916
|
-
const valueExpr = !isFunctionLike && isAccessorBase && baseIdent ? (() => {
|
|
23917
|
-
ctx.helpersUsed.add("propGetter");
|
|
23918
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
23919
|
-
t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseIdent), []))
|
|
23920
|
-
]);
|
|
23921
|
-
})() : usesTracked && t2.isExpression(lowered) ? (() => {
|
|
23922
|
-
if (useMemoProp) {
|
|
23923
|
-
ctx.helpersUsed.add("prop");
|
|
23924
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
23925
|
-
t2.arrowFunctionExpression(
|
|
23926
|
-
[],
|
|
23927
|
-
trackedExpr ?? lowered
|
|
23928
|
-
)
|
|
23929
|
-
]);
|
|
23930
|
-
}
|
|
23931
|
-
ctx.helpersUsed.add("propGetter");
|
|
23932
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
23933
|
-
t2.arrowFunctionExpression(
|
|
23934
|
-
[],
|
|
23935
|
-
trackedExpr ?? lowered
|
|
23936
|
-
)
|
|
23937
|
-
]);
|
|
23938
|
-
})() : lowered;
|
|
23939
|
-
properties.push(t2.objectProperty(toPropKey(attr.name), valueExpr));
|
|
23940
|
-
} else {
|
|
23941
|
-
properties.push(t2.objectProperty(toPropKey(attr.name), t2.booleanLiteral(true)));
|
|
23942
|
-
}
|
|
23943
|
-
}
|
|
23944
|
-
if (spreads.length > 0) {
|
|
23945
|
-
return t2.objectExpression([...spreads, ...properties]);
|
|
23946
|
-
}
|
|
23947
|
-
return t2.objectExpression(properties);
|
|
23948
|
-
} finally {
|
|
23949
|
-
ctx.inPropsContext = prevPropsContext;
|
|
23950
|
-
}
|
|
23951
|
-
}
|
|
23952
24186
|
function isDOMProperty(name) {
|
|
23953
24187
|
return ["value", "checked", "selected", "disabled", "readOnly", "multiple", "muted"].includes(
|
|
23954
24188
|
name
|
|
@@ -23965,6 +24199,8 @@ function lowerHIRWithRegions(program, t2, options) {
|
|
|
23965
24199
|
let topLevelCtxInjected = false;
|
|
23966
24200
|
const emittedFunctionNames = /* @__PURE__ */ new Set();
|
|
23967
24201
|
const originalBody = program.originalBody ?? [];
|
|
24202
|
+
ctx.moduleDeclaredNames = collectDeclaredNames(originalBody, t2);
|
|
24203
|
+
ctx.moduleRuntimeNames = collectRuntimeImportNames(originalBody, t2);
|
|
23968
24204
|
for (const stmt of originalBody) {
|
|
23969
24205
|
if (t2.isVariableDeclaration(stmt)) {
|
|
23970
24206
|
for (const decl of stmt.declarations) {
|
|
@@ -24362,6 +24598,12 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24362
24598
|
const functionShadowed = new Set(prevShadowed ?? []);
|
|
24363
24599
|
shadowedParams.forEach((n) => functionShadowed.add(n));
|
|
24364
24600
|
ctx.shadowedNames = functionShadowed;
|
|
24601
|
+
const prevLocalDeclared = ctx.localDeclaredNames;
|
|
24602
|
+
const localDeclared = new Set(prevLocalDeclared ?? []);
|
|
24603
|
+
for (const name of collectLocalDeclaredNames(fn.params, fn.blocks, t2)) {
|
|
24604
|
+
localDeclared.add(name);
|
|
24605
|
+
}
|
|
24606
|
+
ctx.localDeclaredNames = localDeclared;
|
|
24365
24607
|
const prevExternalTracked = ctx.externalTracked;
|
|
24366
24608
|
const inheritedTracked = new Set(ctx.trackedVars);
|
|
24367
24609
|
ctx.externalTracked = inheritedTracked;
|
|
@@ -24446,13 +24688,72 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24446
24688
|
let usesProp = false;
|
|
24447
24689
|
let usesPropsRest = false;
|
|
24448
24690
|
let warnedNested = false;
|
|
24691
|
+
const reportedPatternNodes = /* @__PURE__ */ new Set();
|
|
24692
|
+
const reportPatternDiagnostic = (node, code) => {
|
|
24693
|
+
if (reportedPatternNodes.has(node)) return;
|
|
24694
|
+
reportedPatternNodes.add(node);
|
|
24695
|
+
reportDiagnostic(ctx, code, node);
|
|
24696
|
+
};
|
|
24697
|
+
const reportPropsPatternIssues = (objectPattern, allowRest) => {
|
|
24698
|
+
for (const prop of objectPattern.properties) {
|
|
24699
|
+
if (t2.isObjectProperty(prop)) {
|
|
24700
|
+
if (prop.computed) {
|
|
24701
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24702
|
+
continue;
|
|
24703
|
+
}
|
|
24704
|
+
const keyName = t2.isIdentifier(prop.key) ? prop.key.name : t2.isStringLiteral(prop.key) ? prop.key.value : t2.isNumericLiteral(prop.key) ? String(prop.key.value) : null;
|
|
24705
|
+
if (!keyName) {
|
|
24706
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24707
|
+
continue;
|
|
24708
|
+
}
|
|
24709
|
+
const value = prop.value;
|
|
24710
|
+
if (t2.isIdentifier(value)) {
|
|
24711
|
+
continue;
|
|
24712
|
+
}
|
|
24713
|
+
if (t2.isObjectPattern(value)) {
|
|
24714
|
+
reportPropsPatternIssues(value, false);
|
|
24715
|
+
continue;
|
|
24716
|
+
}
|
|
24717
|
+
if (t2.isAssignmentPattern(value)) {
|
|
24718
|
+
if (t2.isIdentifier(value.left)) {
|
|
24719
|
+
continue;
|
|
24720
|
+
}
|
|
24721
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24722
|
+
continue;
|
|
24723
|
+
}
|
|
24724
|
+
if (t2.isArrayPattern(value)) {
|
|
24725
|
+
const hasRest = value.elements.some((el) => t2.isRestElement(el));
|
|
24726
|
+
reportPatternDiagnostic(
|
|
24727
|
+
value,
|
|
24728
|
+
hasRest ? "FICT-P002" /* FICT_P002 */ : "FICT-P001" /* FICT_P001 */
|
|
24729
|
+
);
|
|
24730
|
+
continue;
|
|
24731
|
+
}
|
|
24732
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24733
|
+
continue;
|
|
24734
|
+
}
|
|
24735
|
+
if (t2.isRestElement(prop)) {
|
|
24736
|
+
if (!allowRest || !t2.isIdentifier(prop.argument)) {
|
|
24737
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24738
|
+
}
|
|
24739
|
+
continue;
|
|
24740
|
+
}
|
|
24741
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24742
|
+
}
|
|
24743
|
+
};
|
|
24449
24744
|
const memberExprForKey = (base, key) => t2.memberExpression(base, t2.identifier(key), false);
|
|
24450
24745
|
const buildDestructure = (objectPattern, baseExpr, allowRest) => {
|
|
24451
24746
|
for (const prop of objectPattern.properties) {
|
|
24452
|
-
if (t2.isObjectProperty(prop)
|
|
24747
|
+
if (t2.isObjectProperty(prop)) {
|
|
24748
|
+
if (prop.computed) {
|
|
24749
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24750
|
+
supported = false;
|
|
24751
|
+
warnedNested = true;
|
|
24752
|
+
break;
|
|
24753
|
+
}
|
|
24453
24754
|
const keyName = t2.isIdentifier(prop.key) ? prop.key.name : t2.isStringLiteral(prop.key) ? prop.key.value : t2.isNumericLiteral(prop.key) ? String(prop.key.value) : null;
|
|
24454
24755
|
if (!keyName) {
|
|
24455
|
-
|
|
24756
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24456
24757
|
supported = false;
|
|
24457
24758
|
warnedNested = true;
|
|
24458
24759
|
break;
|
|
@@ -24485,26 +24786,44 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24485
24786
|
if (!supported) break;
|
|
24486
24787
|
continue;
|
|
24487
24788
|
}
|
|
24488
|
-
if (t2.isAssignmentPattern(value)
|
|
24489
|
-
|
|
24490
|
-
|
|
24491
|
-
|
|
24492
|
-
|
|
24789
|
+
if (t2.isAssignmentPattern(value)) {
|
|
24790
|
+
if (t2.isIdentifier(value.left)) {
|
|
24791
|
+
const shouldWrapProp = !calledIdentifiers.has(value.left.name);
|
|
24792
|
+
if (shouldWrapProp) {
|
|
24793
|
+
usesProp = true;
|
|
24794
|
+
propsPlanAliases.add(value.left.name);
|
|
24795
|
+
}
|
|
24796
|
+
const baseInit = t2.logicalExpression("??", member, value.right);
|
|
24797
|
+
const init = shouldWrapProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
24798
|
+
t2.arrowFunctionExpression([], baseInit)
|
|
24799
|
+
]) : baseInit;
|
|
24800
|
+
stmts.push(
|
|
24801
|
+
t2.variableDeclaration("const", [
|
|
24802
|
+
t2.variableDeclarator(t2.identifier(value.left.name), init)
|
|
24803
|
+
])
|
|
24804
|
+
);
|
|
24805
|
+
continue;
|
|
24493
24806
|
}
|
|
24494
|
-
|
|
24495
|
-
|
|
24496
|
-
|
|
24497
|
-
|
|
24498
|
-
|
|
24499
|
-
|
|
24500
|
-
|
|
24501
|
-
|
|
24807
|
+
supported = false;
|
|
24808
|
+
if (!warnedNested) {
|
|
24809
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24810
|
+
warnedNested = true;
|
|
24811
|
+
}
|
|
24812
|
+
break;
|
|
24813
|
+
}
|
|
24814
|
+
if (t2.isArrayPattern(value)) {
|
|
24815
|
+
const hasRest = value.elements.some((el) => t2.isRestElement(el));
|
|
24816
|
+
reportPatternDiagnostic(
|
|
24817
|
+
value,
|
|
24818
|
+
hasRest ? "FICT-P002" /* FICT_P002 */ : "FICT-P001" /* FICT_P001 */
|
|
24502
24819
|
);
|
|
24503
|
-
|
|
24820
|
+
supported = false;
|
|
24821
|
+
warnedNested = true;
|
|
24822
|
+
break;
|
|
24504
24823
|
}
|
|
24505
24824
|
supported = false;
|
|
24506
24825
|
if (!warnedNested) {
|
|
24507
|
-
|
|
24826
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24508
24827
|
warnedNested = true;
|
|
24509
24828
|
}
|
|
24510
24829
|
break;
|
|
@@ -24525,13 +24844,14 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24525
24844
|
} else {
|
|
24526
24845
|
supported = false;
|
|
24527
24846
|
if (!warnedNested) {
|
|
24528
|
-
|
|
24847
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24529
24848
|
warnedNested = true;
|
|
24530
24849
|
}
|
|
24531
24850
|
break;
|
|
24532
24851
|
}
|
|
24533
24852
|
}
|
|
24534
24853
|
};
|
|
24854
|
+
reportPropsPatternIssues(pattern, true);
|
|
24535
24855
|
buildDestructure(pattern, t2.identifier("__props"), true);
|
|
24536
24856
|
if (supported) {
|
|
24537
24857
|
propsDestructurePlan = {
|
|
@@ -24578,6 +24898,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24578
24898
|
if (!hasJSX && !hasTrackedValues) {
|
|
24579
24899
|
ctx.needsCtx = prevNeedsCtx;
|
|
24580
24900
|
ctx.shadowedNames = prevShadowed;
|
|
24901
|
+
ctx.localDeclaredNames = prevLocalDeclared;
|
|
24581
24902
|
ctx.trackedVars = prevTracked;
|
|
24582
24903
|
ctx.externalTracked = prevExternalTracked;
|
|
24583
24904
|
ctx.signalVars = prevSignalVars;
|
|
@@ -24660,6 +24981,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24660
24981
|
);
|
|
24661
24982
|
ctx.needsCtx = prevNeedsCtx;
|
|
24662
24983
|
ctx.shadowedNames = prevShadowed;
|
|
24984
|
+
ctx.localDeclaredNames = prevLocalDeclared;
|
|
24663
24985
|
ctx.trackedVars = prevTracked;
|
|
24664
24986
|
ctx.externalTracked = prevExternalTracked;
|
|
24665
24987
|
ctx.signalVars = prevSignalVars;
|