@marko/runtime-tags 6.4.7 → 6.4.8
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/translator/index.js +278 -190
- package/dist/translator/util/known-tag.d.ts +6 -2
- package/dist/translator/util/reasons.d.ts +1 -2
- package/dist/translator/util/references.d.ts +2 -0
- package/dist/translator/util/sections.d.ts +6 -5
- package/dist/translator/util/solve-reasons.d.ts +1 -0
- package/dist/translator/util/write-guard.d.ts +2 -1
- package/package.json +4 -4
- package/tags-html.d.ts +3 -0
package/dist/translator/index.js
CHANGED
|
@@ -2015,7 +2015,7 @@ function finalizeRegistrations() {
|
|
|
2015
2015
|
const programExtra = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
|
|
2016
2016
|
for (const fnExtra of getReferencesByFn().keys()) if (fnExtra.reason) {
|
|
2017
2017
|
registerFunction(fnExtra);
|
|
2018
|
-
programExtra.isInteractive ||=
|
|
2018
|
+
programExtra.isInteractive ||= !isGuardedReason(fnExtra.reason);
|
|
2019
2019
|
}
|
|
2020
2020
|
for (const [{ node, local, registered, fnRoots }, exprExtras] of getReferencesByImport()) {
|
|
2021
2021
|
const reason = fnRoots ? resolveTemplateReason(exprExtras) : resolveReason(exprExtras);
|
|
@@ -2025,7 +2025,7 @@ function finalizeRegistrations() {
|
|
|
2025
2025
|
extra.registeredImports ??= /* @__PURE__ */ new Map();
|
|
2026
2026
|
extra.registeredImports.set(local, registered);
|
|
2027
2027
|
}
|
|
2028
|
-
programExtra.isInteractive ||=
|
|
2028
|
+
programExtra.isInteractive ||= !isGuardedReason(reason);
|
|
2029
2029
|
}
|
|
2030
2030
|
}
|
|
2031
2031
|
}
|
|
@@ -2276,7 +2276,8 @@ function getBranchExprReason(section) {
|
|
|
2276
2276
|
const { derives, branchExpr } = section;
|
|
2277
2277
|
if (derives) {
|
|
2278
2278
|
let reason = mergeSources(getRendererReason(section) || void 0, getSourcesForDerived(derives));
|
|
2279
|
-
forEach(section.
|
|
2279
|
+
forEach(section.calls, (call) => {
|
|
2280
|
+
const callSection = call.childScopeBinding.section;
|
|
2280
2281
|
reason = mergeSources(reason, getBranchExprReasonUntil(callSection, isSameOrAncestorSection(section, callSection) ? section : section.parent));
|
|
2281
2282
|
});
|
|
2282
2283
|
return reason;
|
|
@@ -2304,7 +2305,8 @@ function addClosureReasons(section) {
|
|
|
2304
2305
|
});
|
|
2305
2306
|
}
|
|
2306
2307
|
function addCallOwnerReasons(body) {
|
|
2307
|
-
if (body.readsOwner) forEach(body.
|
|
2308
|
+
if (body.readsOwner) forEach(body.calls, (call) => {
|
|
2309
|
+
const callSection = call.childScopeBinding.section;
|
|
2308
2310
|
addOwnerReason(callSection, body.parent, getBranchExprReasonUntil(callSection, body.parent));
|
|
2309
2311
|
});
|
|
2310
2312
|
}
|
|
@@ -2338,13 +2340,17 @@ function getReasonForBinding(binding, properties) {
|
|
|
2338
2340
|
function getReasonForExpr(extra) {
|
|
2339
2341
|
return extra.isEffect ? ALWAYS : extraReaders(extra).reason;
|
|
2340
2342
|
}
|
|
2343
|
+
function bindingLandsRetained(binding, properties) {
|
|
2344
|
+
return someRead(bindingReaders(binding, properties), isRetainedInput);
|
|
2345
|
+
}
|
|
2341
2346
|
function landsRetained(extra) {
|
|
2342
2347
|
if (extra.retained) return true;
|
|
2343
|
-
if (!extra.isEffect)
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
+
if (!extra.isEffect) return someRead(extraReaders(extra), isRetained);
|
|
2349
|
+
return false;
|
|
2350
|
+
}
|
|
2351
|
+
function someRead({ reads }, leaf) {
|
|
2352
|
+
if (reads) {
|
|
2353
|
+
for (const [read, tagNameOnly] of reads) if (leaf(read, tagNameOnly)) return true;
|
|
2348
2354
|
}
|
|
2349
2355
|
return false;
|
|
2350
2356
|
}
|
|
@@ -2398,7 +2404,7 @@ function computeBindingReaders(binding, properties) {
|
|
|
2398
2404
|
if (!(head === "content" && expr.rendersContent && bindingUtil.has(expr.spreadFrom, binding))) readers = mergeReaders(readers, ALWAYS_READ);
|
|
2399
2405
|
continue;
|
|
2400
2406
|
}
|
|
2401
|
-
readers = mergeReaders(withLandingRead(readers, expr), readersOfDerives(expr, binding, properties));
|
|
2407
|
+
readers = mergeReaders(withLandingRead(readers, expr, binding), readersOfDerives(expr, binding, properties));
|
|
2402
2408
|
}
|
|
2403
2409
|
for (const alias of binding.aliases) readers = mergeReaders(readers, bindingReaders(alias, properties));
|
|
2404
2410
|
if (properties === void 0) return readers;
|
|
@@ -2428,16 +2434,31 @@ function mergeReaders(a, b) {
|
|
|
2428
2434
|
reads
|
|
2429
2435
|
};
|
|
2430
2436
|
}
|
|
2431
|
-
function withLandingRead(readers, read) {
|
|
2432
|
-
|
|
2437
|
+
function withLandingRead(readers, read, binding) {
|
|
2438
|
+
const had = readers.reads?.get(read);
|
|
2439
|
+
const tagNameOnly = (had ?? true) && every(binding.reads.get(read), isTagNameRead);
|
|
2440
|
+
return had === tagNameOnly ? readers : {
|
|
2433
2441
|
reason: readers.reason,
|
|
2434
|
-
reads: new
|
|
2442
|
+
reads: new Map(readers.reads).set(read, tagNameOnly)
|
|
2435
2443
|
};
|
|
2436
2444
|
}
|
|
2445
|
+
function isRetainedInput(read, tagNameOnly) {
|
|
2446
|
+
return !tagNameOnly && isRetained(read);
|
|
2447
|
+
}
|
|
2448
|
+
function isRetained(read) {
|
|
2449
|
+
return !!read.retained;
|
|
2450
|
+
}
|
|
2451
|
+
function isTagNameRead({ extra }) {
|
|
2452
|
+
return !!extra.exprRoot?.tagName;
|
|
2453
|
+
}
|
|
2437
2454
|
function unionReads(a, b) {
|
|
2438
2455
|
if (!a || !b || a === b) return a || b;
|
|
2439
2456
|
let result;
|
|
2440
|
-
for (const read of b)
|
|
2457
|
+
for (const [read, tagNameOnly] of b) {
|
|
2458
|
+
const had = a.get(read);
|
|
2459
|
+
const merged = (had ?? true) && tagNameOnly;
|
|
2460
|
+
if (had !== merged) (result ??= new Map(a)).set(read, merged);
|
|
2461
|
+
}
|
|
2441
2462
|
return result || a;
|
|
2442
2463
|
}
|
|
2443
2464
|
//#endregion
|
|
@@ -3001,6 +3022,191 @@ function isMarkoPlaceholder(node) {
|
|
|
3001
3022
|
return _marko_compiler.types.isMarkoPlaceholder(node);
|
|
3002
3023
|
}
|
|
3003
3024
|
//#endregion
|
|
3025
|
+
//#region src/translator/util/with-comment.ts
|
|
3026
|
+
function withLeadingComment(node, value) {
|
|
3027
|
+
if (value) {
|
|
3028
|
+
const comment = {
|
|
3029
|
+
type: "CommentBlock",
|
|
3030
|
+
value: ` ${value} `
|
|
3031
|
+
};
|
|
3032
|
+
node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
|
|
3033
|
+
}
|
|
3034
|
+
return node;
|
|
3035
|
+
}
|
|
3036
|
+
//#endregion
|
|
3037
|
+
//#region src/translator/util/write-guard.ts
|
|
3038
|
+
function isSameReason(a, b) {
|
|
3039
|
+
return a === b || (a && b ? a.always && b.always || compareSources(a, b) === 0 : false);
|
|
3040
|
+
}
|
|
3041
|
+
const groupCheckPrefixes = {
|
|
3042
|
+
_write_guard: "wg",
|
|
3043
|
+
_write_if: "wi"
|
|
3044
|
+
};
|
|
3045
|
+
const [getSectionGuards] = createOutputSectionState((section) => ({
|
|
3046
|
+
hoists: /* @__PURE__ */ new Map(),
|
|
3047
|
+
declarators: [_marko_compiler.types.variableDeclarator(scopeReasonIdentifier(section), callRuntime("_scope_reason"))]
|
|
3048
|
+
}));
|
|
3049
|
+
function buildGroupMask(groups) {
|
|
3050
|
+
let mask = 0;
|
|
3051
|
+
let maskNames = "";
|
|
3052
|
+
let dynamic;
|
|
3053
|
+
const props = [];
|
|
3054
|
+
let needsObject = false;
|
|
3055
|
+
let any = false;
|
|
3056
|
+
for (let i = 0; i < groups.length; i++) {
|
|
3057
|
+
const { value, names } = groups[i];
|
|
3058
|
+
if (value === void 0) continue;
|
|
3059
|
+
any = true;
|
|
3060
|
+
if (value === 0) continue;
|
|
3061
|
+
if (i >= 15) needsObject = true;
|
|
3062
|
+
else if (typeof value === "number") {
|
|
3063
|
+
mask |= value << 1 + 2 * i;
|
|
3064
|
+
if (names) maskNames += maskNames ? ` | ${names}` : names;
|
|
3065
|
+
} else {
|
|
3066
|
+
const shifted = _marko_compiler.types.binaryExpression("<<", value, withLeadingComment(_marko_compiler.types.numericLiteral(1 + 2 * i), names));
|
|
3067
|
+
dynamic = dynamic ? _marko_compiler.types.binaryExpression("|", dynamic, shifted) : shifted;
|
|
3068
|
+
}
|
|
3069
|
+
props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), names), typeof value === "number" ? _marko_compiler.types.numericLiteral(value) : value));
|
|
3070
|
+
}
|
|
3071
|
+
if (needsObject) return _marko_compiler.types.objectExpression(props);
|
|
3072
|
+
if (!any) return;
|
|
3073
|
+
const literal = mask ? withLeadingComment(_marko_compiler.types.numericLiteral(mask), maskNames) : void 0;
|
|
3074
|
+
return literal && dynamic ? _marko_compiler.types.binaryExpression("|", literal, dynamic) : literal || dynamic || _marko_compiler.types.numericLiteral(0);
|
|
3075
|
+
}
|
|
3076
|
+
function getScopeReasonStatement(section) {
|
|
3077
|
+
return hasGuardedReason(section) ? _marko_compiler.types.variableDeclaration("const", getSectionGuards(section).declarators) : _marko_compiler.types.expressionStatement(callRuntime("_scope_reason"));
|
|
3078
|
+
}
|
|
3079
|
+
function getWriteReason(binding) {
|
|
3080
|
+
return findSlot(binding)?.reason;
|
|
3081
|
+
}
|
|
3082
|
+
function getBranchWriteReason(section) {
|
|
3083
|
+
return findSectionSlot(section, 9)?.reason;
|
|
3084
|
+
}
|
|
3085
|
+
function getWriteGuard(section, reason, omitUnconditional) {
|
|
3086
|
+
if (!isDynamicWriteGuard(section, reason)) {
|
|
3087
|
+
if (!reason) return _marko_compiler.types.numericLiteral(0);
|
|
3088
|
+
return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.always ? void 0 : reason.state));
|
|
3089
|
+
}
|
|
3090
|
+
const bit = getGroupsBit(reason.param);
|
|
3091
|
+
if (bit !== void 0) return bit && omitUnconditional ? void 0 : _marko_compiler.types.numericLiteral(bit);
|
|
3092
|
+
return orEachParamGroup(reason.param, "_write_guard");
|
|
3093
|
+
}
|
|
3094
|
+
function getWriteGuardForAny(section, reasons, omitUnconditional) {
|
|
3095
|
+
if (!Array.isArray(reasons)) return getWriteGuard(section, reasons, omitUnconditional);
|
|
3096
|
+
for (const reason of reasons) if (getWriteBit(section, reason) === 1) return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.state));
|
|
3097
|
+
let expr;
|
|
3098
|
+
for (const reason of reasons) if (getWriteBit(section, reason) !== 0) expr = orGuard(expr, getWriteGuard(section, reason, false));
|
|
3099
|
+
return expr || _marko_compiler.types.numericLiteral(0);
|
|
3100
|
+
}
|
|
3101
|
+
function getExprIfWritten(section, reason, expr) {
|
|
3102
|
+
const ownReason = mapBodyParams(section, reason);
|
|
3103
|
+
if (!isGuardedReason(ownReason)) return ownReason && expr;
|
|
3104
|
+
const bit = getGroupsBit(ownReason.param);
|
|
3105
|
+
if (bit !== void 0) return bit ? expr : void 0;
|
|
3106
|
+
return andGuard(orEachParamGroup(ownReason.param, "_write_if"), expr);
|
|
3107
|
+
}
|
|
3108
|
+
function isEverWritten(section, reason) {
|
|
3109
|
+
const ownReason = mapBodyParams(section, reason);
|
|
3110
|
+
return isGuardedReason(ownReason) ? getGroupsBit(ownReason.param) !== 0 : !!ownReason;
|
|
3111
|
+
}
|
|
3112
|
+
function getWriteBit(section, reason) {
|
|
3113
|
+
return isDynamicWriteGuard(section, reason) ? getGroupsBit(reason.param) : reason ? 1 : 0;
|
|
3114
|
+
}
|
|
3115
|
+
function getGroupsBit(params) {
|
|
3116
|
+
return reduceParamGroups(params, addGroupBit, 0);
|
|
3117
|
+
}
|
|
3118
|
+
function addGroupBit(bit, section, group) {
|
|
3119
|
+
const groupBit = getStaticGroupBit(section, group);
|
|
3120
|
+
return bit === 1 || groupBit === 1 ? 1 : bit === 0 && groupBit === 0 ? 0 : void 0;
|
|
3121
|
+
}
|
|
3122
|
+
function orEachParamGroup(params, check) {
|
|
3123
|
+
return reduceParamGroups(params, orGroupChecks[check], void 0);
|
|
3124
|
+
}
|
|
3125
|
+
const orGroupChecks = {
|
|
3126
|
+
_write_guard: orGroupCheck("_write_guard"),
|
|
3127
|
+
_write_if: orGroupCheck("_write_if")
|
|
3128
|
+
};
|
|
3129
|
+
function orGroupCheck(check) {
|
|
3130
|
+
return (expr, section, group) => getStaticGroupBit(section, group) === 0 ? expr : orGuard(expr, getOrHoistSectionGuard(section, group, check));
|
|
3131
|
+
}
|
|
3132
|
+
function orGuard(guard, other) {
|
|
3133
|
+
return guard ? _marko_compiler.types.logicalExpression("||", guard, other) : other;
|
|
3134
|
+
}
|
|
3135
|
+
function andGuard(guard, expr) {
|
|
3136
|
+
return guard ? _marko_compiler.types.logicalExpression("&&", guard, expr) : expr;
|
|
3137
|
+
}
|
|
3138
|
+
function getOrHoistSectionGuard(section, params, check) {
|
|
3139
|
+
if (!section.paramReasonGroups) return scopeReasonIdentifier(section);
|
|
3140
|
+
const state = getSectionGuards(section);
|
|
3141
|
+
let tracking = state.hoists.get(check);
|
|
3142
|
+
if (!tracking) state.hoists.set(check, tracking = createGuardHoists());
|
|
3143
|
+
const index = getParamReasonGroupIndex(section, params);
|
|
3144
|
+
const name = tracking.names.get(index);
|
|
3145
|
+
if (name) return _marko_compiler.types.identifier(name);
|
|
3146
|
+
const guard = callRuntime(check, scopeReasonIdentifier(section), withLeadingComment(_marko_compiler.types.numericLiteral(index), getDebugNames(params)));
|
|
3147
|
+
const pending = tracking.pending.get(index);
|
|
3148
|
+
if (!pending) {
|
|
3149
|
+
const expr = _marko_compiler.types.parenthesizedExpression(guard);
|
|
3150
|
+
tracking.pending.set(index, expr);
|
|
3151
|
+
return expr;
|
|
3152
|
+
}
|
|
3153
|
+
const hoisted = generateUid(`${groupCheckPrefixes[check]}__${getDebugNamesAsIdentifier(params)}`);
|
|
3154
|
+
tracking.names.set(index, hoisted);
|
|
3155
|
+
tracking.pending.delete(index);
|
|
3156
|
+
state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(hoisted), guard));
|
|
3157
|
+
pending.expression = _marko_compiler.types.identifier(hoisted);
|
|
3158
|
+
return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(hoisted));
|
|
3159
|
+
}
|
|
3160
|
+
function isDynamicWriteGuard(section, reason) {
|
|
3161
|
+
return isGuardedReason(reason) && !isCrossSection(section, reason);
|
|
3162
|
+
}
|
|
3163
|
+
function isCrossSection(section, reason) {
|
|
3164
|
+
return some(reason.param, (param) => !isSameOrAncestorSection(param.section, section));
|
|
3165
|
+
}
|
|
3166
|
+
const [getStaticGroupBits] = createAnalysisSectionState(() => /* @__PURE__ */ new Map());
|
|
3167
|
+
function getStaticGroupBit(body, group) {
|
|
3168
|
+
const bits = getStaticGroupBits(body);
|
|
3169
|
+
const index = getParamReasonGroupIndex(body, group);
|
|
3170
|
+
if (!bits.has(index)) {
|
|
3171
|
+
bits.set(index, void 0);
|
|
3172
|
+
bits.set(index, isOnlyCalled(body) ? getCallsBit(body, group) : void 0);
|
|
3173
|
+
}
|
|
3174
|
+
return bits.get(index);
|
|
3175
|
+
}
|
|
3176
|
+
function getCallsBit(body, group) {
|
|
3177
|
+
const calls = body.calls;
|
|
3178
|
+
let bit;
|
|
3179
|
+
for (const call of Array.isArray(calls) ? calls : [calls]) {
|
|
3180
|
+
const callSection = call.childScopeBinding.section;
|
|
3181
|
+
const callBit = getWriteBit(callSection, findSlot(call.childScopeBinding, 5, callSection, group)?.reason);
|
|
3182
|
+
if (callBit === void 0 || bit !== void 0 && bit !== callBit) return;
|
|
3183
|
+
bit = callBit;
|
|
3184
|
+
}
|
|
3185
|
+
return bit;
|
|
3186
|
+
}
|
|
3187
|
+
function isOnlyCalled(body) {
|
|
3188
|
+
return !!body.calls && !!body.derives && !some(body.derives.binding, isUsed);
|
|
3189
|
+
}
|
|
3190
|
+
function isUsed(binding) {
|
|
3191
|
+
return !!binding.reads.size || !!binding.aliases.size || !!binding.propertyAliases.size;
|
|
3192
|
+
}
|
|
3193
|
+
function createGuardHoists() {
|
|
3194
|
+
return {
|
|
3195
|
+
names: /* @__PURE__ */ new Map(),
|
|
3196
|
+
pending: /* @__PURE__ */ new Map()
|
|
3197
|
+
};
|
|
3198
|
+
}
|
|
3199
|
+
function hasGuardedReason(section) {
|
|
3200
|
+
if (section.paramReasonGroups || isGuardedReason(mapBodyParams(section, section.reason))) return true;
|
|
3201
|
+
return some(section.slots, isConditionalSlot);
|
|
3202
|
+
}
|
|
3203
|
+
function isConditionalSlot(slot) {
|
|
3204
|
+
return isGuardedReason(mapBodyParams(slot.section, slot.reason));
|
|
3205
|
+
}
|
|
3206
|
+
function scopeReasonIdentifier(section) {
|
|
3207
|
+
return _marko_compiler.types.identifier(ensureSharedUid(`scope${section.id}_reason`, section));
|
|
3208
|
+
}
|
|
3209
|
+
//#endregion
|
|
3004
3210
|
//#region src/translator/util/sections.ts
|
|
3005
3211
|
const sectionUtil = new Sorted(function compareSections(a, b) {
|
|
3006
3212
|
return a.id - b.id;
|
|
@@ -3036,7 +3242,7 @@ function ensureBodySection(path) {
|
|
|
3036
3242
|
returnValueExpr: void 0,
|
|
3037
3243
|
content: getContentInfo(path),
|
|
3038
3244
|
branchExpr: void 0,
|
|
3039
|
-
|
|
3245
|
+
calls: void 0,
|
|
3040
3246
|
knownTags: void 0,
|
|
3041
3247
|
derives: void 0,
|
|
3042
3248
|
dropped: !!extra.dropped,
|
|
@@ -3081,11 +3287,23 @@ function forEachSection(fn) {
|
|
|
3081
3287
|
sections?.forEach(fn);
|
|
3082
3288
|
}
|
|
3083
3289
|
function getDynamicTagContentClosures(section) {
|
|
3084
|
-
|
|
3290
|
+
const { derives } = section;
|
|
3291
|
+
if (section.branchExpr?.tagNameType === 2 || derives && some(derives.binding, (binding) => bindingLandsRetained(binding, derives.properties))) return bindingUtil.filter(getClosuresFromAbove(section, section, /* @__PURE__ */ new Set()), mayBeUnwritten);
|
|
3292
|
+
}
|
|
3293
|
+
function mayBeUnwritten(closure) {
|
|
3294
|
+
const reason = getWriteReason(closure);
|
|
3295
|
+
return !reason || isGuardedReason(reason);
|
|
3085
3296
|
}
|
|
3086
|
-
function getClosuresFromAbove(section, top) {
|
|
3297
|
+
function getClosuresFromAbove(section, top, seen) {
|
|
3087
3298
|
let closures = bindingUtil.leadingRun(section.referencedClosures, bindingToSection, sectionUtil.compare, top);
|
|
3088
|
-
for (const child of section.children) closures = bindingUtil.union(closures, getClosuresFromAbove(child, top));
|
|
3299
|
+
for (const child of section.children) closures = bindingUtil.union(closures, getClosuresFromAbove(child, top, seen));
|
|
3300
|
+
for (const tagExtra of section.knownTags || []) {
|
|
3301
|
+
const body = tagExtra.childSection;
|
|
3302
|
+
if (!seen.has(body)) {
|
|
3303
|
+
seen.add(body);
|
|
3304
|
+
closures = bindingUtil.union(closures, getClosuresFromAbove(body, isSameOrAncestorSection(top, body) ? top : body, seen));
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3089
3307
|
return closures;
|
|
3090
3308
|
}
|
|
3091
3309
|
function forEachAncestorSection(from, to, fn, arg) {
|
|
@@ -3197,7 +3415,7 @@ function ensureSlotReasonGroups(slot) {
|
|
|
3197
3415
|
}
|
|
3198
3416
|
function ensureReasonGroups(section, reason) {
|
|
3199
3417
|
const ownReason = mapBodyParams(section, reason);
|
|
3200
|
-
if (
|
|
3418
|
+
if (isGuardedReason(ownReason)) forEachParamGroup(ownReason.param, ensureParamReasonGroup);
|
|
3201
3419
|
}
|
|
3202
3420
|
function ensureParamReasonGroup(section, group) {
|
|
3203
3421
|
const { paramReasonGroups } = section;
|
|
@@ -3527,7 +3745,8 @@ function finalizeSetupWork() {
|
|
|
3527
3745
|
});
|
|
3528
3746
|
}
|
|
3529
3747
|
function setCallSectionsSetup(body) {
|
|
3530
|
-
forEach(body.
|
|
3748
|
+
forEach(body.calls, (call) => {
|
|
3749
|
+
const callSection = call.childScopeBinding.section;
|
|
3531
3750
|
if (!callSection.hasSetupWork) {
|
|
3532
3751
|
callSection.hasSetupWork = true;
|
|
3533
3752
|
setCallSectionsSetup(callSection);
|
|
@@ -3840,139 +4059,6 @@ function getDestructurePattern(id) {
|
|
|
3840
4059
|
}
|
|
3841
4060
|
}
|
|
3842
4061
|
//#endregion
|
|
3843
|
-
//#region src/translator/util/with-comment.ts
|
|
3844
|
-
function withLeadingComment(node, value) {
|
|
3845
|
-
if (value) {
|
|
3846
|
-
const comment = {
|
|
3847
|
-
type: "CommentBlock",
|
|
3848
|
-
value: ` ${value} `
|
|
3849
|
-
};
|
|
3850
|
-
node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
|
|
3851
|
-
}
|
|
3852
|
-
return node;
|
|
3853
|
-
}
|
|
3854
|
-
//#endregion
|
|
3855
|
-
//#region src/translator/util/write-guard.ts
|
|
3856
|
-
function isSameReason(a, b) {
|
|
3857
|
-
return a === b || (a && b ? a.always && b.always || compareSources(a, b) === 0 : false);
|
|
3858
|
-
}
|
|
3859
|
-
const groupCheckPrefixes = {
|
|
3860
|
-
_write_guard: "wg",
|
|
3861
|
-
_write_if: "wi"
|
|
3862
|
-
};
|
|
3863
|
-
const [getSectionGuards] = createOutputSectionState((section) => ({
|
|
3864
|
-
hoists: /* @__PURE__ */ new Map(),
|
|
3865
|
-
declarators: [_marko_compiler.types.variableDeclarator(scopeReasonIdentifier(section), callRuntime("_scope_reason"))]
|
|
3866
|
-
}));
|
|
3867
|
-
function buildGroupMask(groups) {
|
|
3868
|
-
let mask = 0;
|
|
3869
|
-
let maskNames = "";
|
|
3870
|
-
let dynamic;
|
|
3871
|
-
const props = [];
|
|
3872
|
-
let needsObject = false;
|
|
3873
|
-
let any = false;
|
|
3874
|
-
for (let i = 0; i < groups.length; i++) {
|
|
3875
|
-
const { value, names } = groups[i];
|
|
3876
|
-
if (value === void 0) continue;
|
|
3877
|
-
any = true;
|
|
3878
|
-
if (value === 0) continue;
|
|
3879
|
-
if (i >= 15) needsObject = true;
|
|
3880
|
-
else if (typeof value === "number") {
|
|
3881
|
-
mask |= value << 1 + 2 * i;
|
|
3882
|
-
if (names) maskNames += maskNames ? ` | ${names}` : names;
|
|
3883
|
-
} else {
|
|
3884
|
-
const shifted = _marko_compiler.types.binaryExpression("<<", value, withLeadingComment(_marko_compiler.types.numericLiteral(1 + 2 * i), names));
|
|
3885
|
-
dynamic = dynamic ? _marko_compiler.types.binaryExpression("|", dynamic, shifted) : shifted;
|
|
3886
|
-
}
|
|
3887
|
-
props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), names), typeof value === "number" ? _marko_compiler.types.numericLiteral(value) : value));
|
|
3888
|
-
}
|
|
3889
|
-
if (needsObject) return _marko_compiler.types.objectExpression(props);
|
|
3890
|
-
if (!any) return;
|
|
3891
|
-
const literal = mask ? withLeadingComment(_marko_compiler.types.numericLiteral(mask), maskNames) : void 0;
|
|
3892
|
-
return literal && dynamic ? _marko_compiler.types.binaryExpression("|", literal, dynamic) : literal || dynamic || _marko_compiler.types.numericLiteral(0);
|
|
3893
|
-
}
|
|
3894
|
-
function getScopeReasonStatement(section) {
|
|
3895
|
-
return hasConditionalReason(section) ? _marko_compiler.types.variableDeclaration("const", getSectionGuards(section).declarators) : _marko_compiler.types.expressionStatement(callRuntime("_scope_reason"));
|
|
3896
|
-
}
|
|
3897
|
-
function getWriteReason(binding) {
|
|
3898
|
-
return findSlot(binding)?.reason;
|
|
3899
|
-
}
|
|
3900
|
-
function getBranchWriteReason(section) {
|
|
3901
|
-
return findSectionSlot(section, 9)?.reason;
|
|
3902
|
-
}
|
|
3903
|
-
function getWriteGuard(section, reason, omitUnconditional) {
|
|
3904
|
-
if (!isDynamicWriteGuard(section, reason)) {
|
|
3905
|
-
if (!reason) return _marko_compiler.types.numericLiteral(0);
|
|
3906
|
-
return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.always ? void 0 : reason.state));
|
|
3907
|
-
}
|
|
3908
|
-
return orEachParamGroup(reason.param, "_write_guard");
|
|
3909
|
-
}
|
|
3910
|
-
function getWriteGuardForAny(section, reasons, omitUnconditional) {
|
|
3911
|
-
if (!Array.isArray(reasons)) return getWriteGuard(section, reasons, omitUnconditional);
|
|
3912
|
-
for (const reason of reasons) if (!isConditionalReason(reason)) return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.state));
|
|
3913
|
-
let expr;
|
|
3914
|
-
for (const reason of reasons) expr = orGuard(expr, getWriteGuard(section, reason, false));
|
|
3915
|
-
return expr;
|
|
3916
|
-
}
|
|
3917
|
-
function getExprIfWritten(section, reason, expr) {
|
|
3918
|
-
const ownReason = mapBodyParams(section, reason);
|
|
3919
|
-
if (!isConditionalReason(ownReason)) return ownReason && expr;
|
|
3920
|
-
return andGuard(orEachParamGroup(ownReason.param, "_write_if"), expr);
|
|
3921
|
-
}
|
|
3922
|
-
function orEachParamGroup(params, check) {
|
|
3923
|
-
return reduceParamGroups(params, (expr, section, group) => orGuard(expr, getOrHoistSectionGuard(section, group, check)), void 0);
|
|
3924
|
-
}
|
|
3925
|
-
function orGuard(guard, other) {
|
|
3926
|
-
return guard ? _marko_compiler.types.logicalExpression("||", guard, other) : other;
|
|
3927
|
-
}
|
|
3928
|
-
function andGuard(guard, expr) {
|
|
3929
|
-
return guard ? _marko_compiler.types.logicalExpression("&&", guard, expr) : expr;
|
|
3930
|
-
}
|
|
3931
|
-
function getOrHoistSectionGuard(section, params, check) {
|
|
3932
|
-
if (!section.paramReasonGroups) return scopeReasonIdentifier(section);
|
|
3933
|
-
const state = getSectionGuards(section);
|
|
3934
|
-
let tracking = state.hoists.get(check);
|
|
3935
|
-
if (!tracking) state.hoists.set(check, tracking = createGuardHoists());
|
|
3936
|
-
const index = getParamReasonGroupIndex(section, params);
|
|
3937
|
-
const name = tracking.names.get(index);
|
|
3938
|
-
if (name) return _marko_compiler.types.identifier(name);
|
|
3939
|
-
const guard = callRuntime(check, scopeReasonIdentifier(section), withLeadingComment(_marko_compiler.types.numericLiteral(index), getDebugNames(params)));
|
|
3940
|
-
const pending = tracking.pending.get(index);
|
|
3941
|
-
if (!pending) {
|
|
3942
|
-
const expr = _marko_compiler.types.parenthesizedExpression(guard);
|
|
3943
|
-
tracking.pending.set(index, expr);
|
|
3944
|
-
return expr;
|
|
3945
|
-
}
|
|
3946
|
-
const hoisted = generateUid(`${groupCheckPrefixes[check]}__${getDebugNamesAsIdentifier(params)}`);
|
|
3947
|
-
tracking.names.set(index, hoisted);
|
|
3948
|
-
tracking.pending.delete(index);
|
|
3949
|
-
state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(hoisted), guard));
|
|
3950
|
-
pending.expression = _marko_compiler.types.identifier(hoisted);
|
|
3951
|
-
return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(hoisted));
|
|
3952
|
-
}
|
|
3953
|
-
function isDynamicWriteGuard(section, reason) {
|
|
3954
|
-
return isConditionalReason(reason) && !isCrossSection(section, reason);
|
|
3955
|
-
}
|
|
3956
|
-
function isCrossSection(section, reason) {
|
|
3957
|
-
return some(reason.param, (param) => !isSameOrAncestorSection(param.section, section));
|
|
3958
|
-
}
|
|
3959
|
-
function createGuardHoists() {
|
|
3960
|
-
return {
|
|
3961
|
-
names: /* @__PURE__ */ new Map(),
|
|
3962
|
-
pending: /* @__PURE__ */ new Map()
|
|
3963
|
-
};
|
|
3964
|
-
}
|
|
3965
|
-
function hasConditionalReason(section) {
|
|
3966
|
-
if (section.paramReasonGroups || isConditionalReason(mapBodyParams(section, section.reason))) return true;
|
|
3967
|
-
return some(section.slots, isConditionalSlot);
|
|
3968
|
-
}
|
|
3969
|
-
function isConditionalSlot(slot) {
|
|
3970
|
-
return isConditionalReason(mapBodyParams(slot.section, slot.reason));
|
|
3971
|
-
}
|
|
3972
|
-
function scopeReasonIdentifier(section) {
|
|
3973
|
-
return _marko_compiler.types.identifier(ensureSharedUid(`scope${section.id}_reason`, section));
|
|
3974
|
-
}
|
|
3975
|
-
//#endregion
|
|
3976
4062
|
//#region src/translator/util/build-string-expression.ts
|
|
3977
4063
|
function buildStringExpression(parts, useIife) {
|
|
3978
4064
|
const strs = [""];
|
|
@@ -4090,7 +4176,7 @@ function setSectionOwnerResumedByMarker(section) {
|
|
|
4090
4176
|
setOwnerResumedByMarker(section, true);
|
|
4091
4177
|
}
|
|
4092
4178
|
function getContentClosureValues(bodySection) {
|
|
4093
|
-
const contentClosures =
|
|
4179
|
+
const contentClosures = getDynamicTagContentClosures(bodySection);
|
|
4094
4180
|
if (!contentClosures) return;
|
|
4095
4181
|
const scope = generateUidIdentifier("scope");
|
|
4096
4182
|
const closures = Array.isArray(contentClosures) ? contentClosures : [contentClosures];
|
|
@@ -4111,9 +4197,6 @@ function getContentClosureValues(bodySection) {
|
|
|
4111
4197
|
levels: levels.reverse()
|
|
4112
4198
|
};
|
|
4113
4199
|
}
|
|
4114
|
-
function mayBeUnwritten(closure) {
|
|
4115
|
-
return !isUnconditionalReason(getWriteReason(closure));
|
|
4116
|
-
}
|
|
4117
4200
|
const [getScopeProperties] = createOutputSectionState(() => /* @__PURE__ */ new Map());
|
|
4118
4201
|
function writeSlot(slot, expression) {
|
|
4119
4202
|
const reason = slot?.reason;
|
|
@@ -4537,9 +4620,9 @@ function writeHTMLResumeStatements(path) {
|
|
|
4537
4620
|
const closureIndex = getDynamicClosureIndex(closure, section);
|
|
4538
4621
|
if (closureIndex) writeSlot(findSlot(closure, 3, section), _marko_compiler.types.numericLiteral(closureIndex));
|
|
4539
4622
|
const closureScopesReason = findSlot(closure, 2)?.reason;
|
|
4540
|
-
const subscribeArg =
|
|
4623
|
+
const subscribeArg = isGuardedReason(closureScopesReason) && !isSameReason(closureScopesReason, sectionReason) ? getExprIfWritten(closure.section, closureScopesReason, identifier) : identifier;
|
|
4541
4624
|
const changeable = isChangeableDynamicClosure(section, closure);
|
|
4542
|
-
addWriteScopeBuilder(section, (expr) => {
|
|
4625
|
+
if (subscribeArg) addWriteScopeBuilder(section, (expr) => {
|
|
4543
4626
|
const resumeId = changeable && _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "subscribe"));
|
|
4544
4627
|
return callRuntime("_subscribe", subscribeArg, expr, resumeId, resumeId && markerGuard);
|
|
4545
4628
|
});
|
|
@@ -4564,7 +4647,8 @@ function writeHTMLResumeStatements(path) {
|
|
|
4564
4647
|
if (!reason) return;
|
|
4565
4648
|
const accessor = getScopeAccessor(binding);
|
|
4566
4649
|
pendingProperties.delete(accessor);
|
|
4567
|
-
|
|
4650
|
+
const value = ifWritten(reason, getDeclaredBindingExpression(binding));
|
|
4651
|
+
if (value) scopeProperties.push(toObjectProperty(accessor, value));
|
|
4568
4652
|
if (debug) {
|
|
4569
4653
|
const { root, access } = getDebugAccess(binding, false, toAccess);
|
|
4570
4654
|
const locExpr = root.loc && _marko_compiler.types.stringLiteral(getDebugLoc(root.loc));
|
|
@@ -4579,10 +4663,14 @@ function writeHTMLResumeStatements(path) {
|
|
|
4579
4663
|
const ownerReason = findSectionSlot(section, 7)?.reason;
|
|
4580
4664
|
if (ownerReason) {
|
|
4581
4665
|
pendingProperties.delete(ownerAccessor);
|
|
4582
|
-
|
|
4666
|
+
const owner = !getOwnerResumedByMarker(section) && ifWritten(ownerReason, callRuntime("_scope_with_id", getScopeIdIdentifier(section.parent)));
|
|
4667
|
+
if (owner) scopeProperties.push(toObjectProperty(ownerAccessor, owner));
|
|
4583
4668
|
}
|
|
4584
4669
|
}
|
|
4585
|
-
for (const [key, { expression, reason }] of pendingProperties)
|
|
4670
|
+
for (const [key, { expression, reason }] of pendingProperties) {
|
|
4671
|
+
const value = ifWritten(reason, expression);
|
|
4672
|
+
if (value) scopeProperties.push(toObjectProperty(key, value));
|
|
4673
|
+
}
|
|
4586
4674
|
if (sectionReason) {
|
|
4587
4675
|
for (const prop of scopeProperties) if (prop.key.type === "Identifier" && prop.value.type === "Identifier" && prop.key.name === prop.value.name) prop.shorthand = true;
|
|
4588
4676
|
const writeScopeArgs = [scopeIdIdentifier, _marko_compiler.types.objectExpression(scopeProperties)];
|
|
@@ -4591,8 +4679,8 @@ function writeHTMLResumeStatements(path) {
|
|
|
4591
4679
|
for (const [accessor, varLoc] of getSectionDebugVars(section)) (debugVars ||= []).push(toObjectProperty(accessor, _marko_compiler.types.valueToNode(varLoc)));
|
|
4592
4680
|
if (debugVars) writeScopeArgs.push(_marko_compiler.types.objectExpression(debugVars));
|
|
4593
4681
|
}
|
|
4594
|
-
const
|
|
4595
|
-
body.push(_marko_compiler.types.expressionStatement(
|
|
4682
|
+
const write = getExprIfWritten(section, sectionReason, writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs));
|
|
4683
|
+
if (write) body.push(_marko_compiler.types.expressionStatement(write));
|
|
4596
4684
|
}
|
|
4597
4685
|
if (!isOptionalBranch(section) && (section.hasAbortSignal || !!section.referencedClosures || sectionReason && some(section.bindings, isLetBinding)) && markerGuard) {
|
|
4598
4686
|
const call = callRuntime("_resume_branch", scopeIdIdentifier);
|
|
@@ -4967,7 +5055,6 @@ function getSingleKnownSpread(paramsTree, attributes) {
|
|
|
4967
5055
|
//#region src/translator/util/known-tag.ts
|
|
4968
5056
|
const [getTagVarBindings] = createOutputSectionState(() => []);
|
|
4969
5057
|
const [getCallSiteSourcesByParam] = createAnalysisState(() => /* @__PURE__ */ new Map());
|
|
4970
|
-
const kChildSection = Symbol("known tag child section");
|
|
4971
5058
|
const kParamsTree = Symbol("known tag params tree");
|
|
4972
5059
|
const kKnownExprs = Symbol("known tag exprs");
|
|
4973
5060
|
const [getRecursiveTags] = createAnalysisState(() => []);
|
|
@@ -4977,15 +5064,15 @@ function knownTagAnalyze(tag, childSection, childParamsTree) {
|
|
|
4977
5064
|
const tagBody = tag.get("body");
|
|
4978
5065
|
const tagExtra = tag.node.extra ??= {};
|
|
4979
5066
|
tagExtra.childScopeBinding = createBinding("#childScope", 0, section);
|
|
5067
|
+
tagExtra.childSection = childSection;
|
|
4980
5068
|
ensureBodySection(tagBody);
|
|
4981
5069
|
trackParamsReferences(tagBody, 2);
|
|
4982
5070
|
(section.knownTags ||= []).push(tagExtra);
|
|
4983
|
-
tagExtra[kChildSection] = childSection;
|
|
4984
5071
|
const varBinding = trackVarReferences(tag, 4);
|
|
4985
5072
|
const recursive = isSameOrAncestorSection(childSection, section);
|
|
4986
5073
|
let exprs;
|
|
4987
5074
|
if (childSection.program === section.program) {
|
|
4988
|
-
childSection.
|
|
5075
|
+
childSection.calls = push(childSection.calls, tagExtra);
|
|
4989
5076
|
if (recursive) getRecursiveTags().push(tag);
|
|
4990
5077
|
else exprs = analyzeKnownTagParams(tag, exposeChildParamsTree(childSection));
|
|
4991
5078
|
} else exprs = analyzeKnownTagParams(tag, childParamsTree);
|
|
@@ -5009,7 +5096,7 @@ function knownTagAnalyze(tag, childSection, childParamsTree) {
|
|
|
5009
5096
|
}
|
|
5010
5097
|
function analyzeRecursiveTags() {
|
|
5011
5098
|
for (const tag of getRecursiveTags()) {
|
|
5012
|
-
const childSection = tag.node.extra
|
|
5099
|
+
const childSection = tag.node.extra.childSection;
|
|
5013
5100
|
assertTerminates(tag, childSection);
|
|
5014
5101
|
const exprs = analyzeKnownTagParams(tag, exposeChildParamsTree(childSection));
|
|
5015
5102
|
if (tag.node.var) {
|
|
@@ -5024,8 +5111,8 @@ function assertTerminates(tag, childSection) {
|
|
|
5024
5111
|
const callers = /* @__PURE__ */ new Set([getSection(tag)]);
|
|
5025
5112
|
for (const caller of callers) {
|
|
5026
5113
|
if (caller === childSection) throw tag.get("name").buildCodeFrameError(`A ${childSection === (0, _marko_compiler_babel_utils.getProgram)().node.extra.section ? "template" : "`<define>`"} that renders itself outside a branch never terminates. Render \`<${getTagNameHint(tag.node)}>\` inside a branch that eventually stops, such as \`<if>\`.`);
|
|
5027
|
-
forEach(caller.
|
|
5028
|
-
callers.add(
|
|
5114
|
+
forEach(caller.calls, (call) => {
|
|
5115
|
+
callers.add(call.childScopeBinding.section);
|
|
5029
5116
|
});
|
|
5030
5117
|
}
|
|
5031
5118
|
}
|
|
@@ -5048,8 +5135,8 @@ function getReturnParams(section) {
|
|
|
5048
5135
|
function assertReturns(tag, childSection) {
|
|
5049
5136
|
if (!childSection.returnValueExpr) throw tag.get("var").buildCodeFrameError(`The \`${getTagNameHint(tag.node)}\` tag does not [\`<return>\`](https://markojs.com/docs/reference/core-tag#return) a value, so it does not support a [tag variable](https://markojs.com/docs/reference/language#tag-variables). Remove the variable, or add a \`<return>\` to the tag.`);
|
|
5050
5137
|
}
|
|
5051
|
-
function isChildScopeResumed(tagExtra) {
|
|
5052
|
-
return
|
|
5138
|
+
function isChildScopeResumed(section, tagExtra) {
|
|
5139
|
+
return isEverWritten(section, findSlot(tagExtra.childScopeBinding)?.reason);
|
|
5053
5140
|
}
|
|
5054
5141
|
function getRenderArgs(tag, properties) {
|
|
5055
5142
|
const args = tag.node.arguments;
|
|
@@ -5066,7 +5153,7 @@ function toRenderArg(arg) {
|
|
|
5066
5153
|
function knownTagTranslateHTML(tag, tagIdentifier) {
|
|
5067
5154
|
const { node } = tag;
|
|
5068
5155
|
const tagExtra = node.extra;
|
|
5069
|
-
const childSection = tagExtra
|
|
5156
|
+
const childSection = tagExtra.childSection;
|
|
5070
5157
|
const paramsTree = getSettledParamsTree(tagExtra[kParamsTree]);
|
|
5071
5158
|
writeHTMLResumeStatements(tag);
|
|
5072
5159
|
const tagVar = node.var;
|
|
@@ -5078,8 +5165,8 @@ function knownTagTranslateHTML(tag, tagIdentifier) {
|
|
|
5078
5165
|
};
|
|
5079
5166
|
const childScopeBinding = tagExtra.childScopeBinding;
|
|
5080
5167
|
let varStatement;
|
|
5081
|
-
if (isChildScopeResumed(tagExtra)) {
|
|
5082
|
-
const peekScopeId = generateUidIdentifier(childScopeBinding
|
|
5168
|
+
if (isChildScopeResumed(section, tagExtra)) {
|
|
5169
|
+
const peekScopeId = generateUidIdentifier(childScopeBinding.name);
|
|
5083
5170
|
statements.push(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(peekScopeId, callRuntime("_peek_scope_id"))]));
|
|
5084
5171
|
const childScopeSlot = findSlot(childScopeBinding);
|
|
5085
5172
|
writeSlot(childScopeSlot, callRuntime("_existing_scope", peekScopeId));
|
|
@@ -5104,7 +5191,7 @@ function knownTagTranslateDOM(tag, getBindingIdentifier, callSetup) {
|
|
|
5104
5191
|
if (node.var) {
|
|
5105
5192
|
const varBinding = node.var.extra.binding;
|
|
5106
5193
|
const signal = initValue(varBinding);
|
|
5107
|
-
signal.register = isChildScopeResumed(extra);
|
|
5194
|
+
signal.register = isChildScopeResumed(getSection(tag), extra);
|
|
5108
5195
|
signal.referenced = true;
|
|
5109
5196
|
signal.buildAssignment = (valueSection, value) => buildVarChange(createScopeReadExpression(childScopeBinding, valueSection), value, varBinding);
|
|
5110
5197
|
getTagVarBindings(tagSection).push(_marko_compiler.types.expressionStatement(callRuntime("_var", scopeIdentifier, getScopeAccessorLiteral(childScopeBinding, true), signal.identifier)));
|
|
@@ -5122,8 +5209,8 @@ function getCallSiteSources(param) {
|
|
|
5122
5209
|
if (sourcesByParam.has(param)) return sourcesByParam.get(param);
|
|
5123
5210
|
const body = param.section;
|
|
5124
5211
|
let sources;
|
|
5125
|
-
forEach(body.
|
|
5126
|
-
|
|
5212
|
+
forEach(body.calls, (call) => {
|
|
5213
|
+
sources = mergeSources(sources, getSourcesForExprs(mapParamBindingToExpr(call[kKnownExprs], param)));
|
|
5127
5214
|
});
|
|
5128
5215
|
sourcesByParam.set(param, sources);
|
|
5129
5216
|
return sources;
|
|
@@ -5136,8 +5223,8 @@ function addKnownTagReasons(section) {
|
|
|
5136
5223
|
for (const tagExtra of section.knownTags || []) {
|
|
5137
5224
|
const { childScopeBinding } = tagExtra;
|
|
5138
5225
|
const knownExprs = tagExtra[kKnownExprs];
|
|
5139
|
-
const childSection = tagExtra
|
|
5140
|
-
if (knownExprs &&
|
|
5226
|
+
const { childSection } = tagExtra;
|
|
5227
|
+
if (knownExprs && childSection.paramReasonGroups) {
|
|
5141
5228
|
for (const group of childSection.paramReasonGroups) if (!findSlot(childScopeBinding, 5, section, group)) {
|
|
5142
5229
|
const slot = ensureSlot(childScopeBinding, 5, section, group);
|
|
5143
5230
|
slot.reasonExprs = mapParamReasonToExpr(knownExprs, group);
|
|
@@ -5148,7 +5235,7 @@ function addKnownTagReasons(section) {
|
|
|
5148
5235
|
}
|
|
5149
5236
|
function callsOtherTemplateSetup(section) {
|
|
5150
5237
|
for (const tagExtra of section.knownTags || []) {
|
|
5151
|
-
const childSection = tagExtra
|
|
5238
|
+
const { childSection } = tagExtra;
|
|
5152
5239
|
if (tagExtra.tagNameLoad || childSection.program !== section.program && childSection.hasSetupWork) return true;
|
|
5153
5240
|
}
|
|
5154
5241
|
return false;
|
|
@@ -5609,12 +5696,9 @@ function mapBodyParams(section, reason, seen) {
|
|
|
5609
5696
|
if (params === reason.param) return reason;
|
|
5610
5697
|
return mergeSources(mapBodyParams(section, mapped, seen), withSources(reason, reason.state, params)) || ALWAYS;
|
|
5611
5698
|
}
|
|
5612
|
-
function
|
|
5699
|
+
function isGuardedReason(reason) {
|
|
5613
5700
|
return !!reason && !reason.always && !reason.state;
|
|
5614
5701
|
}
|
|
5615
|
-
function isUnconditionalReason(reason) {
|
|
5616
|
-
return !!reason && !isConditionalReason(reason);
|
|
5617
|
-
}
|
|
5618
5702
|
function isStateReason(reason) {
|
|
5619
5703
|
return !!reason && !reason.always && !!reason.state;
|
|
5620
5704
|
}
|
|
@@ -5942,7 +6026,9 @@ function initBranchSection(bodySection, branchExpr, branch) {
|
|
|
5942
6026
|
}
|
|
5943
6027
|
function resumeOwnerByMarkerWhenUnconditional(bodySection, nodeBinding) {
|
|
5944
6028
|
const branchExprReason = findSlot(nodeBinding, 4)?.reason;
|
|
5945
|
-
|
|
6029
|
+
const branchReason = getBranchWriteReason(bodySection);
|
|
6030
|
+
const nodeReason = getWriteReason(nodeBinding);
|
|
6031
|
+
if (isStateReason(branchExprReason) && some(branchExprReason.state, hasResumableAssignment) && branchReason && !isGuardedReason(branchReason) && nodeReason && !isGuardedReason(nodeReason)) setSectionOwnerResumedByMarker(bodySection);
|
|
5946
6032
|
}
|
|
5947
6033
|
function getBranchResumeArgs(tag, branchReasons, singleNode) {
|
|
5948
6034
|
const tagSection = getSection(tag);
|
|
@@ -8085,8 +8171,8 @@ function resolveBindings() {
|
|
|
8085
8171
|
}
|
|
8086
8172
|
}
|
|
8087
8173
|
function addSectionReasons(section) {
|
|
8088
|
-
if (section.readsOwner) forEach(section.
|
|
8089
|
-
setReadsOwner(
|
|
8174
|
+
if (section.readsOwner) forEach(section.calls, (call) => {
|
|
8175
|
+
setReadsOwner(call.childScopeBinding.section, section.parent);
|
|
8090
8176
|
});
|
|
8091
8177
|
if (section.isHoistThrough) addReason(ensureSectionSlot(section, 6), ALWAYS);
|
|
8092
8178
|
forEach(section.referencedClosures, (closure) => {
|
|
@@ -9816,6 +9902,7 @@ var dynamic_tag_default = {
|
|
|
9816
9902
|
analyzeAttributeTags(tag);
|
|
9817
9903
|
const tagSection = ensureSection(tag);
|
|
9818
9904
|
const inputNodes = getAllTagReferenceNodes(node);
|
|
9905
|
+
(node.name.extra ??= {}).tagName = true;
|
|
9819
9906
|
const tagExtra = mergeReferences(tagSection, node, [node.name, ...inputNodes]);
|
|
9820
9907
|
if (inputNodes.length) tagExtra.retained = true;
|
|
9821
9908
|
const tagBody = tag.get("body");
|
|
@@ -9841,7 +9928,7 @@ var dynamic_tag_default = {
|
|
|
9841
9928
|
trackParamsReferences(tagBody, 2);
|
|
9842
9929
|
if (usesVar) addAlwaysReason(nodeBinding);
|
|
9843
9930
|
addReasonExprs(ensureSlot(nodeBinding), tagExtra);
|
|
9844
|
-
if (!hasVar && !node.arguments && !node.attributes.length && !node.body.body.length) tagExtra.nameOnly = true;
|
|
9931
|
+
if (!hasVar && !node.arguments && !node.attributes.length && !node.body.body.length && !tagExtra.attrTagLookup) tagExtra.nameOnly = true;
|
|
9845
9932
|
marker(tag, nodeBinding);
|
|
9846
9933
|
enterShallow(tag);
|
|
9847
9934
|
if (bodySection && tagExtra.featureType === "class" && !(0, _marko_compiler_babel_utils.getTagTemplate)(tag)) bodySection.structure = null;
|
|
@@ -10234,7 +10321,8 @@ var program_default = {
|
|
|
10234
10321
|
if (paramsBinding && !paramsBinding.pruned) programExtra.paramsTree = exposeParamsTree(paramsBinding);
|
|
10235
10322
|
const section = programExtra.section;
|
|
10236
10323
|
forEachSection((childSection) => {
|
|
10237
|
-
|
|
10324
|
+
const reason = mapBodyParams(childSection, childSection.reason);
|
|
10325
|
+
programExtra.hasResumes ||= !!(reason && !isGuardedReason(reason) || childSection !== section && !isSectionRendererElided(childSection) && getRendererReason(childSection));
|
|
10238
10326
|
});
|
|
10239
10327
|
finalizeSetupWork();
|
|
10240
10328
|
}
|
|
@@ -4,19 +4,23 @@ import { type ParamsTree } from "./params-tree";
|
|
|
4
4
|
import { type KnownExprs } from "./reasons";
|
|
5
5
|
import { type Section } from "./sections";
|
|
6
6
|
import { type Sources } from "./sources";
|
|
7
|
-
declare const kChildSection: unique symbol;
|
|
8
7
|
declare const kParamsTree: unique symbol;
|
|
9
8
|
declare const kKnownExprs: unique symbol;
|
|
10
9
|
declare module "@marko/compiler/dist/types" {
|
|
11
10
|
interface MarkoTagExtra {
|
|
12
11
|
/** The dom binding a known tag holds its child's scope in. */
|
|
13
12
|
childScopeBinding?: Binding;
|
|
14
|
-
|
|
13
|
+
/** The section a known tag renders: another template's, a `<define>` body. */
|
|
14
|
+
childSection?: Section;
|
|
15
15
|
/** The child's params tree the call site was analyzed against. */
|
|
16
16
|
[kParamsTree]?: ParamsTree;
|
|
17
17
|
[kKnownExprs]?: KnownExprs;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
+
export interface KnownTagExtra extends t.MarkoTagExtra {
|
|
21
|
+
childScopeBinding: Binding;
|
|
22
|
+
childSection: Section;
|
|
23
|
+
}
|
|
20
24
|
export declare function knownTagAnalyze(tag: t.NodePath<t.MarkoTag>, childSection: Section, childParamsTree?: ParamsTree): void;
|
|
21
25
|
export declare function analyzeRecursiveTags(): void;
|
|
22
26
|
export declare function knownTagTranslateHTML(tag: t.NodePath<t.MarkoTag>, tagIdentifier: t.Expression): void;
|
|
@@ -11,11 +11,10 @@ export declare function addAlwaysReason(binding: Binding): void;
|
|
|
11
11
|
export declare function addReasonExprs(slot: Slot, expr: Opt<t.NodeExtra>): void;
|
|
12
12
|
export declare function addOwnerReason(from: Section, to: Section, reason: undefined | false | Reason): void;
|
|
13
13
|
export declare function mapBodyParams(section: Section, reason: undefined | Reason, seen?: Set<ParamBinding>): Reason | undefined;
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function isGuardedReason(reason: undefined | Reason): reason is Sources & {
|
|
15
15
|
state: undefined;
|
|
16
16
|
always: undefined;
|
|
17
17
|
};
|
|
18
|
-
export declare function isUnconditionalReason(reason: undefined | Reason): reason is Reason;
|
|
19
18
|
export declare function isStateReason(reason: undefined | Reason): reason is Sources;
|
|
20
19
|
export declare function getSourcesForExpr(expr: t.NodeExtra): Sources | undefined;
|
|
21
20
|
export declare function getSourcesForExprs(exprs: Opt<t.NodeExtra> | boolean): Sources | undefined;
|
|
@@ -63,6 +63,8 @@ declare module "@marko/compiler/dist/types" {
|
|
|
63
63
|
assignment?: Binding;
|
|
64
64
|
assignmentTo?: Binding;
|
|
65
65
|
read?: ResolvedRead;
|
|
66
|
+
/** An expression root that is a dynamic tag's name, not one of its inputs. */
|
|
67
|
+
tagName?: true;
|
|
66
68
|
dropped?: true;
|
|
67
69
|
/** The expression this node sits in: dropped or merged as one. */
|
|
68
70
|
exprRoot?: NodeExtra;
|
|
@@ -3,6 +3,7 @@ import { type Binding, type Intersection, type IntersectionMeta, type ParamBindi
|
|
|
3
3
|
import * as ContentType from "./constants/content-type";
|
|
4
4
|
import type * as Step from "./constants/step";
|
|
5
5
|
import * as StructureKind from "./constants/structure-kind";
|
|
6
|
+
import type { KnownTagExtra } from "./known-tag";
|
|
6
7
|
import { type OneMany, type Opt, Sorted, type SortedOpt } from "./optional";
|
|
7
8
|
import { type KnownExprs, type Reason } from "./reasons";
|
|
8
9
|
import { type Slot } from "./slots";
|
|
@@ -70,11 +71,11 @@ export interface Section {
|
|
|
70
71
|
returnValueExpr: t.NodeExtra | undefined;
|
|
71
72
|
isHoistThrough: true | undefined;
|
|
72
73
|
branchExpr: t.NodeExtra | undefined;
|
|
73
|
-
/** For a `<define>` body or a template rendering itself, the
|
|
74
|
-
* direct calls render it. */
|
|
75
|
-
|
|
74
|
+
/** For a `<define>` body or a template rendering itself, the known tags whose
|
|
75
|
+
* direct calls render it (each in its child scope binding's section). */
|
|
76
|
+
calls: Opt<KnownTagExtra>;
|
|
76
77
|
/** The known tags rendering in it, in analyze order. */
|
|
77
|
-
knownTags:
|
|
78
|
+
knownTags: KnownTagExtra[] | undefined;
|
|
78
79
|
/** The content's rendering tag (its extra), and each child binding that
|
|
79
80
|
* derives from the content, at `properties`. */
|
|
80
81
|
derives: {
|
|
@@ -128,7 +129,7 @@ export declare function getSection(path: t.NodePath): Section;
|
|
|
128
129
|
export declare const getScopeIdIdentifier: (section: Section) => t.Identifier;
|
|
129
130
|
export declare const getBranchRendererArgs: (section: Section) => [template?: t.Expression | undefined, walks?: t.Expression | undefined, setup?: t.Expression | undefined, params?: t.Expression | undefined], setBranchRendererArgs: (section: Section, value: [template?: t.Expression | undefined, walks?: t.Expression | undefined, setup?: t.Expression | undefined, params?: t.Expression | undefined]) => void;
|
|
130
131
|
export declare function forEachSection(fn: (section: Section) => void): void;
|
|
131
|
-
export declare function getDynamicTagContentClosures(section: Section):
|
|
132
|
+
export declare function getDynamicTagContentClosures(section: Section): SortedOpt<Binding>;
|
|
132
133
|
export declare function forEachAncestorSection<A>(from: Section, to: Section, fn: (section: Section, arg: A) => void, arg: A): void;
|
|
133
134
|
export declare function forEachSectionReverse(fn: (section: Section) => void): void;
|
|
134
135
|
export declare function getNodeContentType(path: t.NodePath<t.Statement>, edge: "startType" | "endType"): ContentType.Value | null;
|
|
@@ -6,4 +6,5 @@ import { type Section } from "./sections";
|
|
|
6
6
|
export declare function solveReasons(intersectionsBySection: Map<Section, Intersection[]>): void;
|
|
7
7
|
export declare function getReasonForBinding(binding: Binding, properties?: Opt<string> | true): undefined | Reason;
|
|
8
8
|
export declare function getReasonForExpr(extra: t.NodeExtra): undefined | Reason;
|
|
9
|
+
export declare function bindingLandsRetained(binding: Binding, properties: Opt<string>): boolean;
|
|
9
10
|
export declare function landsRetained(extra: t.NodeExtra): boolean;
|
|
@@ -13,4 +13,5 @@ export declare function getWriteReason(binding: Binding): Sources | undefined;
|
|
|
13
13
|
export declare function getBranchWriteReason(section: Section): Sources | undefined;
|
|
14
14
|
export declare function getWriteGuard(section: Section, reason: undefined | Reason, omitUnconditional: boolean): t.Expression | undefined;
|
|
15
15
|
export declare function getWriteGuardForAny(section: Section, reasons: undefined | Reasons, omitUnconditional: boolean): t.Expression | undefined;
|
|
16
|
-
export declare function getExprIfWritten
|
|
16
|
+
export declare function getExprIfWritten(section: Section, reason: undefined | Reason, expr: t.Expression): t.Expression | undefined;
|
|
17
|
+
export declare function isEverWritten(section: Section, reason: undefined | Reason): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marko/runtime-tags",
|
|
3
|
-
"version": "6.4.
|
|
3
|
+
"version": "6.4.8",
|
|
4
4
|
"description": "Optimized runtime for Marko templates.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -51,14 +51,14 @@
|
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@marko/compiler": "^5.42.
|
|
54
|
+
"@marko/compiler": "^5.42.14",
|
|
55
55
|
"csstype": "^3.2.3",
|
|
56
56
|
"fastest-levenshtein": "^1.0.16",
|
|
57
57
|
"magic-string": "^0.30.21"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@marko/runtime-tags": "6.4.
|
|
61
|
-
"marko": "5.39.
|
|
60
|
+
"@marko/runtime-tags": "6.4.8",
|
|
61
|
+
"marko": "5.39.48"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=22"
|
package/tags-html.d.ts
CHANGED
|
@@ -97,6 +97,7 @@ declare global {
|
|
|
97
97
|
search: NativeTag<Marko.HTML.Search, HTMLElement>;
|
|
98
98
|
section: NativeTag<Marko.HTML.Section, HTMLElement>;
|
|
99
99
|
select: NativeTag<Marko.HTML.Select, HTMLSelectElement>;
|
|
100
|
+
selectedcontent: NativeTag<Marko.HTML.SelectedContent, HTMLElement>;
|
|
100
101
|
slot: NativeTag<Marko.HTML.Slot, HTMLSlotElement>;
|
|
101
102
|
small: NativeTag<Marko.HTML.Small, HTMLElement>;
|
|
102
103
|
source: NativeTag<Marko.HTML.Source, HTMLSourceElement>;
|
|
@@ -2056,6 +2057,8 @@ declare global {
|
|
|
2056
2057
|
) => void);
|
|
2057
2058
|
}
|
|
2058
2059
|
|
|
2060
|
+
interface SelectedContent extends HTMLAttributes<HTMLElement> {}
|
|
2061
|
+
|
|
2059
2062
|
interface Slot extends HTMLAttributes<HTMLSlotElement> {
|
|
2060
2063
|
/**
|
|
2061
2064
|
* Used to assign slots to other elements
|