@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.cjs
CHANGED
|
@@ -15559,6 +15559,17 @@ function processStatement(stmt, bb, jumpTarget, ctx) {
|
|
|
15559
15559
|
}
|
|
15560
15560
|
function convertExpression(node) {
|
|
15561
15561
|
const loc = getLoc(node);
|
|
15562
|
+
const convertCallArguments = (args) => args.map((arg) => {
|
|
15563
|
+
if (t.isSpreadElement(arg)) {
|
|
15564
|
+
return {
|
|
15565
|
+
kind: "SpreadElement",
|
|
15566
|
+
argument: convertExpression(arg.argument),
|
|
15567
|
+
loc: getLoc(arg)
|
|
15568
|
+
};
|
|
15569
|
+
}
|
|
15570
|
+
if (t.isExpression(arg)) return convertExpression(arg);
|
|
15571
|
+
return void 0;
|
|
15572
|
+
}).filter(Boolean);
|
|
15562
15573
|
if (t.isIdentifier(node)) return { kind: "Identifier", name: node.name, loc };
|
|
15563
15574
|
if (t.isStringLiteral(node) || t.isNumericLiteral(node) || t.isBooleanLiteral(node) || t.isNullLiteral(node))
|
|
15564
15575
|
return { kind: "Literal", value: node.value ?? null, loc };
|
|
@@ -15566,7 +15577,7 @@ function convertExpression(node) {
|
|
|
15566
15577
|
const call = {
|
|
15567
15578
|
kind: "CallExpression",
|
|
15568
15579
|
callee: convertExpression(node.callee),
|
|
15569
|
-
arguments: node.arguments
|
|
15580
|
+
arguments: convertCallArguments(node.arguments),
|
|
15570
15581
|
loc
|
|
15571
15582
|
};
|
|
15572
15583
|
return call;
|
|
@@ -15846,7 +15857,7 @@ function convertExpression(node) {
|
|
|
15846
15857
|
return {
|
|
15847
15858
|
kind: "NewExpression",
|
|
15848
15859
|
callee: convertExpression(node.callee),
|
|
15849
|
-
arguments: node.arguments
|
|
15860
|
+
arguments: convertCallArguments(node.arguments),
|
|
15850
15861
|
loc
|
|
15851
15862
|
};
|
|
15852
15863
|
}
|
|
@@ -15869,7 +15880,7 @@ function convertExpression(node) {
|
|
|
15869
15880
|
return {
|
|
15870
15881
|
kind: "OptionalCallExpression",
|
|
15871
15882
|
callee: convertExpression(node.callee),
|
|
15872
|
-
arguments: node.arguments
|
|
15883
|
+
arguments: convertCallArguments(node.arguments),
|
|
15873
15884
|
optional: node.optional,
|
|
15874
15885
|
loc
|
|
15875
15886
|
};
|
|
@@ -16079,6 +16090,7 @@ var DiagnosticMessages = {
|
|
|
16079
16090
|
["FICT-P002" /* FICT_P002 */]: "Array rest in props destructuring falls back to non-reactive binding.",
|
|
16080
16091
|
["FICT-P003" /* FICT_P003 */]: "Computed property in props pattern cannot be made reactive.",
|
|
16081
16092
|
["FICT-P004" /* FICT_P004 */]: "Nested props destructuring falls back to non-reactive binding; access props directly or use prop.",
|
|
16093
|
+
["FICT-P005" /* FICT_P005 */]: "Dynamic props spread may not stay reactive; consider explicit props or mergeProps(() => source).",
|
|
16082
16094
|
["FICT-S001" /* FICT_S001 */]: "State variable mutation detected outside component scope.",
|
|
16083
16095
|
["FICT-S002" /* FICT_S002 */]: "State variable escaped to external scope, may cause memory leaks.",
|
|
16084
16096
|
["FICT-E001" /* FICT_E001 */]: "Effect without reactive dependencies will run only once; consider adding state reads or removing the effect.",
|
|
@@ -16108,6 +16120,7 @@ var DiagnosticSeverities = {
|
|
|
16108
16120
|
["FICT-P002" /* FICT_P002 */]: "warning" /* Warning */,
|
|
16109
16121
|
["FICT-P003" /* FICT_P003 */]: "warning" /* Warning */,
|
|
16110
16122
|
["FICT-P004" /* FICT_P004 */]: "warning" /* Warning */,
|
|
16123
|
+
["FICT-P005" /* FICT_P005 */]: "warning" /* Warning */,
|
|
16111
16124
|
["FICT-S001" /* FICT_S001 */]: "error" /* Error */,
|
|
16112
16125
|
["FICT-S002" /* FICT_S002 */]: "warning" /* Warning */,
|
|
16113
16126
|
["FICT-E001" /* FICT_E001 */]: "warning" /* Warning */,
|
|
@@ -16160,6 +16173,215 @@ function reportDiagnostic(ctx, code, node, context) {
|
|
|
16160
16173
|
}
|
|
16161
16174
|
}
|
|
16162
16175
|
|
|
16176
|
+
// src/ir/props-plan.ts
|
|
16177
|
+
function buildPropsPlan(attributes, children, ctx, helpers) {
|
|
16178
|
+
const { t: t2 } = ctx;
|
|
16179
|
+
const prevPropsContext = ctx.inPropsContext;
|
|
16180
|
+
ctx.inPropsContext = true;
|
|
16181
|
+
try {
|
|
16182
|
+
if (attributes.length === 0 && children.length === 0) return null;
|
|
16183
|
+
const segments = [];
|
|
16184
|
+
const flags = {
|
|
16185
|
+
needsMergeProps: false,
|
|
16186
|
+
hasLazySource: false
|
|
16187
|
+
};
|
|
16188
|
+
let bucket = [];
|
|
16189
|
+
const toPropKey = (name) => /^[a-zA-Z_$][\w$]*$/.test(name) ? t2.identifier(name) : t2.stringLiteral(name);
|
|
16190
|
+
const isAccessorName = (name) => (ctx.memoVars?.has(name) ?? false) || (ctx.signalVars?.has(name) ?? false) || (ctx.aliasVars?.has(name) ?? false);
|
|
16191
|
+
const isZeroArgFunction = (expr) => (t2.isArrowFunctionExpression(expr) || t2.isFunctionExpression(expr)) && expr.params.length === 0;
|
|
16192
|
+
const wrapAccessorSource = (node) => {
|
|
16193
|
+
if (t2.isCallExpression(node) && t2.isIdentifier(node.callee) && node.arguments.length === 0) {
|
|
16194
|
+
const baseName2 = helpers.deSSAVarName(node.callee.name);
|
|
16195
|
+
if (isAccessorName(baseName2)) {
|
|
16196
|
+
return t2.arrowFunctionExpression([], node);
|
|
16197
|
+
}
|
|
16198
|
+
}
|
|
16199
|
+
if (t2.isIdentifier(node)) {
|
|
16200
|
+
const baseName2 = helpers.deSSAVarName(node.name);
|
|
16201
|
+
if (isAccessorName(baseName2)) {
|
|
16202
|
+
return t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseName2), []));
|
|
16203
|
+
}
|
|
16204
|
+
}
|
|
16205
|
+
return node;
|
|
16206
|
+
};
|
|
16207
|
+
const isAccessorSource = (expr) => {
|
|
16208
|
+
if (expr.kind === "Identifier") {
|
|
16209
|
+
return isAccessorName(helpers.deSSAVarName(expr.name));
|
|
16210
|
+
}
|
|
16211
|
+
if (expr.kind === "CallExpression" || expr.kind === "OptionalCallExpression") {
|
|
16212
|
+
if (expr.callee.kind === "Identifier" && expr.arguments.length === 0) {
|
|
16213
|
+
return isAccessorName(helpers.deSSAVarName(expr.callee.name));
|
|
16214
|
+
}
|
|
16215
|
+
}
|
|
16216
|
+
return false;
|
|
16217
|
+
};
|
|
16218
|
+
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));
|
|
16219
|
+
const isMergePropsCall = (expr) => expr.kind === "CallExpression" && expr.callee.kind === "Identifier" && expr.callee.name === RUNTIME_ALIASES.mergeProps && isRuntimeMergeProps();
|
|
16220
|
+
const isDynamicMemberSpread = (expr) => {
|
|
16221
|
+
if (expr.kind !== "MemberExpression" && expr.kind !== "OptionalMemberExpression") return false;
|
|
16222
|
+
if (expr.computed) return true;
|
|
16223
|
+
if (expr.kind === "OptionalMemberExpression" && expr.optional) return true;
|
|
16224
|
+
let current = expr;
|
|
16225
|
+
while (current.kind === "MemberExpression" || current.kind === "OptionalMemberExpression") {
|
|
16226
|
+
const obj = current.object;
|
|
16227
|
+
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") {
|
|
16228
|
+
return true;
|
|
16229
|
+
}
|
|
16230
|
+
if (obj.kind === "OptionalMemberExpression" && obj.optional) {
|
|
16231
|
+
return true;
|
|
16232
|
+
}
|
|
16233
|
+
if (obj.kind !== "MemberExpression" && obj.kind !== "OptionalMemberExpression") {
|
|
16234
|
+
return obj.kind !== "Identifier";
|
|
16235
|
+
}
|
|
16236
|
+
current = obj;
|
|
16237
|
+
}
|
|
16238
|
+
return false;
|
|
16239
|
+
};
|
|
16240
|
+
const isDynamicPropsSpread = (expr) => {
|
|
16241
|
+
if (isAccessorSource(expr) || isMergePropsCall(expr)) return false;
|
|
16242
|
+
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") {
|
|
16243
|
+
return true;
|
|
16244
|
+
}
|
|
16245
|
+
if (expr.kind === "MemberExpression" || expr.kind === "OptionalMemberExpression") {
|
|
16246
|
+
return isDynamicMemberSpread(expr);
|
|
16247
|
+
}
|
|
16248
|
+
if (expr.kind === "ObjectExpression") {
|
|
16249
|
+
return expr.properties.some((p) => p.kind === "SpreadElement");
|
|
16250
|
+
}
|
|
16251
|
+
return false;
|
|
16252
|
+
};
|
|
16253
|
+
const flushBucket = () => {
|
|
16254
|
+
if (bucket.length === 0) return;
|
|
16255
|
+
segments.push({ kind: "object", properties: bucket });
|
|
16256
|
+
bucket = [];
|
|
16257
|
+
};
|
|
16258
|
+
const pushSpread = (expr) => {
|
|
16259
|
+
flags.needsMergeProps = true;
|
|
16260
|
+
if (isZeroArgFunction(expr)) {
|
|
16261
|
+
flags.hasLazySource = true;
|
|
16262
|
+
}
|
|
16263
|
+
segments.push({ kind: "spread", expr });
|
|
16264
|
+
};
|
|
16265
|
+
for (const attr of attributes) {
|
|
16266
|
+
if (attr.isSpread && attr.spreadExpr) {
|
|
16267
|
+
flushBucket();
|
|
16268
|
+
if (isDynamicPropsSpread(attr.spreadExpr)) {
|
|
16269
|
+
reportDiagnostic(ctx, "FICT-P005" /* FICT_P005 */, attr.spreadExpr);
|
|
16270
|
+
}
|
|
16271
|
+
let spreadExpr = helpers.lowerDomExpression(attr.spreadExpr, ctx);
|
|
16272
|
+
if (t2.isCallExpression(spreadExpr) && t2.isIdentifier(spreadExpr.callee) && spreadExpr.callee.name === RUNTIME_ALIASES.mergeProps && isRuntimeMergeProps()) {
|
|
16273
|
+
const callExpr = spreadExpr;
|
|
16274
|
+
const rewrittenArgs = callExpr.arguments.map(
|
|
16275
|
+
(arg) => t2.isExpression(arg) ? wrapAccessorSource(arg) : arg
|
|
16276
|
+
);
|
|
16277
|
+
if (rewrittenArgs.some((arg, idx) => arg !== callExpr.arguments[idx])) {
|
|
16278
|
+
spreadExpr = t2.callExpression(
|
|
16279
|
+
callExpr.callee,
|
|
16280
|
+
rewrittenArgs
|
|
16281
|
+
);
|
|
16282
|
+
}
|
|
16283
|
+
const flattenArgs = [];
|
|
16284
|
+
let canFlatten = true;
|
|
16285
|
+
for (const arg of rewrittenArgs) {
|
|
16286
|
+
if (t2.isExpression(arg)) {
|
|
16287
|
+
flattenArgs.push(arg);
|
|
16288
|
+
} else {
|
|
16289
|
+
canFlatten = false;
|
|
16290
|
+
break;
|
|
16291
|
+
}
|
|
16292
|
+
}
|
|
16293
|
+
if (canFlatten) {
|
|
16294
|
+
for (const arg of flattenArgs) {
|
|
16295
|
+
pushSpread(arg);
|
|
16296
|
+
}
|
|
16297
|
+
continue;
|
|
16298
|
+
}
|
|
16299
|
+
}
|
|
16300
|
+
spreadExpr = wrapAccessorSource(spreadExpr);
|
|
16301
|
+
pushSpread(spreadExpr);
|
|
16302
|
+
continue;
|
|
16303
|
+
}
|
|
16304
|
+
if (attr.value) {
|
|
16305
|
+
const isFunctionLike = attr.value.kind === "ArrowFunction" || attr.value.kind === "FunctionExpression";
|
|
16306
|
+
const prevPropsCtx = ctx.inPropsContext;
|
|
16307
|
+
if (isFunctionLike) {
|
|
16308
|
+
ctx.inPropsContext = false;
|
|
16309
|
+
}
|
|
16310
|
+
const lowered = helpers.lowerDomExpression(attr.value, ctx);
|
|
16311
|
+
if (isFunctionLike) {
|
|
16312
|
+
ctx.inPropsContext = prevPropsCtx;
|
|
16313
|
+
}
|
|
16314
|
+
const baseIdent = attr.value.kind === "Identifier" ? helpers.deSSAVarName(attr.value.name) : void 0;
|
|
16315
|
+
const isAccessorBase = baseIdent && ((ctx.memoVars?.has(baseIdent) ?? false) || (ctx.signalVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false));
|
|
16316
|
+
const isStoreBase = baseIdent ? ctx.storeVars?.has(baseIdent) ?? false : false;
|
|
16317
|
+
const alreadyGetter = isFunctionLike || (baseIdent ? isStoreBase || (ctx.memoVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false) : false);
|
|
16318
|
+
const usesTracked = (!ctx.nonReactiveScopeDepth || ctx.nonReactiveScopeDepth === 0) && helpers.expressionUsesTracked(attr.value, ctx) && !alreadyGetter;
|
|
16319
|
+
const trackedExpr = usesTracked ? helpers.lowerTrackedExpression(
|
|
16320
|
+
attr.value,
|
|
16321
|
+
ctx
|
|
16322
|
+
) : null;
|
|
16323
|
+
const useMemoProp = usesTracked && trackedExpr && t2.isExpression(trackedExpr) && !t2.isIdentifier(trackedExpr) && !t2.isMemberExpression(trackedExpr) && !t2.isLiteral(trackedExpr);
|
|
16324
|
+
const valueExpr = !isFunctionLike && isAccessorBase && baseIdent ? (() => {
|
|
16325
|
+
ctx.helpersUsed.add("propGetter");
|
|
16326
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
16327
|
+
t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseIdent), []))
|
|
16328
|
+
]);
|
|
16329
|
+
})() : usesTracked && t2.isExpression(lowered) ? (() => {
|
|
16330
|
+
if (useMemoProp) {
|
|
16331
|
+
ctx.helpersUsed.add("prop");
|
|
16332
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
16333
|
+
t2.arrowFunctionExpression([], trackedExpr ?? lowered)
|
|
16334
|
+
]);
|
|
16335
|
+
}
|
|
16336
|
+
ctx.helpersUsed.add("propGetter");
|
|
16337
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
16338
|
+
t2.arrowFunctionExpression([], trackedExpr ?? lowered)
|
|
16339
|
+
]);
|
|
16340
|
+
})() : lowered;
|
|
16341
|
+
bucket.push(t2.objectProperty(toPropKey(attr.name), valueExpr));
|
|
16342
|
+
continue;
|
|
16343
|
+
}
|
|
16344
|
+
bucket.push(t2.objectProperty(toPropKey(attr.name), t2.booleanLiteral(true)));
|
|
16345
|
+
}
|
|
16346
|
+
if (children.length === 1 && children[0]) {
|
|
16347
|
+
bucket.push(t2.objectProperty(t2.identifier("children"), children[0]));
|
|
16348
|
+
} else if (children.length > 1) {
|
|
16349
|
+
bucket.push(t2.objectProperty(t2.identifier("children"), t2.arrayExpression(children)));
|
|
16350
|
+
}
|
|
16351
|
+
flushBucket();
|
|
16352
|
+
if (segments.length === 0) return null;
|
|
16353
|
+
return { segments, flags };
|
|
16354
|
+
} finally {
|
|
16355
|
+
ctx.inPropsContext = prevPropsContext;
|
|
16356
|
+
}
|
|
16357
|
+
}
|
|
16358
|
+
function lowerPropsPlan(plan, ctx) {
|
|
16359
|
+
const { t: t2 } = ctx;
|
|
16360
|
+
const args = [];
|
|
16361
|
+
for (const segment of plan.segments) {
|
|
16362
|
+
if (segment.kind === "object") {
|
|
16363
|
+
if (segment.properties.length === 0) continue;
|
|
16364
|
+
args.push(t2.objectExpression(segment.properties));
|
|
16365
|
+
continue;
|
|
16366
|
+
}
|
|
16367
|
+
args.push(segment.expr);
|
|
16368
|
+
}
|
|
16369
|
+
if (args.length === 0) return null;
|
|
16370
|
+
if (!plan.flags.needsMergeProps) {
|
|
16371
|
+
return args[0] ?? null;
|
|
16372
|
+
}
|
|
16373
|
+
if (args.length === 1 && !plan.flags.hasLazySource) {
|
|
16374
|
+
return args[0];
|
|
16375
|
+
}
|
|
16376
|
+
ctx.helpersUsed.add("mergeProps");
|
|
16377
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.mergeProps), args);
|
|
16378
|
+
}
|
|
16379
|
+
function buildPropsExpression(attributes, children, ctx, helpers) {
|
|
16380
|
+
const plan = buildPropsPlan(attributes, children, ctx, helpers);
|
|
16381
|
+
if (!plan) return null;
|
|
16382
|
+
return lowerPropsPlan(plan, ctx);
|
|
16383
|
+
}
|
|
16384
|
+
|
|
16163
16385
|
// src/ir/ssa.ts
|
|
16164
16386
|
function analyzeCFG(blocks) {
|
|
16165
16387
|
const predecessors = computePredecessors(blocks);
|
|
@@ -16657,6 +16879,9 @@ function collectExprReads(expr, into, paths, bound = /* @__PURE__ */ new Set(),
|
|
|
16657
16879
|
expr.arguments?.forEach((a) => collectExprReads(a, into, paths, bound));
|
|
16658
16880
|
return;
|
|
16659
16881
|
}
|
|
16882
|
+
case "SpreadElement":
|
|
16883
|
+
collectExprReads(expr.argument, into, paths, bound);
|
|
16884
|
+
return;
|
|
16660
16885
|
case "MemberExpression":
|
|
16661
16886
|
case "OptionalMemberExpression": {
|
|
16662
16887
|
const depPath = extractDependencyPath(expr);
|
|
@@ -18151,11 +18376,15 @@ function containsJSXExpr(expr) {
|
|
|
18151
18376
|
case "ArrayExpression":
|
|
18152
18377
|
return expr.elements?.some((el) => containsJSXExpr(el)) ?? false;
|
|
18153
18378
|
case "ObjectExpression":
|
|
18154
|
-
return expr.properties?.some(
|
|
18379
|
+
return expr.properties?.some(
|
|
18380
|
+
(p) => p.kind === "SpreadElement" ? containsJSXExpr(p.argument) : containsJSXExpr(p.value)
|
|
18381
|
+
) ?? false;
|
|
18155
18382
|
case "ConditionalExpression":
|
|
18156
18383
|
return containsJSXExpr(expr.consequent) || containsJSXExpr(expr.alternate);
|
|
18157
18384
|
case "ArrowFunction":
|
|
18158
18385
|
return containsJSXExpr(expr.body);
|
|
18386
|
+
case "SpreadElement":
|
|
18387
|
+
return containsJSXExpr(expr.argument);
|
|
18159
18388
|
default:
|
|
18160
18389
|
return false;
|
|
18161
18390
|
}
|
|
@@ -18185,6 +18414,8 @@ function expressionUsesTracked(expr, ctx) {
|
|
|
18185
18414
|
});
|
|
18186
18415
|
case "TemplateLiteral":
|
|
18187
18416
|
return expr.expressions.some((e) => expressionUsesTracked(e, ctx));
|
|
18417
|
+
case "SpreadElement":
|
|
18418
|
+
return expressionUsesTracked(expr.argument, ctx);
|
|
18188
18419
|
default:
|
|
18189
18420
|
return false;
|
|
18190
18421
|
}
|
|
@@ -20231,6 +20462,9 @@ function collectCalledIdentifiers(fn) {
|
|
|
20231
20462
|
function createCodegenContext(t2) {
|
|
20232
20463
|
return {
|
|
20233
20464
|
t: t2,
|
|
20465
|
+
moduleDeclaredNames: /* @__PURE__ */ new Set(),
|
|
20466
|
+
moduleRuntimeNames: /* @__PURE__ */ new Set(),
|
|
20467
|
+
localDeclaredNames: /* @__PURE__ */ new Set(),
|
|
20234
20468
|
helpersUsed: /* @__PURE__ */ new Set(),
|
|
20235
20469
|
tempCounter: 0,
|
|
20236
20470
|
trackedVars: /* @__PURE__ */ new Set(),
|
|
@@ -21375,8 +21609,7 @@ function lowerTerminator(block, ctx) {
|
|
|
21375
21609
|
return applyLoc([]);
|
|
21376
21610
|
}
|
|
21377
21611
|
}
|
|
21378
|
-
function
|
|
21379
|
-
if (ctx.helpersUsed.size === 0) return body;
|
|
21612
|
+
function collectDeclaredNames(body, t2) {
|
|
21380
21613
|
const declared = /* @__PURE__ */ new Set();
|
|
21381
21614
|
const addPatternNames = (pattern) => {
|
|
21382
21615
|
if (t2.isIdentifier(pattern)) {
|
|
@@ -21450,6 +21683,78 @@ function attachHelperImports(ctx, body, t2) {
|
|
|
21450
21683
|
declared.add(stmt.declaration.name);
|
|
21451
21684
|
}
|
|
21452
21685
|
}
|
|
21686
|
+
return declared;
|
|
21687
|
+
}
|
|
21688
|
+
function collectRuntimeImportNames(body, t2) {
|
|
21689
|
+
const runtimeModules = /* @__PURE__ */ new Set([RUNTIME_MODULE, "@fictjs/runtime", "fict"]);
|
|
21690
|
+
const imported = /* @__PURE__ */ new Set();
|
|
21691
|
+
for (const stmt of body) {
|
|
21692
|
+
if (!t2.isImportDeclaration(stmt)) continue;
|
|
21693
|
+
if (!runtimeModules.has(stmt.source.value)) continue;
|
|
21694
|
+
for (const spec of stmt.specifiers) {
|
|
21695
|
+
imported.add(spec.local.name);
|
|
21696
|
+
}
|
|
21697
|
+
}
|
|
21698
|
+
return imported;
|
|
21699
|
+
}
|
|
21700
|
+
function collectLocalDeclaredNames(params, blocks, t2) {
|
|
21701
|
+
const declared = /* @__PURE__ */ new Set();
|
|
21702
|
+
const addPatternNames = (pattern) => {
|
|
21703
|
+
if (t2.isIdentifier(pattern)) {
|
|
21704
|
+
declared.add(deSSAVarName(pattern.name));
|
|
21705
|
+
return;
|
|
21706
|
+
}
|
|
21707
|
+
if (t2.isAssignmentPattern(pattern)) {
|
|
21708
|
+
addPatternNames(pattern.left);
|
|
21709
|
+
return;
|
|
21710
|
+
}
|
|
21711
|
+
if (t2.isRestElement(pattern)) {
|
|
21712
|
+
addPatternNames(pattern.argument);
|
|
21713
|
+
return;
|
|
21714
|
+
}
|
|
21715
|
+
if (t2.isObjectPattern(pattern)) {
|
|
21716
|
+
for (const prop of pattern.properties) {
|
|
21717
|
+
if (t2.isRestElement(prop)) {
|
|
21718
|
+
addPatternNames(prop.argument);
|
|
21719
|
+
} else if (t2.isObjectProperty(prop)) {
|
|
21720
|
+
addPatternNames(prop.value);
|
|
21721
|
+
}
|
|
21722
|
+
}
|
|
21723
|
+
return;
|
|
21724
|
+
}
|
|
21725
|
+
if (t2.isArrayPattern(pattern)) {
|
|
21726
|
+
for (const el of pattern.elements) {
|
|
21727
|
+
if (!el) continue;
|
|
21728
|
+
if (t2.isPatternLike(el)) addPatternNames(el);
|
|
21729
|
+
}
|
|
21730
|
+
}
|
|
21731
|
+
};
|
|
21732
|
+
params.forEach((param) => declared.add(deSSAVarName(param.name)));
|
|
21733
|
+
if (!blocks) return declared;
|
|
21734
|
+
for (const block of blocks) {
|
|
21735
|
+
for (const instr of block.instructions) {
|
|
21736
|
+
if (instr.kind !== "Assign") continue;
|
|
21737
|
+
const target = deSSAVarName(instr.target.name);
|
|
21738
|
+
const isFunctionDecl = instr.value.kind === "FunctionExpression" && !!instr.value.name && deSSAVarName(instr.value.name) === target;
|
|
21739
|
+
if (instr.declarationKind || isFunctionDecl) {
|
|
21740
|
+
declared.add(target);
|
|
21741
|
+
}
|
|
21742
|
+
}
|
|
21743
|
+
const term = block.terminator;
|
|
21744
|
+
if (term.kind === "ForOf" || term.kind === "ForIn") {
|
|
21745
|
+
declared.add(deSSAVarName(term.variable));
|
|
21746
|
+
if (term.pattern) {
|
|
21747
|
+
addPatternNames(term.pattern);
|
|
21748
|
+
}
|
|
21749
|
+
} else if (term.kind === "Try" && term.catchParam) {
|
|
21750
|
+
declared.add(deSSAVarName(term.catchParam));
|
|
21751
|
+
}
|
|
21752
|
+
}
|
|
21753
|
+
return declared;
|
|
21754
|
+
}
|
|
21755
|
+
function attachHelperImports(ctx, body, t2) {
|
|
21756
|
+
if (ctx.helpersUsed.size === 0) return body;
|
|
21757
|
+
const declared = collectDeclaredNames(body, t2);
|
|
21453
21758
|
const specifiers = [];
|
|
21454
21759
|
for (const name of ctx.helpersUsed) {
|
|
21455
21760
|
const alias = RUNTIME_ALIASES[name];
|
|
@@ -21519,11 +21824,21 @@ function lowerExpression(expr, ctx, isAssigned = false) {
|
|
|
21519
21824
|
function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
21520
21825
|
const { t: t2 } = ctx;
|
|
21521
21826
|
const mapParams = (params) => params.map((p) => t2.identifier(deSSAVarName(p.name)));
|
|
21522
|
-
const
|
|
21827
|
+
const lowerArgsAsExpressions = (args) => args.map(
|
|
21828
|
+
(arg) => arg.kind === "SpreadElement" ? lowerExpression(arg.argument, ctx) : lowerExpression(arg, ctx)
|
|
21829
|
+
);
|
|
21830
|
+
const lowerCallArguments = (args, mapArg) => args.map((arg, idx) => {
|
|
21831
|
+
if (arg.kind === "SpreadElement") {
|
|
21832
|
+
return t2.spreadElement(lowerExpression(arg.argument, ctx));
|
|
21833
|
+
}
|
|
21834
|
+
return mapArg ? mapArg(arg, idx) : lowerExpression(arg, ctx);
|
|
21835
|
+
});
|
|
21836
|
+
const withFunctionScope = (paramNames, fn, localDeclared) => {
|
|
21523
21837
|
const prevTracked = ctx.trackedVars;
|
|
21524
21838
|
const prevAlias = ctx.aliasVars;
|
|
21525
21839
|
const prevExternal = ctx.externalTracked;
|
|
21526
21840
|
const prevShadowed = ctx.shadowedNames;
|
|
21841
|
+
const prevLocalDeclared = ctx.localDeclaredNames;
|
|
21527
21842
|
const scoped = new Set(ctx.trackedVars);
|
|
21528
21843
|
paramNames.forEach((n) => scoped.delete(deSSAVarName(n)));
|
|
21529
21844
|
ctx.trackedVars = scoped;
|
|
@@ -21532,11 +21847,19 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21532
21847
|
const shadowed = new Set(prevShadowed ?? []);
|
|
21533
21848
|
paramNames.forEach((n) => shadowed.add(deSSAVarName(n)));
|
|
21534
21849
|
ctx.shadowedNames = shadowed;
|
|
21850
|
+
const localNames = new Set(prevLocalDeclared ?? []);
|
|
21851
|
+
if (localDeclared) {
|
|
21852
|
+
for (const name of localDeclared) {
|
|
21853
|
+
localNames.add(deSSAVarName(name));
|
|
21854
|
+
}
|
|
21855
|
+
}
|
|
21856
|
+
ctx.localDeclaredNames = localNames;
|
|
21535
21857
|
const result = fn();
|
|
21536
21858
|
ctx.trackedVars = prevTracked;
|
|
21537
21859
|
ctx.aliasVars = prevAlias;
|
|
21538
21860
|
ctx.externalTracked = prevExternal;
|
|
21539
21861
|
ctx.shadowedNames = prevShadowed;
|
|
21862
|
+
ctx.localDeclaredNames = prevLocalDeclared;
|
|
21540
21863
|
return result;
|
|
21541
21864
|
};
|
|
21542
21865
|
const lowerBlocksToStatements = (blocks) => {
|
|
@@ -21598,7 +21921,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21598
21921
|
ctx.needsCtx = true;
|
|
21599
21922
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useSignal), [
|
|
21600
21923
|
t2.identifier("__fictCtx"),
|
|
21601
|
-
...expr.arguments
|
|
21924
|
+
...lowerCallArguments(expr.arguments)
|
|
21602
21925
|
]);
|
|
21603
21926
|
}
|
|
21604
21927
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "$effect") {
|
|
@@ -21606,14 +21929,15 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21606
21929
|
ctx.needsCtx = true;
|
|
21607
21930
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useEffect), [
|
|
21608
21931
|
t2.identifier("__fictCtx"),
|
|
21609
|
-
...
|
|
21932
|
+
...lowerCallArguments(
|
|
21933
|
+
expr.arguments,
|
|
21610
21934
|
(arg) => arg.kind === "ArrowFunction" || arg.kind === "FunctionExpression" ? withNonReactiveScope(ctx, () => lowerExpression(arg, ctx)) : lowerExpression(arg, ctx)
|
|
21611
21935
|
)
|
|
21612
21936
|
]);
|
|
21613
21937
|
}
|
|
21614
21938
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "__forOf") {
|
|
21615
21939
|
ctx.needsForOfHelper = true;
|
|
21616
|
-
const [iterable, cb] = expr.arguments
|
|
21940
|
+
const [iterable, cb] = lowerArgsAsExpressions(expr.arguments);
|
|
21617
21941
|
return t2.callExpression(t2.identifier("__fictForOf"), [
|
|
21618
21942
|
iterable ?? t2.identifier("undefined"),
|
|
21619
21943
|
cb ?? t2.arrowFunctionExpression([], t2.identifier("undefined"))
|
|
@@ -21621,7 +21945,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21621
21945
|
}
|
|
21622
21946
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "__forIn") {
|
|
21623
21947
|
ctx.needsForInHelper = true;
|
|
21624
|
-
const [obj, cb] = expr.arguments
|
|
21948
|
+
const [obj, cb] = lowerArgsAsExpressions(expr.arguments);
|
|
21625
21949
|
return t2.callExpression(t2.identifier("__fictForIn"), [
|
|
21626
21950
|
obj ?? t2.identifier("undefined"),
|
|
21627
21951
|
cb ?? t2.arrowFunctionExpression([], t2.identifier("undefined"))
|
|
@@ -21629,12 +21953,12 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21629
21953
|
}
|
|
21630
21954
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "__fictPropsRest") {
|
|
21631
21955
|
ctx.helpersUsed.add("propsRest");
|
|
21632
|
-
const args = expr.arguments
|
|
21956
|
+
const args = lowerCallArguments(expr.arguments);
|
|
21633
21957
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propsRest), args);
|
|
21634
21958
|
}
|
|
21635
21959
|
if (expr.callee.kind === "Identifier" && expr.callee.name === "mergeProps") {
|
|
21636
21960
|
ctx.helpersUsed.add("mergeProps");
|
|
21637
|
-
const args = expr.arguments
|
|
21961
|
+
const args = lowerCallArguments(expr.arguments);
|
|
21638
21962
|
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.mergeProps), args);
|
|
21639
21963
|
}
|
|
21640
21964
|
const isIIFE = (expr.callee.kind === "ArrowFunction" || expr.callee.kind === "FunctionExpression") && expr.arguments.length === 0 && expr.callee.params.length === 0;
|
|
@@ -21642,7 +21966,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21642
21966
|
const calleeIsMemoAccessor = !!calleeName && ctx.memoVars?.has(calleeName);
|
|
21643
21967
|
const calleeIsSignalLike = !!calleeName && (ctx.signalVars?.has(calleeName) || ctx.storeVars?.has(calleeName));
|
|
21644
21968
|
if (calleeIsMemoAccessor && !calleeIsSignalLike && expr.arguments.length > 0) {
|
|
21645
|
-
const loweredArgs2 = expr.arguments
|
|
21969
|
+
const loweredArgs2 = lowerCallArguments(expr.arguments);
|
|
21646
21970
|
return t2.callExpression(t2.callExpression(t2.identifier(calleeName), []), loweredArgs2);
|
|
21647
21971
|
}
|
|
21648
21972
|
const lowerCallee = () => isIIFE ? withNonReactiveScope(ctx, () => lowerExpression(expr.callee, ctx)) : lowerExpression(expr.callee, ctx);
|
|
@@ -21651,7 +21975,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21651
21975
|
) || expr.callee.property.kind === "Literal" && ["map", "reduce", "forEach", "filter", "flatMap", "some", "every", "find"].includes(
|
|
21652
21976
|
String(expr.callee.property.value)
|
|
21653
21977
|
));
|
|
21654
|
-
const loweredArgs = expr.arguments
|
|
21978
|
+
const loweredArgs = lowerCallArguments(expr.arguments, (a, idx) => {
|
|
21655
21979
|
if (idx === 0 && isIteratingMethod && (a.kind === "ArrowFunction" || a.kind === "FunctionExpression")) {
|
|
21656
21980
|
return withNoMemoAndDynamicHooks(ctx, () => lowerExpression(a, ctx));
|
|
21657
21981
|
}
|
|
@@ -21757,67 +22081,81 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21757
22081
|
case "ArrowFunction": {
|
|
21758
22082
|
const paramIds = mapParams(expr.params);
|
|
21759
22083
|
const shadowed = new Set(expr.params.map((p) => deSSAVarName(p.name)));
|
|
22084
|
+
const localDeclared = collectLocalDeclaredNames(
|
|
22085
|
+
expr.params,
|
|
22086
|
+
Array.isArray(expr.body) ? expr.body : null,
|
|
22087
|
+
t2
|
|
22088
|
+
);
|
|
21760
22089
|
return withNonReactiveScope(
|
|
21761
22090
|
ctx,
|
|
21762
|
-
() => withFunctionScope(
|
|
21763
|
-
|
|
21764
|
-
|
|
21765
|
-
|
|
21766
|
-
|
|
21767
|
-
|
|
21768
|
-
|
|
21769
|
-
|
|
22091
|
+
() => withFunctionScope(
|
|
22092
|
+
shadowed,
|
|
22093
|
+
() => {
|
|
22094
|
+
let fn;
|
|
22095
|
+
if (expr.isExpression && !Array.isArray(expr.body)) {
|
|
22096
|
+
const { result: bodyExpr, cacheDeclarations } = withGetterCache(
|
|
22097
|
+
ctx,
|
|
22098
|
+
() => lowerTrackedExpression(expr.body, ctx)
|
|
22099
|
+
);
|
|
22100
|
+
if (cacheDeclarations.length > 0) {
|
|
22101
|
+
fn = t2.arrowFunctionExpression(
|
|
22102
|
+
paramIds,
|
|
22103
|
+
t2.blockStatement([...cacheDeclarations, t2.returnStatement(bodyExpr)])
|
|
22104
|
+
);
|
|
22105
|
+
} else {
|
|
22106
|
+
fn = t2.arrowFunctionExpression(paramIds, bodyExpr);
|
|
22107
|
+
}
|
|
22108
|
+
} else if (Array.isArray(expr.body)) {
|
|
22109
|
+
const { result: stmts, cacheDeclarations } = withGetterCache(
|
|
22110
|
+
ctx,
|
|
22111
|
+
() => lowerStructuredBlocks(expr.body, expr.params, paramIds)
|
|
22112
|
+
);
|
|
21770
22113
|
fn = t2.arrowFunctionExpression(
|
|
21771
22114
|
paramIds,
|
|
21772
|
-
t2.blockStatement([...cacheDeclarations,
|
|
22115
|
+
t2.blockStatement([...cacheDeclarations, ...stmts])
|
|
21773
22116
|
);
|
|
21774
22117
|
} else {
|
|
21775
|
-
fn = t2.arrowFunctionExpression(paramIds,
|
|
22118
|
+
fn = t2.arrowFunctionExpression(paramIds, t2.blockStatement([]));
|
|
21776
22119
|
}
|
|
21777
|
-
|
|
21778
|
-
|
|
21779
|
-
|
|
21780
|
-
|
|
21781
|
-
|
|
21782
|
-
fn = t2.arrowFunctionExpression(
|
|
21783
|
-
paramIds,
|
|
21784
|
-
t2.blockStatement([...cacheDeclarations, ...stmts])
|
|
21785
|
-
);
|
|
21786
|
-
} else {
|
|
21787
|
-
fn = t2.arrowFunctionExpression(paramIds, t2.blockStatement([]));
|
|
21788
|
-
}
|
|
21789
|
-
fn.async = expr.isAsync ?? false;
|
|
21790
|
-
return fn;
|
|
21791
|
-
})
|
|
22120
|
+
fn.async = expr.isAsync ?? false;
|
|
22121
|
+
return fn;
|
|
22122
|
+
},
|
|
22123
|
+
localDeclared
|
|
22124
|
+
)
|
|
21792
22125
|
);
|
|
21793
22126
|
}
|
|
21794
22127
|
case "FunctionExpression": {
|
|
21795
22128
|
const paramIds = mapParams(expr.params);
|
|
21796
22129
|
const shadowed = new Set(expr.params.map((p) => deSSAVarName(p.name)));
|
|
22130
|
+
const localDeclared = collectLocalDeclaredNames(expr.params, expr.body, t2);
|
|
21797
22131
|
return withNonReactiveScope(
|
|
21798
22132
|
ctx,
|
|
21799
|
-
() => withFunctionScope(
|
|
21800
|
-
|
|
21801
|
-
|
|
21802
|
-
|
|
21803
|
-
|
|
21804
|
-
|
|
21805
|
-
|
|
21806
|
-
|
|
21807
|
-
|
|
21808
|
-
|
|
21809
|
-
|
|
21810
|
-
|
|
21811
|
-
|
|
21812
|
-
|
|
21813
|
-
|
|
21814
|
-
|
|
21815
|
-
|
|
21816
|
-
|
|
21817
|
-
|
|
21818
|
-
|
|
21819
|
-
|
|
21820
|
-
|
|
22133
|
+
() => withFunctionScope(
|
|
22134
|
+
shadowed,
|
|
22135
|
+
() => {
|
|
22136
|
+
let fn;
|
|
22137
|
+
if (Array.isArray(expr.body)) {
|
|
22138
|
+
const { result: stmts, cacheDeclarations } = withGetterCache(
|
|
22139
|
+
ctx,
|
|
22140
|
+
() => lowerStructuredBlocks(expr.body, expr.params, paramIds)
|
|
22141
|
+
);
|
|
22142
|
+
fn = t2.functionExpression(
|
|
22143
|
+
expr.name ? t2.identifier(deSSAVarName(expr.name)) : null,
|
|
22144
|
+
paramIds,
|
|
22145
|
+
t2.blockStatement([...cacheDeclarations, ...stmts])
|
|
22146
|
+
);
|
|
22147
|
+
} else {
|
|
22148
|
+
fn = t2.functionExpression(
|
|
22149
|
+
expr.name ? t2.identifier(deSSAVarName(expr.name)) : null,
|
|
22150
|
+
paramIds,
|
|
22151
|
+
t2.blockStatement([])
|
|
22152
|
+
);
|
|
22153
|
+
}
|
|
22154
|
+
fn.async = expr.isAsync ?? false;
|
|
22155
|
+
return fn;
|
|
22156
|
+
},
|
|
22157
|
+
localDeclared
|
|
22158
|
+
)
|
|
21821
22159
|
);
|
|
21822
22160
|
}
|
|
21823
22161
|
case "AssignmentExpression":
|
|
@@ -21951,10 +22289,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21951
22289
|
case "AwaitExpression":
|
|
21952
22290
|
return t2.awaitExpression(lowerExpression(expr.argument, ctx));
|
|
21953
22291
|
case "NewExpression":
|
|
21954
|
-
return t2.newExpression(
|
|
21955
|
-
lowerExpression(expr.callee, ctx),
|
|
21956
|
-
expr.arguments.map((a) => lowerExpression(a, ctx))
|
|
21957
|
-
);
|
|
22292
|
+
return t2.newExpression(lowerExpression(expr.callee, ctx), lowerCallArguments(expr.arguments));
|
|
21958
22293
|
case "SequenceExpression":
|
|
21959
22294
|
return t2.sequenceExpression(expr.expressions.map((e) => lowerExpression(e, ctx)));
|
|
21960
22295
|
case "YieldExpression":
|
|
@@ -21965,7 +22300,7 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21965
22300
|
case "OptionalCallExpression":
|
|
21966
22301
|
return t2.optionalCallExpression(
|
|
21967
22302
|
lowerExpression(expr.callee, ctx),
|
|
21968
|
-
expr.arguments
|
|
22303
|
+
lowerCallArguments(expr.arguments),
|
|
21969
22304
|
expr.optional
|
|
21970
22305
|
);
|
|
21971
22306
|
case "TaggedTemplateExpression":
|
|
@@ -22097,26 +22432,17 @@ function lowerJSXElement(jsx, ctx) {
|
|
|
22097
22432
|
]);
|
|
22098
22433
|
}
|
|
22099
22434
|
ctx.helpersUsed.add("createElement");
|
|
22100
|
-
const propsObj = buildPropsObject(jsx.attributes, ctx);
|
|
22101
22435
|
const children = jsx.children.map((c) => lowerJSXChild(c, ctx));
|
|
22436
|
+
const propsExpr = buildPropsExpression(jsx.attributes, children, ctx, {
|
|
22437
|
+
lowerDomExpression,
|
|
22438
|
+
lowerTrackedExpression,
|
|
22439
|
+
expressionUsesTracked,
|
|
22440
|
+
deSSAVarName
|
|
22441
|
+
});
|
|
22102
22442
|
const componentRef = typeof jsx.tagName === "string" ? t2.identifier(jsx.tagName) : lowerExpression(jsx.tagName, ctx);
|
|
22103
|
-
const propsWithChildren = [];
|
|
22104
|
-
if (propsObj && t2.isObjectExpression(propsObj)) {
|
|
22105
|
-
propsWithChildren.push(...propsObj.properties);
|
|
22106
|
-
}
|
|
22107
|
-
if (children.length === 1 && children[0]) {
|
|
22108
|
-
propsWithChildren.push(t2.objectProperty(t2.identifier("children"), children[0]));
|
|
22109
|
-
} else if (children.length > 1) {
|
|
22110
|
-
propsWithChildren.push(
|
|
22111
|
-
t2.objectProperty(t2.identifier("children"), t2.arrayExpression(children))
|
|
22112
|
-
);
|
|
22113
|
-
}
|
|
22114
22443
|
return t2.objectExpression([
|
|
22115
22444
|
t2.objectProperty(t2.identifier("type"), componentRef),
|
|
22116
|
-
t2.objectProperty(
|
|
22117
|
-
t2.identifier("props"),
|
|
22118
|
-
propsWithChildren.length > 0 ? t2.objectExpression(propsWithChildren) : t2.nullLiteral()
|
|
22119
|
-
)
|
|
22445
|
+
t2.objectProperty(t2.identifier("props"), propsExpr ?? t2.nullLiteral())
|
|
22120
22446
|
]);
|
|
22121
22447
|
}
|
|
22122
22448
|
const useFineGrainedDom = !ctx.noMemo;
|
|
@@ -23869,98 +24195,6 @@ function lowerJSXChild(child, ctx) {
|
|
|
23869
24195
|
return applyRegionMetadataToExpression(lowerExpression(child.value, ctx), ctx);
|
|
23870
24196
|
}
|
|
23871
24197
|
}
|
|
23872
|
-
function buildPropsObject(attributes, ctx) {
|
|
23873
|
-
const { t: t2 } = ctx;
|
|
23874
|
-
const prevPropsContext = ctx.inPropsContext;
|
|
23875
|
-
ctx.inPropsContext = true;
|
|
23876
|
-
try {
|
|
23877
|
-
if (attributes.length === 0) return null;
|
|
23878
|
-
const properties = [];
|
|
23879
|
-
const spreads = [];
|
|
23880
|
-
const toPropKey = (name) => /^[a-zA-Z_$][\w$]*$/.test(name) ? t2.identifier(name) : t2.stringLiteral(name);
|
|
23881
|
-
const isAccessorName = (name) => (ctx.memoVars?.has(name) ?? false) || (ctx.signalVars?.has(name) ?? false) || (ctx.aliasVars?.has(name) ?? false);
|
|
23882
|
-
const wrapAccessorSource = (node) => {
|
|
23883
|
-
if (t2.isCallExpression(node) && t2.isIdentifier(node.callee) && node.arguments.length === 0) {
|
|
23884
|
-
const baseName2 = deSSAVarName(node.callee.name);
|
|
23885
|
-
if (isAccessorName(baseName2)) {
|
|
23886
|
-
return t2.arrowFunctionExpression([], node);
|
|
23887
|
-
}
|
|
23888
|
-
}
|
|
23889
|
-
if (t2.isIdentifier(node)) {
|
|
23890
|
-
const baseName2 = deSSAVarName(node.name);
|
|
23891
|
-
if (isAccessorName(baseName2)) {
|
|
23892
|
-
return t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseName2), []));
|
|
23893
|
-
}
|
|
23894
|
-
}
|
|
23895
|
-
return node;
|
|
23896
|
-
};
|
|
23897
|
-
for (const attr of attributes) {
|
|
23898
|
-
if (attr.isSpread && attr.spreadExpr) {
|
|
23899
|
-
let spreadExpr = lowerDomExpression(attr.spreadExpr, ctx);
|
|
23900
|
-
if (t2.isCallExpression(spreadExpr)) {
|
|
23901
|
-
const callExpr = spreadExpr;
|
|
23902
|
-
const rewrittenArgs = callExpr.arguments.map(
|
|
23903
|
-
(arg) => t2.isExpression(arg) ? wrapAccessorSource(arg) : arg
|
|
23904
|
-
);
|
|
23905
|
-
if (rewrittenArgs.some((arg, idx) => arg !== callExpr.arguments[idx])) {
|
|
23906
|
-
spreadExpr = t2.callExpression(callExpr.callee, rewrittenArgs);
|
|
23907
|
-
}
|
|
23908
|
-
}
|
|
23909
|
-
spreadExpr = wrapAccessorSource(spreadExpr);
|
|
23910
|
-
spreads.push(t2.spreadElement(spreadExpr));
|
|
23911
|
-
} else if (attr.value) {
|
|
23912
|
-
const isFunctionLike = attr.value.kind === "ArrowFunction" || attr.value.kind === "FunctionExpression";
|
|
23913
|
-
const prevPropsCtx = ctx.inPropsContext;
|
|
23914
|
-
if (isFunctionLike) {
|
|
23915
|
-
ctx.inPropsContext = false;
|
|
23916
|
-
}
|
|
23917
|
-
const lowered = lowerDomExpression(attr.value, ctx);
|
|
23918
|
-
if (isFunctionLike) {
|
|
23919
|
-
ctx.inPropsContext = prevPropsCtx;
|
|
23920
|
-
}
|
|
23921
|
-
const baseIdent = attr.value.kind === "Identifier" ? deSSAVarName(attr.value.name) : void 0;
|
|
23922
|
-
const isAccessorBase = baseIdent && ((ctx.memoVars?.has(baseIdent) ?? false) || (ctx.signalVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false));
|
|
23923
|
-
const isStoreBase = baseIdent ? ctx.storeVars?.has(baseIdent) ?? false : false;
|
|
23924
|
-
const alreadyGetter = isFunctionLike || (baseIdent ? isStoreBase || (ctx.memoVars?.has(baseIdent) ?? false) || (ctx.aliasVars?.has(baseIdent) ?? false) : false);
|
|
23925
|
-
const usesTracked = (!ctx.nonReactiveScopeDepth || ctx.nonReactiveScopeDepth === 0) && expressionUsesTracked(attr.value, ctx) && !alreadyGetter;
|
|
23926
|
-
const trackedExpr = usesTracked ? lowerTrackedExpression(attr.value, ctx) : null;
|
|
23927
|
-
const useMemoProp = usesTracked && trackedExpr && t2.isExpression(trackedExpr) && !t2.isIdentifier(trackedExpr) && !t2.isMemberExpression(trackedExpr) && !t2.isLiteral(trackedExpr);
|
|
23928
|
-
const valueExpr = !isFunctionLike && isAccessorBase && baseIdent ? (() => {
|
|
23929
|
-
ctx.helpersUsed.add("propGetter");
|
|
23930
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
23931
|
-
t2.arrowFunctionExpression([], t2.callExpression(t2.identifier(baseIdent), []))
|
|
23932
|
-
]);
|
|
23933
|
-
})() : usesTracked && t2.isExpression(lowered) ? (() => {
|
|
23934
|
-
if (useMemoProp) {
|
|
23935
|
-
ctx.helpersUsed.add("prop");
|
|
23936
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
23937
|
-
t2.arrowFunctionExpression(
|
|
23938
|
-
[],
|
|
23939
|
-
trackedExpr ?? lowered
|
|
23940
|
-
)
|
|
23941
|
-
]);
|
|
23942
|
-
}
|
|
23943
|
-
ctx.helpersUsed.add("propGetter");
|
|
23944
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.propGetter), [
|
|
23945
|
-
t2.arrowFunctionExpression(
|
|
23946
|
-
[],
|
|
23947
|
-
trackedExpr ?? lowered
|
|
23948
|
-
)
|
|
23949
|
-
]);
|
|
23950
|
-
})() : lowered;
|
|
23951
|
-
properties.push(t2.objectProperty(toPropKey(attr.name), valueExpr));
|
|
23952
|
-
} else {
|
|
23953
|
-
properties.push(t2.objectProperty(toPropKey(attr.name), t2.booleanLiteral(true)));
|
|
23954
|
-
}
|
|
23955
|
-
}
|
|
23956
|
-
if (spreads.length > 0) {
|
|
23957
|
-
return t2.objectExpression([...spreads, ...properties]);
|
|
23958
|
-
}
|
|
23959
|
-
return t2.objectExpression(properties);
|
|
23960
|
-
} finally {
|
|
23961
|
-
ctx.inPropsContext = prevPropsContext;
|
|
23962
|
-
}
|
|
23963
|
-
}
|
|
23964
24198
|
function isDOMProperty(name) {
|
|
23965
24199
|
return ["value", "checked", "selected", "disabled", "readOnly", "multiple", "muted"].includes(
|
|
23966
24200
|
name
|
|
@@ -23977,6 +24211,8 @@ function lowerHIRWithRegions(program, t2, options) {
|
|
|
23977
24211
|
let topLevelCtxInjected = false;
|
|
23978
24212
|
const emittedFunctionNames = /* @__PURE__ */ new Set();
|
|
23979
24213
|
const originalBody = program.originalBody ?? [];
|
|
24214
|
+
ctx.moduleDeclaredNames = collectDeclaredNames(originalBody, t2);
|
|
24215
|
+
ctx.moduleRuntimeNames = collectRuntimeImportNames(originalBody, t2);
|
|
23980
24216
|
for (const stmt of originalBody) {
|
|
23981
24217
|
if (t2.isVariableDeclaration(stmt)) {
|
|
23982
24218
|
for (const decl of stmt.declarations) {
|
|
@@ -24374,6 +24610,12 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24374
24610
|
const functionShadowed = new Set(prevShadowed ?? []);
|
|
24375
24611
|
shadowedParams.forEach((n) => functionShadowed.add(n));
|
|
24376
24612
|
ctx.shadowedNames = functionShadowed;
|
|
24613
|
+
const prevLocalDeclared = ctx.localDeclaredNames;
|
|
24614
|
+
const localDeclared = new Set(prevLocalDeclared ?? []);
|
|
24615
|
+
for (const name of collectLocalDeclaredNames(fn.params, fn.blocks, t2)) {
|
|
24616
|
+
localDeclared.add(name);
|
|
24617
|
+
}
|
|
24618
|
+
ctx.localDeclaredNames = localDeclared;
|
|
24377
24619
|
const prevExternalTracked = ctx.externalTracked;
|
|
24378
24620
|
const inheritedTracked = new Set(ctx.trackedVars);
|
|
24379
24621
|
ctx.externalTracked = inheritedTracked;
|
|
@@ -24458,13 +24700,72 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24458
24700
|
let usesProp = false;
|
|
24459
24701
|
let usesPropsRest = false;
|
|
24460
24702
|
let warnedNested = false;
|
|
24703
|
+
const reportedPatternNodes = /* @__PURE__ */ new Set();
|
|
24704
|
+
const reportPatternDiagnostic = (node, code) => {
|
|
24705
|
+
if (reportedPatternNodes.has(node)) return;
|
|
24706
|
+
reportedPatternNodes.add(node);
|
|
24707
|
+
reportDiagnostic(ctx, code, node);
|
|
24708
|
+
};
|
|
24709
|
+
const reportPropsPatternIssues = (objectPattern, allowRest) => {
|
|
24710
|
+
for (const prop of objectPattern.properties) {
|
|
24711
|
+
if (t2.isObjectProperty(prop)) {
|
|
24712
|
+
if (prop.computed) {
|
|
24713
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24714
|
+
continue;
|
|
24715
|
+
}
|
|
24716
|
+
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;
|
|
24717
|
+
if (!keyName) {
|
|
24718
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24719
|
+
continue;
|
|
24720
|
+
}
|
|
24721
|
+
const value = prop.value;
|
|
24722
|
+
if (t2.isIdentifier(value)) {
|
|
24723
|
+
continue;
|
|
24724
|
+
}
|
|
24725
|
+
if (t2.isObjectPattern(value)) {
|
|
24726
|
+
reportPropsPatternIssues(value, false);
|
|
24727
|
+
continue;
|
|
24728
|
+
}
|
|
24729
|
+
if (t2.isAssignmentPattern(value)) {
|
|
24730
|
+
if (t2.isIdentifier(value.left)) {
|
|
24731
|
+
continue;
|
|
24732
|
+
}
|
|
24733
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24734
|
+
continue;
|
|
24735
|
+
}
|
|
24736
|
+
if (t2.isArrayPattern(value)) {
|
|
24737
|
+
const hasRest = value.elements.some((el) => t2.isRestElement(el));
|
|
24738
|
+
reportPatternDiagnostic(
|
|
24739
|
+
value,
|
|
24740
|
+
hasRest ? "FICT-P002" /* FICT_P002 */ : "FICT-P001" /* FICT_P001 */
|
|
24741
|
+
);
|
|
24742
|
+
continue;
|
|
24743
|
+
}
|
|
24744
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24745
|
+
continue;
|
|
24746
|
+
}
|
|
24747
|
+
if (t2.isRestElement(prop)) {
|
|
24748
|
+
if (!allowRest || !t2.isIdentifier(prop.argument)) {
|
|
24749
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24750
|
+
}
|
|
24751
|
+
continue;
|
|
24752
|
+
}
|
|
24753
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24754
|
+
}
|
|
24755
|
+
};
|
|
24461
24756
|
const memberExprForKey = (base, key) => t2.memberExpression(base, t2.identifier(key), false);
|
|
24462
24757
|
const buildDestructure = (objectPattern, baseExpr, allowRest) => {
|
|
24463
24758
|
for (const prop of objectPattern.properties) {
|
|
24464
|
-
if (t2.isObjectProperty(prop)
|
|
24759
|
+
if (t2.isObjectProperty(prop)) {
|
|
24760
|
+
if (prop.computed) {
|
|
24761
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24762
|
+
supported = false;
|
|
24763
|
+
warnedNested = true;
|
|
24764
|
+
break;
|
|
24765
|
+
}
|
|
24465
24766
|
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;
|
|
24466
24767
|
if (!keyName) {
|
|
24467
|
-
|
|
24768
|
+
reportPatternDiagnostic(prop, "FICT-P003" /* FICT_P003 */);
|
|
24468
24769
|
supported = false;
|
|
24469
24770
|
warnedNested = true;
|
|
24470
24771
|
break;
|
|
@@ -24497,26 +24798,44 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24497
24798
|
if (!supported) break;
|
|
24498
24799
|
continue;
|
|
24499
24800
|
}
|
|
24500
|
-
if (t2.isAssignmentPattern(value)
|
|
24501
|
-
|
|
24502
|
-
|
|
24503
|
-
|
|
24504
|
-
|
|
24801
|
+
if (t2.isAssignmentPattern(value)) {
|
|
24802
|
+
if (t2.isIdentifier(value.left)) {
|
|
24803
|
+
const shouldWrapProp = !calledIdentifiers.has(value.left.name);
|
|
24804
|
+
if (shouldWrapProp) {
|
|
24805
|
+
usesProp = true;
|
|
24806
|
+
propsPlanAliases.add(value.left.name);
|
|
24807
|
+
}
|
|
24808
|
+
const baseInit = t2.logicalExpression("??", member, value.right);
|
|
24809
|
+
const init = shouldWrapProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
24810
|
+
t2.arrowFunctionExpression([], baseInit)
|
|
24811
|
+
]) : baseInit;
|
|
24812
|
+
stmts.push(
|
|
24813
|
+
t2.variableDeclaration("const", [
|
|
24814
|
+
t2.variableDeclarator(t2.identifier(value.left.name), init)
|
|
24815
|
+
])
|
|
24816
|
+
);
|
|
24817
|
+
continue;
|
|
24505
24818
|
}
|
|
24506
|
-
|
|
24507
|
-
|
|
24508
|
-
|
|
24509
|
-
|
|
24510
|
-
|
|
24511
|
-
|
|
24512
|
-
|
|
24513
|
-
|
|
24819
|
+
supported = false;
|
|
24820
|
+
if (!warnedNested) {
|
|
24821
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24822
|
+
warnedNested = true;
|
|
24823
|
+
}
|
|
24824
|
+
break;
|
|
24825
|
+
}
|
|
24826
|
+
if (t2.isArrayPattern(value)) {
|
|
24827
|
+
const hasRest = value.elements.some((el) => t2.isRestElement(el));
|
|
24828
|
+
reportPatternDiagnostic(
|
|
24829
|
+
value,
|
|
24830
|
+
hasRest ? "FICT-P002" /* FICT_P002 */ : "FICT-P001" /* FICT_P001 */
|
|
24514
24831
|
);
|
|
24515
|
-
|
|
24832
|
+
supported = false;
|
|
24833
|
+
warnedNested = true;
|
|
24834
|
+
break;
|
|
24516
24835
|
}
|
|
24517
24836
|
supported = false;
|
|
24518
24837
|
if (!warnedNested) {
|
|
24519
|
-
|
|
24838
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24520
24839
|
warnedNested = true;
|
|
24521
24840
|
}
|
|
24522
24841
|
break;
|
|
@@ -24537,13 +24856,14 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24537
24856
|
} else {
|
|
24538
24857
|
supported = false;
|
|
24539
24858
|
if (!warnedNested) {
|
|
24540
|
-
|
|
24859
|
+
reportPatternDiagnostic(prop, "FICT-P004" /* FICT_P004 */);
|
|
24541
24860
|
warnedNested = true;
|
|
24542
24861
|
}
|
|
24543
24862
|
break;
|
|
24544
24863
|
}
|
|
24545
24864
|
}
|
|
24546
24865
|
};
|
|
24866
|
+
reportPropsPatternIssues(pattern, true);
|
|
24547
24867
|
buildDestructure(pattern, t2.identifier("__props"), true);
|
|
24548
24868
|
if (supported) {
|
|
24549
24869
|
propsDestructurePlan = {
|
|
@@ -24590,6 +24910,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24590
24910
|
if (!hasJSX && !hasTrackedValues) {
|
|
24591
24911
|
ctx.needsCtx = prevNeedsCtx;
|
|
24592
24912
|
ctx.shadowedNames = prevShadowed;
|
|
24913
|
+
ctx.localDeclaredNames = prevLocalDeclared;
|
|
24593
24914
|
ctx.trackedVars = prevTracked;
|
|
24594
24915
|
ctx.externalTracked = prevExternalTracked;
|
|
24595
24916
|
ctx.signalVars = prevSignalVars;
|
|
@@ -24672,6 +24993,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24672
24993
|
);
|
|
24673
24994
|
ctx.needsCtx = prevNeedsCtx;
|
|
24674
24995
|
ctx.shadowedNames = prevShadowed;
|
|
24996
|
+
ctx.localDeclaredNames = prevLocalDeclared;
|
|
24675
24997
|
ctx.trackedVars = prevTracked;
|
|
24676
24998
|
ctx.externalTracked = prevExternalTracked;
|
|
24677
24999
|
ctx.signalVars = prevSignalVars;
|