@barefootjs/jsx 0.29.0 → 0.30.2
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/adapters/child-scope.d.ts +17 -0
- package/dist/adapters/child-scope.d.ts.map +1 -0
- package/dist/adapters/loop-bound-names.d.ts.map +1 -1
- package/dist/analyzer-context.d.ts.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +990 -367
- package/dist/ir-to-client-js/collect-elements.d.ts +5 -25
- package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts +66 -2
- package/dist/ir-to-client-js/control-flow/plan/build-lazy-row.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-reactive-effects.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts +92 -0
- package/dist/ir-to-client-js/control-flow/plan/lazy-conditional.d.ts.map +1 -0
- package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts +134 -0
- package/dist/ir-to-client-js/control-flow/plan/lazy-preamble.d.ts.map +1 -0
- package/dist/ir-to-client-js/control-flow/plan/lazy-row-eligibility.d.ts +46 -11
- package/dist/ir-to-client-js/control-flow/plan/lazy-row-eligibility.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/reactive-effects.d.ts +7 -0
- package/dist/ir-to-client-js/control-flow/plan/reactive-effects.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/lazy-row.d.ts.map +1 -1
- package/dist/ir-to-client-js/csr-substitute.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +2 -3
- package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
- package/dist/ir-to-client-js/plan/declaration-emit.d.ts +6 -0
- package/dist/ir-to-client-js/plan/declaration-emit.d.ts.map +1 -1
- package/dist/ir-to-client-js/reactivity.d.ts +1 -10
- package/dist/ir-to-client-js/reactivity.d.ts.map +1 -1
- package/dist/ir-to-client-js/types.d.ts +12 -0
- package/dist/ir-to-client-js/types.d.ts.map +1 -1
- package/dist/jsx-to-ir.d.ts.map +1 -1
- package/dist/prop-rewrite.d.ts +24 -7
- package/dist/prop-rewrite.d.ts.map +1 -1
- package/dist/rich-type-evidence.d.ts.map +1 -1
- package/dist/ssr-defaults.d.ts.map +1 -1
- package/dist/to-locale-date-lowering.d.ts.map +1 -1
- package/dist/types.d.ts +78 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +6 -24
- package/src/__tests__/branch-loop-plain.test.ts +28 -45
- package/src/__tests__/csr-substitution-safety-divergence.test.ts +9 -3
- package/src/__tests__/csr-template-scope-soundness.test.ts +167 -0
- package/src/__tests__/early-return-branch-switch.test.ts +96 -0
- package/src/__tests__/form-control-value-ssr.test.ts +102 -0
- package/src/__tests__/lazy-conditional.test.ts +190 -0
- package/src/__tests__/lazy-preamble.test.ts +297 -0
- package/src/__tests__/lazy-row-eligibility.test.ts +97 -28
- package/src/__tests__/loop-item-root-scope.test.ts +213 -0
- package/src/__tests__/map-multi-return-body.test.ts +30 -3
- package/src/__tests__/nested-loop-conditional.test.ts +27 -6
- package/src/__tests__/preamble-attr-reactivity.test.ts +217 -0
- package/src/__tests__/preamble-declarations.test.ts +207 -0
- package/src/__tests__/ssr-defaults.test.ts +44 -0
- package/src/adapters/child-scope.ts +22 -0
- package/src/adapters/loop-bound-names.ts +6 -0
- package/src/analyzer-context.ts +43 -0
- package/src/analyzer.ts +33 -3
- package/src/index.ts +1 -0
- package/src/ir-to-client-js/collect-elements.ts +51 -10
- package/src/ir-to-client-js/control-flow/plan/build-branch-loop.ts +1 -1
- package/src/ir-to-client-js/control-flow/plan/build-composite-loop.ts +2 -2
- package/src/ir-to-client-js/control-flow/plan/build-event-delegation.ts +3 -3
- package/src/ir-to-client-js/control-flow/plan/build-inner-loop.ts +2 -2
- package/src/ir-to-client-js/control-flow/plan/build-lazy-row.ts +147 -5
- package/src/ir-to-client-js/control-flow/plan/build-loop.ts +2 -2
- package/src/ir-to-client-js/control-flow/plan/build-reactive-effects.ts +1 -0
- package/src/ir-to-client-js/control-flow/plan/lazy-conditional.ts +151 -0
- package/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts +287 -0
- package/src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts +85 -22
- package/src/ir-to-client-js/control-flow/plan/reactive-effects.ts +7 -0
- package/src/ir-to-client-js/control-flow/stringify/lazy-row.ts +133 -35
- package/src/ir-to-client-js/control-flow/stringify/reactive-effects.ts +24 -4
- package/src/ir-to-client-js/csr-substitute.ts +6 -1
- package/src/ir-to-client-js/emit-registration.ts +1 -1
- package/src/ir-to-client-js/html-template.ts +51 -40
- package/src/ir-to-client-js/index.ts +1 -1
- package/src/ir-to-client-js/plan/build-declaration-emit.ts +2 -0
- package/src/ir-to-client-js/plan/build-static-array-child-init.ts +1 -1
- package/src/ir-to-client-js/plan/declaration-emit.ts +6 -0
- package/src/ir-to-client-js/reactivity.ts +25 -0
- package/src/ir-to-client-js/stringify/declaration-emit.ts +9 -4
- package/src/ir-to-client-js/types.ts +12 -0
- package/src/jsx-to-ir.ts +409 -24
- package/src/prop-rewrite.ts +149 -19
- package/src/rich-type-evidence.ts +6 -7
- package/src/ssr-defaults.ts +7 -2
- package/src/to-locale-date-lowering.ts +8 -2
- package/src/types.ts +80 -0
package/dist/index.js
CHANGED
|
@@ -3073,7 +3073,7 @@ function buildSignalMemoEnv(signals, memos, propsObjectName) {
|
|
|
3073
3073
|
for (const m of memos) {
|
|
3074
3074
|
substitutions.set(m.name, {
|
|
3075
3075
|
kind: "call",
|
|
3076
|
-
replacement: extractMemoBodyExpr(m.computation),
|
|
3076
|
+
replacement: extractMemoBodyExpr(m.templateComputation ?? m.computation),
|
|
3077
3077
|
freeIdentifiers: m.computationFreeIdentifiers ?? new Set
|
|
3078
3078
|
});
|
|
3079
3079
|
}
|
|
@@ -3091,6 +3091,13 @@ function normalizeSignalInitial(signal, propsObjectName) {
|
|
|
3091
3091
|
|
|
3092
3092
|
// src/ir-to-client-js/html-template.ts
|
|
3093
3093
|
import { BF_PARENT_SCOPE_PLACEHOLDER, BF_SCOPE, escapeHtml } from "@barefootjs/shared";
|
|
3094
|
+
|
|
3095
|
+
// src/adapters/child-scope.ts
|
|
3096
|
+
function derivesScopeFromSlot(comp) {
|
|
3097
|
+
return comp.slotId != null && comp.loopItemRoot !== true;
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
// src/ir-to-client-js/html-template.ts
|
|
3094
3101
|
function createStringProtector() {
|
|
3095
3102
|
const strings = [];
|
|
3096
3103
|
const protect = (s) => {
|
|
@@ -3423,7 +3430,7 @@ function renderFlatMapClientBody(cb, restSpreadNames) {
|
|
|
3423
3430
|
rawLeaf: true,
|
|
3424
3431
|
renderLeaf: (ir) => {
|
|
3425
3432
|
const key = flatMapLeafKeyExpr(ir);
|
|
3426
|
-
const html = irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, 1, undefined, undefined
|
|
3433
|
+
const html = irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, 1, undefined, undefined);
|
|
3427
3434
|
return `({ k: ${key ?? "undefined"}, h: \`${html}\` })`;
|
|
3428
3435
|
}
|
|
3429
3436
|
});
|
|
@@ -3435,7 +3442,7 @@ function renderFlatMapProjectionClientBody(inner, restSpreadNames) {
|
|
|
3435
3442
|
const chained = applyLoopChain(inner);
|
|
3436
3443
|
const params = inner.index ? `(${inner.param}, ${inner.index})` : `(${inner.param})`;
|
|
3437
3444
|
const key = inner.key ? `(${inner.key})` : "undefined";
|
|
3438
|
-
const html = inner.children.map((c) => irToHtmlTemplate(escapeLeafTextExpressions(c), restSpreadNames, 1, undefined, undefined
|
|
3445
|
+
const html = inner.children.map((c) => irToHtmlTemplate(escapeLeafTextExpressions(c), restSpreadNames, 1, undefined, undefined)).join("");
|
|
3439
3446
|
return `${chained}.map(${params} => ({ k: ${key}, h: \`${html}\` }))`;
|
|
3440
3447
|
}
|
|
3441
3448
|
function escapeLeafTextExpressions(ir) {
|
|
@@ -3461,8 +3468,8 @@ function escapeLeafTextExpressions(ir) {
|
|
|
3461
3468
|
return ir;
|
|
3462
3469
|
}
|
|
3463
3470
|
}
|
|
3464
|
-
function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, branchSlotsVar,
|
|
3465
|
-
const recurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar,
|
|
3471
|
+
function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, branchSlotsVar, inHoistedChildren = false) {
|
|
3472
|
+
const recurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, inHoistedChildren);
|
|
3466
3473
|
const wrapExpr = (expr) => wrapExprWithLoopParams(expr, loopParams);
|
|
3467
3474
|
const wrapInterpolation = (expr) => branchSlotsVar ? `__bfSlot(${expr}, ${branchSlotsVar})` : expr;
|
|
3468
3475
|
switch (node.type) {
|
|
@@ -3493,7 +3500,7 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3493
3500
|
attrParts.push(`bf="${node.slotId}"`);
|
|
3494
3501
|
}
|
|
3495
3502
|
const attrs = attrParts.join(" ");
|
|
3496
|
-
const childrenRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar,
|
|
3503
|
+
const childrenRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, false);
|
|
3497
3504
|
const children = dangerouslyHtmlChildren(node.attrs, (v) => wrapExpr(v.expr)) ?? node.children.map(childrenRecurse).join("");
|
|
3498
3505
|
if (children || !VOID_ELEMENTS.has(node.tag)) {
|
|
3499
3506
|
return `<${node.tag}${attrs ? " " + attrs : ""}>${children}</${node.tag}>`;
|
|
@@ -3530,12 +3537,12 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3530
3537
|
if (node.name === "Portal") {
|
|
3531
3538
|
return node.children.map(recurse).join("");
|
|
3532
3539
|
}
|
|
3533
|
-
const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
|
|
3540
|
+
const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => p.name !== "ref" && !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
|
|
3534
3541
|
if (p.clientOnly)
|
|
3535
3542
|
return null;
|
|
3536
3543
|
switch (p.value.kind) {
|
|
3537
3544
|
case "jsx-children": {
|
|
3538
|
-
const hoistedRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar,
|
|
3545
|
+
const hoistedRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth, loopParams, branchSlotsVar, true);
|
|
3539
3546
|
const childHtml = p.value.children.map((c) => hoistedRecurse(c)).join("");
|
|
3540
3547
|
return `${quotePropName(p.name)}: \`${childHtml}\``;
|
|
3541
3548
|
}
|
|
@@ -3548,7 +3555,7 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3548
3555
|
case "expression":
|
|
3549
3556
|
case "template":
|
|
3550
3557
|
case "spread": {
|
|
3551
|
-
const expr = attrValueToString(p.value) ?? "undefined";
|
|
3558
|
+
const expr = attrValueToString(p.value, { useTemplate: true }) ?? "undefined";
|
|
3552
3559
|
return `${quotePropName(p.name)}: ${expr}`;
|
|
3553
3560
|
}
|
|
3554
3561
|
}
|
|
@@ -3559,11 +3566,11 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3559
3566
|
const propsExpr = propsEntries.length > 0 ? `{${propsEntries.join(", ")}}` : "{}";
|
|
3560
3567
|
const keyProp = node.props.find((p) => p.name === "key");
|
|
3561
3568
|
const keyArg = keyProp ? `, ${attrValueToString(keyProp.value) ?? "undefined"}` : "";
|
|
3562
|
-
const slotArg =
|
|
3569
|
+
const slotArg = derivesScopeFromSlot(node) ? `, '${node.slotId}'` : "";
|
|
3563
3570
|
return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
|
|
3564
3571
|
}
|
|
3565
3572
|
case "loop": {
|
|
3566
|
-
const innerRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar
|
|
3573
|
+
const innerRecurse = (n) => irToHtmlTemplate(n, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar);
|
|
3567
3574
|
let childTemplate = node.children.map(innerRecurse).join("");
|
|
3568
3575
|
if (node.bodyIsItemConditional && node.key) {
|
|
3569
3576
|
childTemplate = `${itemAnchorTemplate(node.key)}${childTemplate}`;
|
|
@@ -3576,11 +3583,11 @@ function irToHtmlTemplate(node, restSpreadNames, loopDepth = 0, loopParams, bran
|
|
|
3576
3583
|
let mapExpr;
|
|
3577
3584
|
if (node.flatMapCallback) {
|
|
3578
3585
|
const body = renderPreamble(node.flatMapCallback, {
|
|
3579
|
-
renderLeaf: (ir) => irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar
|
|
3586
|
+
renderLeaf: (ir) => irToHtmlTemplate(stripLeafKeyAttr(ir), restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar)
|
|
3580
3587
|
});
|
|
3581
3588
|
mapExpr = `\${${wrappedArray}.flatMap(${node.flatMapCallback.params} => ${body}).join('')}`;
|
|
3582
3589
|
} else if (node.preamble) {
|
|
3583
|
-
const preamble = renderPreamble(node.preamble, { textVariant: "client", renderLeaf: (ir) => irToHtmlTemplate(ir, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar
|
|
3590
|
+
const preamble = renderPreamble(node.preamble, { textVariant: "client", renderLeaf: (ir) => irToHtmlTemplate(ir, restSpreadNames, loopDepth + 1, loopParams, branchSlotsVar) });
|
|
3584
3591
|
mapExpr = `\${${wrappedArray}.${iterMethod}(${callbackParam} => { ${preamble} return \`${childTemplate}\` }).join('')}`;
|
|
3585
3592
|
} else {
|
|
3586
3593
|
mapExpr = `\${${wrappedArray}.${iterMethod}(${callbackParam} => \`${childTemplate}\`).join('')}`;
|
|
@@ -4085,7 +4092,7 @@ function irToComponentTemplateWithOpts(node, opts) {
|
|
|
4085
4092
|
if (node.name === "Portal") {
|
|
4086
4093
|
return node.children.map(recurse).join("");
|
|
4087
4094
|
}
|
|
4088
|
-
const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
|
|
4095
|
+
const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => p.name !== "ref" && !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
|
|
4089
4096
|
if (p.clientOnly)
|
|
4090
4097
|
return null;
|
|
4091
4098
|
switch (p.value.kind) {
|
|
@@ -4202,7 +4209,7 @@ function canGenerateStaticTemplate(node, propNames, inlinableConstants, unsafeLo
|
|
|
4202
4209
|
return assertNever(node);
|
|
4203
4210
|
}
|
|
4204
4211
|
}
|
|
4205
|
-
function generateCsrTemplate(node, inlinableConstants, ctx,
|
|
4212
|
+
function generateCsrTemplate(node, inlinableConstants, ctx, restSpreadNames, propsObjectName, unsafeLocalNames, deferredChildSlots) {
|
|
4206
4213
|
const base = buildSignalMemoEnv(ctx.signals, ctx.memos, propsObjectName ?? null);
|
|
4207
4214
|
const csrEnv = { substitutions: new Map(base.substitutions), propsObjectName: base.propsObjectName };
|
|
4208
4215
|
if (inlinableConstants) {
|
|
@@ -4213,7 +4220,7 @@ function generateCsrTemplate(node, inlinableConstants, ctx, insideLoop, restSpre
|
|
|
4213
4220
|
}
|
|
4214
4221
|
}
|
|
4215
4222
|
const effectiveUnsafeLocalNames = mergeCsrNullUnsafe(ctx, unsafeLocalNames);
|
|
4216
|
-
return generateCsrTemplateWithOpts(node, { inlinableConstants, restSpreadNames, propsObjectName, csrEnv,
|
|
4223
|
+
return generateCsrTemplateWithOpts(node, { inlinableConstants, restSpreadNames, propsObjectName, csrEnv, unsafeLocalNames: effectiveUnsafeLocalNames, deferredChildSlots, loopDepth: -1 });
|
|
4217
4224
|
}
|
|
4218
4225
|
function mergeCsrNullUnsafe(ctx, unsafeLocalNames) {
|
|
4219
4226
|
let merged = null;
|
|
@@ -4278,6 +4285,8 @@ function computeDeferredChildSlots(node, ctx, inlinableConstants, unsafeLocalNam
|
|
|
4278
4285
|
const dropped = n.props.some((p) => {
|
|
4279
4286
|
if (p.name === "..." || p.name.startsWith("...") || p.name === "key")
|
|
4280
4287
|
return false;
|
|
4288
|
+
if (p.name === "ref")
|
|
4289
|
+
return false;
|
|
4281
4290
|
if (p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())
|
|
4282
4291
|
return false;
|
|
4283
4292
|
if (p.clientOnly)
|
|
@@ -4307,7 +4316,7 @@ function computeDeferredChildSlots(node, ctx, inlinableConstants, unsafeLocalNam
|
|
|
4307
4316
|
return deferred;
|
|
4308
4317
|
}
|
|
4309
4318
|
function generateCsrTemplateWithOpts(node, opts) {
|
|
4310
|
-
const { restSpreadNames, propsObjectName, csrEnv,
|
|
4319
|
+
const { restSpreadNames, propsObjectName, csrEnv, unsafeLocalNames, loopDepth = 0 } = opts;
|
|
4311
4320
|
const env = csrEnv ?? { substitutions: new Map, propsObjectName: propsObjectName ?? null };
|
|
4312
4321
|
const transformExpr = (expr, templateExpr) => {
|
|
4313
4322
|
const source = templateExpr ?? expr;
|
|
@@ -4321,7 +4330,6 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4321
4330
|
};
|
|
4322
4331
|
const recurse = (n) => generateCsrTemplateWithOpts(n, opts);
|
|
4323
4332
|
const childrenRecurse = (n) => generateCsrTemplateWithOpts(n, { ...opts, inHoistedChildren: false });
|
|
4324
|
-
const recurseInLoop = (n) => generateCsrTemplateWithOpts(n, { ...opts, insideLoop: true, loopDepth: loopDepth + 1, inHoistedChildren: false });
|
|
4325
4333
|
switch (node.type) {
|
|
4326
4334
|
case "element": {
|
|
4327
4335
|
const mergeCtx = {
|
|
@@ -4414,7 +4422,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4414
4422
|
if (node.slotId && opts.deferredChildSlots?.has(node.slotId)) {
|
|
4415
4423
|
return `<div ${DATA_BF_PH}="${node.slotId}"></div>`;
|
|
4416
4424
|
}
|
|
4417
|
-
const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
|
|
4425
|
+
const propsEntries = node.props.filter((p) => p.name !== "..." && !p.name.startsWith("...") && p.name !== "key").filter((p) => p.name !== "ref" && !(p.name.startsWith("on") && p.name.length > 2 && p.name[2] === p.name[2].toUpperCase())).map((p) => {
|
|
4418
4426
|
if (p.clientOnly)
|
|
4419
4427
|
return null;
|
|
4420
4428
|
switch (p.value.kind) {
|
|
@@ -4452,7 +4460,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4452
4460
|
const propsExpr = propsEntries.length > 0 ? `{${propsEntries.join(", ")}}` : "{}";
|
|
4453
4461
|
const keyProp = node.props.find((p) => p.name === "key");
|
|
4454
4462
|
const keyArg = keyProp ? `, ${transformKeyValue(keyProp.value, transformExpr)}` : "";
|
|
4455
|
-
const slotArg =
|
|
4463
|
+
const slotArg = derivesScopeFromSlot(node) ? `, '${node.slotId}'` : "";
|
|
4456
4464
|
return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
|
|
4457
4465
|
}
|
|
4458
4466
|
case "loop": {
|
|
@@ -4471,7 +4479,6 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4471
4479
|
};
|
|
4472
4480
|
const recurseInLoopBody = (n) => generateCsrTemplateWithOpts(n, {
|
|
4473
4481
|
...opts,
|
|
4474
|
-
insideLoop: true,
|
|
4475
4482
|
loopDepth: loopDepth + 1,
|
|
4476
4483
|
inHoistedChildren: false,
|
|
4477
4484
|
loopBoundNames: boundHere,
|
|
@@ -4535,20 +4542,115 @@ function isSimplePropExpression(expr, propNames) {
|
|
|
4535
4542
|
}
|
|
4536
4543
|
|
|
4537
4544
|
// src/prop-rewrite.ts
|
|
4545
|
+
function collectBindingNames(name, out) {
|
|
4546
|
+
if (ts5.isIdentifier(name)) {
|
|
4547
|
+
out.add(name.text);
|
|
4548
|
+
return;
|
|
4549
|
+
}
|
|
4550
|
+
for (const el of name.elements) {
|
|
4551
|
+
if (ts5.isBindingElement(el))
|
|
4552
|
+
collectBindingNames(el.name, out);
|
|
4553
|
+
}
|
|
4554
|
+
}
|
|
4555
|
+
function scopeFrameOf(n) {
|
|
4556
|
+
if (ts5.isFunctionLike(n)) {
|
|
4557
|
+
const frame = new Set;
|
|
4558
|
+
for (const p of n.parameters)
|
|
4559
|
+
collectBindingNames(p.name, frame);
|
|
4560
|
+
if ((ts5.isFunctionExpression(n) || ts5.isFunctionDeclaration(n)) && n.name)
|
|
4561
|
+
frame.add(n.name.text);
|
|
4562
|
+
return frame.size > 0 ? frame : null;
|
|
4563
|
+
}
|
|
4564
|
+
if (ts5.isBlock(n)) {
|
|
4565
|
+
const frame = new Set;
|
|
4566
|
+
for (const st of n.statements) {
|
|
4567
|
+
if (ts5.isVariableStatement(st)) {
|
|
4568
|
+
for (const d of st.declarationList.declarations)
|
|
4569
|
+
collectBindingNames(d.name, frame);
|
|
4570
|
+
} else if (ts5.isFunctionDeclaration(st) && st.name) {
|
|
4571
|
+
frame.add(st.name.text);
|
|
4572
|
+
}
|
|
4573
|
+
}
|
|
4574
|
+
return frame.size > 0 ? frame : null;
|
|
4575
|
+
}
|
|
4576
|
+
if (ts5.isCatchClause(n) && n.variableDeclaration) {
|
|
4577
|
+
const frame = new Set;
|
|
4578
|
+
collectBindingNames(n.variableDeclaration.name, frame);
|
|
4579
|
+
return frame.size > 0 ? frame : null;
|
|
4580
|
+
}
|
|
4581
|
+
return null;
|
|
4582
|
+
}
|
|
4583
|
+
function walkWithScope(root, visit) {
|
|
4584
|
+
const scopeStack = [];
|
|
4585
|
+
const isShadowed = (name) => scopeStack.some((frame) => frame.has(name));
|
|
4586
|
+
function rec(n, parent) {
|
|
4587
|
+
const frame = scopeFrameOf(n);
|
|
4588
|
+
if (frame)
|
|
4589
|
+
scopeStack.push(frame);
|
|
4590
|
+
if (ts5.isIdentifier(n))
|
|
4591
|
+
visit(n, parent, isShadowed(n.text));
|
|
4592
|
+
ts5.forEachChild(n, (child) => rec(child, n));
|
|
4593
|
+
if (frame)
|
|
4594
|
+
scopeStack.pop();
|
|
4595
|
+
}
|
|
4596
|
+
rec(root);
|
|
4597
|
+
}
|
|
4598
|
+
function isNonValuePosition(n, parent) {
|
|
4599
|
+
if (!parent)
|
|
4600
|
+
return false;
|
|
4601
|
+
if (ts5.isPropertyAssignment(parent) && parent.name === n)
|
|
4602
|
+
return true;
|
|
4603
|
+
if (ts5.isPropertyAccessExpression(parent) && parent.name === n)
|
|
4604
|
+
return true;
|
|
4605
|
+
if (ts5.isQualifiedName(parent) && parent.right === n)
|
|
4606
|
+
return true;
|
|
4607
|
+
if ((ts5.isParameter(parent) || ts5.isVariableDeclaration(parent) || ts5.isBindingElement(parent)) && parent.name === n)
|
|
4608
|
+
return true;
|
|
4609
|
+
if (ts5.isTypeReferenceNode(parent))
|
|
4610
|
+
return true;
|
|
4611
|
+
return false;
|
|
4612
|
+
}
|
|
4538
4613
|
function collectAstPropRefs(node, propNames, out) {
|
|
4539
|
-
|
|
4540
|
-
if (
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4614
|
+
walkWithScope(node, (n, parent, shadowed) => {
|
|
4615
|
+
if (shadowed || !propNames.has(n.text))
|
|
4616
|
+
return;
|
|
4617
|
+
if (parent && ts5.isShorthandPropertyAssignment(parent) && parent.name === n)
|
|
4618
|
+
return;
|
|
4619
|
+
if (isNonValuePosition(n, parent))
|
|
4620
|
+
return;
|
|
4621
|
+
out.add(n.text);
|
|
4622
|
+
});
|
|
4623
|
+
}
|
|
4624
|
+
function applyScopedPropRefRewrite(text, propRefs) {
|
|
4625
|
+
const prefix = "(";
|
|
4626
|
+
const sf = ts5.createSourceFile("__bf_prop_rewrite.ts", `${prefix}${text}
|
|
4627
|
+
)`, ts5.ScriptTarget.Latest, true);
|
|
4628
|
+
const parseDiagnostics = sf.parseDiagnostics;
|
|
4629
|
+
if (parseDiagnostics && parseDiagnostics.length > 0)
|
|
4630
|
+
return null;
|
|
4631
|
+
const edits = [];
|
|
4632
|
+
walkWithScope(sf, (n, parent, shadowed) => {
|
|
4633
|
+
if (shadowed || !propRefs.has(n.text))
|
|
4634
|
+
return;
|
|
4635
|
+
if (isNonValuePosition(n, parent))
|
|
4636
|
+
return;
|
|
4637
|
+
const start = n.getStart(sf) - prefix.length;
|
|
4638
|
+
const end = n.getEnd() - prefix.length;
|
|
4639
|
+
if (start < 0 || end > text.length)
|
|
4640
|
+
return;
|
|
4641
|
+
if (parent && ts5.isShorthandPropertyAssignment(parent) && parent.name === n) {
|
|
4642
|
+
edits.push({ start, end, replacement: `${n.text}: ${PROPS_PARAM}.${n.text}` });
|
|
4643
|
+
return;
|
|
4548
4644
|
}
|
|
4549
|
-
|
|
4645
|
+
edits.push({ start, end, replacement: `${PROPS_PARAM}.${n.text}` });
|
|
4646
|
+
});
|
|
4647
|
+
if (edits.length === 0)
|
|
4648
|
+
return text;
|
|
4649
|
+
let result = text;
|
|
4650
|
+
for (const edit of edits.sort((a, b) => b.start - a.start)) {
|
|
4651
|
+
result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);
|
|
4550
4652
|
}
|
|
4551
|
-
|
|
4653
|
+
return result;
|
|
4552
4654
|
}
|
|
4553
4655
|
function applyRegexPropRefRewrite(text, propRefs) {
|
|
4554
4656
|
const { protect, restore } = createTemplateAwareStringProtector();
|
|
@@ -4578,7 +4680,7 @@ function rewriteBarePropRefs(text, node, propNames, extraPropRefs) {
|
|
|
4578
4680
|
}
|
|
4579
4681
|
if (foundPropRefs.size === 0)
|
|
4580
4682
|
return;
|
|
4581
|
-
return applyRegexPropRefRewrite(text, foundPropRefs);
|
|
4683
|
+
return applyScopedPropRefRewrite(text, foundPropRefs) ?? applyRegexPropRefRewrite(text, foundPropRefs);
|
|
4582
4684
|
}
|
|
4583
4685
|
|
|
4584
4686
|
// src/instrumentation.ts
|
|
@@ -4948,6 +5050,30 @@ function typeNodeToTypeInfo(typeNode, sourceFile, rawOf) {
|
|
|
4948
5050
|
if (ts7.isArrayTypeNode(typeNode)) {
|
|
4949
5051
|
return { kind: "array", raw, elementType: recurse(typeNode.elementType) };
|
|
4950
5052
|
}
|
|
5053
|
+
if (ts7.isLiteralTypeNode(typeNode)) {
|
|
5054
|
+
const lit = typeNode.literal;
|
|
5055
|
+
if (ts7.isStringLiteral(lit) || ts7.isNoSubstitutionTemplateLiteral(lit)) {
|
|
5056
|
+
return { kind: "primitive", raw, primitive: "string", literalValue: lit.text };
|
|
5057
|
+
}
|
|
5058
|
+
if (ts7.isNumericLiteral(lit)) {
|
|
5059
|
+
return { kind: "primitive", raw, primitive: "number", literalValue: lit.text };
|
|
5060
|
+
}
|
|
5061
|
+
if (ts7.isPrefixUnaryExpression(lit) && lit.operator === ts7.SyntaxKind.MinusToken && ts7.isNumericLiteral(lit.operand)) {
|
|
5062
|
+
return { kind: "primitive", raw, primitive: "number", literalValue: `-${lit.operand.text}` };
|
|
5063
|
+
}
|
|
5064
|
+
if (lit.kind === ts7.SyntaxKind.TrueKeyword || lit.kind === ts7.SyntaxKind.FalseKeyword) {
|
|
5065
|
+
return {
|
|
5066
|
+
kind: "primitive",
|
|
5067
|
+
raw,
|
|
5068
|
+
primitive: "boolean",
|
|
5069
|
+
literalValue: lit.kind === ts7.SyntaxKind.TrueKeyword ? "true" : "false"
|
|
5070
|
+
};
|
|
5071
|
+
}
|
|
5072
|
+
if (lit.kind === ts7.SyntaxKind.NullKeyword) {
|
|
5073
|
+
return { kind: "primitive", raw, primitive: "null" };
|
|
5074
|
+
}
|
|
5075
|
+
return { kind: "unknown", raw };
|
|
5076
|
+
}
|
|
4951
5077
|
if (ts7.isUnionTypeNode(typeNode)) {
|
|
4952
5078
|
return { kind: "union", raw, unionTypes: typeNode.types.map(recurse) };
|
|
4953
5079
|
}
|
|
@@ -5515,9 +5641,7 @@ function baseTypeName(raw) {
|
|
|
5515
5641
|
return (idx === -1 ? raw : raw.slice(0, idx)).trim();
|
|
5516
5642
|
}
|
|
5517
5643
|
function isNullishArm(t) {
|
|
5518
|
-
|
|
5519
|
-
return true;
|
|
5520
|
-
return t.kind === "unknown" && (t.raw === "null" || t.raw === "undefined");
|
|
5644
|
+
return t.kind === "primitive" && (t.primitive === "null" || t.primitive === "undefined");
|
|
5521
5645
|
}
|
|
5522
5646
|
function stripUnion(type) {
|
|
5523
5647
|
if (!type || type.kind !== "union" || !type.unionTypes)
|
|
@@ -6236,14 +6360,17 @@ function collectSignal(node, ctx) {
|
|
|
6236
6360
|
const pattern = node.name;
|
|
6237
6361
|
const callExpr = node.initializer;
|
|
6238
6362
|
const elements = pattern.elements;
|
|
6239
|
-
|
|
6363
|
+
const getterElided = elements.length === 2 && ts8.isOmittedExpression(elements[0]);
|
|
6364
|
+
if (elements.length < 1 || elements.length > 2 || !getterElided && (!ts8.isBindingElement(elements[0]) || !ts8.isIdentifier(elements[0].name))) {
|
|
6240
6365
|
return;
|
|
6241
6366
|
}
|
|
6242
6367
|
if (elements.length === 2 && (!ts8.isBindingElement(elements[1]) || !ts8.isIdentifier(elements[1].name))) {
|
|
6243
6368
|
return;
|
|
6244
6369
|
}
|
|
6245
|
-
const getter = elements[0].name.text;
|
|
6246
6370
|
const setter = elements.length === 2 && ts8.isBindingElement(elements[1]) && ts8.isIdentifier(elements[1].name) ? elements[1].name.text : null;
|
|
6371
|
+
if (getterElided && !setter)
|
|
6372
|
+
return;
|
|
6373
|
+
const getter = getterElided ? `__bfGet_${setter}` : elements[0].name.text;
|
|
6247
6374
|
const initialValue = callExpr.arguments[0] ? ctx.getJS(callExpr.arguments[0]) : "";
|
|
6248
6375
|
const typedInitialValue = callExpr.arguments[0] ? callExpr.arguments[0].getText(ctx.sourceFile) : undefined;
|
|
6249
6376
|
let type = { kind: "unknown", raw: "unknown" };
|
|
@@ -6264,6 +6391,7 @@ function collectSignal(node, ctx) {
|
|
|
6264
6391
|
ctx.signals.push({
|
|
6265
6392
|
getter,
|
|
6266
6393
|
setter,
|
|
6394
|
+
getterElided: getterElided || undefined,
|
|
6267
6395
|
initialValue,
|
|
6268
6396
|
typedInitialValue: typedInitialValue !== initialValue ? typedInitialValue : undefined,
|
|
6269
6397
|
templateInitialValue,
|
|
@@ -6454,9 +6582,17 @@ function collectMemo(node, ctx) {
|
|
|
6454
6582
|
const blockBody = arrowNode && ts8.isArrowFunction(arrowNode) && ts8.isBlock(arrowNode.body) ? arrowNode.body : undefined;
|
|
6455
6583
|
const parsedBlock = blockBody ? parseBlockBodyTolerant(blockBody, ctx.sourceFile, (node2) => ctx.getJS(node2)) : undefined;
|
|
6456
6584
|
const parsedBlockComplete = parsedBlock && blockBody ? parsedBlock.length === blockBody.statements.length : undefined;
|
|
6585
|
+
let templateComputation;
|
|
6586
|
+
if (!ctx.propsObjectName && callExpr.arguments[0]) {
|
|
6587
|
+
const propNames = new Set(ctx.propsParams.map((p) => p.name));
|
|
6588
|
+
if (propNames.size > 0) {
|
|
6589
|
+
templateComputation = rewriteBarePropRefs(computation, callExpr.arguments[0], propNames);
|
|
6590
|
+
}
|
|
6591
|
+
}
|
|
6457
6592
|
ctx.memos.push({
|
|
6458
6593
|
name,
|
|
6459
6594
|
computation,
|
|
6595
|
+
templateComputation,
|
|
6460
6596
|
parsedBlock,
|
|
6461
6597
|
parsedBlockComplete,
|
|
6462
6598
|
typedComputation: typedComputation !== computation ? typedComputation : undefined,
|
|
@@ -9677,8 +9813,10 @@ function deriveFormat(locale, probeOptions) {
|
|
|
9677
9813
|
return { pattern, names };
|
|
9678
9814
|
}
|
|
9679
9815
|
function unionMemberLiteral(member) {
|
|
9680
|
-
|
|
9681
|
-
|
|
9816
|
+
if (member.kind === "primitive" && member.primitive === "string" && member.literalValue !== undefined) {
|
|
9817
|
+
return member.literalValue;
|
|
9818
|
+
}
|
|
9819
|
+
return null;
|
|
9682
9820
|
}
|
|
9683
9821
|
function resolveLocaleUnionMembers(locale, metadata) {
|
|
9684
9822
|
let sourcePropName = null;
|
|
@@ -10284,6 +10422,13 @@ function jsxToIR(analyzer) {
|
|
|
10284
10422
|
function buildIRRoot(analyzer) {
|
|
10285
10423
|
if (analyzer.conditionalReturns.length > 0) {
|
|
10286
10424
|
const ctx2 = createTransformContext(analyzer);
|
|
10425
|
+
const allReactiveNoLocals = analyzer.jsxReturn != null && analyzer.conditionalReturns.every((cr) => cr.scopeVariables.length === 0 && exprCallsReactiveGetters(cr.condition, ctx2));
|
|
10426
|
+
if (allReactiveNoLocals) {
|
|
10427
|
+
const chain = buildIfStatementChain(analyzer, ctx2, { asConditional: true });
|
|
10428
|
+
if (!chain)
|
|
10429
|
+
return null;
|
|
10430
|
+
return chain.type === "conditional" ? wrapInScopeElement(chain) : chain;
|
|
10431
|
+
}
|
|
10287
10432
|
return buildIfStatementChain(analyzer, ctx2);
|
|
10288
10433
|
}
|
|
10289
10434
|
if (!analyzer.jsxReturn)
|
|
@@ -10439,11 +10584,52 @@ function transformJsxElement(node, ctx) {
|
|
|
10439
10584
|
}
|
|
10440
10585
|
return transformHtmlElement(node, ctx, tagName);
|
|
10441
10586
|
}
|
|
10587
|
+
function lowerFormControlValueSsr(tagName, attrs, children) {
|
|
10588
|
+
if (tagName !== "textarea" && tagName !== "select")
|
|
10589
|
+
return;
|
|
10590
|
+
const valueAttr = attrs.find((a) => a.name === "value");
|
|
10591
|
+
if (!valueAttr || valueAttr.clientOnly || valueAttr.value.kind !== "expression")
|
|
10592
|
+
return;
|
|
10593
|
+
const { expr, templateExpr } = valueAttr.value;
|
|
10594
|
+
valueAttr.clientOnly = true;
|
|
10595
|
+
if (tagName === "textarea") {
|
|
10596
|
+
if (children.length > 0)
|
|
10597
|
+
return;
|
|
10598
|
+
children.push({
|
|
10599
|
+
type: "expression",
|
|
10600
|
+
expr,
|
|
10601
|
+
templateExpr: `escapeText(${templateExpr ?? expr})`,
|
|
10602
|
+
typeInfo: null,
|
|
10603
|
+
reactive: false,
|
|
10604
|
+
slotId: null,
|
|
10605
|
+
loc: valueAttr.loc,
|
|
10606
|
+
origin: { phase: "ssr", scope: "template", effect: "pure" }
|
|
10607
|
+
});
|
|
10608
|
+
return;
|
|
10609
|
+
}
|
|
10610
|
+
const selectedFor = (optValue) => AttrValueOf.expression(`(${expr}) === ${JSON.stringify(optValue)}`, templateExpr !== undefined ? { templateExpr: `(${templateExpr}) === ${JSON.stringify(optValue)}` } : undefined);
|
|
10611
|
+
const distribute = (nodes) => {
|
|
10612
|
+
for (const n of nodes) {
|
|
10613
|
+
if (n.type === "element" && n.tag === "option") {
|
|
10614
|
+
if (n.attrs.some((a) => a.name === "selected"))
|
|
10615
|
+
continue;
|
|
10616
|
+
const optValue = n.attrs.find((a) => a.name === "value");
|
|
10617
|
+
if (!optValue || optValue.value.kind !== "literal")
|
|
10618
|
+
continue;
|
|
10619
|
+
n.attrs.push({ name: "selected", value: selectedFor(optValue.value.value), loc: n.loc });
|
|
10620
|
+
} else if (n.type === "fragment" || n.type === "element" && n.tag === "optgroup") {
|
|
10621
|
+
distribute(n.children);
|
|
10622
|
+
}
|
|
10623
|
+
}
|
|
10624
|
+
};
|
|
10625
|
+
distribute(children);
|
|
10626
|
+
}
|
|
10442
10627
|
function transformHtmlElement(node, ctx, tagName) {
|
|
10443
10628
|
const { attrs, events, ref } = processAttributes(node.openingElement.attributes, ctx);
|
|
10444
10629
|
const needsScope = ctx.isRoot;
|
|
10445
10630
|
ctx.isRoot = false;
|
|
10446
10631
|
const children = transformChildren(node.children, ctx);
|
|
10632
|
+
lowerFormControlValueSsr(tagName, attrs, children);
|
|
10447
10633
|
const needsSlot = events.length > 0 || hasDynamicContent(children) || hasReactiveAttributes(attrs, ctx) || ref !== null;
|
|
10448
10634
|
const slotId = needsSlot ? generateSlotId(ctx) : null;
|
|
10449
10635
|
if (slotId) {
|
|
@@ -10475,6 +10661,8 @@ function transformSelfClosingElement(node, ctx) {
|
|
|
10475
10661
|
return transformSelfClosingComponent(node, ctx, resolved ?? tagName);
|
|
10476
10662
|
}
|
|
10477
10663
|
const { attrs, events, ref } = processAttributes(node.attributes, ctx);
|
|
10664
|
+
const selfClosingChildren = [];
|
|
10665
|
+
lowerFormControlValueSsr(tagName, attrs, selfClosingChildren);
|
|
10478
10666
|
const needsSlot = events.length > 0 || hasReactiveAttributes(attrs, ctx) || ref !== null;
|
|
10479
10667
|
const slotId = needsSlot ? generateSlotId(ctx) : null;
|
|
10480
10668
|
const needsScope = ctx.isRoot;
|
|
@@ -10485,7 +10673,7 @@ function transformSelfClosingElement(node, ctx) {
|
|
|
10485
10673
|
attrs,
|
|
10486
10674
|
events,
|
|
10487
10675
|
ref,
|
|
10488
|
-
children:
|
|
10676
|
+
children: selfClosingChildren,
|
|
10489
10677
|
slotId,
|
|
10490
10678
|
needsScope,
|
|
10491
10679
|
loc: getSourceLocation(node, ctx.sourceFile, ctx.filePath)
|
|
@@ -11868,6 +12056,15 @@ function branchHasNoElement(node) {
|
|
|
11868
12056
|
}
|
|
11869
12057
|
return true;
|
|
11870
12058
|
}
|
|
12059
|
+
function tagLoopItemRootComponents(nodes) {
|
|
12060
|
+
for (const node of nodes) {
|
|
12061
|
+
if (node.type === "component") {
|
|
12062
|
+
node.loopItemRoot = true;
|
|
12063
|
+
} else if (node.type === "conditional") {
|
|
12064
|
+
tagLoopItemRootComponents([node.whenTrue, node.whenFalse]);
|
|
12065
|
+
}
|
|
12066
|
+
}
|
|
12067
|
+
}
|
|
11871
12068
|
function loopBodyItemConditional(children) {
|
|
11872
12069
|
const real = children.filter((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
|
|
11873
12070
|
if (real.length !== 1)
|
|
@@ -12105,9 +12302,9 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
12105
12302
|
const pre = multiReturn.preamble ?? [];
|
|
12106
12303
|
if (pre.length > 0) {
|
|
12107
12304
|
preamble = preambleFromValueStatements(pre, ctx);
|
|
12108
|
-
if (!isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
|
|
12305
|
+
if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
|
|
12109
12306
|
ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, loc, {
|
|
12110
|
-
message: "A .map() callback body with a
|
|
12307
|
+
message: "A .map() callback body with a preamble before its branches cannot be " + "lowered to a template: the preamble is not a sequence of value " + "declarations, so this backend has no per-row local to carry into the " + "branches.",
|
|
12111
12308
|
suggestion: {
|
|
12112
12309
|
message: "Add /* @client */ to evaluate this expression on the client only"
|
|
12113
12310
|
}
|
|
@@ -12174,6 +12371,14 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
12174
12371
|
}
|
|
12175
12372
|
if (valueStmts.length > 0) {
|
|
12176
12373
|
preamble = preambleFromValueStatements(valueStmts, ctx);
|
|
12374
|
+
if (!preamble.declarations && !isClientOnly && !(ctx.analyzer.acceptsCallbackBody?.("map") ?? false)) {
|
|
12375
|
+
ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, getSourceLocation(body, ctx.sourceFile, ctx.filePath), {
|
|
12376
|
+
message: "A .map() callback preamble that is not a sequence of value " + "declarations cannot be lowered to a template: this backend can " + "declare a per-row local, but cannot run arbitrary statements per row.",
|
|
12377
|
+
suggestion: {
|
|
12378
|
+
message: "Add /* @client */ to evaluate this expression on the client only"
|
|
12379
|
+
}
|
|
12380
|
+
}));
|
|
12381
|
+
}
|
|
12177
12382
|
}
|
|
12178
12383
|
}
|
|
12179
12384
|
}
|
|
@@ -12259,6 +12464,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
12259
12464
|
}));
|
|
12260
12465
|
preamble = undefined;
|
|
12261
12466
|
}
|
|
12467
|
+
tagLoopItemRootComponents(children);
|
|
12262
12468
|
let childComponent;
|
|
12263
12469
|
if (children.length === 1 && children[0].type === "component") {
|
|
12264
12470
|
const comp = children[0];
|
|
@@ -12279,6 +12485,9 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
12279
12485
|
const isDirectPropArray = method !== "flatMap" && isArrayExprDirectPropRef(arrayExpr, ctx);
|
|
12280
12486
|
const isStaticArray = !isSignalOrMemoArray(array, ctx) && !isDirectPropArray && !hasCalls && !objectIteration;
|
|
12281
12487
|
const preambleRegions = preamble && !isStaticArray ? collectPreambleRegions(children, new Set(preamble.declaredNames), ctx) : undefined;
|
|
12488
|
+
if (preamble && !isStaticArray) {
|
|
12489
|
+
markPreambleAttrSlots(children, new Set(preamble.declaredNames), ctx);
|
|
12490
|
+
}
|
|
12282
12491
|
const nestedComponents = collectNestedComponents(children).filter((c) => c.name !== childComponent?.name);
|
|
12283
12492
|
return {
|
|
12284
12493
|
type: "loop",
|
|
@@ -12503,20 +12712,66 @@ function collectPreambleRegions(nodes, declared, ctx) {
|
|
|
12503
12712
|
visit2(nodes);
|
|
12504
12713
|
return regions;
|
|
12505
12714
|
}
|
|
12506
|
-
function
|
|
12715
|
+
function markPreambleAttrSlots(nodes, declared, ctx) {
|
|
12716
|
+
const readsDeclared = (attr) => {
|
|
12717
|
+
if (attr.name === "key")
|
|
12718
|
+
return false;
|
|
12719
|
+
const value = attr.value;
|
|
12720
|
+
if (value.kind !== "expression" && value.kind !== "template")
|
|
12721
|
+
return false;
|
|
12722
|
+
const refs = attr.freeIdentifiers ?? extractFreeIdentifiersFromText(attrValueText(value));
|
|
12723
|
+
for (const r of refs)
|
|
12724
|
+
if (declared.has(r))
|
|
12725
|
+
return true;
|
|
12726
|
+
return false;
|
|
12727
|
+
};
|
|
12728
|
+
const visit2 = (list) => {
|
|
12729
|
+
for (const node of list) {
|
|
12730
|
+
switch (node.type) {
|
|
12731
|
+
case "element":
|
|
12732
|
+
if (!node.slotId && node.attrs.some(readsDeclared))
|
|
12733
|
+
node.slotId = generateSlotId(ctx);
|
|
12734
|
+
visit2(node.children);
|
|
12735
|
+
break;
|
|
12736
|
+
case "fragment":
|
|
12737
|
+
visit2(node.children);
|
|
12738
|
+
break;
|
|
12739
|
+
case "conditional":
|
|
12740
|
+
visit2([node.whenTrue, ...node.whenFalse ? [node.whenFalse] : []]);
|
|
12741
|
+
break;
|
|
12742
|
+
}
|
|
12743
|
+
}
|
|
12744
|
+
};
|
|
12745
|
+
visit2(nodes);
|
|
12746
|
+
}
|
|
12747
|
+
function attrValueText(value) {
|
|
12748
|
+
if (value.kind === "expression")
|
|
12749
|
+
return value.expr;
|
|
12750
|
+
if (value.kind !== "template")
|
|
12751
|
+
return "";
|
|
12752
|
+
const out = [];
|
|
12753
|
+
for (const p of value.parts) {
|
|
12754
|
+
if (p.type === "ternary")
|
|
12755
|
+
out.push(p.condition, p.whenTrue, p.whenFalse);
|
|
12756
|
+
else if (p.type === "lookup")
|
|
12757
|
+
out.push(p.key);
|
|
12758
|
+
}
|
|
12759
|
+
return out.join(" ");
|
|
12760
|
+
}
|
|
12761
|
+
function collectBindingNames2(name, out) {
|
|
12507
12762
|
if (ts11.isIdentifier(name)) {
|
|
12508
12763
|
out.add(name.text);
|
|
12509
12764
|
return;
|
|
12510
12765
|
}
|
|
12511
12766
|
for (const el of name.elements) {
|
|
12512
12767
|
if (ts11.isBindingElement(el))
|
|
12513
|
-
|
|
12768
|
+
collectBindingNames2(el.name, out);
|
|
12514
12769
|
}
|
|
12515
12770
|
}
|
|
12516
12771
|
function collectPreambleDeclaredNames(stmt, out) {
|
|
12517
12772
|
if (ts11.isVariableStatement(stmt)) {
|
|
12518
12773
|
for (const decl of stmt.declarationList.declarations) {
|
|
12519
|
-
|
|
12774
|
+
collectBindingNames2(decl.name, out);
|
|
12520
12775
|
}
|
|
12521
12776
|
} else if (ts11.isFunctionDeclaration(stmt) && stmt.name) {
|
|
12522
12777
|
out.add(stmt.name.text);
|
|
@@ -12540,9 +12795,32 @@ function preambleFromValueStatements(statements, ctx) {
|
|
|
12540
12795
|
segments: trimPreambleSegments(segments),
|
|
12541
12796
|
ssrText: tsxSourceText(typedParts.join(" ")),
|
|
12542
12797
|
declaredNames: [...declared],
|
|
12543
|
-
builderNames: []
|
|
12798
|
+
builderNames: [],
|
|
12799
|
+
declarations: neutralPreambleDeclarations(statements, ctx) ?? undefined
|
|
12544
12800
|
};
|
|
12545
12801
|
}
|
|
12802
|
+
function neutralPreambleDeclarations(statements, ctx) {
|
|
12803
|
+
const out = [];
|
|
12804
|
+
for (const stmt of statements) {
|
|
12805
|
+
if (!ts11.isVariableStatement(stmt))
|
|
12806
|
+
return null;
|
|
12807
|
+
for (const decl of stmt.declarationList.declarations) {
|
|
12808
|
+
if (!ts11.isIdentifier(decl.name))
|
|
12809
|
+
return null;
|
|
12810
|
+
if (!decl.initializer)
|
|
12811
|
+
return null;
|
|
12812
|
+
const valueParsed = tsNodeToParsedExpr(decl.initializer);
|
|
12813
|
+
if (!isSupported(valueParsed).supported)
|
|
12814
|
+
return null;
|
|
12815
|
+
out.push({
|
|
12816
|
+
name: decl.name.text,
|
|
12817
|
+
valueParsed,
|
|
12818
|
+
raw: decl.initializer.getText(ctx.sourceFile)
|
|
12819
|
+
});
|
|
12820
|
+
}
|
|
12821
|
+
}
|
|
12822
|
+
return out.length > 0 ? out : null;
|
|
12823
|
+
}
|
|
12546
12824
|
function trimPreambleSegments(segments) {
|
|
12547
12825
|
const last = segments[segments.length - 1];
|
|
12548
12826
|
if (last?.kind === "js") {
|
|
@@ -12886,6 +13164,8 @@ function parseTemplateLiteral(expr, ctx) {
|
|
|
12886
13164
|
}
|
|
12887
13165
|
function tryResolveTemplateSpanFromConst(expr, ctx) {
|
|
12888
13166
|
if (ts11.isIdentifier(expr)) {
|
|
13167
|
+
if (ctx.loopParams.has(expr.text))
|
|
13168
|
+
return null;
|
|
12889
13169
|
const constInfo = findLocalConst(expr.text, ctx.analyzer);
|
|
12890
13170
|
if (!constInfo)
|
|
12891
13171
|
return null;
|
|
@@ -12900,6 +13180,8 @@ function tryResolveTemplateSpanFromConst(expr, ctx) {
|
|
|
12900
13180
|
if (ts11.isElementAccessExpression(expr)) {
|
|
12901
13181
|
if (!ts11.isIdentifier(expr.expression))
|
|
12902
13182
|
return null;
|
|
13183
|
+
if (ctx.loopParams.has(expr.expression.text))
|
|
13184
|
+
return null;
|
|
12903
13185
|
const constInfo = findLocalConst(expr.expression.text, ctx.analyzer);
|
|
12904
13186
|
if (!constInfo)
|
|
12905
13187
|
return null;
|
|
@@ -12988,6 +13270,9 @@ function tryResolveIdentifierAsTemplateLiteral(ident, ctx) {
|
|
|
12988
13270
|
if (ts11.isNoSubstitutionTemplateLiteral(ast) || ts11.isStringLiteral(ast)) {
|
|
12989
13271
|
return [{ type: "string", value: ast.text }];
|
|
12990
13272
|
}
|
|
13273
|
+
if (ts11.isElementAccessExpression(ast) && !ts11.isStringLiteralLike(ast.argumentExpression) && !ts11.isNumericLiteral(ast.argumentExpression)) {
|
|
13274
|
+
return tryResolveTemplateSpanFromConst(ast, ctx);
|
|
13275
|
+
}
|
|
12991
13276
|
if (!ts11.isTemplateExpression(ast))
|
|
12992
13277
|
return null;
|
|
12993
13278
|
let resolvedAny = false;
|
|
@@ -13235,8 +13520,11 @@ function processComponentProps(attributes, ctx) {
|
|
|
13235
13520
|
}
|
|
13236
13521
|
let value = getAttributeValue(attr, ctx);
|
|
13237
13522
|
if (value.kind === "template") {
|
|
13238
|
-
|
|
13239
|
-
|
|
13523
|
+
const collapsed = templatePartsToJsString(value.parts);
|
|
13524
|
+
const collapsedTemplate = templatePartsToJsString(value.parts, { useTemplate: true });
|
|
13525
|
+
value = AttrValueOf.expression(collapsed, {
|
|
13526
|
+
parts: value.parts,
|
|
13527
|
+
...collapsedTemplate !== collapsed && { templateExpr: collapsedTemplate }
|
|
13240
13528
|
});
|
|
13241
13529
|
} else if (value.kind === "boolean-attr") {
|
|
13242
13530
|
value = AttrValueOf.booleanShorthand();
|
|
@@ -13265,16 +13553,18 @@ function processComponentProps(attributes, ctx) {
|
|
|
13265
13553
|
}
|
|
13266
13554
|
return props;
|
|
13267
13555
|
}
|
|
13268
|
-
function templatePartsToJsString(parts) {
|
|
13556
|
+
function templatePartsToJsString(parts, opts) {
|
|
13269
13557
|
let result = "`";
|
|
13270
13558
|
for (const part of parts) {
|
|
13271
13559
|
if (part.type === "string") {
|
|
13272
|
-
result += part.value;
|
|
13560
|
+
result += opts?.useTemplate && part.templateValue ? part.templateValue : part.value;
|
|
13273
13561
|
} else if (part.type === "ternary") {
|
|
13274
|
-
|
|
13562
|
+
const cond = opts?.useTemplate && part.templateCondition ? part.templateCondition : part.condition;
|
|
13563
|
+
result += `\${${cond} ? '${part.whenTrue}' : '${part.whenFalse}'}`;
|
|
13275
13564
|
} else if (part.type === "lookup") {
|
|
13565
|
+
const key = opts?.useTemplate && part.templateKey ? part.templateKey : part.key;
|
|
13276
13566
|
const obj = "{" + Object.entries(part.cases).map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`).join(", ") + "}";
|
|
13277
|
-
result += `\${(${obj})[${
|
|
13567
|
+
result += `\${(${obj})[${key}]}`;
|
|
13278
13568
|
}
|
|
13279
13569
|
}
|
|
13280
13570
|
result += "`";
|
|
@@ -13485,11 +13775,12 @@ function replaceBranchLocalRefs(text, branchNames, resolve2) {
|
|
|
13485
13775
|
const pattern = new RegExp(`(?<![\\w$])(${branchNames.join("|")})(?![\\w$])`, "g");
|
|
13486
13776
|
return replaceInExprContexts(text, pattern, (_match, name) => resolve2(name));
|
|
13487
13777
|
}
|
|
13488
|
-
function buildIfStatementChain(analyzer, ctx) {
|
|
13778
|
+
function buildIfStatementChain(analyzer, ctx, opts) {
|
|
13489
13779
|
const conditionalReturns = analyzer.conditionalReturns;
|
|
13780
|
+
const asConditional = opts?.asConditional === true;
|
|
13490
13781
|
let alternate = null;
|
|
13491
13782
|
if (analyzer.jsxReturn) {
|
|
13492
|
-
ctx.isRoot =
|
|
13783
|
+
ctx.isRoot = !asConditional;
|
|
13493
13784
|
alternate = transformNode(analyzer.jsxReturn, ctx);
|
|
13494
13785
|
}
|
|
13495
13786
|
for (let i = conditionalReturns.length - 1;i >= 0; i--) {
|
|
@@ -13558,7 +13849,7 @@ function buildIfStatementChain(analyzer, ctx) {
|
|
|
13558
13849
|
ctx.getJS = substitutedGetJS;
|
|
13559
13850
|
ctx.analyzer.getJS = substitutedGetJS;
|
|
13560
13851
|
}
|
|
13561
|
-
ctx.isRoot =
|
|
13852
|
+
ctx.isRoot = !asConditional;
|
|
13562
13853
|
let consequent;
|
|
13563
13854
|
try {
|
|
13564
13855
|
consequent = transformNode(condReturn.jsxReturn, ctx);
|
|
@@ -13588,6 +13879,27 @@ function buildIfStatementChain(analyzer, ctx) {
|
|
|
13588
13879
|
}
|
|
13589
13880
|
}
|
|
13590
13881
|
const loc = getSourceLocation(condReturn.ifStatement, analyzer.sourceFile, analyzer.filePath);
|
|
13882
|
+
if (asConditional && alternate) {
|
|
13883
|
+
const conditional = {
|
|
13884
|
+
type: "conditional",
|
|
13885
|
+
condition,
|
|
13886
|
+
templateCondition,
|
|
13887
|
+
conditionType: null,
|
|
13888
|
+
reactive: true,
|
|
13889
|
+
whenTrue: consequent,
|
|
13890
|
+
whenFalse: alternate,
|
|
13891
|
+
slotId: generateSlotId(ctx),
|
|
13892
|
+
loc,
|
|
13893
|
+
origin: {
|
|
13894
|
+
phase: "tick",
|
|
13895
|
+
scope: "template",
|
|
13896
|
+
effect: "pure",
|
|
13897
|
+
freeRefs: resolveFreeRefs(condReturn.condition, makeBindingEnv(ctx))
|
|
13898
|
+
}
|
|
13899
|
+
};
|
|
13900
|
+
alternate = conditional;
|
|
13901
|
+
continue;
|
|
13902
|
+
}
|
|
13591
13903
|
const ifStmt = {
|
|
13592
13904
|
type: "if-statement",
|
|
13593
13905
|
condition,
|
|
@@ -13901,7 +14213,13 @@ function collectLoopChildReactiveTexts(node, ctx, loopParam, loopParamBindings,
|
|
|
13901
14213
|
});
|
|
13902
14214
|
return texts;
|
|
13903
14215
|
}
|
|
13904
|
-
function
|
|
14216
|
+
function anyNameIn(names, set) {
|
|
14217
|
+
for (const n of names)
|
|
14218
|
+
if (set.has(n))
|
|
14219
|
+
return true;
|
|
14220
|
+
return false;
|
|
14221
|
+
}
|
|
14222
|
+
function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings, stopAtReactiveConditionals = false, preambleNames) {
|
|
13905
14223
|
const attrs = [];
|
|
13906
14224
|
traverseElements(node, (el) => {
|
|
13907
14225
|
if (el.slotId) {
|
|
@@ -13916,7 +14234,8 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings,
|
|
|
13916
14234
|
if (!valueStr)
|
|
13917
14235
|
continue;
|
|
13918
14236
|
const expanded = expandConstantForReactivity(valueStr, ctx, attr.freeIdentifiers);
|
|
13919
|
-
const
|
|
14237
|
+
const readsPreamble = preambleNames !== undefined && preambleNames.size > 0 && anyNameIn(expanded.freeIds ?? extractFreeIdentifiersFromText(expanded.expr), preambleNames);
|
|
14238
|
+
const reactive = classifyReactivity(expanded.expr, ctx, loopParam, loopParamBindings, expanded.freeIds).kind !== "none" || readsPreamble || attr.callsReactiveGetters || attr.hasFunctionCalls;
|
|
13920
14239
|
if (!attr.clientOnly && !reactive)
|
|
13921
14240
|
continue;
|
|
13922
14241
|
attrs.push({
|
|
@@ -13924,7 +14243,8 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings,
|
|
|
13924
14243
|
attrName: attr.name,
|
|
13925
14244
|
expression: expanded.expr,
|
|
13926
14245
|
...pickAttrMetaFromIR(attr),
|
|
13927
|
-
...expanded.freeIds !== undefined && { freeIdentifiers: expanded.freeIds }
|
|
14246
|
+
...expanded.freeIds !== undefined && { freeIdentifiers: expanded.freeIds },
|
|
14247
|
+
...readsPreamble && { readsPreamble: true }
|
|
13928
14248
|
});
|
|
13929
14249
|
}
|
|
13930
14250
|
}
|
|
@@ -14220,10 +14540,11 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
14220
14540
|
const template = n.children.map((c) => irToPlaceholderTemplate(c, undefined, emitDepth, loopParamsForTemplate)).join("");
|
|
14221
14541
|
const refsOuter = outerLoopParam ? new RegExp(`\\b${outerLoopParam}\\b`).test(n.array) : false;
|
|
14222
14542
|
const bindings = emptyLoopChildBindings();
|
|
14543
|
+
const innerPreambleNames = preambleNamesOf(n);
|
|
14223
14544
|
if (ctx) {
|
|
14224
14545
|
for (const child of n.children) {
|
|
14225
14546
|
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings));
|
|
14226
|
-
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings));
|
|
14547
|
+
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, false, innerPreambleNames));
|
|
14227
14548
|
bindings.refs.push(...collectLoopChildRefs(child));
|
|
14228
14549
|
}
|
|
14229
14550
|
}
|
|
@@ -14446,7 +14767,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
14446
14767
|
return;
|
|
14447
14768
|
const projectionInner = l.method === "flatMap" && l.children.length === 1 && l.children[0].type === "loop" ? l.children[0] : undefined;
|
|
14448
14769
|
const childHandlers = [];
|
|
14449
|
-
const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings);
|
|
14770
|
+
const bindings = projectionInner ? emptyLoopChildBindings() : collectLoopChildBindings(l.children, ctx, siblingOffsets, l.param, l.paramBindings, preambleNamesOf(l));
|
|
14450
14771
|
if (!projectionInner) {
|
|
14451
14772
|
for (const child of l.children) {
|
|
14452
14773
|
childHandlers.push(...collectEventHandlersFromIR(child));
|
|
@@ -14469,7 +14790,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
14469
14790
|
if (l.childComponent) {
|
|
14470
14791
|
template = "";
|
|
14471
14792
|
if (l.isStaticArray && l.children[0]) {
|
|
14472
|
-
staticItemTemplate = irToHtmlTemplate(l.children[0], buildRestSpreadNames(ctx), 0, undefined, undefined
|
|
14793
|
+
staticItemTemplate = irToHtmlTemplate(l.children[0], buildRestSpreadNames(ctx), 0, undefined, undefined);
|
|
14473
14794
|
}
|
|
14474
14795
|
} else if (l.children[0] && !projectionInner) {
|
|
14475
14796
|
const loopParamSpec = [{ param: l.param, bindings: l.paramBindings }];
|
|
@@ -14701,7 +15022,7 @@ function collectBranchLoops(node, ctx, siblingOffsets) {
|
|
|
14701
15022
|
} else {
|
|
14702
15023
|
childTemplate = n.children.map((c) => irToHtmlTemplate(c, undefined, 0, branchLoopParamSpec)).join("");
|
|
14703
15024
|
}
|
|
14704
|
-
const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings) : emptyLoopChildBindings();
|
|
15025
|
+
const branchBindings = ctx && !projectionInner ? collectLoopChildBindings(n.children, ctx, siblingOffsets, n.param, n.paramBindings, preambleNamesOf(n)) : emptyLoopChildBindings();
|
|
14705
15026
|
loops.push({
|
|
14706
15027
|
kind: "branch",
|
|
14707
15028
|
array: n.array,
|
|
@@ -14781,11 +15102,17 @@ function collectBranchConditionals(node, ctx, siblingOffsets) {
|
|
|
14781
15102
|
});
|
|
14782
15103
|
return result;
|
|
14783
15104
|
}
|
|
14784
|
-
function
|
|
15105
|
+
function preambleNamesOf(loop) {
|
|
15106
|
+
if (loop.isStaticArray)
|
|
15107
|
+
return;
|
|
15108
|
+
const declared = loop.preamble?.declaredNames;
|
|
15109
|
+
return declared && declared.length > 0 ? new Set(declared) : undefined;
|
|
15110
|
+
}
|
|
15111
|
+
function collectLoopChildBindings(children, ctx, siblingOffsets, loopParam, loopParamBindings, preambleNames) {
|
|
14785
15112
|
const bindings = emptyLoopChildBindings();
|
|
14786
15113
|
for (const child of children) {
|
|
14787
15114
|
bindings.events.push(...collectLoopChildEventsWithNesting(child));
|
|
14788
|
-
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true));
|
|
15115
|
+
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, loopParam, loopParamBindings, true, preambleNames));
|
|
14789
15116
|
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, loopParam, loopParamBindings, true));
|
|
14790
15117
|
bindings.refs.push(...collectLoopChildRefs(child));
|
|
14791
15118
|
bindings.conditionals.push(...collectLoopChildConditionals(child, ctx, siblingOffsets, loopParam, loopParamBindings));
|
|
@@ -16399,7 +16726,7 @@ function emitRegistrationAndHydration(lines, ctx, _ir, graph, inlinability) {
|
|
|
16399
16726
|
}
|
|
16400
16727
|
} else {
|
|
16401
16728
|
const csrInlinableConstants = csrInlinableConstantsFromCtx(ctx);
|
|
16402
|
-
const templateHtml = generateCsrTemplate(_ir.root, csrInlinableConstants, ctx,
|
|
16729
|
+
const templateHtml = generateCsrTemplate(_ir.root, csrInlinableConstants, ctx, restSpreadNames, ctx.propsObjectName, unsafeLocalNames, ctx.deferredChildSlots);
|
|
16403
16730
|
if (templateHtml) {
|
|
16404
16731
|
defParts.push(`template: (${PROPS_PARAM}) => \`${templateHtml}\``);
|
|
16405
16732
|
}
|
|
@@ -16797,6 +17124,7 @@ function buildSignalPlan(signal, ctx, lookups) {
|
|
|
16797
17124
|
kind: "signal",
|
|
16798
17125
|
getter: signal.getter,
|
|
16799
17126
|
setter: signal.setter,
|
|
17127
|
+
getterElided: signal.getterElided,
|
|
16800
17128
|
initialValueExpr: "",
|
|
16801
17129
|
controlledEffect: null,
|
|
16802
17130
|
initializerOverride: `${factory}()`
|
|
@@ -16811,6 +17139,7 @@ function buildSignalPlan(signal, ctx, lookups) {
|
|
|
16811
17139
|
kind: "signal",
|
|
16812
17140
|
getter: signal.getter,
|
|
16813
17141
|
setter: signal.setter,
|
|
17142
|
+
getterElided: signal.getterElided,
|
|
16814
17143
|
initialValueExpr: resolveSignalInitialValue(signal, ctx, lookups),
|
|
16815
17144
|
controlledEffect,
|
|
16816
17145
|
branchCondition: signal.branchCondition,
|
|
@@ -16882,9 +17211,10 @@ function bfIdArg(bfId) {
|
|
|
16882
17211
|
return bfId ? `, ${JSON.stringify(bfId)}` : "";
|
|
16883
17212
|
}
|
|
16884
17213
|
function emitSignal(lines, plan) {
|
|
17214
|
+
const getterSlot = plan.getterElided ? "" : plan.getter;
|
|
16885
17215
|
if (plan.initializerOverride) {
|
|
16886
17216
|
if (plan.setter) {
|
|
16887
|
-
lines.push(` const [${
|
|
17217
|
+
lines.push(` const [${getterSlot}, ${plan.setter}] = ${plan.initializerOverride}`);
|
|
16888
17218
|
} else {
|
|
16889
17219
|
lines.push(` const [${plan.getter}] = ${plan.initializerOverride}`);
|
|
16890
17220
|
}
|
|
@@ -16893,9 +17223,9 @@ function emitSignal(lines, plan) {
|
|
|
16893
17223
|
const id = bfIdArg(plan.bfId);
|
|
16894
17224
|
if (plan.branchCondition) {
|
|
16895
17225
|
if (plan.setter) {
|
|
16896
|
-
lines.push(` let ${plan.getter}, ${plan.setter}`);
|
|
17226
|
+
lines.push(plan.getterElided ? ` let ${plan.setter}` : ` let ${plan.getter}, ${plan.setter}`);
|
|
16897
17227
|
lines.push(` if (${plan.branchCondition}) {`);
|
|
16898
|
-
lines.push(` ;[${
|
|
17228
|
+
lines.push(` ;[${getterSlot}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
|
|
16899
17229
|
lines.push(` }`);
|
|
16900
17230
|
} else {
|
|
16901
17231
|
lines.push(` let ${plan.getter}`);
|
|
@@ -16906,7 +17236,7 @@ function emitSignal(lines, plan) {
|
|
|
16906
17236
|
return;
|
|
16907
17237
|
}
|
|
16908
17238
|
if (plan.setter) {
|
|
16909
|
-
lines.push(` const [${
|
|
17239
|
+
lines.push(` const [${getterSlot}, ${plan.setter}] = createSignal(${plan.initialValueExpr}${id})`);
|
|
16910
17240
|
} else {
|
|
16911
17241
|
lines.push(` const [${plan.getter}] = createSignal(${plan.initialValueExpr}${id})`);
|
|
16912
17242
|
}
|
|
@@ -17485,7 +17815,7 @@ function emitComponentAndEventSetup(ls, indent, elVar, comps, events, loopParam,
|
|
|
17485
17815
|
// src/ir-to-client-js/plan/build-static-array-child-init.ts
|
|
17486
17816
|
function staticPreludeStatements(preamble) {
|
|
17487
17817
|
return preamble ? [renderPreamble(preamble, {
|
|
17488
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined
|
|
17818
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
|
|
17489
17819
|
})] : [];
|
|
17490
17820
|
}
|
|
17491
17821
|
function buildStaticArrayChildInitsPlan(ctx) {
|
|
@@ -18040,7 +18370,8 @@ function buildReactiveEffectsPlan(args) {
|
|
|
18040
18370
|
attrs: slotAttrs.map((attr) => ({
|
|
18041
18371
|
attrName: attr.attrName,
|
|
18042
18372
|
wrappedExpression: wrap(attr.expression),
|
|
18043
|
-
meta: pickAttrMeta(attr)
|
|
18373
|
+
meta: pickAttrMeta(attr),
|
|
18374
|
+
...attr.readsPreamble && { readsPreamble: true }
|
|
18044
18375
|
}))
|
|
18045
18376
|
});
|
|
18046
18377
|
}
|
|
@@ -18240,7 +18571,7 @@ function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, o
|
|
|
18240
18571
|
] : [{ param: inner.param, bindings: inner.paramBindings }];
|
|
18241
18572
|
preludeStatements.push(renderPreamble(inner.preamble, {
|
|
18242
18573
|
transformJs: (t) => wrapInner(wrapOuter(t)),
|
|
18243
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, leafLoopParams, undefined
|
|
18574
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, leafLoopParams, undefined)
|
|
18244
18575
|
}));
|
|
18245
18576
|
}
|
|
18246
18577
|
const childRefs = buildChildRefBindings(inner.bindings.refs, inner.param, inner.paramBindings);
|
|
@@ -18266,7 +18597,7 @@ function buildStaticEmit(inner, level, uidSuffix) {
|
|
|
18266
18597
|
preludeStatements.push(indexAlias);
|
|
18267
18598
|
if (inner.preamble) {
|
|
18268
18599
|
preludeStatements.push(renderPreamble(inner.preamble, {
|
|
18269
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined
|
|
18600
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
|
|
18270
18601
|
}));
|
|
18271
18602
|
}
|
|
18272
18603
|
return {
|
|
@@ -18298,7 +18629,7 @@ function buildTopLevelCompositePlan(elem, profileComponentName) {
|
|
|
18298
18629
|
indexParam: elem.index || "__idx",
|
|
18299
18630
|
mapPreambleWrapped: elem.preamble ? renderPreamble(elem.preamble, {
|
|
18300
18631
|
transformJs: wrap,
|
|
18301
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined
|
|
18632
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
|
|
18302
18633
|
}) : "",
|
|
18303
18634
|
template: elem.template,
|
|
18304
18635
|
outerComps: filterCondCompsOut(outerCompsByDepth, elem.bindings.conditionals),
|
|
@@ -18348,7 +18679,7 @@ function buildBranchCompositePlan(loop, cv, profileComponentName) {
|
|
|
18348
18679
|
indexParam: loop.index || "__idx",
|
|
18349
18680
|
mapPreambleWrapped: loop.preamble ? renderPreamble(loop.preamble, {
|
|
18350
18681
|
transformJs: wrap,
|
|
18351
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined
|
|
18682
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined)
|
|
18352
18683
|
}) : "",
|
|
18353
18684
|
template: loop.template,
|
|
18354
18685
|
outerComps: filterCondCompsOut(outerCompsByDepth, loop.bindings.conditionals),
|
|
@@ -18413,7 +18744,7 @@ function buildDynamicLoopDelegationPlan(elem, profileComponentName) {
|
|
|
18413
18744
|
key: elem.key,
|
|
18414
18745
|
index: elem.index,
|
|
18415
18746
|
mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
|
|
18416
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined
|
|
18747
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
|
|
18417
18748
|
}) : null,
|
|
18418
18749
|
mapPreambleDeclaredNames: elem.preamble?.declaredNames ?? []
|
|
18419
18750
|
})
|
|
@@ -18432,7 +18763,7 @@ function buildBranchLoopDelegationPlan(loop, cv, profileComponentName) {
|
|
|
18432
18763
|
key: loop.key,
|
|
18433
18764
|
index: loop.index,
|
|
18434
18765
|
mapPreamble: loop.preamble ? renderPreamble(loop.preamble, {
|
|
18435
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined
|
|
18766
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
|
|
18436
18767
|
}) : null,
|
|
18437
18768
|
mapPreambleDeclaredNames: loop.preamble?.declaredNames ?? []
|
|
18438
18769
|
})
|
|
@@ -18449,7 +18780,7 @@ function buildStaticArrayDelegationPlan(elem, profileComponentName) {
|
|
|
18449
18780
|
arrayExpr: buildChainedArrayExpr(elem),
|
|
18450
18781
|
param: elem.param,
|
|
18451
18782
|
mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
|
|
18452
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined
|
|
18783
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, undefined, undefined)
|
|
18453
18784
|
}) : null,
|
|
18454
18785
|
mapPreambleDeclaredNames: elem.preamble?.declaredNames ?? [],
|
|
18455
18786
|
offset: elem.offset ?? null,
|
|
@@ -18484,6 +18815,181 @@ function buildKeyedOrIndexLookup(args) {
|
|
|
18484
18815
|
};
|
|
18485
18816
|
}
|
|
18486
18817
|
|
|
18818
|
+
// src/ir-to-client-js/control-flow/plan/lazy-conditional.ts
|
|
18819
|
+
var NO = (reason) => ({ lazySafe: false, reason });
|
|
18820
|
+
function wiringOn(branch) {
|
|
18821
|
+
const found = [];
|
|
18822
|
+
if (branch.childComponents.length > 0)
|
|
18823
|
+
found.push("child components");
|
|
18824
|
+
if (branch.innerLoops && branch.innerLoops.length > 0)
|
|
18825
|
+
found.push("an inner loop");
|
|
18826
|
+
if (branch.conditionals && branch.conditionals.length > 0)
|
|
18827
|
+
found.push("a nested conditional");
|
|
18828
|
+
if (branch.events && branch.events.length > 0)
|
|
18829
|
+
found.push("events");
|
|
18830
|
+
if (branch.reactiveAttrs && branch.reactiveAttrs.length > 0)
|
|
18831
|
+
found.push("reactive attrs");
|
|
18832
|
+
if (branch.reactiveTexts && branch.reactiveTexts.length > 0)
|
|
18833
|
+
found.push("reactive text");
|
|
18834
|
+
return found;
|
|
18835
|
+
}
|
|
18836
|
+
function analyzeLazyConditional(cond, indexParam, arms) {
|
|
18837
|
+
for (const [label, branch] of [["true", cond.whenTrue], ["false", cond.whenFalse]]) {
|
|
18838
|
+
const wiring = wiringOn(branch);
|
|
18839
|
+
if (wiring.length > 0) {
|
|
18840
|
+
return NO(`conditional on slot ${cond.slotId}: its ${label} arm owns ${wiring.join(" + ")}`);
|
|
18841
|
+
}
|
|
18842
|
+
}
|
|
18843
|
+
for (const [label, html] of [["true", arms.whenTrueHtml], ["false", arms.whenFalseHtml]]) {
|
|
18844
|
+
if (html.includes("bf-cond-start:")) {
|
|
18845
|
+
return NO(`conditional on slot ${cond.slotId}: its ${label} arm is a fragment conditional`);
|
|
18846
|
+
}
|
|
18847
|
+
if (!html.includes(`bf-c="${cond.slotId}"`)) {
|
|
18848
|
+
return NO(`conditional on slot ${cond.slotId}: its ${label} arm has no single bf-c root`);
|
|
18849
|
+
}
|
|
18850
|
+
if (html.includes("${")) {
|
|
18851
|
+
return NO(`conditional on slot ${cond.slotId}: its ${label} arm interpolates a value`);
|
|
18852
|
+
}
|
|
18853
|
+
}
|
|
18854
|
+
if (!cond.conditionFreeIdentifiers) {
|
|
18855
|
+
return NO(`conditional on slot ${cond.slotId}: condition has no analyzable identifier set`);
|
|
18856
|
+
}
|
|
18857
|
+
if (cond.conditionFreeIdentifiers.has(indexParam)) {
|
|
18858
|
+
return NO(`conditional on slot ${cond.slotId}: condition reads the loop index parameter '${indexParam}'`);
|
|
18859
|
+
}
|
|
18860
|
+
return {
|
|
18861
|
+
lazySafe: true,
|
|
18862
|
+
facts: {
|
|
18863
|
+
slotId: cond.slotId,
|
|
18864
|
+
condition: cond.condition,
|
|
18865
|
+
whenTrueHtml: arms.whenTrueHtml,
|
|
18866
|
+
whenFalseHtml: arms.whenFalseHtml
|
|
18867
|
+
}
|
|
18868
|
+
};
|
|
18869
|
+
}
|
|
18870
|
+
|
|
18871
|
+
// src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
|
|
18872
|
+
import ts15 from "typescript";
|
|
18873
|
+
var NO_PREAMBLE = {
|
|
18874
|
+
lazySafe: true,
|
|
18875
|
+
facts: { declaredNames: new Set, freeNames: new Set }
|
|
18876
|
+
};
|
|
18877
|
+
var NO2 = (reason) => ({ lazySafe: false, reason });
|
|
18878
|
+
function analyzeLazyPreamble(preamble, indexParam, primableNames) {
|
|
18879
|
+
if (!preamble)
|
|
18880
|
+
return NO_PREAMBLE;
|
|
18881
|
+
if (preamble.builderNames.length > 0) {
|
|
18882
|
+
return NO2(`map-callback preamble accumulates JSX leaves (${preamble.builderNames.join(", ")})`);
|
|
18883
|
+
}
|
|
18884
|
+
for (const seg of preamble.segments) {
|
|
18885
|
+
if (seg.kind !== "js")
|
|
18886
|
+
return NO2("map-callback preamble contains a JSX leaf");
|
|
18887
|
+
}
|
|
18888
|
+
const text = preambleAnalysisText(preamble);
|
|
18889
|
+
if (text.trim().length === 0)
|
|
18890
|
+
return NO_PREAMBLE;
|
|
18891
|
+
const declaredNames = new Set;
|
|
18892
|
+
const sf = ts15.createSourceFile("__lazy_preamble__.ts", text, ts15.ScriptTarget.Latest, true, ts15.ScriptKind.TS);
|
|
18893
|
+
for (const stmt of sf.statements) {
|
|
18894
|
+
if (!ts15.isVariableStatement(stmt)) {
|
|
18895
|
+
return NO2(`map-callback preamble has a non-declaration statement (${ts15.SyntaxKind[stmt.kind]})`);
|
|
18896
|
+
}
|
|
18897
|
+
const isConst = (stmt.declarationList.flags & ts15.NodeFlags.Const) !== 0;
|
|
18898
|
+
if (!isConst)
|
|
18899
|
+
return NO2("map-callback preamble declares a mutable binding (let/var)");
|
|
18900
|
+
for (const decl of stmt.declarationList.declarations) {
|
|
18901
|
+
collectBindingNames3(decl.name, declaredNames);
|
|
18902
|
+
if (!decl.initializer) {
|
|
18903
|
+
return NO2("map-callback preamble has a declaration with no initializer");
|
|
18904
|
+
}
|
|
18905
|
+
const impure = findImpureNode(decl.initializer, primableNames);
|
|
18906
|
+
if (impure) {
|
|
18907
|
+
return NO2(`map-callback preamble initializer is not re-runnable (${impure})`);
|
|
18908
|
+
}
|
|
18909
|
+
}
|
|
18910
|
+
}
|
|
18911
|
+
for (const name of declaredNames) {
|
|
18912
|
+
if (primableNames.has(name)) {
|
|
18913
|
+
return NO2(`map-callback preamble shadows the signal/memo getter '${name}'`);
|
|
18914
|
+
}
|
|
18915
|
+
}
|
|
18916
|
+
const readNames = extractFreeIdentifiersFromStatementText(text);
|
|
18917
|
+
if (readNames.has(indexParam) && !declaredNames.has(indexParam)) {
|
|
18918
|
+
return NO2(`map-callback preamble reads the loop index parameter '${indexParam}'`);
|
|
18919
|
+
}
|
|
18920
|
+
const freeNames = new Set(readNames);
|
|
18921
|
+
for (const declared of declaredNames)
|
|
18922
|
+
freeNames.delete(declared);
|
|
18923
|
+
return { lazySafe: true, facts: { declaredNames, freeNames } };
|
|
18924
|
+
}
|
|
18925
|
+
function collectBindingNames3(name, out) {
|
|
18926
|
+
if (ts15.isIdentifier(name)) {
|
|
18927
|
+
out.add(name.text);
|
|
18928
|
+
return;
|
|
18929
|
+
}
|
|
18930
|
+
for (const element of name.elements) {
|
|
18931
|
+
if (ts15.isOmittedExpression(element))
|
|
18932
|
+
continue;
|
|
18933
|
+
collectBindingNames3(element.name, out);
|
|
18934
|
+
}
|
|
18935
|
+
}
|
|
18936
|
+
function findImpureNode(root, primableNames) {
|
|
18937
|
+
let found = null;
|
|
18938
|
+
const visit3 = (node) => {
|
|
18939
|
+
if (found)
|
|
18940
|
+
return;
|
|
18941
|
+
if (ts15.isCallExpression(node)) {
|
|
18942
|
+
const callee = node.expression;
|
|
18943
|
+
const isSignalRead = ts15.isIdentifier(callee) && primableNames.has(callee.text) && node.arguments.length === 0 && node.questionDotToken === undefined;
|
|
18944
|
+
if (!isSignalRead) {
|
|
18945
|
+
found = `call to ${callee.getText(callee.getSourceFile())}`;
|
|
18946
|
+
return;
|
|
18947
|
+
}
|
|
18948
|
+
}
|
|
18949
|
+
if (ts15.isNewExpression(node)) {
|
|
18950
|
+
found = "new expression";
|
|
18951
|
+
return;
|
|
18952
|
+
}
|
|
18953
|
+
if (ts15.isTaggedTemplateExpression(node)) {
|
|
18954
|
+
found = "tagged template";
|
|
18955
|
+
return;
|
|
18956
|
+
}
|
|
18957
|
+
if (ts15.isAwaitExpression(node)) {
|
|
18958
|
+
found = "await";
|
|
18959
|
+
return;
|
|
18960
|
+
}
|
|
18961
|
+
if (ts15.isYieldExpression(node)) {
|
|
18962
|
+
found = "yield";
|
|
18963
|
+
return;
|
|
18964
|
+
}
|
|
18965
|
+
if (ts15.isPrefixUnaryExpression(node) || ts15.isPostfixUnaryExpression(node)) {
|
|
18966
|
+
const op = node.operator;
|
|
18967
|
+
if (op === ts15.SyntaxKind.PlusPlusToken || op === ts15.SyntaxKind.MinusMinusToken) {
|
|
18968
|
+
found = "increment/decrement";
|
|
18969
|
+
return;
|
|
18970
|
+
}
|
|
18971
|
+
}
|
|
18972
|
+
if (ts15.isDeleteExpression(node)) {
|
|
18973
|
+
found = "delete";
|
|
18974
|
+
return;
|
|
18975
|
+
}
|
|
18976
|
+
if (ts15.isFunctionExpression(node) || ts15.isArrowFunction(node) || ts15.isClassExpression(node)) {
|
|
18977
|
+
found = "function or class expression";
|
|
18978
|
+
return;
|
|
18979
|
+
}
|
|
18980
|
+
if (ts15.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
|
|
18981
|
+
found = "assignment";
|
|
18982
|
+
return;
|
|
18983
|
+
}
|
|
18984
|
+
ts15.forEachChild(node, visit3);
|
|
18985
|
+
};
|
|
18986
|
+
visit3(root);
|
|
18987
|
+
return found;
|
|
18988
|
+
}
|
|
18989
|
+
function isAssignmentOperator(kind) {
|
|
18990
|
+
return kind >= ts15.SyntaxKind.FirstAssignment && kind <= ts15.SyntaxKind.LastAssignment;
|
|
18991
|
+
}
|
|
18992
|
+
|
|
18487
18993
|
// src/ir-to-client-js/control-flow/plan/lazy-row-eligibility.ts
|
|
18488
18994
|
var PURE_SOURCE_GLOBALS = new Set([
|
|
18489
18995
|
"Object",
|
|
@@ -18527,51 +19033,51 @@ var INERT_BINDING_GLOBALS = new Set([
|
|
|
18527
19033
|
"decodeURI"
|
|
18528
19034
|
]);
|
|
18529
19035
|
var UNKNOWN_IDENTIFIERS = "<unknown>";
|
|
18530
|
-
var
|
|
19036
|
+
var NO3 = (reason) => ({ eligible: false, reason });
|
|
18531
19037
|
function lazyRowEligibility(args) {
|
|
18532
19038
|
const { shape, bindings, arraySourceIdentifiers, scope } = args;
|
|
18533
19039
|
if (scope.profile)
|
|
18534
|
-
return
|
|
19040
|
+
return NO3("profile mode keeps the granular eager emission");
|
|
18535
19041
|
if (shape.callSite !== "plain" && shape.callSite !== "branch-plain") {
|
|
18536
|
-
return
|
|
19042
|
+
return NO3(`call site '${shape.callSite}' is not a plain loop row`);
|
|
18537
19043
|
}
|
|
18538
19044
|
if (shape.flatMapLeafItem)
|
|
18539
|
-
return
|
|
19045
|
+
return NO3("flatMap descriptor loop (build-or-patch renderItem)");
|
|
18540
19046
|
if (shape.anchored)
|
|
18541
|
-
return
|
|
19047
|
+
return NO3("anchored whole-item-conditional loop");
|
|
18542
19048
|
if (shape.bodyIsMultiRoot)
|
|
18543
|
-
return
|
|
19049
|
+
return NO3("multi-root (Fragment) row");
|
|
18544
19050
|
if (!shape.hasExplicitKey)
|
|
18545
|
-
return
|
|
18546
|
-
if (shape.
|
|
18547
|
-
return
|
|
19051
|
+
return NO3("index-keyed loop (no explicit key)");
|
|
19052
|
+
if (shape.conditionalRefusal)
|
|
19053
|
+
return NO3(shape.conditionalRefusal);
|
|
18548
19054
|
if (shape.childRefCount > 0)
|
|
18549
|
-
return
|
|
19055
|
+
return NO3("row has imperative child refs");
|
|
18550
19056
|
if (shape.hasChildComponent)
|
|
18551
|
-
return
|
|
19057
|
+
return NO3("row body is a child component");
|
|
18552
19058
|
if (shape.nestedComponentCount > 0)
|
|
18553
|
-
return
|
|
19059
|
+
return NO3("row contains nested child components");
|
|
18554
19060
|
if (shape.innerLoopCount > 0)
|
|
18555
|
-
return
|
|
18556
|
-
if (shape.
|
|
18557
|
-
return
|
|
19061
|
+
return NO3("row contains an inner loop");
|
|
19062
|
+
if (shape.mapPreambleRefusal)
|
|
19063
|
+
return NO3(shape.mapPreambleRefusal);
|
|
18558
19064
|
if (shape.preambleRegionCount > 0)
|
|
18559
|
-
return
|
|
19065
|
+
return NO3("row has preamble-patched regions");
|
|
18560
19066
|
if (shape.hasParamUnwrap)
|
|
18561
|
-
return
|
|
19067
|
+
return NO3("destructured loop param without param bindings");
|
|
18562
19068
|
for (const b of bindings) {
|
|
18563
19069
|
if (b.referencesIndex) {
|
|
18564
|
-
return
|
|
19070
|
+
return NO3(`binding on slot ${b.slotId} references the loop index parameter`);
|
|
18565
19071
|
}
|
|
18566
19072
|
if (b.opaqueOuterNames.includes(UNKNOWN_IDENTIFIERS)) {
|
|
18567
|
-
return
|
|
19073
|
+
return NO3(`binding on slot ${b.slotId} has no analyzable identifier set`);
|
|
18568
19074
|
}
|
|
18569
19075
|
}
|
|
18570
19076
|
if (!arraySourceIdentifiers)
|
|
18571
|
-
return
|
|
19077
|
+
return NO3("loop source free identifiers unavailable");
|
|
18572
19078
|
const sourceGate = checkSourceConsistency(arraySourceIdentifiers, scope);
|
|
18573
19079
|
if (sourceGate)
|
|
18574
|
-
return
|
|
19080
|
+
return NO3(`loop source is not provably hydration-consistent: ${sourceGate}`);
|
|
18575
19081
|
return { eligible: true };
|
|
18576
19082
|
}
|
|
18577
19083
|
function checkSourceConsistency(names, scope) {
|
|
@@ -18622,6 +19128,7 @@ function checkSourceConsistency(names, scope) {
|
|
|
18622
19128
|
}
|
|
18623
19129
|
function classifyLazyBinding(args) {
|
|
18624
19130
|
const { kind, slotId, free, rowLocalNames, indexParam, scope } = args;
|
|
19131
|
+
const preamble = args.preamble;
|
|
18625
19132
|
if (free === null) {
|
|
18626
19133
|
return {
|
|
18627
19134
|
kind,
|
|
@@ -18630,33 +19137,44 @@ function classifyLazyBinding(args) {
|
|
|
18630
19137
|
readsOuter: true,
|
|
18631
19138
|
reactiveOuterNames: [],
|
|
18632
19139
|
opaqueOuterNames: [UNKNOWN_IDENTIFIERS],
|
|
18633
|
-
referencesIndex: false
|
|
19140
|
+
referencesIndex: false,
|
|
19141
|
+
readsPreamble: preamble != null && preamble.declaredNames.size > 0
|
|
18634
19142
|
};
|
|
18635
19143
|
}
|
|
18636
19144
|
let readsItem = false;
|
|
18637
19145
|
let referencesIndex = false;
|
|
19146
|
+
let readsPreamble = false;
|
|
18638
19147
|
const reactiveOuterNames = [];
|
|
18639
19148
|
const opaqueOuterNames = [];
|
|
18640
|
-
|
|
19149
|
+
const classifyName = (name) => {
|
|
18641
19150
|
if (rowLocalNames.has(name)) {
|
|
18642
19151
|
readsItem = true;
|
|
18643
|
-
|
|
19152
|
+
return;
|
|
18644
19153
|
}
|
|
18645
19154
|
if (name === indexParam) {
|
|
18646
19155
|
referencesIndex = true;
|
|
18647
|
-
|
|
19156
|
+
return;
|
|
18648
19157
|
}
|
|
18649
19158
|
if (INERT_BINDING_GLOBALS.has(name))
|
|
18650
|
-
|
|
19159
|
+
return;
|
|
18651
19160
|
if (scope.signals.has(name) || scope.memos.has(name)) {
|
|
18652
19161
|
if (!reactiveOuterNames.includes(name))
|
|
18653
19162
|
reactiveOuterNames.push(name);
|
|
18654
|
-
|
|
19163
|
+
return;
|
|
18655
19164
|
}
|
|
18656
19165
|
const constFree = scope.constants.get(name);
|
|
18657
19166
|
if (constFree !== undefined && constFree !== null && constFree.size === 0)
|
|
18658
|
-
|
|
19167
|
+
return;
|
|
18659
19168
|
opaqueOuterNames.push(name);
|
|
19169
|
+
};
|
|
19170
|
+
for (const name of free) {
|
|
19171
|
+
if (preamble?.declaredNames.has(name)) {
|
|
19172
|
+
readsPreamble = true;
|
|
19173
|
+
for (const dep of preamble.freeNames)
|
|
19174
|
+
classifyName(dep);
|
|
19175
|
+
continue;
|
|
19176
|
+
}
|
|
19177
|
+
classifyName(name);
|
|
18660
19178
|
}
|
|
18661
19179
|
return {
|
|
18662
19180
|
kind,
|
|
@@ -18665,7 +19183,8 @@ function classifyLazyBinding(args) {
|
|
|
18665
19183
|
readsOuter: reactiveOuterNames.length > 0 || opaqueOuterNames.length > 0,
|
|
18666
19184
|
reactiveOuterNames,
|
|
18667
19185
|
opaqueOuterNames,
|
|
18668
|
-
referencesIndex
|
|
19186
|
+
referencesIndex,
|
|
19187
|
+
readsPreamble
|
|
18669
19188
|
};
|
|
18670
19189
|
}
|
|
18671
19190
|
|
|
@@ -18682,6 +19201,23 @@ function decideLazyRow(args) {
|
|
|
18682
19201
|
const rowLocalNames = new Set([loop.param]);
|
|
18683
19202
|
for (const b of loop.paramBindings ?? [])
|
|
18684
19203
|
rowLocalNames.add(b.name);
|
|
19204
|
+
const primableNames = new Set([...scope.signals.keys(), ...scope.memos]);
|
|
19205
|
+
const preambleAnalysis = analyzeLazyPreamble(loop.preamble, args.indexParam, primableNames);
|
|
19206
|
+
const rawConditionals = loop.bindings.conditionals ?? [];
|
|
19207
|
+
const condFacts = [];
|
|
19208
|
+
let conditionalRefusal = null;
|
|
19209
|
+
for (const cond of rawConditionals) {
|
|
19210
|
+
const verdict = analyzeLazyConditional(cond, args.indexParam, {
|
|
19211
|
+
whenTrueHtml: addCondAttrToTemplate(wrap(cond.whenTrueHtml), cond.slotId),
|
|
19212
|
+
whenFalseHtml: addCondAttrToTemplate(wrap(cond.whenFalseHtml), cond.slotId)
|
|
19213
|
+
});
|
|
19214
|
+
if (!verdict.lazySafe) {
|
|
19215
|
+
conditionalRefusal = verdict.reason;
|
|
19216
|
+
break;
|
|
19217
|
+
}
|
|
19218
|
+
condFacts.push(verdict.facts);
|
|
19219
|
+
}
|
|
19220
|
+
const preambleFacts = preambleAnalysis.lazySafe ? preambleAnalysis.facts : undefined;
|
|
18685
19221
|
const classified = [];
|
|
18686
19222
|
const attrClass = new Map;
|
|
18687
19223
|
loop.bindings.reactiveAttrs.forEach((attr, i) => {
|
|
@@ -18691,7 +19227,8 @@ function decideLazyRow(args) {
|
|
|
18691
19227
|
free: attrFreeIdentifiers2(attr.expression),
|
|
18692
19228
|
rowLocalNames,
|
|
18693
19229
|
indexParam: args.indexParam,
|
|
18694
|
-
scope
|
|
19230
|
+
scope,
|
|
19231
|
+
preamble: preambleFacts
|
|
18695
19232
|
});
|
|
18696
19233
|
attrClass.set(i, c);
|
|
18697
19234
|
classified.push(c);
|
|
@@ -18704,23 +19241,38 @@ function decideLazyRow(args) {
|
|
|
18704
19241
|
free: text.freeIdentifiers ?? null,
|
|
18705
19242
|
rowLocalNames,
|
|
18706
19243
|
indexParam: args.indexParam,
|
|
18707
|
-
scope
|
|
19244
|
+
scope,
|
|
19245
|
+
preamble: preambleFacts
|
|
18708
19246
|
});
|
|
18709
19247
|
textClass.set(i, c);
|
|
18710
19248
|
classified.push(c);
|
|
18711
19249
|
});
|
|
19250
|
+
const condClass = new Map;
|
|
19251
|
+
condFacts.forEach((c, i) => {
|
|
19252
|
+
const k = classifyLazyBinding({
|
|
19253
|
+
kind: "attr",
|
|
19254
|
+
slotId: c.slotId,
|
|
19255
|
+
free: rawConditionals[i].conditionFreeIdentifiers ?? null,
|
|
19256
|
+
rowLocalNames,
|
|
19257
|
+
indexParam: args.indexParam,
|
|
19258
|
+
scope,
|
|
19259
|
+
preamble: preambleFacts
|
|
19260
|
+
});
|
|
19261
|
+
condClass.set(i, k);
|
|
19262
|
+
classified.push(k);
|
|
19263
|
+
});
|
|
18712
19264
|
const shape = {
|
|
18713
19265
|
callSite: args.callSite,
|
|
18714
19266
|
flatMapLeafItem: args.flatMapLeafItem,
|
|
18715
19267
|
anchored: args.anchored,
|
|
18716
19268
|
bodyIsMultiRoot: loop.bodyIsMultiRoot ?? false,
|
|
18717
19269
|
hasExplicitKey: loop.key != null,
|
|
18718
|
-
|
|
19270
|
+
conditionalRefusal,
|
|
18719
19271
|
childRefCount: loop.bindings.refs?.length ?? 0,
|
|
18720
19272
|
nestedComponentCount: loop.nestedComponents?.length ?? 0,
|
|
18721
19273
|
innerLoopCount: loop.innerLoops?.length ?? 0,
|
|
18722
19274
|
hasChildComponent: "childComponent" in loop && loop.childComponent != null,
|
|
18723
|
-
|
|
19275
|
+
mapPreambleRefusal: preambleAnalysis.lazySafe ? null : preambleAnalysis.reason,
|
|
18724
19276
|
preambleRegionCount: args.preambleRegionCount,
|
|
18725
19277
|
hasParamUnwrap: args.paramUnwrap.length > 0
|
|
18726
19278
|
};
|
|
@@ -18748,7 +19300,8 @@ function decideLazyRow(args) {
|
|
|
18748
19300
|
refIndex: attrSlotIds.indexOf(attr.childSlotId),
|
|
18749
19301
|
ordinal: ordinal++,
|
|
18750
19302
|
readsItem: c.readsItem,
|
|
18751
|
-
readsOuter: c.readsOuter
|
|
19303
|
+
readsOuter: c.readsOuter,
|
|
19304
|
+
readsPreamble: c.readsPreamble
|
|
18752
19305
|
};
|
|
18753
19306
|
});
|
|
18754
19307
|
const texts = loop.bindings.reactiveTexts.map((text, i) => {
|
|
@@ -18758,7 +19311,8 @@ function decideLazyRow(args) {
|
|
|
18758
19311
|
wrappedExpression: wrap(text.expression),
|
|
18759
19312
|
ordinal: ordinal++,
|
|
18760
19313
|
readsItem: c.readsItem || !c.readsOuter,
|
|
18761
|
-
readsOuter: c.readsOuter
|
|
19314
|
+
readsOuter: c.readsOuter,
|
|
19315
|
+
readsPreamble: c.readsPreamble
|
|
18762
19316
|
};
|
|
18763
19317
|
});
|
|
18764
19318
|
const outerPrimeGetters = [];
|
|
@@ -18768,6 +19322,21 @@ function decideLazyRow(args) {
|
|
|
18768
19322
|
outerPrimeGetters.push(name);
|
|
18769
19323
|
}
|
|
18770
19324
|
}
|
|
19325
|
+
const condRefBase = attrSlotIds.length + (texts.length > 0 ? 1 : 0);
|
|
19326
|
+
const conditionals = condFacts.map((c, i) => {
|
|
19327
|
+
const klass = condClass.get(i);
|
|
19328
|
+
return {
|
|
19329
|
+
slotId: c.slotId,
|
|
19330
|
+
wrappedCondition: wrap(c.condition),
|
|
19331
|
+
whenTrueHtml: c.whenTrueHtml,
|
|
19332
|
+
whenFalseHtml: c.whenFalseHtml,
|
|
19333
|
+
refIndex: condRefBase + i,
|
|
19334
|
+
ordinal: ordinal++,
|
|
19335
|
+
readsItem: klass.readsItem || !klass.readsOuter,
|
|
19336
|
+
readsOuter: klass.readsOuter,
|
|
19337
|
+
readsPreamble: klass.readsPreamble
|
|
19338
|
+
};
|
|
19339
|
+
});
|
|
18771
19340
|
return {
|
|
18772
19341
|
plan: {
|
|
18773
19342
|
attrSlotIds,
|
|
@@ -18777,7 +19346,10 @@ function decideLazyRow(args) {
|
|
|
18777
19346
|
textNeedsRead: texts.some((t) => t.readsOuter),
|
|
18778
19347
|
lastCount: ordinal,
|
|
18779
19348
|
outerPrimeGetters,
|
|
18780
|
-
|
|
19349
|
+
preambleStatements: args.mapPreambleWrapped,
|
|
19350
|
+
itemNeedsPreamble: [...attrs, ...texts, ...conditionals].some((b) => b.readsItem && b.readsPreamble),
|
|
19351
|
+
outerNeedsPreamble: [...attrs, ...texts, ...conditionals].some((b) => b.readsOuter && b.readsPreamble),
|
|
19352
|
+
conditionals
|
|
18781
19353
|
},
|
|
18782
19354
|
decision
|
|
18783
19355
|
};
|
|
@@ -18849,7 +19421,7 @@ function buildBranchLoopPlan(loop, profileComponentName, lazyScope) {
|
|
|
18849
19421
|
const indexParam = loop.index || "__idx";
|
|
18850
19422
|
const mapPreambleWrapped = loop.preamble ? renderPreamble(loop.preamble, {
|
|
18851
19423
|
transformJs: (t) => wrapLoopParamAsAccessor(t, loop.param, loop.paramBindings),
|
|
18852
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined
|
|
19424
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: loop.param, bindings: loop.paramBindings }], undefined)
|
|
18853
19425
|
}) : "";
|
|
18854
19426
|
const preambleRegions = buildPreambleRegionPlans(loop.preambleRegions, loop.param, loop.paramBindings);
|
|
18855
19427
|
const plan = {
|
|
@@ -18945,7 +19517,7 @@ function buildArmBody(branch, options) {
|
|
|
18945
19517
|
}
|
|
18946
19518
|
|
|
18947
19519
|
// src/ir-to-client-js/emit-reactive.ts
|
|
18948
|
-
import
|
|
19520
|
+
import ts16 from "typescript";
|
|
18949
19521
|
|
|
18950
19522
|
// src/ir-to-client-js/control-flow/stringify/claim-plan.ts
|
|
18951
19523
|
function slotSpecLiteral(slot) {
|
|
@@ -19048,20 +19620,20 @@ function lowerToLocaleCallsInReactiveExpr(expr, matcher) {
|
|
|
19048
19620
|
return expr;
|
|
19049
19621
|
let sourceFile;
|
|
19050
19622
|
try {
|
|
19051
|
-
sourceFile =
|
|
19623
|
+
sourceFile = ts16.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts16.ScriptTarget.Latest, true, ts16.ScriptKind.TS);
|
|
19052
19624
|
} catch {
|
|
19053
19625
|
return expr;
|
|
19054
19626
|
}
|
|
19055
19627
|
const stmt = sourceFile.statements[0];
|
|
19056
|
-
if (!stmt || !
|
|
19628
|
+
if (!stmt || !ts16.isExpressionStatement(stmt))
|
|
19057
19629
|
return expr;
|
|
19058
|
-
const root =
|
|
19630
|
+
const root = ts16.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
|
|
19059
19631
|
const candidates = [];
|
|
19060
19632
|
const visit3 = (n) => {
|
|
19061
|
-
if (
|
|
19633
|
+
if (ts16.isCallExpression(n) && n.arguments.length === 2 && ts16.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && n.expression.name.text === "toLocaleDateString") {
|
|
19062
19634
|
candidates.push(n);
|
|
19063
19635
|
}
|
|
19064
|
-
|
|
19636
|
+
ts16.forEachChild(n, visit3);
|
|
19065
19637
|
};
|
|
19066
19638
|
visit3(root);
|
|
19067
19639
|
if (candidates.length === 0)
|
|
@@ -19097,20 +19669,20 @@ function lowerDateCallsInReactiveExpr(expr, matcher) {
|
|
|
19097
19669
|
return expr;
|
|
19098
19670
|
let sourceFile;
|
|
19099
19671
|
try {
|
|
19100
|
-
sourceFile =
|
|
19672
|
+
sourceFile = ts16.createSourceFile("__reactive_expr__.ts", `(${expr});`, ts16.ScriptTarget.Latest, true, ts16.ScriptKind.TS);
|
|
19101
19673
|
} catch {
|
|
19102
19674
|
return expr;
|
|
19103
19675
|
}
|
|
19104
19676
|
const stmt = sourceFile.statements[0];
|
|
19105
|
-
if (!stmt || !
|
|
19677
|
+
if (!stmt || !ts16.isExpressionStatement(stmt))
|
|
19106
19678
|
return expr;
|
|
19107
|
-
const root =
|
|
19679
|
+
const root = ts16.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
|
|
19108
19680
|
const candidates = [];
|
|
19109
19681
|
const visit3 = (n) => {
|
|
19110
|
-
if (
|
|
19682
|
+
if (ts16.isCallExpression(n) && n.arguments.length === 0 && ts16.isPropertyAccessExpression(n.expression) && !n.expression.questionDotToken && DATE_METHODS.has(n.expression.name.text)) {
|
|
19111
19683
|
candidates.push(n);
|
|
19112
19684
|
}
|
|
19113
|
-
|
|
19685
|
+
ts16.forEachChild(n, visit3);
|
|
19114
19686
|
};
|
|
19115
19687
|
visit3(root);
|
|
19116
19688
|
if (candidates.length === 0)
|
|
@@ -19418,7 +19990,7 @@ function stringifyReactiveEffects(lines, plan, opts) {
|
|
|
19418
19990
|
const outerTexts = plan?.outerTexts ?? [];
|
|
19419
19991
|
const conditionals = plan?.conditionals ?? [];
|
|
19420
19992
|
if (pc) {
|
|
19421
|
-
emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId);
|
|
19993
|
+
emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId, mapPreambleWrapped);
|
|
19422
19994
|
emitOuterTexts(lines, indent, elVar, outerTexts, bindingBfId, textClaimPathExprs);
|
|
19423
19995
|
emitPreambleRegionsEffect(lines, indent, elVar, preambleRegions, mapPreambleWrapped);
|
|
19424
19996
|
} else {
|
|
@@ -19428,7 +20000,7 @@ function stringifyReactiveEffects(lines, plan, opts) {
|
|
|
19428
20000
|
emitOuterConditional(lines, indent, elVar, cond, pc);
|
|
19429
20001
|
}
|
|
19430
20002
|
}
|
|
19431
|
-
function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId) {
|
|
20003
|
+
function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementIndexBySlot, bindingBfId, mapPreambleWrapped) {
|
|
19432
20004
|
for (const slot of attrSlots) {
|
|
19433
20005
|
const varName = `__ra_${varSlotId(slot.slotId)}`;
|
|
19434
20006
|
const lookupExpr = attrLookupExpr(slot.slotId, varName, elVar, lookup, elementIndexBySlot);
|
|
@@ -19436,6 +20008,9 @@ function emitAttrSlotsGranular(lines, indent, elVar, lookup, attrSlots, elementI
|
|
|
19436
20008
|
lines.push(`${indent}if (${varName}) {`);
|
|
19437
20009
|
for (const attr of slot.attrs) {
|
|
19438
20010
|
lines.push(`${indent} createEffect(() => {`);
|
|
20011
|
+
if (attr.readsPreamble && mapPreambleWrapped) {
|
|
20012
|
+
lines.push(`${indent} ${mapPreambleWrapped}`);
|
|
20013
|
+
}
|
|
19439
20014
|
for (const stmt of emitAttrUpdate(varName, attr.attrName, attr.wrappedExpression, attr.meta)) {
|
|
19440
20015
|
lines.push(`${indent} ${stmt}`);
|
|
19441
20016
|
}
|
|
@@ -19458,6 +20033,9 @@ function emitPreambleRegionsEffect(lines, indent, elVar, preambleRegions, mapPre
|
|
|
19458
20033
|
}
|
|
19459
20034
|
lines.push(`${indent}})`);
|
|
19460
20035
|
}
|
|
20036
|
+
function attrsReadPreamble(attrSlots) {
|
|
20037
|
+
return attrSlots.some((slot) => slot.attrs.some((a) => a.readsPreamble));
|
|
20038
|
+
}
|
|
19461
20039
|
function attrLookupExpr(slotId, varName, elVar, lookup, elementIndexBySlot) {
|
|
19462
20040
|
const pIdx = elementIndexBySlot?.get(slotId);
|
|
19463
20041
|
return pIdx !== undefined ? `__p ? __p[${pIdx}] : ${lookup}(${elVar}, '[bf="${slotId}"]')` : `${lookup}(${elVar}, '[bf="${slotId}"]')`;
|
|
@@ -19483,6 +20061,9 @@ function emitConsolidatedRowEffect(lines, indent, elVar, lookup, attrSlots, oute
|
|
|
19483
20061
|
return;
|
|
19484
20062
|
}
|
|
19485
20063
|
lines.push(`${indent}createEffect(() => {`);
|
|
20064
|
+
if (mapPreambleWrapped && (preambleRegions.length > 0 || attrsReadPreamble(attrSlots))) {
|
|
20065
|
+
lines.push(`${indent} ${mapPreambleWrapped}`);
|
|
20066
|
+
}
|
|
19486
20067
|
for (const slot of attrSlots) {
|
|
19487
20068
|
const varName = `__ra_${varSlotId(slot.slotId)}`;
|
|
19488
20069
|
lines.push(`${indent} if (${varName}) {`);
|
|
@@ -19495,9 +20076,6 @@ function emitConsolidatedRowEffect(lines, indent, elVar, lookup, attrSlots, oute
|
|
|
19495
20076
|
}
|
|
19496
20077
|
lines.push(`${indent} }`);
|
|
19497
20078
|
}
|
|
19498
|
-
if (preambleRegions.length > 0 && mapPreambleWrapped) {
|
|
19499
|
-
lines.push(`${indent} ${mapPreambleWrapped}`);
|
|
19500
|
-
}
|
|
19501
20079
|
for (const text of outerTexts) {
|
|
19502
20080
|
lines.push(`${indent} ${writer}('${text.slotId}', String(${text.wrappedExpression}))`);
|
|
19503
20081
|
}
|
|
@@ -19631,9 +20209,8 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
19631
20209
|
const { indent, lazyRow, paramHead } = o;
|
|
19632
20210
|
const mid = o.markerId.replace(/[^A-Za-z0-9_$]/g, "_");
|
|
19633
20211
|
const tplVar = `__tpl_${mid}`;
|
|
19634
|
-
const claimVar = `__lzc_${mid}`;
|
|
19635
20212
|
const hasRefs = lazyRow.attrSlotIds.length > 0 || lazyRow.texts.length > 0;
|
|
19636
|
-
const hasBindings = lazyRow.attrs.length > 0 || lazyRow.texts.length > 0;
|
|
20213
|
+
const hasBindings = lazyRow.attrs.length > 0 || lazyRow.texts.length > 0 || lazyRow.conditionals.length > 0;
|
|
19637
20214
|
const rwDoor = lazyRow.textNeedsRead;
|
|
19638
20215
|
const paths = o.skeletonPaths;
|
|
19639
20216
|
const useHoisted = Boolean(o.skeletonTemplate);
|
|
@@ -19663,13 +20240,10 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
19663
20240
|
freshPlanVar = adoptedPlanVar;
|
|
19664
20241
|
}
|
|
19665
20242
|
}
|
|
19666
|
-
|
|
19667
|
-
const
|
|
19668
|
-
lines
|
|
19669
|
-
|
|
19670
|
-
lines.push(`${indent} const __el = __e.primaryEl`);
|
|
19671
|
-
lines.push(`${indent} return [${parts.join(", ")}]`);
|
|
19672
|
-
lines.push(`${indent}}`);
|
|
20243
|
+
for (const c of lazyRow.conditionals) {
|
|
20244
|
+
const v = condVars(mid, c.slotId);
|
|
20245
|
+
emitHoistedTemplateDecl(lines, indent, v.trueTpl, c.whenTrueHtml);
|
|
20246
|
+
emitHoistedTemplateDecl(lines, indent, v.falseTpl, c.whenFalseHtml);
|
|
19673
20247
|
}
|
|
19674
20248
|
const call = `mapArrayLazy(() => ${o.arrayExpr}, ${o.containerVar}, ${o.keyFn}, {`;
|
|
19675
20249
|
lines.push(`${indent}${o.guardContainer ? `if (${o.containerVar}) ` : ""}${call}`);
|
|
@@ -19677,6 +20251,8 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
19677
20251
|
const b2 = `${indent} `;
|
|
19678
20252
|
lines.push(`${b1}createRow: (__e, ${o.indexParam}) => {`);
|
|
19679
20253
|
lines.push(`${b2}const ${paramHead} = () => __e.item`);
|
|
20254
|
+
if (lazyRow.preambleStatements)
|
|
20255
|
+
lines.push(`${b2}${lazyRow.preambleStatements}`);
|
|
19680
20256
|
const cloneExpr = useHoisted ? hoistedCloneExpr(tplVar, o.skeletonTemplate) : `(() => { ${emitTemplateCloneInline(o.template)} })()`;
|
|
19681
20257
|
lines.push(`${b2}const __el = ${cloneExpr}`);
|
|
19682
20258
|
if (hasRefs) {
|
|
@@ -19690,17 +20266,23 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
19690
20266
|
for (const t of lazyRow.texts)
|
|
19691
20267
|
emitTextBinding(lines, b2, t, createDoor, "create", rwDoor);
|
|
19692
20268
|
}
|
|
20269
|
+
for (const c of lazyRow.conditionals)
|
|
20270
|
+
emitConditional(lines, b2, mid, c, "create");
|
|
19693
20271
|
lines.push(`${b2}return __el`);
|
|
19694
20272
|
lines.push(`${b1}},`);
|
|
19695
20273
|
const itemAttrs = lazyRow.attrs.filter((a) => a.readsItem);
|
|
19696
20274
|
const itemTexts = lazyRow.texts.filter((t) => t.readsItem);
|
|
19697
|
-
|
|
20275
|
+
const itemConds = lazyRow.conditionals.filter((c) => c.readsItem);
|
|
20276
|
+
if (itemAttrs.length === 0 && itemTexts.length === 0 && itemConds.length === 0) {
|
|
19698
20277
|
lines.push(`${b1}applyItem: () => {},`);
|
|
19699
20278
|
} else {
|
|
19700
20279
|
lines.push(`${b1}applyItem: (__e) => {`);
|
|
19701
20280
|
lines.push(`${b2}const ${paramHead} = () => __e.item`);
|
|
19702
|
-
lines.push(`${b2}const __r = __e.refs ?? (__e.refs =
|
|
20281
|
+
lines.push(`${b2}const __r = __e.refs ?? (__e.refs = [])`);
|
|
19703
20282
|
lines.push(`${b2}const __l = __e.last ?? (__e.last = [])`);
|
|
20283
|
+
if (lazyRow.itemNeedsPreamble && lazyRow.preambleStatements) {
|
|
20284
|
+
lines.push(`${b2}${lazyRow.preambleStatements}`);
|
|
20285
|
+
}
|
|
19704
20286
|
for (const a of itemAttrs)
|
|
19705
20287
|
emitAttrBinding(lines, b2, a, "item");
|
|
19706
20288
|
if (itemTexts.length > 0) {
|
|
@@ -19708,19 +20290,25 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
19708
20290
|
for (const t of itemTexts)
|
|
19709
20291
|
emitTextBinding(lines, b2, t, "__d", "item", rwDoor);
|
|
19710
20292
|
}
|
|
20293
|
+
for (const c of itemConds)
|
|
20294
|
+
emitConditional(lines, b2, mid, c, "item");
|
|
19711
20295
|
lines.push(`${b1}},`);
|
|
19712
20296
|
}
|
|
19713
20297
|
const outerAttrs = lazyRow.attrs.filter((a) => a.readsOuter);
|
|
19714
20298
|
const outerTexts = lazyRow.texts.filter((t) => t.readsOuter);
|
|
19715
|
-
|
|
20299
|
+
const outerConds = lazyRow.conditionals.filter((c) => c.readsOuter);
|
|
20300
|
+
if (outerAttrs.length > 0 || outerTexts.length > 0 || outerConds.length > 0) {
|
|
19716
20301
|
const b3 = `${indent} `;
|
|
19717
20302
|
lines.push(`${b1}applyOuter: (__es, __seed) => {`);
|
|
19718
20303
|
for (const g of lazyRow.outerPrimeGetters)
|
|
19719
20304
|
lines.push(`${b2}${g}()`);
|
|
19720
20305
|
lines.push(`${b2}for (const __e of __es) {`);
|
|
19721
20306
|
lines.push(`${b3}const ${paramHead} = () => __e.item`);
|
|
19722
|
-
lines.push(`${b3}const __r = __e.refs ?? (__e.refs =
|
|
20307
|
+
lines.push(`${b3}const __r = __e.refs ?? (__e.refs = [])`);
|
|
19723
20308
|
lines.push(`${b3}const __l = __e.last ?? (__e.last = [])`);
|
|
20309
|
+
if (lazyRow.outerNeedsPreamble && lazyRow.preambleStatements) {
|
|
20310
|
+
lines.push(`${b3}${lazyRow.preambleStatements}`);
|
|
20311
|
+
}
|
|
19724
20312
|
for (const a of outerAttrs)
|
|
19725
20313
|
emitAttrBinding(lines, b3, a, "outer");
|
|
19726
20314
|
if (outerTexts.length > 0) {
|
|
@@ -19728,22 +20316,28 @@ function stringifyLazyRowLoop(lines, o) {
|
|
|
19728
20316
|
for (const t of outerTexts)
|
|
19729
20317
|
emitTextBinding(lines, b3, t, "__d", "outer", rwDoor);
|
|
19730
20318
|
}
|
|
20319
|
+
for (const c of outerConds)
|
|
20320
|
+
emitConditional(lines, b3, mid, c, "outer");
|
|
19731
20321
|
lines.push(`${b2}}`);
|
|
19732
20322
|
lines.push(`${b1}},`);
|
|
19733
20323
|
}
|
|
19734
20324
|
lines.push(`${indent}}, '${o.markerId}')`);
|
|
19735
20325
|
}
|
|
19736
|
-
function refParts(lazyRow, elVar, skeletonPaths, planVar
|
|
20326
|
+
function refParts(lazyRow, elVar, skeletonPaths, planVar) {
|
|
19737
20327
|
const parts = [];
|
|
19738
20328
|
for (const slotId of lazyRow.attrSlotIds) {
|
|
19739
20329
|
const path = skeletonPaths?.elementPaths.get(slotId);
|
|
19740
20330
|
parts.push(path ? pathExpr(elVar, path) : `qsa(${elVar}, '[bf="${slotId}"]')`);
|
|
19741
20331
|
}
|
|
19742
20332
|
if (lazyRow.texts.length > 0) {
|
|
19743
|
-
parts.push(
|
|
20333
|
+
parts.push(`${doorCtor(lazyRow)}(${elVar}, ${planVar})`);
|
|
19744
20334
|
}
|
|
19745
20335
|
return parts;
|
|
19746
20336
|
}
|
|
20337
|
+
function elementAccess(a) {
|
|
20338
|
+
const slot = `__r[${a.refIndex}]`;
|
|
20339
|
+
return `${a.refIndex} in __r ? ${slot} : (${slot} = qsa(__e.primaryEl, '[bf="${a.slotId}"]'))`;
|
|
20340
|
+
}
|
|
19747
20341
|
function doorCtor(lazyRow) {
|
|
19748
20342
|
return lazyRow.textNeedsRead ? "lazyClaimSlots" : "lazySlots";
|
|
19749
20343
|
}
|
|
@@ -19751,11 +20345,36 @@ function doorAccess(lazyRow, writerIndex, adoptedPlanVar) {
|
|
|
19751
20345
|
const slot = `__r[${writerIndex}]`;
|
|
19752
20346
|
return `${slot} ?? (${slot} = ${doorCtor(lazyRow)}(__e.primaryEl, ${adoptedPlanVar}))`;
|
|
19753
20347
|
}
|
|
20348
|
+
function condVars(mid, slotId) {
|
|
20349
|
+
const key = `${mid}_${slotId.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
20350
|
+
return { trueTpl: `__cbt_${key}`, falseTpl: `__cbf_${key}` };
|
|
20351
|
+
}
|
|
20352
|
+
function emitConditional(lines, ind, mid, c, mode) {
|
|
20353
|
+
const v = condVars(mid, c.slotId);
|
|
20354
|
+
if (mode === "create") {
|
|
20355
|
+
lines.push(`${ind}__l[${c.ordinal}] = !!(${c.wrappedCondition})`);
|
|
20356
|
+
return;
|
|
20357
|
+
}
|
|
20358
|
+
const slot = `__r[${c.refIndex}]`;
|
|
20359
|
+
lines.push(`${ind}{ const __c = ${c.refIndex} in __r ? ${slot} : (${slot} = qsa(__e.primaryEl, '[bf-c="${c.slotId}"]'))`);
|
|
20360
|
+
lines.push(`${ind}if (__c) {`);
|
|
20361
|
+
lines.push(`${ind} const __x = !!(${c.wrappedCondition})`);
|
|
20362
|
+
lines.push(`${ind} const __w = (__x ? ${v.trueTpl} : ${v.falseTpl}).content.firstElementChild`);
|
|
20363
|
+
const guard = mode === "item" ? dedupGuard(c.ordinal) : `__seed ? (__c.outerHTML !== __w.outerHTML) : (${dedupGuard(c.ordinal)})`;
|
|
20364
|
+
lines.push(`${ind} if (${guard}) {`);
|
|
20365
|
+
lines.push(`${ind} const __n = __w.cloneNode(true)`);
|
|
20366
|
+
lines.push(`${ind} __c.replaceWith(__n)`);
|
|
20367
|
+
lines.push(`${ind} ${slot} = __n`);
|
|
20368
|
+
lines.push(`${ind} }`);
|
|
20369
|
+
lines.push(`${ind} __l[${c.ordinal}] = __x`);
|
|
20370
|
+
lines.push(`${ind}} }`);
|
|
20371
|
+
}
|
|
19754
20372
|
function dedupGuard(ordinal) {
|
|
19755
20373
|
return `!(${ordinal} in __l) || !Object.is(__l[${ordinal}], __x)`;
|
|
19756
20374
|
}
|
|
19757
20375
|
function emitAttrBinding(lines, ind, a, mode) {
|
|
19758
|
-
|
|
20376
|
+
const target = mode === "create" ? `__r[${a.refIndex}]` : elementAccess(a);
|
|
20377
|
+
lines.push(`${ind}{ const __t = ${target}`);
|
|
19759
20378
|
lines.push(`${ind}if (__t) {`);
|
|
19760
20379
|
lines.push(`${ind} const __x = ${a.wrappedExpression}`);
|
|
19761
20380
|
const guard = mode === "create" ? null : mode === "item" ? dedupGuard(a.ordinal) : `__seed ? (${seedDiffersExpr("__t", a)}) : (${dedupGuard(a.ordinal)})`;
|
|
@@ -20752,7 +21371,7 @@ function buildPlainLoopPlan(elem, profileComponentName, lazyScope) {
|
|
|
20752
21371
|
const indexParam = elem.index || "__idx";
|
|
20753
21372
|
const mapPreambleWrapped = elem.preamble ? renderPreamble(elem.preamble, {
|
|
20754
21373
|
transformJs: wrap,
|
|
20755
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined
|
|
21374
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
|
|
20756
21375
|
}) : "";
|
|
20757
21376
|
const preambleRegions = buildPreambleRegionPlans(elem.preambleRegions, elem.param, elem.paramBindings);
|
|
20758
21377
|
return {
|
|
@@ -20829,7 +21448,7 @@ function buildStaticLoopMaterialize(elem, unsafeLocalNames) {
|
|
|
20829
21448
|
return {
|
|
20830
21449
|
itemTemplate: elem.staticItemTemplate,
|
|
20831
21450
|
mapPreamble: elem.preamble ? renderPreamble(elem.preamble, {
|
|
20832
|
-
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined
|
|
21451
|
+
renderLeaf: (ir) => irToHtmlTemplate(ir, undefined, 1, [{ param: elem.param, bindings: elem.paramBindings }], undefined)
|
|
20833
21452
|
}) : "",
|
|
20834
21453
|
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false
|
|
20835
21454
|
};
|
|
@@ -21066,20 +21685,20 @@ var PHASES = [
|
|
|
21066
21685
|
];
|
|
21067
21686
|
|
|
21068
21687
|
// src/ir-to-client-js/rewrite-props-object.ts
|
|
21069
|
-
import
|
|
21688
|
+
import ts17 from "typescript";
|
|
21070
21689
|
function rewritePropsObjectRef(code, propsObjectName) {
|
|
21071
21690
|
const srcPropsName = propsObjectName ?? "props";
|
|
21072
21691
|
if (srcPropsName === PROPS_PARAM)
|
|
21073
21692
|
return code;
|
|
21074
21693
|
if (!new RegExp(`\\b${srcPropsName}\\b`).test(code))
|
|
21075
21694
|
return code;
|
|
21076
|
-
const sourceFile =
|
|
21695
|
+
const sourceFile = ts17.createSourceFile("init-body.ts", code, ts17.ScriptTarget.Latest, true, ts17.ScriptKind.TS);
|
|
21077
21696
|
const spans = [];
|
|
21078
21697
|
function visit3(node) {
|
|
21079
|
-
if (
|
|
21698
|
+
if (ts17.isIdentifier(node) && node.text === srcPropsName && shouldRewrite(node)) {
|
|
21080
21699
|
spans.push([node.getStart(sourceFile), node.getEnd()]);
|
|
21081
21700
|
}
|
|
21082
|
-
|
|
21701
|
+
ts17.forEachChild(node, visit3);
|
|
21083
21702
|
}
|
|
21084
21703
|
visit3(sourceFile);
|
|
21085
21704
|
if (spans.length === 0)
|
|
@@ -21095,17 +21714,17 @@ function shouldRewrite(node) {
|
|
|
21095
21714
|
const parent = node.parent;
|
|
21096
21715
|
if (!parent)
|
|
21097
21716
|
return true;
|
|
21098
|
-
if (
|
|
21717
|
+
if (ts17.isPropertyAccessExpression(parent) && parent.name === node)
|
|
21099
21718
|
return false;
|
|
21100
|
-
if (
|
|
21719
|
+
if (ts17.isPropertyAssignment(parent) && parent.name === node)
|
|
21101
21720
|
return false;
|
|
21102
|
-
if (
|
|
21721
|
+
if (ts17.isShorthandPropertyAssignment(parent) && parent.name === node)
|
|
21103
21722
|
return false;
|
|
21104
|
-
if (
|
|
21723
|
+
if (ts17.isPropertySignature(parent) && parent.name === node)
|
|
21105
21724
|
return false;
|
|
21106
|
-
if (
|
|
21725
|
+
if (ts17.isPropertyDeclaration(parent) && parent.name === node)
|
|
21107
21726
|
return false;
|
|
21108
|
-
if (
|
|
21727
|
+
if (ts17.isBindingElement(parent) && parent.name === node)
|
|
21109
21728
|
return false;
|
|
21110
21729
|
return true;
|
|
21111
21730
|
}
|
|
@@ -21449,7 +22068,7 @@ function generateTemplateOnlyMount(ir, ctx) {
|
|
|
21449
22068
|
}
|
|
21450
22069
|
if (!templateHtml) {
|
|
21451
22070
|
const csrInlinableConstants = csrInlinableConstantsFromCtx(ctx);
|
|
21452
|
-
templateHtml = generateCsrTemplate(ir.root, csrInlinableConstants, ctx,
|
|
22071
|
+
templateHtml = generateCsrTemplate(ir.root, csrInlinableConstants, ctx, restSpreadNames, ctx.propsObjectName, unsafeLocalNames);
|
|
21453
22072
|
}
|
|
21454
22073
|
if (!templateHtml) {
|
|
21455
22074
|
return "";
|
|
@@ -21735,7 +22354,7 @@ function walkIR2(node, visitor) {
|
|
|
21735
22354
|
}
|
|
21736
22355
|
|
|
21737
22356
|
// src/preprocess-inline-jsx-callbacks.ts
|
|
21738
|
-
import
|
|
22357
|
+
import ts18 from "typescript";
|
|
21739
22358
|
var SYNTHETIC_PREFIX = "BFInlineJsxCallback";
|
|
21740
22359
|
var MAX_FIXPOINT_ITERATIONS = 16;
|
|
21741
22360
|
function preprocessInlineJsxCallbacks(source, filePath) {
|
|
@@ -21757,8 +22376,8 @@ function preprocessInlineJsxCallbacks(source, filePath) {
|
|
|
21757
22376
|
return { source: current, errors, syntheticNames };
|
|
21758
22377
|
}
|
|
21759
22378
|
function runSinglePass(source, filePath, startingCounter) {
|
|
21760
|
-
const sourceFile =
|
|
21761
|
-
const hasUseClient = sourceFile.statements.some((stmt) =>
|
|
22379
|
+
const sourceFile = ts18.createSourceFile(filePath, source, ts18.ScriptTarget.Latest, true, ts18.ScriptKind.TSX);
|
|
22380
|
+
const hasUseClient = sourceFile.statements.some((stmt) => ts18.isExpressionStatement(stmt) && ts18.isStringLiteral(stmt.expression) && (stmt.expression.text === "use client" || stmt.expression.text === "'use client'"));
|
|
21762
22381
|
if (!hasUseClient) {
|
|
21763
22382
|
return { source, errors: [], syntheticNames: [], counterAfter: startingCounter };
|
|
21764
22383
|
}
|
|
@@ -21780,22 +22399,22 @@ function runSinglePass(source, filePath, startingCounter) {
|
|
|
21780
22399
|
}
|
|
21781
22400
|
}
|
|
21782
22401
|
function visit3(node) {
|
|
21783
|
-
if (
|
|
22402
|
+
if (ts18.isJsxAttribute(node) && node.initializer && ts18.isJsxExpression(node.initializer) && node.initializer.expression) {
|
|
21784
22403
|
if (tryHandleArrowValue(node.initializer.expression)) {
|
|
21785
22404
|
return;
|
|
21786
22405
|
}
|
|
21787
22406
|
}
|
|
21788
|
-
if (
|
|
22407
|
+
if (ts18.isPropertyAssignment(node) && node.initializer) {
|
|
21789
22408
|
if (tryHandleArrowValue(node.initializer))
|
|
21790
22409
|
return;
|
|
21791
22410
|
}
|
|
21792
|
-
|
|
22411
|
+
ts18.forEachChild(node, visit3);
|
|
21793
22412
|
}
|
|
21794
22413
|
function tryHandleArrowValue(initializer) {
|
|
21795
22414
|
let expr = initializer;
|
|
21796
|
-
while (
|
|
22415
|
+
while (ts18.isParenthesizedExpression(expr))
|
|
21797
22416
|
expr = expr.expression;
|
|
21798
|
-
if (
|
|
22417
|
+
if (ts18.isArrowFunction(expr) && arrowBodyContainsJsx(expr)) {
|
|
21799
22418
|
return handleInlineArrow(expr);
|
|
21800
22419
|
}
|
|
21801
22420
|
return false;
|
|
@@ -21832,7 +22451,7 @@ function runSinglePass(source, filePath, startingCounter) {
|
|
|
21832
22451
|
replacements.push({ start: arrowStart, end: arrowEnd, text: name });
|
|
21833
22452
|
return true;
|
|
21834
22453
|
}
|
|
21835
|
-
|
|
22454
|
+
ts18.forEachChild(sourceFile, visit3);
|
|
21836
22455
|
if (replacements.length === 0) {
|
|
21837
22456
|
return { source, errors, syntheticNames, counterAfter: counter };
|
|
21838
22457
|
}
|
|
@@ -21855,11 +22474,11 @@ function errorMessageForCapture(captures) {
|
|
|
21855
22474
|
return `Inline JSX-returning arrow function captures non-module identifier(s): ` + `${captures.sort().join(", ")}. ` + `Extract the callback into a top-level '\\'use client\\'' component (e.g. ` + `\`function MyNode(n) { return <div/> }\` then \`renderNode={MyNode}\`) ` + `or pass captured values via component props.`;
|
|
21856
22475
|
}
|
|
21857
22476
|
function arrowBodyContainsJsx(arrow) {
|
|
21858
|
-
if (
|
|
22477
|
+
if (ts18.isBlock(arrow.body)) {
|
|
21859
22478
|
return blockReturnsJsx(arrow.body);
|
|
21860
22479
|
}
|
|
21861
22480
|
let body = arrow.body;
|
|
21862
|
-
while (
|
|
22481
|
+
while (ts18.isParenthesizedExpression(body))
|
|
21863
22482
|
body = body.expression;
|
|
21864
22483
|
return isJsxLike(body);
|
|
21865
22484
|
}
|
|
@@ -21868,41 +22487,41 @@ function blockReturnsJsx(block) {
|
|
|
21868
22487
|
function visit3(n) {
|
|
21869
22488
|
if (found)
|
|
21870
22489
|
return;
|
|
21871
|
-
if (
|
|
22490
|
+
if (ts18.isReturnStatement(n) && n.expression) {
|
|
21872
22491
|
let e = n.expression;
|
|
21873
|
-
while (
|
|
22492
|
+
while (ts18.isParenthesizedExpression(e))
|
|
21874
22493
|
e = e.expression;
|
|
21875
22494
|
if (isJsxLike(e)) {
|
|
21876
22495
|
found = true;
|
|
21877
22496
|
return;
|
|
21878
22497
|
}
|
|
21879
22498
|
}
|
|
21880
|
-
if (
|
|
22499
|
+
if (ts18.isArrowFunction(n) || ts18.isFunctionDeclaration(n) || ts18.isFunctionExpression(n))
|
|
21881
22500
|
return;
|
|
21882
|
-
|
|
22501
|
+
ts18.forEachChild(n, visit3);
|
|
21883
22502
|
}
|
|
21884
|
-
|
|
22503
|
+
ts18.forEachChild(block, visit3);
|
|
21885
22504
|
return found;
|
|
21886
22505
|
}
|
|
21887
22506
|
function isJsxLike(expr) {
|
|
21888
|
-
return
|
|
22507
|
+
return ts18.isJsxElement(expr) || ts18.isJsxSelfClosingElement(expr) || ts18.isJsxFragment(expr);
|
|
21889
22508
|
}
|
|
21890
22509
|
function collectArrowParamNames(arrow) {
|
|
21891
22510
|
const names = new Set;
|
|
21892
22511
|
for (const p of arrow.parameters)
|
|
21893
|
-
|
|
22512
|
+
collectBindingNames4(p.name, names);
|
|
21894
22513
|
return names;
|
|
21895
22514
|
}
|
|
21896
|
-
function
|
|
22515
|
+
function collectBindingNames4(name, out) {
|
|
21897
22516
|
const push = Array.isArray(out) ? (n) => out.push(n) : (n) => out.add(n);
|
|
21898
|
-
if (
|
|
22517
|
+
if (ts18.isIdentifier(name)) {
|
|
21899
22518
|
push(name.text);
|
|
21900
|
-
} else if (
|
|
21901
|
-
name.elements.forEach((el) =>
|
|
21902
|
-
} else if (
|
|
22519
|
+
} else if (ts18.isObjectBindingPattern(name)) {
|
|
22520
|
+
name.elements.forEach((el) => collectBindingNames4(el.name, out));
|
|
22521
|
+
} else if (ts18.isArrayBindingPattern(name)) {
|
|
21903
22522
|
name.elements.forEach((el) => {
|
|
21904
|
-
if (!
|
|
21905
|
-
|
|
22523
|
+
if (!ts18.isOmittedExpression(el))
|
|
22524
|
+
collectBindingNames4(el.name, out);
|
|
21906
22525
|
});
|
|
21907
22526
|
}
|
|
21908
22527
|
}
|
|
@@ -21911,12 +22530,12 @@ function collectFreeIdentifiers(arrow) {
|
|
|
21911
22530
|
const bound = [];
|
|
21912
22531
|
for (const p of arrow.parameters) {
|
|
21913
22532
|
const names = [];
|
|
21914
|
-
|
|
22533
|
+
collectBindingNames4(p.name, names);
|
|
21915
22534
|
bound.push(...names);
|
|
21916
22535
|
}
|
|
21917
22536
|
function pushBindings(name) {
|
|
21918
22537
|
const names = [];
|
|
21919
|
-
|
|
22538
|
+
collectBindingNames4(name, names);
|
|
21920
22539
|
bound.push(...names);
|
|
21921
22540
|
return names;
|
|
21922
22541
|
}
|
|
@@ -21928,48 +22547,48 @@ function collectFreeIdentifiers(arrow) {
|
|
|
21928
22547
|
return bound.includes(name);
|
|
21929
22548
|
}
|
|
21930
22549
|
function visit3(node) {
|
|
21931
|
-
if (
|
|
22550
|
+
if (ts18.isIdentifier(node)) {
|
|
21932
22551
|
const parent = node.parent;
|
|
21933
|
-
if (parent &&
|
|
22552
|
+
if (parent && ts18.isPropertyAccessExpression(parent) && parent.name === node)
|
|
21934
22553
|
return;
|
|
21935
|
-
if (parent &&
|
|
22554
|
+
if (parent && ts18.isPropertyAssignment(parent) && parent.name === node)
|
|
21936
22555
|
return;
|
|
21937
|
-
if (parent &&
|
|
22556
|
+
if (parent && ts18.isPropertySignature(parent) && parent.name === node)
|
|
21938
22557
|
return;
|
|
21939
|
-
if (parent &&
|
|
22558
|
+
if (parent && ts18.isPropertyDeclaration(parent) && parent.name === node)
|
|
21940
22559
|
return;
|
|
21941
|
-
if (parent &&
|
|
22560
|
+
if (parent && ts18.isMethodDeclaration(parent) && parent.name === node)
|
|
21942
22561
|
return;
|
|
21943
|
-
if (parent &&
|
|
22562
|
+
if (parent && ts18.isMethodSignature(parent) && parent.name === node)
|
|
21944
22563
|
return;
|
|
21945
|
-
if (parent &&
|
|
22564
|
+
if (parent && ts18.isGetAccessorDeclaration(parent) && parent.name === node)
|
|
21946
22565
|
return;
|
|
21947
|
-
if (parent &&
|
|
22566
|
+
if (parent && ts18.isSetAccessorDeclaration(parent) && parent.name === node)
|
|
21948
22567
|
return;
|
|
21949
|
-
if (parent &&
|
|
22568
|
+
if (parent && ts18.isEnumMember(parent) && parent.name === node)
|
|
21950
22569
|
return;
|
|
21951
|
-
if (parent &&
|
|
22570
|
+
if (parent && ts18.isBindingElement(parent) && parent.propertyName === node)
|
|
21952
22571
|
return;
|
|
21953
|
-
if (parent &&
|
|
22572
|
+
if (parent && ts18.isShorthandPropertyAssignment(parent) && parent.name === node) {
|
|
21954
22573
|
if (!isBound(node.text))
|
|
21955
22574
|
ids.add(node.text);
|
|
21956
22575
|
return;
|
|
21957
22576
|
}
|
|
21958
|
-
if (parent &&
|
|
22577
|
+
if (parent && ts18.isParameter(parent) && parent.name === node)
|
|
21959
22578
|
return;
|
|
21960
|
-
if (parent &&
|
|
22579
|
+
if (parent && ts18.isVariableDeclaration(parent) && parent.name === node)
|
|
21961
22580
|
return;
|
|
21962
|
-
if (parent &&
|
|
22581
|
+
if (parent && ts18.isFunctionDeclaration(parent) && parent.name === node)
|
|
21963
22582
|
return;
|
|
21964
|
-
if (parent &&
|
|
22583
|
+
if (parent && ts18.isClassDeclaration(parent) && parent.name === node)
|
|
21965
22584
|
return;
|
|
21966
|
-
if (parent &&
|
|
22585
|
+
if (parent && ts18.isJsxAttribute(parent) && parent.name === node)
|
|
21967
22586
|
return;
|
|
21968
|
-
if (parent &&
|
|
22587
|
+
if (parent && ts18.isJsxOpeningElement(parent) && parent.tagName === node) {
|
|
21969
22588
|
if (/^[a-z]/.test(node.text))
|
|
21970
22589
|
return;
|
|
21971
22590
|
}
|
|
21972
|
-
if (parent &&
|
|
22591
|
+
if (parent && ts18.isJsxClosingElement(parent) && parent.tagName === node) {
|
|
21973
22592
|
if (/^[a-z]/.test(node.text))
|
|
21974
22593
|
return;
|
|
21975
22594
|
}
|
|
@@ -21978,43 +22597,43 @@ function collectFreeIdentifiers(arrow) {
|
|
|
21978
22597
|
ids.add(node.text);
|
|
21979
22598
|
return;
|
|
21980
22599
|
}
|
|
21981
|
-
if (
|
|
22600
|
+
if (ts18.isVariableDeclaration(node)) {
|
|
21982
22601
|
const declared = pushBindings(node.name);
|
|
21983
22602
|
if (node.initializer)
|
|
21984
22603
|
visit3(node.initializer);
|
|
21985
22604
|
return;
|
|
21986
22605
|
}
|
|
21987
|
-
if (
|
|
22606
|
+
if (ts18.isFunctionDeclaration(node)) {
|
|
21988
22607
|
if (node.name)
|
|
21989
22608
|
bound.push(node.name.text);
|
|
21990
22609
|
visitInsideNewScope(node);
|
|
21991
22610
|
return;
|
|
21992
22611
|
}
|
|
21993
|
-
if (
|
|
22612
|
+
if (ts18.isClassDeclaration(node)) {
|
|
21994
22613
|
if (node.name)
|
|
21995
22614
|
bound.push(node.name.text);
|
|
21996
|
-
|
|
22615
|
+
ts18.forEachChild(node, visit3);
|
|
21997
22616
|
return;
|
|
21998
22617
|
}
|
|
21999
|
-
if (
|
|
22618
|
+
if (ts18.isArrowFunction(node) || ts18.isFunctionExpression(node)) {
|
|
22000
22619
|
visitInsideNewScope(node);
|
|
22001
22620
|
return;
|
|
22002
22621
|
}
|
|
22003
|
-
if (
|
|
22622
|
+
if (ts18.isCatchClause(node)) {
|
|
22004
22623
|
const before = bound.length;
|
|
22005
22624
|
if (node.variableDeclaration)
|
|
22006
22625
|
pushBindings(node.variableDeclaration.name);
|
|
22007
|
-
|
|
22626
|
+
ts18.forEachChild(node, visit3);
|
|
22008
22627
|
popN(bound.length - before);
|
|
22009
22628
|
return;
|
|
22010
22629
|
}
|
|
22011
|
-
if (
|
|
22630
|
+
if (ts18.isBlock(node)) {
|
|
22012
22631
|
const before = bound.length;
|
|
22013
|
-
|
|
22632
|
+
ts18.forEachChild(node, visit3);
|
|
22014
22633
|
popN(bound.length - before);
|
|
22015
22634
|
return;
|
|
22016
22635
|
}
|
|
22017
|
-
|
|
22636
|
+
ts18.forEachChild(node, visit3);
|
|
22018
22637
|
}
|
|
22019
22638
|
function visitInsideNewScope(fn) {
|
|
22020
22639
|
const before = bound.length;
|
|
@@ -22037,29 +22656,29 @@ function collectFreeIdentifiers(arrow) {
|
|
|
22037
22656
|
function collectModuleScopeNames(sourceFile) {
|
|
22038
22657
|
const names = new Set;
|
|
22039
22658
|
for (const stmt of sourceFile.statements) {
|
|
22040
|
-
if (
|
|
22659
|
+
if (ts18.isFunctionDeclaration(stmt) && stmt.name)
|
|
22041
22660
|
names.add(stmt.name.text);
|
|
22042
|
-
else if (
|
|
22661
|
+
else if (ts18.isClassDeclaration(stmt) && stmt.name)
|
|
22043
22662
|
names.add(stmt.name.text);
|
|
22044
|
-
else if (
|
|
22663
|
+
else if (ts18.isVariableStatement(stmt)) {
|
|
22045
22664
|
for (const decl of stmt.declarationList.declarations)
|
|
22046
|
-
|
|
22047
|
-
} else if (
|
|
22665
|
+
collectBindingNames4(decl.name, names);
|
|
22666
|
+
} else if (ts18.isImportDeclaration(stmt) && stmt.importClause) {
|
|
22048
22667
|
const ic = stmt.importClause;
|
|
22049
22668
|
if (ic.name)
|
|
22050
22669
|
names.add(ic.name.text);
|
|
22051
22670
|
if (ic.namedBindings) {
|
|
22052
|
-
if (
|
|
22671
|
+
if (ts18.isNamespaceImport(ic.namedBindings))
|
|
22053
22672
|
names.add(ic.namedBindings.name.text);
|
|
22054
22673
|
else
|
|
22055
22674
|
for (const e of ic.namedBindings.elements)
|
|
22056
22675
|
names.add(e.name.text);
|
|
22057
22676
|
}
|
|
22058
|
-
} else if (
|
|
22677
|
+
} else if (ts18.isTypeAliasDeclaration(stmt))
|
|
22059
22678
|
names.add(stmt.name.text);
|
|
22060
|
-
else if (
|
|
22679
|
+
else if (ts18.isInterfaceDeclaration(stmt))
|
|
22061
22680
|
names.add(stmt.name.text);
|
|
22062
|
-
else if (
|
|
22681
|
+
else if (ts18.isEnumDeclaration(stmt))
|
|
22063
22682
|
names.add(stmt.name.text);
|
|
22064
22683
|
}
|
|
22065
22684
|
return names;
|
|
@@ -22067,7 +22686,7 @@ function collectModuleScopeNames(sourceFile) {
|
|
|
22067
22686
|
function buildSyntheticDeclaration(name, arrow, sourceFile) {
|
|
22068
22687
|
const paramsText = arrow.parameters.length === 0 ? "" : arrow.parameters.map((p) => p.getText(sourceFile)).join(", ");
|
|
22069
22688
|
let bodyText;
|
|
22070
|
-
if (
|
|
22689
|
+
if (ts18.isBlock(arrow.body)) {
|
|
22071
22690
|
bodyText = arrow.body.getText(sourceFile);
|
|
22072
22691
|
} else {
|
|
22073
22692
|
const expr = arrow.body.getText(sourceFile);
|
|
@@ -22077,7 +22696,7 @@ function buildSyntheticDeclaration(name, arrow, sourceFile) {
|
|
|
22077
22696
|
}
|
|
22078
22697
|
|
|
22079
22698
|
// src/ssr-defaults.ts
|
|
22080
|
-
import
|
|
22699
|
+
import ts19 from "typescript";
|
|
22081
22700
|
var UNRESOLVED = Symbol("unresolved");
|
|
22082
22701
|
var NO_RETURN = Symbol("no-return");
|
|
22083
22702
|
function extractSsrDefaults(metadata) {
|
|
@@ -22090,11 +22709,12 @@ function extractSsrDefaults(metadata) {
|
|
|
22090
22709
|
for (const p of metadata.propsParams) {
|
|
22091
22710
|
if (p.isRest)
|
|
22092
22711
|
continue;
|
|
22712
|
+
const callerPropName = p.sourceName ?? p.name;
|
|
22093
22713
|
if (metadata.propsObjectName === null && p.defaultValue !== undefined) {
|
|
22094
22714
|
const value = tryStaticEval(p.defaultValue, { bindings: {}, propsLike });
|
|
22095
|
-
out[p.name] = { propName:
|
|
22715
|
+
out[p.name] = { propName: callerPropName, value: resultToJsonable(value) };
|
|
22096
22716
|
} else {
|
|
22097
|
-
out[p.name] = { propName:
|
|
22717
|
+
out[p.name] = { propName: callerPropName, value: null };
|
|
22098
22718
|
}
|
|
22099
22719
|
}
|
|
22100
22720
|
if (metadata.restPropsName) {
|
|
@@ -22153,11 +22773,11 @@ function collectPropRefs(expr, propsObjectName, out) {
|
|
|
22153
22773
|
if (!node)
|
|
22154
22774
|
return;
|
|
22155
22775
|
const visit3 = (n) => {
|
|
22156
|
-
if (
|
|
22776
|
+
if (ts19.isPropertyAccessExpression(n) && ts19.isIdentifier(n.expression) && n.expression.text === propsObjectName && ts19.isIdentifier(n.name)) {
|
|
22157
22777
|
out.add(n.name.text);
|
|
22158
22778
|
return;
|
|
22159
22779
|
}
|
|
22160
|
-
|
|
22780
|
+
ts19.forEachChild(n, visit3);
|
|
22161
22781
|
};
|
|
22162
22782
|
visit3(node);
|
|
22163
22783
|
}
|
|
@@ -22178,23 +22798,23 @@ function tryStaticEval(expr, ctx) {
|
|
|
22178
22798
|
}
|
|
22179
22799
|
function evalStatementsForReturn(statements, ctx) {
|
|
22180
22800
|
for (const stmt of statements) {
|
|
22181
|
-
if (
|
|
22801
|
+
if (ts19.isVariableStatement(stmt)) {
|
|
22182
22802
|
for (const d of stmt.declarationList.declarations) {
|
|
22183
|
-
if (!
|
|
22803
|
+
if (!ts19.isIdentifier(d.name) || !d.initializer)
|
|
22184
22804
|
continue;
|
|
22185
22805
|
const v = evalNode(d.initializer, ctx);
|
|
22186
22806
|
if (v !== UNRESOLVED)
|
|
22187
22807
|
ctx.bindings[d.name.text] = v;
|
|
22188
22808
|
}
|
|
22189
|
-
} else if (
|
|
22809
|
+
} else if (ts19.isReturnStatement(stmt)) {
|
|
22190
22810
|
return stmt.expression ? evalNode(stmt.expression, ctx) : UNRESOLVED;
|
|
22191
|
-
} else if (
|
|
22811
|
+
} else if (ts19.isIfStatement(stmt)) {
|
|
22192
22812
|
const cond = evalNode(stmt.expression, ctx);
|
|
22193
22813
|
if (cond === UNRESOLVED)
|
|
22194
22814
|
return UNRESOLVED;
|
|
22195
22815
|
const branch = cond ? stmt.thenStatement : stmt.elseStatement;
|
|
22196
22816
|
if (branch) {
|
|
22197
|
-
const taken = evalStatementsForReturn(
|
|
22817
|
+
const taken = evalStatementsForReturn(ts19.isBlock(branch) ? branch.statements : [branch], ctx);
|
|
22198
22818
|
if (taken !== NO_RETURN)
|
|
22199
22819
|
return taken;
|
|
22200
22820
|
}
|
|
@@ -22205,45 +22825,45 @@ function evalStatementsForReturn(statements, ctx) {
|
|
|
22205
22825
|
return NO_RETURN;
|
|
22206
22826
|
}
|
|
22207
22827
|
function parseExpression2(expr) {
|
|
22208
|
-
const sf =
|
|
22828
|
+
const sf = ts19.createSourceFile("__ssr_default__.ts", `(${expr})`, ts19.ScriptTarget.Latest, false, ts19.ScriptKind.TS);
|
|
22209
22829
|
const stmt = sf.statements[0];
|
|
22210
|
-
if (!stmt || !
|
|
22830
|
+
if (!stmt || !ts19.isExpressionStatement(stmt))
|
|
22211
22831
|
return null;
|
|
22212
|
-
const inner =
|
|
22832
|
+
const inner = ts19.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
|
|
22213
22833
|
return inner;
|
|
22214
22834
|
}
|
|
22215
22835
|
function evalNode(node, ctx) {
|
|
22216
|
-
if (
|
|
22836
|
+
if (ts19.isParenthesizedExpression(node))
|
|
22217
22837
|
return evalNode(node.expression, ctx);
|
|
22218
|
-
if (
|
|
22838
|
+
if (ts19.isAsExpression(node))
|
|
22219
22839
|
return evalNode(node.expression, ctx);
|
|
22220
|
-
if (
|
|
22840
|
+
if (ts19.isSatisfiesExpression(node))
|
|
22221
22841
|
return evalNode(node.expression, ctx);
|
|
22222
|
-
if (
|
|
22842
|
+
if (ts19.isTypeAssertionExpression(node))
|
|
22223
22843
|
return evalNode(node.expression, ctx);
|
|
22224
|
-
if (
|
|
22844
|
+
if (ts19.isNonNullExpression(node))
|
|
22225
22845
|
return evalNode(node.expression, ctx);
|
|
22226
|
-
if (
|
|
22846
|
+
if (ts19.isArrowFunction(node)) {
|
|
22227
22847
|
if (node.parameters.length !== 0)
|
|
22228
22848
|
return UNRESOLVED;
|
|
22229
|
-
if (!
|
|
22849
|
+
if (!ts19.isBlock(node.body))
|
|
22230
22850
|
return evalNode(node.body, ctx);
|
|
22231
22851
|
const localBindings = { ...ctx.bindings };
|
|
22232
22852
|
const localCtx = { ...ctx, bindings: localBindings };
|
|
22233
22853
|
const result = evalStatementsForReturn(node.body.statements, localCtx);
|
|
22234
22854
|
return result === NO_RETURN ? UNRESOLVED : result;
|
|
22235
22855
|
}
|
|
22236
|
-
if (
|
|
22856
|
+
if (ts19.isNumericLiteral(node))
|
|
22237
22857
|
return Number(node.text);
|
|
22238
|
-
if (
|
|
22858
|
+
if (ts19.isStringLiteralLike(node))
|
|
22239
22859
|
return node.text;
|
|
22240
|
-
if (node.kind ===
|
|
22860
|
+
if (node.kind === ts19.SyntaxKind.TrueKeyword)
|
|
22241
22861
|
return true;
|
|
22242
|
-
if (node.kind ===
|
|
22862
|
+
if (node.kind === ts19.SyntaxKind.FalseKeyword)
|
|
22243
22863
|
return false;
|
|
22244
|
-
if (node.kind ===
|
|
22864
|
+
if (node.kind === ts19.SyntaxKind.NullKeyword)
|
|
22245
22865
|
return null;
|
|
22246
|
-
if (
|
|
22866
|
+
if (ts19.isIdentifier(node)) {
|
|
22247
22867
|
if (node.text === "undefined")
|
|
22248
22868
|
return;
|
|
22249
22869
|
if (node.text in ctx.bindings)
|
|
@@ -22252,29 +22872,29 @@ function evalNode(node, ctx) {
|
|
|
22252
22872
|
return;
|
|
22253
22873
|
return UNRESOLVED;
|
|
22254
22874
|
}
|
|
22255
|
-
if (
|
|
22875
|
+
if (ts19.isPrefixUnaryExpression(node)) {
|
|
22256
22876
|
const arg = evalNode(node.operand, ctx);
|
|
22257
22877
|
if (arg === UNRESOLVED)
|
|
22258
22878
|
return UNRESOLVED;
|
|
22259
22879
|
switch (node.operator) {
|
|
22260
|
-
case
|
|
22880
|
+
case ts19.SyntaxKind.MinusToken:
|
|
22261
22881
|
return typeof arg === "number" ? -arg : UNRESOLVED;
|
|
22262
|
-
case
|
|
22882
|
+
case ts19.SyntaxKind.PlusToken:
|
|
22263
22883
|
return typeof arg === "number" ? +arg : UNRESOLVED;
|
|
22264
|
-
case
|
|
22884
|
+
case ts19.SyntaxKind.ExclamationToken:
|
|
22265
22885
|
return !arg;
|
|
22266
22886
|
}
|
|
22267
22887
|
return UNRESOLVED;
|
|
22268
22888
|
}
|
|
22269
|
-
if (
|
|
22889
|
+
if (ts19.isObjectLiteralExpression(node)) {
|
|
22270
22890
|
const obj = {};
|
|
22271
22891
|
for (const prop of node.properties) {
|
|
22272
|
-
if (!
|
|
22892
|
+
if (!ts19.isPropertyAssignment(prop))
|
|
22273
22893
|
return UNRESOLVED;
|
|
22274
22894
|
let key;
|
|
22275
|
-
if (
|
|
22895
|
+
if (ts19.isIdentifier(prop.name) || ts19.isStringLiteralLike(prop.name)) {
|
|
22276
22896
|
key = prop.name.text;
|
|
22277
|
-
} else if (
|
|
22897
|
+
} else if (ts19.isNumericLiteral(prop.name)) {
|
|
22278
22898
|
key = prop.name.text;
|
|
22279
22899
|
} else {
|
|
22280
22900
|
return UNRESOLVED;
|
|
@@ -22286,10 +22906,10 @@ function evalNode(node, ctx) {
|
|
|
22286
22906
|
}
|
|
22287
22907
|
return obj;
|
|
22288
22908
|
}
|
|
22289
|
-
if (
|
|
22909
|
+
if (ts19.isArrayLiteralExpression(node)) {
|
|
22290
22910
|
const arr = [];
|
|
22291
22911
|
for (const elem of node.elements) {
|
|
22292
|
-
if (
|
|
22912
|
+
if (ts19.isOmittedExpression(elem))
|
|
22293
22913
|
return UNRESOLVED;
|
|
22294
22914
|
const v = evalNode(elem, ctx);
|
|
22295
22915
|
if (v === UNRESOLVED)
|
|
@@ -22298,7 +22918,7 @@ function evalNode(node, ctx) {
|
|
|
22298
22918
|
}
|
|
22299
22919
|
return arr;
|
|
22300
22920
|
}
|
|
22301
|
-
if (
|
|
22921
|
+
if (ts19.isElementAccessExpression(node)) {
|
|
22302
22922
|
const base = evalNode(node.expression, ctx);
|
|
22303
22923
|
if (base === undefined)
|
|
22304
22924
|
return;
|
|
@@ -22312,17 +22932,17 @@ function evalNode(node, ctx) {
|
|
|
22312
22932
|
const k = String(key);
|
|
22313
22933
|
return Object.prototype.hasOwnProperty.call(base, k) ? base[k] : undefined;
|
|
22314
22934
|
}
|
|
22315
|
-
if (
|
|
22935
|
+
if (ts19.isPropertyAccessExpression(node)) {
|
|
22316
22936
|
const baseResult = evalNode(node.expression, ctx);
|
|
22317
22937
|
if (baseResult === undefined)
|
|
22318
22938
|
return;
|
|
22319
22939
|
return UNRESOLVED;
|
|
22320
22940
|
}
|
|
22321
|
-
if (
|
|
22322
|
-
if (node.arguments.length === 0 &&
|
|
22941
|
+
if (ts19.isCallExpression(node)) {
|
|
22942
|
+
if (node.arguments.length === 0 && ts19.isIdentifier(node.expression) && node.expression.text in ctx.bindings) {
|
|
22323
22943
|
return ctx.bindings[node.expression.text];
|
|
22324
22944
|
}
|
|
22325
|
-
if (
|
|
22945
|
+
if (ts19.isPropertyAccessExpression(node.expression) && node.expression.name.text === "join") {
|
|
22326
22946
|
const recv = evalNode(node.expression.expression, ctx);
|
|
22327
22947
|
if (Array.isArray(recv)) {
|
|
22328
22948
|
let sep2 = ",";
|
|
@@ -22338,27 +22958,27 @@ function evalNode(node, ctx) {
|
|
|
22338
22958
|
}
|
|
22339
22959
|
return UNRESOLVED;
|
|
22340
22960
|
}
|
|
22341
|
-
if (
|
|
22961
|
+
if (ts19.isConditionalExpression(node)) {
|
|
22342
22962
|
const cond = evalNode(node.condition, ctx);
|
|
22343
22963
|
if (cond === UNRESOLVED)
|
|
22344
22964
|
return UNRESOLVED;
|
|
22345
22965
|
return cond ? evalNode(node.whenTrue, ctx) : evalNode(node.whenFalse, ctx);
|
|
22346
22966
|
}
|
|
22347
|
-
if (
|
|
22967
|
+
if (ts19.isBinaryExpression(node)) {
|
|
22348
22968
|
const op = node.operatorToken.kind;
|
|
22349
|
-
if (op ===
|
|
22969
|
+
if (op === ts19.SyntaxKind.QuestionQuestionToken) {
|
|
22350
22970
|
const l2 = evalNode(node.left, ctx);
|
|
22351
22971
|
if (l2 !== UNRESOLVED && l2 !== null && l2 !== undefined)
|
|
22352
22972
|
return l2;
|
|
22353
22973
|
return evalNode(node.right, ctx);
|
|
22354
22974
|
}
|
|
22355
|
-
if (op ===
|
|
22975
|
+
if (op === ts19.SyntaxKind.BarBarToken) {
|
|
22356
22976
|
const l2 = evalNode(node.left, ctx);
|
|
22357
22977
|
if (l2 !== UNRESOLVED && l2)
|
|
22358
22978
|
return l2;
|
|
22359
22979
|
return evalNode(node.right, ctx);
|
|
22360
22980
|
}
|
|
22361
|
-
if (op ===
|
|
22981
|
+
if (op === ts19.SyntaxKind.AmpersandAmpersandToken) {
|
|
22362
22982
|
const l2 = evalNode(node.left, ctx);
|
|
22363
22983
|
if (l2 === UNRESOLVED)
|
|
22364
22984
|
return UNRESOLVED;
|
|
@@ -22371,30 +22991,30 @@ function evalNode(node, ctx) {
|
|
|
22371
22991
|
if (l === UNRESOLVED || r === UNRESOLVED)
|
|
22372
22992
|
return UNRESOLVED;
|
|
22373
22993
|
switch (op) {
|
|
22374
|
-
case
|
|
22994
|
+
case ts19.SyntaxKind.PlusToken:
|
|
22375
22995
|
if (typeof l === "string" || typeof r === "string")
|
|
22376
22996
|
return `${l}${r}`;
|
|
22377
22997
|
if (typeof l === "number" && typeof r === "number")
|
|
22378
22998
|
return l + r;
|
|
22379
22999
|
return UNRESOLVED;
|
|
22380
|
-
case
|
|
23000
|
+
case ts19.SyntaxKind.MinusToken:
|
|
22381
23001
|
return typeof l === "number" && typeof r === "number" ? l - r : UNRESOLVED;
|
|
22382
|
-
case
|
|
23002
|
+
case ts19.SyntaxKind.AsteriskToken:
|
|
22383
23003
|
return typeof l === "number" && typeof r === "number" ? l * r : UNRESOLVED;
|
|
22384
|
-
case
|
|
23004
|
+
case ts19.SyntaxKind.SlashToken:
|
|
22385
23005
|
return typeof l === "number" && typeof r === "number" && r !== 0 ? l / r : UNRESOLVED;
|
|
22386
|
-
case
|
|
23006
|
+
case ts19.SyntaxKind.PercentToken:
|
|
22387
23007
|
return typeof l === "number" && typeof r === "number" && r !== 0 ? l % r : UNRESOLVED;
|
|
22388
|
-
case
|
|
22389
|
-
case
|
|
23008
|
+
case ts19.SyntaxKind.EqualsEqualsEqualsToken:
|
|
23009
|
+
case ts19.SyntaxKind.EqualsEqualsToken:
|
|
22390
23010
|
return l === r;
|
|
22391
|
-
case
|
|
22392
|
-
case
|
|
23011
|
+
case ts19.SyntaxKind.ExclamationEqualsEqualsToken:
|
|
23012
|
+
case ts19.SyntaxKind.ExclamationEqualsToken:
|
|
22393
23013
|
return l !== r;
|
|
22394
23014
|
}
|
|
22395
23015
|
return UNRESOLVED;
|
|
22396
23016
|
}
|
|
22397
|
-
if (
|
|
23017
|
+
if (ts19.isTemplateExpression(node)) {
|
|
22398
23018
|
if (node.templateSpans.length === 0)
|
|
22399
23019
|
return node.head.text;
|
|
22400
23020
|
let acc = node.head.text;
|
|
@@ -22406,13 +23026,13 @@ function evalNode(node, ctx) {
|
|
|
22406
23026
|
}
|
|
22407
23027
|
return acc;
|
|
22408
23028
|
}
|
|
22409
|
-
if (
|
|
23029
|
+
if (ts19.isNoSubstitutionTemplateLiteral(node))
|
|
22410
23030
|
return node.text;
|
|
22411
23031
|
return UNRESOLVED;
|
|
22412
23032
|
}
|
|
22413
23033
|
|
|
22414
23034
|
// src/augment-inherited-props.ts
|
|
22415
|
-
import
|
|
23035
|
+
import ts20 from "typescript";
|
|
22416
23036
|
function collectContextConsumers(metadata) {
|
|
22417
23037
|
const constants = metadata.localConstants ?? [];
|
|
22418
23038
|
const contextDefaults = new Map;
|
|
@@ -22444,47 +23064,47 @@ function collectContextConsumers(metadata) {
|
|
|
22444
23064
|
}
|
|
22445
23065
|
function parseUseContextArg(source) {
|
|
22446
23066
|
const expr = parseSingleExpression(source);
|
|
22447
|
-
if (!expr || !
|
|
23067
|
+
if (!expr || !ts20.isCallExpression(expr))
|
|
22448
23068
|
return null;
|
|
22449
|
-
if (!
|
|
23069
|
+
if (!ts20.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
|
|
22450
23070
|
return null;
|
|
22451
23071
|
if (expr.arguments.length !== 1)
|
|
22452
23072
|
return null;
|
|
22453
23073
|
const arg = expr.arguments[0];
|
|
22454
|
-
return
|
|
23074
|
+
return ts20.isIdentifier(arg) ? arg.text : null;
|
|
22455
23075
|
}
|
|
22456
23076
|
function parseCreateContextDefault(source) {
|
|
22457
23077
|
const expr = parseSingleExpression(source);
|
|
22458
|
-
if (!expr || !
|
|
23078
|
+
if (!expr || !ts20.isCallExpression(expr))
|
|
22459
23079
|
return null;
|
|
22460
23080
|
if (expr.arguments.length === 0)
|
|
22461
23081
|
return null;
|
|
22462
23082
|
const arg = expr.arguments[0];
|
|
22463
|
-
if (
|
|
23083
|
+
if (ts20.isStringLiteral(arg) || ts20.isNoSubstitutionTemplateLiteral(arg))
|
|
22464
23084
|
return arg.text;
|
|
22465
|
-
if (
|
|
23085
|
+
if (ts20.isNumericLiteral(arg))
|
|
22466
23086
|
return Number(arg.text);
|
|
22467
|
-
if (arg.kind ===
|
|
23087
|
+
if (arg.kind === ts20.SyntaxKind.TrueKeyword)
|
|
22468
23088
|
return true;
|
|
22469
|
-
if (arg.kind ===
|
|
23089
|
+
if (arg.kind === ts20.SyntaxKind.FalseKeyword)
|
|
22470
23090
|
return false;
|
|
22471
23091
|
return null;
|
|
22472
23092
|
}
|
|
22473
23093
|
function isObjectLiteralCreateContextDefault(source) {
|
|
22474
23094
|
const expr = parseSingleExpression(source);
|
|
22475
|
-
if (!expr || !
|
|
23095
|
+
if (!expr || !ts20.isCallExpression(expr))
|
|
22476
23096
|
return false;
|
|
22477
23097
|
if (expr.arguments.length === 0)
|
|
22478
23098
|
return false;
|
|
22479
|
-
return
|
|
23099
|
+
return ts20.isObjectLiteralExpression(expr.arguments[0]);
|
|
22480
23100
|
}
|
|
22481
23101
|
function parseSingleExpression(source) {
|
|
22482
|
-
const sf =
|
|
23102
|
+
const sf = ts20.createSourceFile("__ctx.ts", `(${source})`, ts20.ScriptTarget.Latest, false);
|
|
22483
23103
|
const stmt = sf.statements[0];
|
|
22484
|
-
if (!stmt || !
|
|
23104
|
+
if (!stmt || !ts20.isExpressionStatement(stmt))
|
|
22485
23105
|
return null;
|
|
22486
23106
|
let e = stmt.expression;
|
|
22487
|
-
while (
|
|
23107
|
+
while (ts20.isParenthesizedExpression(e))
|
|
22488
23108
|
e = e.expression;
|
|
22489
23109
|
return e;
|
|
22490
23110
|
}
|
|
@@ -22509,25 +23129,25 @@ function augmentInheritedPropAccesses(ir) {
|
|
|
22509
23129
|
const pinCoalesceLiterals = (s) => {
|
|
22510
23130
|
if (!s || !s.includes(propsObj))
|
|
22511
23131
|
return;
|
|
22512
|
-
const sf =
|
|
23132
|
+
const sf = ts20.createSourceFile("__aug.ts", `(${s})`, ts20.ScriptTarget.Latest, false);
|
|
22513
23133
|
const visit3 = (n) => {
|
|
22514
|
-
if (
|
|
23134
|
+
if (ts20.isBinaryExpression(n) && (n.operatorToken.kind === ts20.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts20.SyntaxKind.BarBarToken)) {
|
|
22515
23135
|
let left = n.left;
|
|
22516
|
-
while (
|
|
23136
|
+
while (ts20.isParenthesizedExpression(left))
|
|
22517
23137
|
left = left.expression;
|
|
22518
|
-
if (
|
|
23138
|
+
if (ts20.isPropertyAccessExpression(left) && ts20.isIdentifier(left.expression) && left.expression.text === propsObj) {
|
|
22519
23139
|
const name = left.name.text;
|
|
22520
23140
|
let right = n.right;
|
|
22521
|
-
while (
|
|
23141
|
+
while (ts20.isParenthesizedExpression(right))
|
|
22522
23142
|
right = right.expression;
|
|
22523
|
-
if (
|
|
23143
|
+
if (ts20.isPrefixUnaryExpression(right))
|
|
22524
23144
|
right = right.operand;
|
|
22525
|
-
const kind =
|
|
23145
|
+
const kind = ts20.isNumericLiteral(right) ? "number" : right.kind === ts20.SyntaxKind.TrueKeyword || right.kind === ts20.SyntaxKind.FalseKeyword ? "boolean" : ts20.isStringLiteralLike(right) ? "string" : null;
|
|
22526
23146
|
if (kind && !coalesceLiteralTypes.has(name))
|
|
22527
23147
|
coalesceLiteralTypes.set(name, kind);
|
|
22528
23148
|
}
|
|
22529
23149
|
}
|
|
22530
|
-
|
|
23150
|
+
ts20.forEachChild(n, visit3);
|
|
22531
23151
|
};
|
|
22532
23152
|
visit3(sf);
|
|
22533
23153
|
};
|
|
@@ -22638,33 +23258,33 @@ function augmentInheritedPropAccesses(ir) {
|
|
|
22638
23258
|
}
|
|
22639
23259
|
}
|
|
22640
23260
|
function parseStaticStringConst(source) {
|
|
22641
|
-
const sf =
|
|
23261
|
+
const sf = ts20.createSourceFile("__const.ts", `const __x = (${source});`, ts20.ScriptTarget.Latest, false);
|
|
22642
23262
|
const stmt = sf.statements[0];
|
|
22643
|
-
if (!stmt || !
|
|
23263
|
+
if (!stmt || !ts20.isVariableStatement(stmt))
|
|
22644
23264
|
return null;
|
|
22645
23265
|
let init = stmt.declarationList.declarations[0]?.initializer;
|
|
22646
|
-
while (init &&
|
|
23266
|
+
while (init && ts20.isParenthesizedExpression(init))
|
|
22647
23267
|
init = init.expression;
|
|
22648
23268
|
if (!init)
|
|
22649
23269
|
return null;
|
|
22650
|
-
if (
|
|
23270
|
+
if (ts20.isStringLiteral(init) || ts20.isNoSubstitutionTemplateLiteral(init)) {
|
|
22651
23271
|
return init.text;
|
|
22652
23272
|
}
|
|
22653
23273
|
return evalStringArrayJoin(source);
|
|
22654
23274
|
}
|
|
22655
23275
|
function evalTemplateOfStringConsts(source, resolved) {
|
|
22656
|
-
const sf =
|
|
23276
|
+
const sf = ts20.createSourceFile("__const.ts", `const __x = (${source});`, ts20.ScriptTarget.Latest, false);
|
|
22657
23277
|
const stmt = sf.statements[0];
|
|
22658
|
-
if (!stmt || !
|
|
23278
|
+
if (!stmt || !ts20.isVariableStatement(stmt))
|
|
22659
23279
|
return null;
|
|
22660
23280
|
let init = stmt.declarationList.declarations[0]?.initializer;
|
|
22661
|
-
while (init &&
|
|
23281
|
+
while (init && ts20.isParenthesizedExpression(init))
|
|
22662
23282
|
init = init.expression;
|
|
22663
|
-
if (!init || !
|
|
23283
|
+
if (!init || !ts20.isTemplateExpression(init))
|
|
22664
23284
|
return null;
|
|
22665
23285
|
let out = init.head.text;
|
|
22666
23286
|
for (const span of init.templateSpans) {
|
|
22667
|
-
if (!
|
|
23287
|
+
if (!ts20.isIdentifier(span.expression))
|
|
22668
23288
|
return null;
|
|
22669
23289
|
const value = resolved.get(span.expression.text);
|
|
22670
23290
|
if (value === undefined)
|
|
@@ -22695,30 +23315,30 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
|
|
|
22695
23315
|
const constInfo = (constants ?? []).find((c) => c.name === objectName && c.isModule);
|
|
22696
23316
|
if (constInfo?.value === undefined)
|
|
22697
23317
|
return null;
|
|
22698
|
-
const sf =
|
|
23318
|
+
const sf = ts20.createSourceFile("__rec.ts", `(${constInfo.value})`, ts20.ScriptTarget.Latest, true);
|
|
22699
23319
|
if (sf.statements.length !== 1)
|
|
22700
23320
|
return null;
|
|
22701
23321
|
const stmt = sf.statements[0];
|
|
22702
|
-
if (!
|
|
23322
|
+
if (!ts20.isExpressionStatement(stmt))
|
|
22703
23323
|
return null;
|
|
22704
23324
|
let parsed = stmt.expression;
|
|
22705
|
-
while (
|
|
23325
|
+
while (ts20.isParenthesizedExpression(parsed))
|
|
22706
23326
|
parsed = parsed.expression;
|
|
22707
|
-
if (!
|
|
23327
|
+
if (!ts20.isObjectLiteralExpression(parsed))
|
|
22708
23328
|
return null;
|
|
22709
23329
|
for (const prop of parsed.properties) {
|
|
22710
|
-
if (!
|
|
23330
|
+
if (!ts20.isPropertyAssignment(prop))
|
|
22711
23331
|
continue;
|
|
22712
23332
|
const name = prop.name;
|
|
22713
|
-
const propKey =
|
|
23333
|
+
const propKey = ts20.isIdentifier(name) || ts20.isStringLiteral(name) || ts20.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
|
|
22714
23334
|
if (propKey !== key)
|
|
22715
23335
|
continue;
|
|
22716
23336
|
let v = prop.initializer;
|
|
22717
|
-
while (
|
|
23337
|
+
while (ts20.isParenthesizedExpression(v))
|
|
22718
23338
|
v = v.expression;
|
|
22719
|
-
if (
|
|
23339
|
+
if (ts20.isNumericLiteral(v))
|
|
22720
23340
|
return { kind: "number", text: v.text };
|
|
22721
|
-
if (
|
|
23341
|
+
if (ts20.isStringLiteral(v) || ts20.isNoSubstitutionTemplateLiteral(v)) {
|
|
22722
23342
|
return { kind: "string", text: v.text };
|
|
22723
23343
|
}
|
|
22724
23344
|
return null;
|
|
@@ -22726,28 +23346,28 @@ function lookupStaticRecordLiteral(objectName, key, constants) {
|
|
|
22726
23346
|
return null;
|
|
22727
23347
|
}
|
|
22728
23348
|
function evalStringArrayJoin(source) {
|
|
22729
|
-
const sf =
|
|
23349
|
+
const sf = ts20.createSourceFile("__join.ts", `const __x = (${source});`, ts20.ScriptTarget.Latest, false);
|
|
22730
23350
|
const stmt = sf.statements[0];
|
|
22731
|
-
if (!stmt || !
|
|
23351
|
+
if (!stmt || !ts20.isVariableStatement(stmt))
|
|
22732
23352
|
return null;
|
|
22733
23353
|
let node = stmt.declarationList.declarations[0]?.initializer;
|
|
22734
|
-
while (node &&
|
|
23354
|
+
while (node && ts20.isParenthesizedExpression(node))
|
|
22735
23355
|
node = node.expression;
|
|
22736
|
-
if (!node || !
|
|
23356
|
+
if (!node || !ts20.isCallExpression(node))
|
|
22737
23357
|
return null;
|
|
22738
23358
|
const callee = node.expression;
|
|
22739
|
-
if (!
|
|
23359
|
+
if (!ts20.isPropertyAccessExpression(callee))
|
|
22740
23360
|
return null;
|
|
22741
23361
|
if (callee.name.text !== "join")
|
|
22742
23362
|
return null;
|
|
22743
23363
|
let recv = callee.expression;
|
|
22744
|
-
while (
|
|
23364
|
+
while (ts20.isParenthesizedExpression(recv))
|
|
22745
23365
|
recv = recv.expression;
|
|
22746
|
-
if (!
|
|
23366
|
+
if (!ts20.isArrayLiteralExpression(recv))
|
|
22747
23367
|
return null;
|
|
22748
23368
|
const parts = [];
|
|
22749
23369
|
for (const el of recv.elements) {
|
|
22750
|
-
if (
|
|
23370
|
+
if (ts20.isStringLiteral(el) || ts20.isNoSubstitutionTemplateLiteral(el)) {
|
|
22751
23371
|
parts.push(el.text);
|
|
22752
23372
|
} else {
|
|
22753
23373
|
return null;
|
|
@@ -22756,7 +23376,7 @@ function evalStringArrayJoin(source) {
|
|
|
22756
23376
|
let sep2 = ",";
|
|
22757
23377
|
if (node.arguments.length >= 1) {
|
|
22758
23378
|
const arg = node.arguments[0];
|
|
22759
|
-
if (
|
|
23379
|
+
if (ts20.isStringLiteral(arg) || ts20.isNoSubstitutionTemplateLiteral(arg))
|
|
22760
23380
|
sep2 = arg.text;
|
|
22761
23381
|
else
|
|
22762
23382
|
return null;
|
|
@@ -22764,11 +23384,11 @@ function evalStringArrayJoin(source) {
|
|
|
22764
23384
|
return parts.join(sep2);
|
|
22765
23385
|
}
|
|
22766
23386
|
function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
|
|
22767
|
-
if (!
|
|
23387
|
+
if (!ts20.isElementAccessExpression(val))
|
|
22768
23388
|
return null;
|
|
22769
23389
|
const obj = val.expression;
|
|
22770
23390
|
const arg = val.argumentExpression;
|
|
22771
|
-
if (!
|
|
23391
|
+
if (!ts20.isIdentifier(obj) || !ts20.isIdentifier(arg))
|
|
22772
23392
|
return null;
|
|
22773
23393
|
let indexPropName;
|
|
22774
23394
|
let defaultKey;
|
|
@@ -22784,35 +23404,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
|
|
|
22784
23404
|
const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
|
|
22785
23405
|
if (constInfo?.value === undefined)
|
|
22786
23406
|
return null;
|
|
22787
|
-
const sf =
|
|
23407
|
+
const sf = ts20.createSourceFile("__rec.ts", `(${constInfo.value})`, ts20.ScriptTarget.Latest, true);
|
|
22788
23408
|
if (sf.statements.length !== 1)
|
|
22789
23409
|
return null;
|
|
22790
23410
|
const stmt = sf.statements[0];
|
|
22791
|
-
if (!
|
|
23411
|
+
if (!ts20.isExpressionStatement(stmt))
|
|
22792
23412
|
return null;
|
|
22793
23413
|
let parsed = stmt.expression;
|
|
22794
|
-
while (
|
|
23414
|
+
while (ts20.isParenthesizedExpression(parsed))
|
|
22795
23415
|
parsed = parsed.expression;
|
|
22796
|
-
if (!
|
|
23416
|
+
if (!ts20.isObjectLiteralExpression(parsed))
|
|
22797
23417
|
return null;
|
|
22798
23418
|
const entries = [];
|
|
22799
23419
|
for (const prop of parsed.properties) {
|
|
22800
|
-
if (!
|
|
23420
|
+
if (!ts20.isPropertyAssignment(prop))
|
|
22801
23421
|
return null;
|
|
22802
23422
|
let key;
|
|
22803
|
-
if (
|
|
23423
|
+
if (ts20.isIdentifier(prop.name)) {
|
|
22804
23424
|
key = prop.name.text;
|
|
22805
|
-
} else if (
|
|
23425
|
+
} else if (ts20.isStringLiteral(prop.name) || ts20.isNoSubstitutionTemplateLiteral(prop.name)) {
|
|
22806
23426
|
key = prop.name.text;
|
|
22807
23427
|
} else {
|
|
22808
23428
|
return null;
|
|
22809
23429
|
}
|
|
22810
23430
|
let v = prop.initializer;
|
|
22811
|
-
while (
|
|
23431
|
+
while (ts20.isParenthesizedExpression(v))
|
|
22812
23432
|
v = v.expression;
|
|
22813
|
-
if (
|
|
23433
|
+
if (ts20.isNumericLiteral(v)) {
|
|
22814
23434
|
entries.push({ key, value: { kind: "number", text: v.text } });
|
|
22815
|
-
} else if (
|
|
23435
|
+
} else if (ts20.isStringLiteral(v) || ts20.isNoSubstitutionTemplateLiteral(v)) {
|
|
22816
23436
|
entries.push({ key, value: { kind: "string", text: v.text } });
|
|
22817
23437
|
} else {
|
|
22818
23438
|
return null;
|
|
@@ -23595,7 +24215,7 @@ function compileJSX(source, filePath, options) {
|
|
|
23595
24215
|
return { files, errors };
|
|
23596
24216
|
}
|
|
23597
24217
|
// src/shared-program.ts
|
|
23598
|
-
import
|
|
24218
|
+
import ts21 from "typescript";
|
|
23599
24219
|
function commonParent(paths) {
|
|
23600
24220
|
if (paths.length === 0)
|
|
23601
24221
|
return process.cwd();
|
|
@@ -23616,10 +24236,10 @@ function commonParent(paths) {
|
|
|
23616
24236
|
function createProgramForCorpus(files, options = {}) {
|
|
23617
24237
|
const baseUrl = options.baseUrl ?? commonParent(files);
|
|
23618
24238
|
const compilerOptions = {
|
|
23619
|
-
target:
|
|
23620
|
-
module:
|
|
23621
|
-
moduleResolution:
|
|
23622
|
-
jsx:
|
|
24239
|
+
target: ts21.ScriptTarget.Latest,
|
|
24240
|
+
module: ts21.ModuleKind.ESNext,
|
|
24241
|
+
moduleResolution: ts21.ModuleResolutionKind.Bundler,
|
|
24242
|
+
jsx: ts21.JsxEmit.ReactJSX,
|
|
23623
24243
|
strict: true,
|
|
23624
24244
|
skipLibCheck: true,
|
|
23625
24245
|
noEmit: true,
|
|
@@ -23629,7 +24249,7 @@ function createProgramForCorpus(files, options = {}) {
|
|
|
23629
24249
|
...options.compilerOptions
|
|
23630
24250
|
};
|
|
23631
24251
|
const absolute = files.map((f) => path_default.resolve(f));
|
|
23632
|
-
return
|
|
24252
|
+
return ts21.createProgram(absolute, compilerOptions, undefined, options.oldProgram);
|
|
23633
24253
|
}
|
|
23634
24254
|
// src/adapters/interface.ts
|
|
23635
24255
|
class BaseAdapter {
|
|
@@ -24184,6 +24804,8 @@ function collectLoopBoundNames(ir) {
|
|
|
24184
24804
|
names.add(binding.name);
|
|
24185
24805
|
if (node.filterPredicate)
|
|
24186
24806
|
names.add(node.filterPredicate.param);
|
|
24807
|
+
for (const name of node.preamble?.declaredNames ?? [])
|
|
24808
|
+
names.add(name);
|
|
24187
24809
|
for (const child of node.children)
|
|
24188
24810
|
visit3(child);
|
|
24189
24811
|
if (node.childComponent) {
|
|
@@ -24611,7 +25233,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
|
|
|
24611
25233
|
};
|
|
24612
25234
|
}
|
|
24613
25235
|
// src/combine-client-js.ts
|
|
24614
|
-
import
|
|
25236
|
+
import ts22 from "typescript";
|
|
24615
25237
|
var CHILD_PLACEHOLDER_RE = /import '\/\* @bf-child:(\w+) \*\/'/g;
|
|
24616
25238
|
function combineParentChildClientJs(files) {
|
|
24617
25239
|
const result = new Map;
|
|
@@ -24668,10 +25290,10 @@ function combineParentChildClientJs(files) {
|
|
|
24668
25290
|
return result;
|
|
24669
25291
|
}
|
|
24670
25292
|
function parseAndMerge(content, importsBySource, otherImports, codeSections) {
|
|
24671
|
-
const sourceFile =
|
|
25293
|
+
const sourceFile = ts22.createSourceFile("combine.js", content, ts22.ScriptTarget.Latest, false, ts22.ScriptKind.JS);
|
|
24672
25294
|
const importSpans = [];
|
|
24673
25295
|
for (const stmt of sourceFile.statements) {
|
|
24674
|
-
if (!
|
|
25296
|
+
if (!ts22.isImportDeclaration(stmt))
|
|
24675
25297
|
continue;
|
|
24676
25298
|
const start = stmt.getStart(sourceFile);
|
|
24677
25299
|
const end = stmt.getEnd();
|
|
@@ -24681,8 +25303,8 @@ function parseAndMerge(content, importsBySource, otherImports, codeSections) {
|
|
|
24681
25303
|
continue;
|
|
24682
25304
|
const clause = stmt.importClause;
|
|
24683
25305
|
const bindings = clause?.namedBindings;
|
|
24684
|
-
const specifier =
|
|
24685
|
-
if (clause && !clause.name && bindings &&
|
|
25306
|
+
const specifier = ts22.isStringLiteral(stmt.moduleSpecifier) ? stmt.moduleSpecifier.text : "";
|
|
25307
|
+
if (clause && !clause.name && bindings && ts22.isNamedImports(bindings)) {
|
|
24686
25308
|
if (!importsBySource.has(specifier)) {
|
|
24687
25309
|
importsBySource.set(specifier, new Set);
|
|
24688
25310
|
}
|
|
@@ -24849,7 +25471,7 @@ function escapeRe(s) {
|
|
|
24849
25471
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
24850
25472
|
}
|
|
24851
25473
|
// src/debug.ts
|
|
24852
|
-
import
|
|
25474
|
+
import ts23 from "typescript";
|
|
24853
25475
|
function buildComponentGraph(source, filePath, componentName) {
|
|
24854
25476
|
const ctx = analyzeComponent(source, filePath, componentName);
|
|
24855
25477
|
if (!ctx.jsxReturn) {
|
|
@@ -26134,7 +26756,7 @@ function truncateExpr(expr, max = 40) {
|
|
|
26134
26756
|
function exprReadsPropMember(expr, propsObjectName) {
|
|
26135
26757
|
let sf;
|
|
26136
26758
|
try {
|
|
26137
|
-
sf =
|
|
26759
|
+
sf = ts23.createSourceFile("__attr.tsx", `(${expr})`, ts23.ScriptTarget.Latest, true, ts23.ScriptKind.TSX);
|
|
26138
26760
|
} catch {
|
|
26139
26761
|
return false;
|
|
26140
26762
|
}
|
|
@@ -26142,11 +26764,11 @@ function exprReadsPropMember(expr, propsObjectName) {
|
|
|
26142
26764
|
const visit3 = (n) => {
|
|
26143
26765
|
if (found)
|
|
26144
26766
|
return;
|
|
26145
|
-
if (
|
|
26767
|
+
if (ts23.isPropertyAccessExpression(n) && ts23.isIdentifier(n.expression) && n.expression.text === propsObjectName && n.name.text !== "children") {
|
|
26146
26768
|
found = true;
|
|
26147
26769
|
return;
|
|
26148
26770
|
}
|
|
26149
|
-
|
|
26771
|
+
ts23.forEachChild(n, visit3);
|
|
26150
26772
|
};
|
|
26151
26773
|
visit3(sf);
|
|
26152
26774
|
return found;
|
|
@@ -26216,7 +26838,7 @@ function findSourceFile2(meta) {
|
|
|
26216
26838
|
return null;
|
|
26217
26839
|
}
|
|
26218
26840
|
// src/profiler.ts
|
|
26219
|
-
import
|
|
26841
|
+
import ts24 from "typescript";
|
|
26220
26842
|
var PROFILE_SCHEMA_VERSION = 1;
|
|
26221
26843
|
var DEFAULT_FANOUT_THRESHOLD = 8;
|
|
26222
26844
|
function buildStaticBudget(source, filePath, componentName, options = {}) {
|
|
@@ -26486,15 +27108,15 @@ function joinProfilerEvents(events, index) {
|
|
|
26486
27108
|
return { joined, unattributed, diagnostics };
|
|
26487
27109
|
}
|
|
26488
27110
|
function findUninstrumentedEffects(source, filePath, instrumentedLines) {
|
|
26489
|
-
const sf =
|
|
27111
|
+
const sf = ts24.createSourceFile(filePath, source, ts24.ScriptTarget.Latest, true, ts24.ScriptKind.TSX);
|
|
26490
27112
|
const out = [];
|
|
26491
27113
|
const visit3 = (node) => {
|
|
26492
|
-
if (
|
|
27114
|
+
if (ts24.isCallExpression(node) && ts24.isIdentifier(node.expression) && node.expression.text === "createEffect") {
|
|
26493
27115
|
const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
|
|
26494
27116
|
if (!instrumentedLines.has(line))
|
|
26495
27117
|
out.push({ file: filePath, line });
|
|
26496
27118
|
}
|
|
26497
|
-
|
|
27119
|
+
ts24.forEachChild(node, visit3);
|
|
26498
27120
|
};
|
|
26499
27121
|
visit3(sf);
|
|
26500
27122
|
out.sort((a, b) => a.line - b.line);
|
|
@@ -26802,13 +27424,13 @@ function assessBatchSafety(args) {
|
|
|
26802
27424
|
const signalGetters = new Set(args.graph.signals.map((s) => s.name));
|
|
26803
27425
|
let sf;
|
|
26804
27426
|
try {
|
|
26805
|
-
sf =
|
|
27427
|
+
sf = ts24.createSourceFile("__h.ts", `const __h = ${args.handler}`, ts24.ScriptTarget.Latest, true);
|
|
26806
27428
|
} catch {
|
|
26807
27429
|
return "unverified";
|
|
26808
27430
|
}
|
|
26809
27431
|
const calls = [];
|
|
26810
27432
|
const visit3 = (node) => {
|
|
26811
|
-
if (
|
|
27433
|
+
if (ts24.isCallExpression(node) && ts24.isIdentifier(node.expression)) {
|
|
26812
27434
|
const name = node.expression.text;
|
|
26813
27435
|
if (setters.has(name))
|
|
26814
27436
|
calls.push({ pos: node.getStart(sf), kind: "write" });
|
|
@@ -26817,7 +27439,7 @@ function assessBatchSafety(args) {
|
|
|
26817
27439
|
else if (!signalGetters.has(name) && !memoNames.has(name))
|
|
26818
27440
|
calls.push({ pos: node.getStart(sf), kind: "risky" });
|
|
26819
27441
|
}
|
|
26820
|
-
|
|
27442
|
+
ts24.forEachChild(node, visit3);
|
|
26821
27443
|
};
|
|
26822
27444
|
visit3(sf);
|
|
26823
27445
|
calls.sort((a, b) => a.pos - b.pos);
|
|
@@ -27559,6 +28181,7 @@ export {
|
|
|
27559
28181
|
diffStaticBudget,
|
|
27560
28182
|
diffProfiles,
|
|
27561
28183
|
describeFallback,
|
|
28184
|
+
derivesScopeFromSlot,
|
|
27562
28185
|
decideClientOnlyElision,
|
|
27563
28186
|
dangerousInnerHtmlMetacharViolation,
|
|
27564
28187
|
dangerousInnerHtmlDiagnostic,
|