@barefootjs/erb 0.31.4 → 0.31.6
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/adapter/erb-adapter.d.ts +26 -11
- package/dist/adapter/erb-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +20 -38
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +31 -43
- package/dist/vite.js +151 -122
- package/package.json +5 -5
- package/src/adapter/erb-adapter.ts +66 -62
- package/src/adapter/expr/emitters.ts +5 -5
- package/src/conformance-pins.ts +14 -5
|
@@ -128,17 +128,23 @@ export declare class ErbAdapter extends BaseAdapter implements IRNodeEmitter<Erb
|
|
|
128
128
|
*/
|
|
129
129
|
private localConstants;
|
|
130
130
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* for TWO things in the ERB adapter
|
|
135
|
-
* only used it to guard
|
|
136
|
-
* fundamental `v[:name]` vs
|
|
137
|
-
* `ErbTopLevelEmitter.identifier` —
|
|
138
|
-
* `isLoopBoundName` docstring for why ERB's
|
|
139
|
-
* where Perl's uniform `$name` sigil does
|
|
140
|
-
|
|
141
|
-
|
|
131
|
+
* The one canonical, position-accurate "names bound by an enclosing loop
|
|
132
|
+
* callback" service (#2482 Stage 2) — replaces the ref-counted
|
|
133
|
+
* `Map<string, number>` this adapter used to push/pop around
|
|
134
|
+
* `renderLoop`'s body. Load-bearing for TWO things in the ERB adapter
|
|
135
|
+
* (more than the Mojo original, which only used it to guard
|
|
136
|
+
* const-inlining): it also decides the fundamental `v[:name]` vs
|
|
137
|
+
* bare-Ruby-local rendering choice in `ErbTopLevelEmitter.identifier` —
|
|
138
|
+
* see `emit-context.ts`'s `isLoopBoundName` docstring for why ERB's
|
|
139
|
+
* two-locals model needs this where Perl's uniform `$name` sigil does
|
|
140
|
+
* not. Threaded via save/restore-by-reference around
|
|
141
|
+
* `renderChildren(loop.children)` in `renderLoop` (immutable — no
|
|
142
|
+
* ref-count bookkeeping), mirroring the Stage 1a/1b `ctx.scope`
|
|
143
|
+
* precedent in `jsx-to-ir.ts`. `IRLoop` already structurally satisfies
|
|
144
|
+
* `LoopBindingSource` (`param`/`index`/`paramBindings`/`preamble`), so
|
|
145
|
+
* `renderLoop` passes the loop node straight to `enterLoopRow`.
|
|
146
|
+
*/
|
|
147
|
+
private scope;
|
|
142
148
|
/**
|
|
143
149
|
* Prop names whose value is `nil` in the template body when the caller
|
|
144
150
|
* omits them — so a bare-reference attribute should be dropped rather
|
|
@@ -379,6 +385,15 @@ export declare class ErbAdapter extends BaseAdapter implements IRNodeEmitter<Erb
|
|
|
379
385
|
/** Whether `name` (a signal getter or prop) holds a string value — gates
|
|
380
386
|
* index-access Hash-vs-Array lowering (see `expr/operand.ts`). */
|
|
381
387
|
private _isStringValueName;
|
|
388
|
+
/**
|
|
389
|
+
* `escape` is the structured claim (#2613) — populate it only with kinds
|
|
390
|
+
* a conformance twin actually demonstrates for this shape, since
|
|
391
|
+
* `escape-coverage.test.ts` checks claims against the twins. The prose
|
|
392
|
+
* in `reason` may legitimately offer more than the structured field
|
|
393
|
+
* (ERB's numbered list opens with an inline-rewrite option that no twin
|
|
394
|
+
* proves); prose stays authoritative for humans, this field for
|
|
395
|
+
* machines.
|
|
396
|
+
*/
|
|
382
397
|
private _recordExprBF101;
|
|
383
398
|
/** Internal hook for higher-order: predicate body re-uses the filter emitter. */
|
|
384
399
|
private _renderRubyFilterExprPublic;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"erb-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/erb-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EACV,WAAW,EAEX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAMP,yBAAyB,EAC1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"erb-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/erb-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -187314,7 +187314,8 @@ import {
|
|
|
187314
187314
|
dangerousInnerHtmlMetacharViolation,
|
|
187315
187315
|
dangerousInnerHtmlDiagnostic,
|
|
187316
187316
|
resolveStaticLoopSource,
|
|
187317
|
-
derivesScopeFromSlot
|
|
187317
|
+
derivesScopeFromSlot,
|
|
187318
|
+
BindingScope
|
|
187318
187319
|
} from "@barefootjs/jsx";
|
|
187319
187320
|
|
|
187320
187321
|
// src/adapter/boolean-result.ts
|
|
@@ -188372,7 +188373,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188372
188373
|
_loweringMatchers = [];
|
|
188373
188374
|
moduleStringConsts = new Map;
|
|
188374
188375
|
localConstants = [];
|
|
188375
|
-
|
|
188376
|
+
scope = BindingScope.EMPTY;
|
|
188376
188377
|
nullableOptionalProps = new Set;
|
|
188377
188378
|
constructor(options = {}) {
|
|
188378
188379
|
super();
|
|
@@ -188394,7 +188395,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188394
188395
|
this._searchParamsLocals = searchParamsLocalNames(ir.metadata);
|
|
188395
188396
|
this._loweringMatchers = prepareLoweringMatchers(ir.metadata);
|
|
188396
188397
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
188397
|
-
this.
|
|
188398
|
+
this.scope = BindingScope.EMPTY;
|
|
188398
188399
|
this.errors = [];
|
|
188399
188400
|
this.childrenCaptureCounter = 0;
|
|
188400
188401
|
if (!options?.siblingTemplatesRegistered) {
|
|
@@ -188452,7 +188453,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188452
188453
|
};
|
|
188453
188454
|
}
|
|
188454
188455
|
resolveLiteralConst(name) {
|
|
188455
|
-
if (this.
|
|
188456
|
+
if (this.scope.isBound(name))
|
|
188456
188457
|
return null;
|
|
188457
188458
|
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
188458
188459
|
if (c?.value === undefined)
|
|
@@ -188466,15 +188467,13 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188466
188467
|
return null;
|
|
188467
188468
|
}
|
|
188468
188469
|
resolveStaticRecordLiteral(objectName, key) {
|
|
188469
|
-
|
|
188470
|
-
return null;
|
|
188471
|
-
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
188470
|
+
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
|
|
188472
188471
|
if (!hit)
|
|
188473
188472
|
return null;
|
|
188474
188473
|
return hit.kind === "number" ? hit.text : rubyStringLiteral(hit.text);
|
|
188475
188474
|
}
|
|
188476
188475
|
resolveModuleStringConst(name) {
|
|
188477
|
-
if (this.
|
|
188476
|
+
if (this.scope.isBound(name))
|
|
188478
188477
|
return null;
|
|
188479
188478
|
const value = this.moduleStringConsts.get(name);
|
|
188480
188479
|
if (value === undefined)
|
|
@@ -188482,7 +188481,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188482
188481
|
return rubyStringLiteral(value);
|
|
188483
188482
|
}
|
|
188484
188483
|
isLoopBoundName(name) {
|
|
188485
|
-
return this.
|
|
188484
|
+
return this.scope.isBound(name);
|
|
188486
188485
|
}
|
|
188487
188486
|
generateScriptRegistrations(ir, scriptBaseName, scriptAssets, preloadAssets) {
|
|
188488
188487
|
if (scriptAssets) {
|
|
@@ -188759,17 +188758,17 @@ ${whenTrue}
|
|
|
188759
188758
|
});
|
|
188760
188759
|
}
|
|
188761
188760
|
const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
|
|
188762
|
-
isNameShadowed:
|
|
188761
|
+
isNameShadowed: this.scope.asShadowPredicate()
|
|
188763
188762
|
});
|
|
188764
188763
|
const staticArray = staticItems !== null ? staticValueToRuby(staticItems) : null;
|
|
188765
188764
|
if (staticArray === null && loop.arrayParsed?.kind === "identifier") {
|
|
188766
188765
|
const arrayName = loop.arrayParsed.name;
|
|
188767
|
-
const isUnresolvableLocalConst = !this.
|
|
188766
|
+
const isUnresolvableLocalConst = !this.scope.isBound(arrayName) && this.resolveModuleStringConst(arrayName) === null && this.resolveLiteralConst(arrayName) === null && this.localConstants.some((c) => c.name === arrayName && !c.isModule);
|
|
188768
188767
|
if (isUnresolvableLocalConst) {
|
|
188769
188768
|
this._recordExprBF101(`Loop array \`${arrayName}\` is a component-scope const computed from a runtime expression the ERB adapter cannot evaluate at SSR render time.`, `Options:
|
|
188770
188769
|
1. Inline the array expression directly in the .map() call instead of a preceding const.
|
|
188771
188770
|
2. Mark the loop position as @client-only so the array materialises on the client.
|
|
188772
|
-
3. Precompute the value server-side and pass it in as a prop
|
|
188771
|
+
3. Precompute the value server-side and pass it in as a prop.`, [{ kind: "prop-precompute" }, { kind: "client-directive" }]);
|
|
188773
188772
|
}
|
|
188774
188773
|
}
|
|
188775
188774
|
const rawArray = staticArray ?? this.convertExpressionToRuby(loop.array);
|
|
@@ -188781,13 +188780,9 @@ ${whenTrue}
|
|
|
188781
188780
|
}
|
|
188782
188781
|
const param = loop.param;
|
|
188783
188782
|
const indexVar = loop.iterationShape === "keys" ? rubyLocal(param) : rubyLocal(loop.index ?? "_i");
|
|
188784
|
-
const loopBound = loop.objectIteration === "entries" ? [param, loop.index ?? "_k"] : loop.objectIteration === "keys" || loop.objectIteration === "values" || loop.iterationShape === "keys" ? [param] : supportableDestructure ? ["__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name), loop.index ?? "_i"] : [param, loop.index ?? "_i"];
|
|
188785
188783
|
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
188786
|
-
|
|
188787
|
-
|
|
188788
|
-
for (const n of loopBound) {
|
|
188789
|
-
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188790
|
-
}
|
|
188784
|
+
const prevScope = this.scope;
|
|
188785
|
+
this.scope = prevScope.enterLoopRow(loop);
|
|
188791
188786
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
188792
188787
|
this.currentLoopKeyDepth = loop.depth;
|
|
188793
188788
|
const renderedChildren = this.renderChildren(loop.children);
|
|
@@ -188797,13 +188792,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188797
188792
|
const lines = [];
|
|
188798
188793
|
lines.push(`<%= bf.comment("loop:${loop.markerId}") %>`);
|
|
188799
188794
|
if (sortedHoist && loop.sortComparator) {
|
|
188800
|
-
|
|
188801
|
-
const c = (this.loopBoundNames.get(n) ?? 1) - 1;
|
|
188802
|
-
if (c <= 0)
|
|
188803
|
-
this.loopBoundNames.delete(n);
|
|
188804
|
-
else
|
|
188805
|
-
this.loopBoundNames.set(n, c);
|
|
188806
|
-
}
|
|
188795
|
+
this.scope = prevScope;
|
|
188807
188796
|
const sortEmit = (e) => this.convertExpressionToRuby("", e);
|
|
188808
188797
|
const sortArrow = loop.sortComparator.arrow;
|
|
188809
188798
|
let sorted = null;
|
|
@@ -188819,9 +188808,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188819
188808
|
this._recordExprBF101(`.sort(...) loop comparator is not lowerable to a template sort`, `Pre-sort the array in the route handler, or mark the loop @client-only.`);
|
|
188820
188809
|
sorted = rawArray;
|
|
188821
188810
|
}
|
|
188822
|
-
|
|
188823
|
-
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188824
|
-
}
|
|
188811
|
+
this.scope = prevScope.enterLoopRow(loop);
|
|
188825
188812
|
lines.push(`<%- ${sortedHoist} = ${sorted} -%>`);
|
|
188826
188813
|
}
|
|
188827
188814
|
if (loop.objectIteration) {
|
|
@@ -188867,13 +188854,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188867
188854
|
lines.push(...preambleLines);
|
|
188868
188855
|
lines.push(children);
|
|
188869
188856
|
}
|
|
188870
|
-
|
|
188871
|
-
const c = (this.loopBoundNames.get(n) ?? 1) - 1;
|
|
188872
|
-
if (c <= 0)
|
|
188873
|
-
this.loopBoundNames.delete(n);
|
|
188874
|
-
else
|
|
188875
|
-
this.loopBoundNames.set(n, c);
|
|
188876
|
-
}
|
|
188857
|
+
this.scope = prevScope;
|
|
188877
188858
|
lines.push(`<%- end -%>`);
|
|
188878
188859
|
lines.push(`<%= bf.comment("/loop:${loop.markerId}") %>`);
|
|
188879
188860
|
return lines.join(`
|
|
@@ -189035,7 +189016,7 @@ ${children}`;
|
|
|
189035
189016
|
if (ternaryHash !== null) {
|
|
189036
189017
|
return `<%= bf.spread_attrs(${ternaryHash}) %>`;
|
|
189037
189018
|
}
|
|
189038
|
-
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.
|
|
189019
|
+
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
|
|
189039
189020
|
const localConst = this.localConstants.find((c) => c.name === trimmed && !c.isModule);
|
|
189040
189021
|
if (localConst?.value !== undefined) {
|
|
189041
189022
|
const initTrimmed = localConst.value.trim();
|
|
@@ -189236,7 +189217,7 @@ Options:
|
|
|
189236
189217
|
_isStringValueName(name) {
|
|
189237
189218
|
return this.stringValueNames.has(name);
|
|
189238
189219
|
}
|
|
189239
|
-
_recordExprBF101(message, reason) {
|
|
189220
|
+
_recordExprBF101(message, reason, escape) {
|
|
189240
189221
|
this.errors.push({
|
|
189241
189222
|
code: "BF101",
|
|
189242
189223
|
severity: "error",
|
|
@@ -189249,7 +189230,8 @@ Options:
|
|
|
189249
189230
|
1. Use /* @client */ for client-side evaluation
|
|
189250
189231
|
2. Pre-compute the value in Ruby` : `Options:
|
|
189251
189232
|
1. Use /* @client */ for client-side evaluation
|
|
189252
|
-
2. Pre-compute the value in Ruby
|
|
189233
|
+
2. Pre-compute the value in Ruby`,
|
|
189234
|
+
...escape ? { escape } : {}
|
|
189253
189235
|
}
|
|
189254
189236
|
});
|
|
189255
189237
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAkJ7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -187314,7 +187314,8 @@ import {
|
|
|
187314
187314
|
dangerousInnerHtmlMetacharViolation,
|
|
187315
187315
|
dangerousInnerHtmlDiagnostic,
|
|
187316
187316
|
resolveStaticLoopSource,
|
|
187317
|
-
derivesScopeFromSlot
|
|
187317
|
+
derivesScopeFromSlot,
|
|
187318
|
+
BindingScope
|
|
187318
187319
|
} from "@barefootjs/jsx";
|
|
187319
187320
|
|
|
187320
187321
|
// src/adapter/boolean-result.ts
|
|
@@ -188372,7 +188373,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188372
188373
|
_loweringMatchers = [];
|
|
188373
188374
|
moduleStringConsts = new Map;
|
|
188374
188375
|
localConstants = [];
|
|
188375
|
-
|
|
188376
|
+
scope = BindingScope.EMPTY;
|
|
188376
188377
|
nullableOptionalProps = new Set;
|
|
188377
188378
|
constructor(options = {}) {
|
|
188378
188379
|
super();
|
|
@@ -188394,7 +188395,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188394
188395
|
this._searchParamsLocals = searchParamsLocalNames(ir.metadata);
|
|
188395
188396
|
this._loweringMatchers = prepareLoweringMatchers(ir.metadata);
|
|
188396
188397
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
188397
|
-
this.
|
|
188398
|
+
this.scope = BindingScope.EMPTY;
|
|
188398
188399
|
this.errors = [];
|
|
188399
188400
|
this.childrenCaptureCounter = 0;
|
|
188400
188401
|
if (!options?.siblingTemplatesRegistered) {
|
|
@@ -188452,7 +188453,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188452
188453
|
};
|
|
188453
188454
|
}
|
|
188454
188455
|
resolveLiteralConst(name) {
|
|
188455
|
-
if (this.
|
|
188456
|
+
if (this.scope.isBound(name))
|
|
188456
188457
|
return null;
|
|
188457
188458
|
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
188458
188459
|
if (c?.value === undefined)
|
|
@@ -188466,15 +188467,13 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188466
188467
|
return null;
|
|
188467
188468
|
}
|
|
188468
188469
|
resolveStaticRecordLiteral(objectName, key) {
|
|
188469
|
-
|
|
188470
|
-
return null;
|
|
188471
|
-
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
188470
|
+
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
|
|
188472
188471
|
if (!hit)
|
|
188473
188472
|
return null;
|
|
188474
188473
|
return hit.kind === "number" ? hit.text : rubyStringLiteral(hit.text);
|
|
188475
188474
|
}
|
|
188476
188475
|
resolveModuleStringConst(name) {
|
|
188477
|
-
if (this.
|
|
188476
|
+
if (this.scope.isBound(name))
|
|
188478
188477
|
return null;
|
|
188479
188478
|
const value = this.moduleStringConsts.get(name);
|
|
188480
188479
|
if (value === undefined)
|
|
@@ -188482,7 +188481,7 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188482
188481
|
return rubyStringLiteral(value);
|
|
188483
188482
|
}
|
|
188484
188483
|
isLoopBoundName(name) {
|
|
188485
|
-
return this.
|
|
188484
|
+
return this.scope.isBound(name);
|
|
188486
188485
|
}
|
|
188487
188486
|
generateScriptRegistrations(ir, scriptBaseName, scriptAssets, preloadAssets) {
|
|
188488
188487
|
if (scriptAssets) {
|
|
@@ -188759,17 +188758,17 @@ ${whenTrue}
|
|
|
188759
188758
|
});
|
|
188760
188759
|
}
|
|
188761
188760
|
const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
|
|
188762
|
-
isNameShadowed:
|
|
188761
|
+
isNameShadowed: this.scope.asShadowPredicate()
|
|
188763
188762
|
});
|
|
188764
188763
|
const staticArray = staticItems !== null ? staticValueToRuby(staticItems) : null;
|
|
188765
188764
|
if (staticArray === null && loop.arrayParsed?.kind === "identifier") {
|
|
188766
188765
|
const arrayName = loop.arrayParsed.name;
|
|
188767
|
-
const isUnresolvableLocalConst = !this.
|
|
188766
|
+
const isUnresolvableLocalConst = !this.scope.isBound(arrayName) && this.resolveModuleStringConst(arrayName) === null && this.resolveLiteralConst(arrayName) === null && this.localConstants.some((c) => c.name === arrayName && !c.isModule);
|
|
188768
188767
|
if (isUnresolvableLocalConst) {
|
|
188769
188768
|
this._recordExprBF101(`Loop array \`${arrayName}\` is a component-scope const computed from a runtime expression the ERB adapter cannot evaluate at SSR render time.`, `Options:
|
|
188770
188769
|
1. Inline the array expression directly in the .map() call instead of a preceding const.
|
|
188771
188770
|
2. Mark the loop position as @client-only so the array materialises on the client.
|
|
188772
|
-
3. Precompute the value server-side and pass it in as a prop
|
|
188771
|
+
3. Precompute the value server-side and pass it in as a prop.`, [{ kind: "prop-precompute" }, { kind: "client-directive" }]);
|
|
188773
188772
|
}
|
|
188774
188773
|
}
|
|
188775
188774
|
const rawArray = staticArray ?? this.convertExpressionToRuby(loop.array);
|
|
@@ -188781,13 +188780,9 @@ ${whenTrue}
|
|
|
188781
188780
|
}
|
|
188782
188781
|
const param = loop.param;
|
|
188783
188782
|
const indexVar = loop.iterationShape === "keys" ? rubyLocal(param) : rubyLocal(loop.index ?? "_i");
|
|
188784
|
-
const loopBound = loop.objectIteration === "entries" ? [param, loop.index ?? "_k"] : loop.objectIteration === "keys" || loop.objectIteration === "values" || loop.iterationShape === "keys" ? [param] : supportableDestructure ? ["__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name), loop.index ?? "_i"] : [param, loop.index ?? "_i"];
|
|
188785
188783
|
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
188786
|
-
|
|
188787
|
-
|
|
188788
|
-
for (const n of loopBound) {
|
|
188789
|
-
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188790
|
-
}
|
|
188784
|
+
const prevScope = this.scope;
|
|
188785
|
+
this.scope = prevScope.enterLoopRow(loop);
|
|
188791
188786
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
188792
188787
|
this.currentLoopKeyDepth = loop.depth;
|
|
188793
188788
|
const renderedChildren = this.renderChildren(loop.children);
|
|
@@ -188797,13 +188792,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188797
188792
|
const lines = [];
|
|
188798
188793
|
lines.push(`<%= bf.comment("loop:${loop.markerId}") %>`);
|
|
188799
188794
|
if (sortedHoist && loop.sortComparator) {
|
|
188800
|
-
|
|
188801
|
-
const c = (this.loopBoundNames.get(n) ?? 1) - 1;
|
|
188802
|
-
if (c <= 0)
|
|
188803
|
-
this.loopBoundNames.delete(n);
|
|
188804
|
-
else
|
|
188805
|
-
this.loopBoundNames.set(n, c);
|
|
188806
|
-
}
|
|
188795
|
+
this.scope = prevScope;
|
|
188807
188796
|
const sortEmit = (e) => this.convertExpressionToRuby("", e);
|
|
188808
188797
|
const sortArrow = loop.sortComparator.arrow;
|
|
188809
188798
|
let sorted = null;
|
|
@@ -188819,9 +188808,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188819
188808
|
this._recordExprBF101(`.sort(...) loop comparator is not lowerable to a template sort`, `Pre-sort the array in the route handler, or mark the loop @client-only.`);
|
|
188820
188809
|
sorted = rawArray;
|
|
188821
188810
|
}
|
|
188822
|
-
|
|
188823
|
-
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188824
|
-
}
|
|
188811
|
+
this.scope = prevScope.enterLoopRow(loop);
|
|
188825
188812
|
lines.push(`<%- ${sortedHoist} = ${sorted} -%>`);
|
|
188826
188813
|
}
|
|
188827
188814
|
if (loop.objectIteration) {
|
|
@@ -188867,13 +188854,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188867
188854
|
lines.push(...preambleLines);
|
|
188868
188855
|
lines.push(children);
|
|
188869
188856
|
}
|
|
188870
|
-
|
|
188871
|
-
const c = (this.loopBoundNames.get(n) ?? 1) - 1;
|
|
188872
|
-
if (c <= 0)
|
|
188873
|
-
this.loopBoundNames.delete(n);
|
|
188874
|
-
else
|
|
188875
|
-
this.loopBoundNames.set(n, c);
|
|
188876
|
-
}
|
|
188857
|
+
this.scope = prevScope;
|
|
188877
188858
|
lines.push(`<%- end -%>`);
|
|
188878
188859
|
lines.push(`<%= bf.comment("/loop:${loop.markerId}") %>`);
|
|
188879
188860
|
return lines.join(`
|
|
@@ -189035,7 +189016,7 @@ ${children}`;
|
|
|
189035
189016
|
if (ternaryHash !== null) {
|
|
189036
189017
|
return `<%= bf.spread_attrs(${ternaryHash}) %>`;
|
|
189037
189018
|
}
|
|
189038
|
-
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.
|
|
189019
|
+
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
|
|
189039
189020
|
const localConst = this.localConstants.find((c) => c.name === trimmed && !c.isModule);
|
|
189040
189021
|
if (localConst?.value !== undefined) {
|
|
189041
189022
|
const initTrimmed = localConst.value.trim();
|
|
@@ -189236,7 +189217,7 @@ Options:
|
|
|
189236
189217
|
_isStringValueName(name) {
|
|
189237
189218
|
return this.stringValueNames.has(name);
|
|
189238
189219
|
}
|
|
189239
|
-
_recordExprBF101(message, reason) {
|
|
189220
|
+
_recordExprBF101(message, reason, escape) {
|
|
189240
189221
|
this.errors.push({
|
|
189241
189222
|
code: "BF101",
|
|
189242
189223
|
severity: "error",
|
|
@@ -189249,7 +189230,8 @@ Options:
|
|
|
189249
189230
|
1. Use /* @client */ for client-side evaluation
|
|
189250
189231
|
2. Pre-compute the value in Ruby` : `Options:
|
|
189251
189232
|
1. Use /* @client */ for client-side evaluation
|
|
189252
|
-
2. Pre-compute the value in Ruby
|
|
189233
|
+
2. Pre-compute the value in Ruby`,
|
|
189234
|
+
...escape ? { escape } : {}
|
|
189253
189235
|
}
|
|
189254
189236
|
});
|
|
189255
189237
|
}
|
|
@@ -189273,14 +189255,20 @@ var conformancePins = {
|
|
|
189273
189255
|
"tag-cloud": [{ code: "BF021", severity: "error" }],
|
|
189274
189256
|
"preamble-cells": [{ code: "BF021", severity: "error" }],
|
|
189275
189257
|
"static-array-from-props": [
|
|
189276
|
-
{
|
|
189258
|
+
{
|
|
189259
|
+
code: "BF101",
|
|
189260
|
+
severity: "error",
|
|
189261
|
+
issue: "https://github.com/piconic-ai/barefootjs/issues/2321"
|
|
189262
|
+
}
|
|
189277
189263
|
],
|
|
189278
189264
|
"static-array-from-props-with-component": [
|
|
189279
|
-
{
|
|
189280
|
-
|
|
189281
|
-
|
|
189282
|
-
|
|
189265
|
+
{
|
|
189266
|
+
code: "BF101",
|
|
189267
|
+
severity: "error",
|
|
189268
|
+
issue: "https://github.com/piconic-ai/barefootjs/issues/2321"
|
|
189269
|
+
}
|
|
189283
189270
|
],
|
|
189271
|
+
"filter-nested-find-predicate": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }],
|
|
189284
189272
|
"date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }]
|
|
189285
189273
|
};
|
|
189286
189274
|
// src/render-divergences.ts
|