@barefootjs/rust 0.32.0 → 0.33.1
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/emit-context.d.ts +4 -1
- package/dist/adapter/emit-context.d.ts.map +1 -1
- package/dist/adapter/expr/emitters.d.ts +1 -1
- package/dist/adapter/expr/emitters.d.ts.map +1 -1
- package/dist/adapter/index.js +23 -6
- package/dist/adapter/lib/minijinja-naming.d.ts +7 -0
- package/dist/adapter/lib/minijinja-naming.d.ts.map +1 -1
- package/dist/adapter/memo/seed.d.ts.map +1 -1
- package/dist/adapter/minijinja-adapter.d.ts.map +1 -1
- package/dist/adapter/spread/spread-codegen.d.ts.map +1 -1
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +27 -12
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +99 -43
- package/package.json +5 -5
- package/runtime/src/evaluator.rs +18 -0
- package/src/adapter/emit-context.ts +4 -1
- package/src/adapter/expr/emitters.ts +40 -12
- package/src/adapter/lib/minijinja-naming.ts +1 -1
- package/src/adapter/memo/seed.ts +2 -1
- package/src/adapter/minijinja-adapter.ts +8 -3
- package/src/adapter/spread/spread-codegen.ts +4 -0
- package/src/conformance-pins.ts +7 -0
- package/src/render-divergences.ts +7 -8
|
@@ -89,8 +89,11 @@ export interface JinjaMemoContext {
|
|
|
89
89
|
/**
|
|
90
90
|
* Lower a JS expression to its Jinja form (the core recursive entry). See
|
|
91
91
|
* `JinjaSpreadContext.convertExpressionToJinja` for the `preParsed` contract.
|
|
92
|
+
* `pos` (default `'rendered'`) must be `'value'` for a derived-seed RHS —
|
|
93
|
+
* an assignment, not a render — so the internal support gate matches the
|
|
94
|
+
* `isSupportedValue` classification the seed plan already used.
|
|
92
95
|
*/
|
|
93
|
-
convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string;
|
|
96
|
+
convertExpressionToJinja(expr: string, preParsed?: ParsedExpr, pos?: 'rendered' | 'value'): string;
|
|
94
97
|
/**
|
|
95
98
|
* Per-compile diagnostic list `convertExpressionToJinja` appends to on an
|
|
96
99
|
* unsupported shape (`_recordExprBF101`). `memo/seed.ts`'s
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEtD,oFAAoF;IACpF,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEjD;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAE3E,wDAAwD;IACxD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExD,yEAAyE;IACzE,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;IAEhC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAErD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAExC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B
|
|
1
|
+
{"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEtD,oFAAoF;IACpF,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEjD;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAE3E,wDAAwD;IACxD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExD,yEAAyE;IACzE,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;IAEhC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAErD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAExC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAA;IAElG;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CACjC"}
|
|
@@ -138,6 +138,6 @@ export declare class JinjaTopLevelEmitter implements ParsedExprEmitter {
|
|
|
138
138
|
arrow(_params: string[], _body: ParsedExpr): string;
|
|
139
139
|
regex(_raw: string): string;
|
|
140
140
|
unsupported(_raw: string, _reason: string): string;
|
|
141
|
-
objectLiteral(properties: ObjectLiteralProperty[],
|
|
141
|
+
objectLiteral(properties: ObjectLiteralProperty[], raw: string, emit: (e: ParsedExpr) => string): string;
|
|
142
142
|
}
|
|
143
143
|
//# sourceMappingURL=emitters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -187297,6 +187297,7 @@ import {
|
|
|
187297
187297
|
parseProviderObjectLiteral,
|
|
187298
187298
|
parseStyleObjectEntries,
|
|
187299
187299
|
isSupported,
|
|
187300
|
+
isSupportedValue,
|
|
187300
187301
|
emitParsedExpr,
|
|
187301
187302
|
emitIRNode,
|
|
187302
187303
|
emitAttrValue,
|
|
@@ -188050,8 +188051,22 @@ class JinjaTopLevelEmitter {
|
|
|
188050
188051
|
unsupported(_raw, _reason) {
|
|
188051
188052
|
return "''";
|
|
188052
188053
|
}
|
|
188053
|
-
objectLiteral(properties,
|
|
188054
|
-
|
|
188054
|
+
objectLiteral(properties, raw, emit) {
|
|
188055
|
+
if (properties.length === 0)
|
|
188056
|
+
return "{}";
|
|
188057
|
+
if (!properties.some((p) => p.kind === "spread")) {
|
|
188058
|
+
return `{${properties.map((p) => p.kind === "prop" ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : "").join(", ")}}`;
|
|
188059
|
+
}
|
|
188060
|
+
const [first, ...rest] = properties;
|
|
188061
|
+
const kwargSafe = (p) => p.keyKind !== "numeric" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !RESERVED_WORDS.has(p.key);
|
|
188062
|
+
const shapeOk = first.kind === "spread" && rest.every((p) => p.kind === "prop" && kwargSafe(p));
|
|
188063
|
+
if (!shapeOk) {
|
|
188064
|
+
this.ctx._recordExprBF101(`Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`, `Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`);
|
|
188065
|
+
return "''";
|
|
188066
|
+
}
|
|
188067
|
+
const kwargs = rest.map((p) => `${p.key}=${emit(p.value)}`);
|
|
188068
|
+
const base = emit(first.expr);
|
|
188069
|
+
return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(", ")})`;
|
|
188055
188070
|
}
|
|
188056
188071
|
}
|
|
188057
188072
|
|
|
@@ -188165,6 +188180,8 @@ function objectLiteralExprToJinjaDict(ctx, expr) {
|
|
|
188165
188180
|
function objectLiteralToJinjaDict(ctx, obj) {
|
|
188166
188181
|
const entries = [];
|
|
188167
188182
|
for (const prop of obj.properties) {
|
|
188183
|
+
if (prop.kind === "spread")
|
|
188184
|
+
return null;
|
|
188168
188185
|
if (prop.shorthand)
|
|
188169
188186
|
return null;
|
|
188170
188187
|
if (prop.keyKind === "numeric")
|
|
@@ -188240,7 +188257,7 @@ function generateDerivedMemoSeed(ctx, ir) {
|
|
|
188240
188257
|
continue;
|
|
188241
188258
|
const materialized = materializeGetterCalls(step.parsed, knownGetterNames);
|
|
188242
188259
|
const errorsBefore = ctx.errors.length;
|
|
188243
|
-
const jinja = ctx.convertExpressionToJinja("", materialized);
|
|
188260
|
+
const jinja = ctx.convertExpressionToJinja("", materialized, "value");
|
|
188244
188261
|
if (ctx.errors.length > errorsBefore) {
|
|
188245
188262
|
ctx.errors.length = errorsBefore;
|
|
188246
188263
|
continue;
|
|
@@ -189068,11 +189085,11 @@ ${reason}` : "";
|
|
|
189068
189085
|
}
|
|
189069
189086
|
get memoCtx() {
|
|
189070
189087
|
return {
|
|
189071
|
-
convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
|
|
189088
|
+
convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
|
|
189072
189089
|
errors: this.errors
|
|
189073
189090
|
};
|
|
189074
189091
|
}
|
|
189075
|
-
convertExpressionToJinja(expr, preParsed) {
|
|
189092
|
+
convertExpressionToJinja(expr, preParsed, pos = "rendered") {
|
|
189076
189093
|
let parsed;
|
|
189077
189094
|
if (preParsed) {
|
|
189078
189095
|
parsed = preParsed;
|
|
@@ -189095,7 +189112,7 @@ ${reason}` : "";
|
|
|
189095
189112
|
}
|
|
189096
189113
|
}
|
|
189097
189114
|
}
|
|
189098
|
-
const support = isSupported(parsed);
|
|
189115
|
+
const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
|
|
189099
189116
|
if (!support.supported) {
|
|
189100
189117
|
this.errors.push({
|
|
189101
189118
|
code: "BF101",
|
|
@@ -52,6 +52,13 @@ export declare function escapeMinijinjaSingleQuoted(s: string): string;
|
|
|
52
52
|
* become a variable lookup instead of a string key.
|
|
53
53
|
*/
|
|
54
54
|
export declare function minijinjaHashKey(name: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Python reserved words (the plan's list) that must not appear as a bare
|
|
57
|
+
* Jinja identifier — see the file header. Kept as the single source of
|
|
58
|
+
* truth, IDENTICAL to adapter-jinja's set; the Rust runtime's
|
|
59
|
+
* `mangle_ident` mirrors this exact set.
|
|
60
|
+
*/
|
|
61
|
+
export declare const RESERVED_WORDS: Set<string>;
|
|
55
62
|
/**
|
|
56
63
|
* Mangle a JS identifier (prop name, signal getter, loop param, …) into a
|
|
57
64
|
* Jinja-safe variable name: reserved words get a trailing `_` suffix,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minijinja-naming.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/minijinja-naming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;
|
|
1
|
+
{"version":3,"file":"minijinja-naming.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/minijinja-naming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,aAKzB,CAAA;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/adapter/memo/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EAIrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAI1D,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/adapter/memo/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EAIrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAI1D,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM,CAuBtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiHG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spread-codegen.d.ts","sourceRoot":"","sources":["../../../src/adapter/spread/spread-codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAG5D;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAcf;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAGf;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC,GACnD,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"spread-codegen.d.ts","sourceRoot":"","sources":["../../../src/adapter/spread/spread-codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAG5D;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAcf;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAGf;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC,GACnD,MAAM,GAAG,IAAI,CA8Cf;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAuBhG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;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;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAuD7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -187297,6 +187297,7 @@ import {
|
|
|
187297
187297
|
parseProviderObjectLiteral,
|
|
187298
187298
|
parseStyleObjectEntries,
|
|
187299
187299
|
isSupported,
|
|
187300
|
+
isSupportedValue,
|
|
187300
187301
|
emitParsedExpr,
|
|
187301
187302
|
emitIRNode,
|
|
187302
187303
|
emitAttrValue,
|
|
@@ -188050,8 +188051,22 @@ class JinjaTopLevelEmitter {
|
|
|
188050
188051
|
unsupported(_raw, _reason) {
|
|
188051
188052
|
return "''";
|
|
188052
188053
|
}
|
|
188053
|
-
objectLiteral(properties,
|
|
188054
|
-
|
|
188054
|
+
objectLiteral(properties, raw, emit) {
|
|
188055
|
+
if (properties.length === 0)
|
|
188056
|
+
return "{}";
|
|
188057
|
+
if (!properties.some((p) => p.kind === "spread")) {
|
|
188058
|
+
return `{${properties.map((p) => p.kind === "prop" ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : "").join(", ")}}`;
|
|
188059
|
+
}
|
|
188060
|
+
const [first, ...rest] = properties;
|
|
188061
|
+
const kwargSafe = (p) => p.keyKind !== "numeric" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !RESERVED_WORDS.has(p.key);
|
|
188062
|
+
const shapeOk = first.kind === "spread" && rest.every((p) => p.kind === "prop" && kwargSafe(p));
|
|
188063
|
+
if (!shapeOk) {
|
|
188064
|
+
this.ctx._recordExprBF101(`Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`, `Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`);
|
|
188065
|
+
return "''";
|
|
188066
|
+
}
|
|
188067
|
+
const kwargs = rest.map((p) => `${p.key}=${emit(p.value)}`);
|
|
188068
|
+
const base = emit(first.expr);
|
|
188069
|
+
return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(", ")})`;
|
|
188055
188070
|
}
|
|
188056
188071
|
}
|
|
188057
188072
|
|
|
@@ -188165,6 +188180,8 @@ function objectLiteralExprToJinjaDict(ctx, expr) {
|
|
|
188165
188180
|
function objectLiteralToJinjaDict(ctx, obj) {
|
|
188166
188181
|
const entries = [];
|
|
188167
188182
|
for (const prop of obj.properties) {
|
|
188183
|
+
if (prop.kind === "spread")
|
|
188184
|
+
return null;
|
|
188168
188185
|
if (prop.shorthand)
|
|
188169
188186
|
return null;
|
|
188170
188187
|
if (prop.keyKind === "numeric")
|
|
@@ -188240,7 +188257,7 @@ function generateDerivedMemoSeed(ctx, ir) {
|
|
|
188240
188257
|
continue;
|
|
188241
188258
|
const materialized = materializeGetterCalls(step.parsed, knownGetterNames);
|
|
188242
188259
|
const errorsBefore = ctx.errors.length;
|
|
188243
|
-
const jinja = ctx.convertExpressionToJinja("", materialized);
|
|
188260
|
+
const jinja = ctx.convertExpressionToJinja("", materialized, "value");
|
|
188244
188261
|
if (ctx.errors.length > errorsBefore) {
|
|
188245
188262
|
ctx.errors.length = errorsBefore;
|
|
188246
188263
|
continue;
|
|
@@ -189068,11 +189085,11 @@ ${reason}` : "";
|
|
|
189068
189085
|
}
|
|
189069
189086
|
get memoCtx() {
|
|
189070
189087
|
return {
|
|
189071
|
-
convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
|
|
189088
|
+
convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
|
|
189072
189089
|
errors: this.errors
|
|
189073
189090
|
};
|
|
189074
189091
|
}
|
|
189075
|
-
convertExpressionToJinja(expr, preParsed) {
|
|
189092
|
+
convertExpressionToJinja(expr, preParsed, pos = "rendered") {
|
|
189076
189093
|
let parsed;
|
|
189077
189094
|
if (preParsed) {
|
|
189078
189095
|
parsed = preParsed;
|
|
@@ -189095,7 +189112,7 @@ ${reason}` : "";
|
|
|
189095
189112
|
}
|
|
189096
189113
|
}
|
|
189097
189114
|
}
|
|
189098
|
-
const support = isSupported(parsed);
|
|
189115
|
+
const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
|
|
189099
189116
|
if (!support.supported) {
|
|
189100
189117
|
this.errors.push({
|
|
189101
189118
|
code: "BF101",
|
|
@@ -189245,14 +189262,12 @@ var conformancePins = {
|
|
|
189245
189262
|
],
|
|
189246
189263
|
"filter-nested-find-predicate": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }],
|
|
189247
189264
|
"date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }],
|
|
189248
|
-
"rich-prop-client-read": [{ code: "BF049", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2648" }]
|
|
189265
|
+
"rich-prop-client-read": [{ code: "BF049", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2648" }],
|
|
189266
|
+
"jsx-element-prop-ternary": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2667" }],
|
|
189267
|
+
"jsx-element-prop-array": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2667" }]
|
|
189249
189268
|
};
|
|
189250
189269
|
// src/render-divergences.ts
|
|
189251
|
-
var renderDivergences = {
|
|
189252
|
-
"todo-app": "the `todos` signal seeds from `(props.initialTodos ?? []).map(t => ({ ...t, editing: false }))` — a different-prop-derived `.map()` chain `extractSsrDefaults` cannot statically resolve, and `computeSsrSeedPlan` classifies it opaque (no in-template recompute), so it seeds `null`; the non-`/* @client */`-marked `{todos().length > 0 && ...}` toggle-all block SSRs as if there are zero todos regardless of `initialTodos` (https://github.com/piconic-ai/barefootjs/issues/2696)",
|
|
189253
|
-
"todo-app-ssr": "same root cause as `todo-app` (https://github.com/piconic-ai/barefootjs/issues/2696); this fixture's todo-list loop carries no `/* @client */` marker and minijinja's `{% for %}` over a null value renders zero rows rather than throwing, so it SSRs an empty `<ul class=\"todo-list\">` with the toggle-all controls also absent, regardless of `initialTodos`",
|
|
189254
|
-
"callback-param-shadows-prop": "the `first` signal seeds from `[{ a: 'p' }].map((title) => title.a).join(',')` — a constant expression `extractSsrDefaults` still cannot statically resolve (`.map()` is unsupported for any receiver) and, unlike the sibling `joined` memo's structurally similar chain, gets no in-template recompute (`computeSsrSeedPlan` classifies it opaque too); `<span>{first()}</span>` SSRs empty instead of `p` (https://github.com/piconic-ai/barefootjs/issues/2696)"
|
|
189255
|
-
};
|
|
189270
|
+
var renderDivergences = {};
|
|
189256
189271
|
export {
|
|
189257
189272
|
renderDivergences,
|
|
189258
189273
|
minijinjaAdapter,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAQxD,eAAO,MAAM,iBAAiB,EAAE,iBAAsB,CAAA"}
|
package/dist/vite.js
CHANGED
|
@@ -263,7 +263,7 @@ function convertNode(node, raw) {
|
|
|
263
263
|
}
|
|
264
264
|
if (n === undefined || Number.isNaN(n)) {
|
|
265
265
|
const parsedDepth = convertNode(depthNode, raw);
|
|
266
|
-
if (checkSupport(parsedDepth).supported) {
|
|
266
|
+
if (checkSupport(parsedDepth, "rendered").supported) {
|
|
267
267
|
depthExpr = parsedDepth;
|
|
268
268
|
flatDepth = 1;
|
|
269
269
|
} else {
|
|
@@ -357,10 +357,12 @@ function convertNode(node, raw) {
|
|
|
357
357
|
const k = objectLiteralKeyName(prop.name);
|
|
358
358
|
if (k === null)
|
|
359
359
|
return { kind: "unsupported", raw, reason: `Unsupported syntax: ${ts.SyntaxKind[node.kind]}` };
|
|
360
|
-
properties.push({ key: k.key, keyKind: k.keyKind, shorthand: false, value: convertNode(prop.initializer, raw) });
|
|
360
|
+
properties.push({ kind: "prop", key: k.key, keyKind: k.keyKind, shorthand: false, value: convertNode(prop.initializer, raw) });
|
|
361
361
|
} else if (ts.isShorthandPropertyAssignment(prop)) {
|
|
362
362
|
const key = prop.name.text;
|
|
363
|
-
properties.push({ key, keyKind: "identifier", shorthand: true, value: { kind: "identifier", name: key } });
|
|
363
|
+
properties.push({ kind: "prop", key, keyKind: "identifier", shorthand: true, value: { kind: "identifier", name: key } });
|
|
364
|
+
} else if (ts.isSpreadAssignment(prop)) {
|
|
365
|
+
properties.push({ kind: "spread", expr: convertNode(prop.expression, raw) });
|
|
364
366
|
} else {
|
|
365
367
|
return { kind: "unsupported", raw, reason: `Unsupported syntax: ${ts.SyntaxKind[node.kind]}` };
|
|
366
368
|
}
|
|
@@ -1040,14 +1042,26 @@ function getUnaryOperatorString(op) {
|
|
|
1040
1042
|
}
|
|
1041
1043
|
}
|
|
1042
1044
|
function isSupported(expr) {
|
|
1043
|
-
return checkSupport(expr);
|
|
1045
|
+
return checkSupport(expr, "rendered");
|
|
1044
1046
|
}
|
|
1045
|
-
function
|
|
1047
|
+
function isSupportedValue(expr) {
|
|
1048
|
+
return checkSupport(expr, "value");
|
|
1049
|
+
}
|
|
1050
|
+
function checkSupport(expr, pos) {
|
|
1046
1051
|
switch (expr.kind) {
|
|
1047
1052
|
case "unsupported":
|
|
1048
1053
|
return { supported: false, reason: expr.reason };
|
|
1049
|
-
case "object-literal":
|
|
1050
|
-
|
|
1054
|
+
case "object-literal": {
|
|
1055
|
+
if (pos !== "value") {
|
|
1056
|
+
return { supported: false, reason: "Unsupported syntax: ObjectLiteralExpression" };
|
|
1057
|
+
}
|
|
1058
|
+
for (const prop of expr.properties) {
|
|
1059
|
+
const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos);
|
|
1060
|
+
if (!propSupport.supported)
|
|
1061
|
+
return propSupport;
|
|
1062
|
+
}
|
|
1063
|
+
return { supported: true, level: "L2" };
|
|
1064
|
+
}
|
|
1051
1065
|
case "identifier":
|
|
1052
1066
|
return { supported: true, level: "L1" };
|
|
1053
1067
|
case "literal":
|
|
@@ -1057,7 +1071,7 @@ function checkSupport(expr) {
|
|
|
1057
1071
|
return { supported: false, reason: "Standalone arrow functions / regex literals are not supported" };
|
|
1058
1072
|
case "array-literal": {
|
|
1059
1073
|
for (const el of expr.elements) {
|
|
1060
|
-
const elSupport = checkSupport(el);
|
|
1074
|
+
const elSupport = checkSupport(el, pos);
|
|
1061
1075
|
if (!elSupport.supported)
|
|
1062
1076
|
return elSupport;
|
|
1063
1077
|
}
|
|
@@ -1070,16 +1084,16 @@ function checkSupport(expr) {
|
|
|
1070
1084
|
reason: `String.prototype.${expr.method} supports only a string pattern + string replacement (the regex form is deferred); use a string pattern or wrap the expression in /* @client */`
|
|
1071
1085
|
};
|
|
1072
1086
|
}
|
|
1073
|
-
const objSupport = checkSupport(expr.object);
|
|
1087
|
+
const objSupport = checkSupport(expr.object, pos);
|
|
1074
1088
|
if (!objSupport.supported)
|
|
1075
1089
|
return objSupport;
|
|
1076
1090
|
for (const arg of expr.args) {
|
|
1077
|
-
const argSupport = checkSupport(arg);
|
|
1091
|
+
const argSupport = checkSupport(arg, pos);
|
|
1078
1092
|
if (!argSupport.supported)
|
|
1079
1093
|
return argSupport;
|
|
1080
1094
|
}
|
|
1081
1095
|
if (expr.method === "flat" && expr.depthExpr) {
|
|
1082
|
-
const depthSupport = checkSupport(expr.depthExpr);
|
|
1096
|
+
const depthSupport = checkSupport(expr.depthExpr, pos);
|
|
1083
1097
|
if (!depthSupport.supported)
|
|
1084
1098
|
return depthSupport;
|
|
1085
1099
|
}
|
|
@@ -1088,10 +1102,10 @@ function checkSupport(expr) {
|
|
|
1088
1102
|
case "call": {
|
|
1089
1103
|
const cb = asCallbackMethodCall(expr);
|
|
1090
1104
|
if (cb) {
|
|
1091
|
-
const objSupport = checkSupport(cb.object);
|
|
1105
|
+
const objSupport = checkSupport(cb.object, pos);
|
|
1092
1106
|
if (!objSupport.supported)
|
|
1093
1107
|
return objSupport;
|
|
1094
|
-
const bodySupport = checkSupport(cb.arrow.body);
|
|
1108
|
+
const bodySupport = checkSupport(cb.arrow.body, pos);
|
|
1095
1109
|
if (!bodySupport.supported) {
|
|
1096
1110
|
return {
|
|
1097
1111
|
supported: false,
|
|
@@ -1100,13 +1114,13 @@ function checkSupport(expr) {
|
|
|
1100
1114
|
};
|
|
1101
1115
|
}
|
|
1102
1116
|
for (const rest of cb.args) {
|
|
1103
|
-
const restSupport = checkSupport(rest);
|
|
1117
|
+
const restSupport = checkSupport(rest, pos);
|
|
1104
1118
|
if (!restSupport.supported)
|
|
1105
1119
|
return restSupport;
|
|
1106
1120
|
}
|
|
1107
1121
|
return { supported: true, level: "L5" };
|
|
1108
1122
|
}
|
|
1109
|
-
const calleeSupport = checkSupport(expr.callee);
|
|
1123
|
+
const calleeSupport = checkSupport(expr.callee, pos);
|
|
1110
1124
|
if (!calleeSupport.supported) {
|
|
1111
1125
|
return calleeSupport;
|
|
1112
1126
|
}
|
|
@@ -1125,7 +1139,7 @@ function checkSupport(expr) {
|
|
|
1125
1139
|
return { supported: true, level: "L1" };
|
|
1126
1140
|
}
|
|
1127
1141
|
for (const arg of expr.args) {
|
|
1128
|
-
const argSupport = checkSupport(arg);
|
|
1142
|
+
const argSupport = checkSupport(arg, pos);
|
|
1129
1143
|
if (!argSupport.supported) {
|
|
1130
1144
|
return argSupport;
|
|
1131
1145
|
}
|
|
@@ -1133,7 +1147,7 @@ function checkSupport(expr) {
|
|
|
1133
1147
|
return { supported: true, level: "L2" };
|
|
1134
1148
|
}
|
|
1135
1149
|
case "member": {
|
|
1136
|
-
const objSupport = checkSupport(expr.object);
|
|
1150
|
+
const objSupport = checkSupport(expr.object, pos);
|
|
1137
1151
|
if (!objSupport.supported) {
|
|
1138
1152
|
return objSupport;
|
|
1139
1153
|
}
|
|
@@ -1143,19 +1157,19 @@ function checkSupport(expr) {
|
|
|
1143
1157
|
return { supported: true, level: "L2" };
|
|
1144
1158
|
}
|
|
1145
1159
|
case "index-access": {
|
|
1146
|
-
const objSupport = checkSupport(expr.object);
|
|
1160
|
+
const objSupport = checkSupport(expr.object, pos);
|
|
1147
1161
|
if (!objSupport.supported)
|
|
1148
1162
|
return objSupport;
|
|
1149
|
-
const indexSupport = checkSupport(expr.index);
|
|
1163
|
+
const indexSupport = checkSupport(expr.index, pos);
|
|
1150
1164
|
if (!indexSupport.supported)
|
|
1151
1165
|
return indexSupport;
|
|
1152
1166
|
return { supported: true, level: "L2" };
|
|
1153
1167
|
}
|
|
1154
1168
|
case "binary": {
|
|
1155
|
-
const leftSupport = checkSupport(expr.left);
|
|
1169
|
+
const leftSupport = checkSupport(expr.left, pos);
|
|
1156
1170
|
if (!leftSupport.supported)
|
|
1157
1171
|
return leftSupport;
|
|
1158
|
-
const rightSupport = checkSupport(expr.right);
|
|
1172
|
+
const rightSupport = checkSupport(expr.right, pos);
|
|
1159
1173
|
if (!rightSupport.supported)
|
|
1160
1174
|
return rightSupport;
|
|
1161
1175
|
if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].includes(expr.op)) {
|
|
@@ -1167,7 +1181,7 @@ function checkSupport(expr) {
|
|
|
1167
1181
|
return { supported: false, reason: `Unknown operator: ${expr.op}` };
|
|
1168
1182
|
}
|
|
1169
1183
|
case "unary": {
|
|
1170
|
-
const argSupport = checkSupport(expr.argument);
|
|
1184
|
+
const argSupport = checkSupport(expr.argument, pos);
|
|
1171
1185
|
if (!argSupport.supported)
|
|
1172
1186
|
return argSupport;
|
|
1173
1187
|
if (expr.op === "!") {
|
|
@@ -1179,25 +1193,25 @@ function checkSupport(expr) {
|
|
|
1179
1193
|
return { supported: false, reason: `Unsupported unary operator: ${expr.op}` };
|
|
1180
1194
|
}
|
|
1181
1195
|
case "logical": {
|
|
1182
|
-
const leftSupport = checkSupport(expr.left);
|
|
1196
|
+
const leftSupport = checkSupport(expr.left, pos);
|
|
1183
1197
|
if (!leftSupport.supported)
|
|
1184
1198
|
return leftSupport;
|
|
1185
1199
|
if (expr.op === "??" && expr.right.kind === "object-literal" && expr.right.properties.length === 0) {
|
|
1186
1200
|
return { supported: true, level: "L4" };
|
|
1187
1201
|
}
|
|
1188
|
-
const rightSupport = checkSupport(expr.right);
|
|
1202
|
+
const rightSupport = checkSupport(expr.right, pos);
|
|
1189
1203
|
if (!rightSupport.supported)
|
|
1190
1204
|
return rightSupport;
|
|
1191
1205
|
return { supported: true, level: "L4" };
|
|
1192
1206
|
}
|
|
1193
1207
|
case "conditional": {
|
|
1194
|
-
const testSupport = checkSupport(expr.test);
|
|
1208
|
+
const testSupport = checkSupport(expr.test, pos);
|
|
1195
1209
|
if (!testSupport.supported)
|
|
1196
1210
|
return testSupport;
|
|
1197
|
-
const consSupport = checkSupport(expr.consequent);
|
|
1211
|
+
const consSupport = checkSupport(expr.consequent, pos);
|
|
1198
1212
|
if (!consSupport.supported)
|
|
1199
1213
|
return consSupport;
|
|
1200
|
-
const altSupport = checkSupport(expr.alternate);
|
|
1214
|
+
const altSupport = checkSupport(expr.alternate, pos);
|
|
1201
1215
|
if (!altSupport.supported)
|
|
1202
1216
|
return altSupport;
|
|
1203
1217
|
return { supported: true, level: "L4" };
|
|
@@ -1205,7 +1219,7 @@ function checkSupport(expr) {
|
|
|
1205
1219
|
case "template-literal": {
|
|
1206
1220
|
for (const part of expr.parts) {
|
|
1207
1221
|
if (part.type === "expression") {
|
|
1208
|
-
const partSupport = checkSupport(part.expr);
|
|
1222
|
+
const partSupport = checkSupport(part.expr, pos);
|
|
1209
1223
|
if (!partSupport.supported)
|
|
1210
1224
|
return partSupport;
|
|
1211
1225
|
}
|
|
@@ -1321,7 +1335,7 @@ function isPureInit(e, pureCallNames) {
|
|
|
1321
1335
|
case "array-literal":
|
|
1322
1336
|
return e.elements.every(pure);
|
|
1323
1337
|
case "object-literal":
|
|
1324
|
-
return e.properties.every((p) => pure(p.value));
|
|
1338
|
+
return e.properties.every((p) => pure(p.kind === "spread" ? p.expr : p.value));
|
|
1325
1339
|
case "call":
|
|
1326
1340
|
return e.callee.kind === "identifier" && e.args.length === 0 && pureCallNames !== undefined && pureCallNames.has(e.callee.name);
|
|
1327
1341
|
case "array-method":
|
|
@@ -1375,7 +1389,7 @@ function usesPerPath(name, expr) {
|
|
|
1375
1389
|
}
|
|
1376
1390
|
return add(walk(e.object), sum(e.args));
|
|
1377
1391
|
case "object-literal":
|
|
1378
|
-
return sum(e.properties.map((p) => p.value));
|
|
1392
|
+
return sum(e.properties.map((p) => p.kind === "spread" ? p.expr : p.value));
|
|
1379
1393
|
case "arrow":
|
|
1380
1394
|
return walk(e.body).max > 0 ? { min: 0, max: Number.POSITIVE_INFINITY } : { min: 0, max: 0 };
|
|
1381
1395
|
}
|
|
@@ -1441,7 +1455,7 @@ function inlineBinding(expr, name, value) {
|
|
|
1441
1455
|
case "object-literal":
|
|
1442
1456
|
return {
|
|
1443
1457
|
kind: "object-literal",
|
|
1444
|
-
properties: e.properties.map((p) => ({ ...p, value: walk(p.value, enclosing) })
|
|
1458
|
+
properties: e.properties.map((p) => p.kind === "spread" ? { ...p, expr: walk(p.expr, enclosing) } : { ...p, value: walk(p.value, enclosing) }),
|
|
1445
1459
|
raw: e.raw
|
|
1446
1460
|
};
|
|
1447
1461
|
case "literal":
|
|
@@ -1651,7 +1665,7 @@ function materializeGetterCalls(expr, names) {
|
|
|
1651
1665
|
return {
|
|
1652
1666
|
kind: "object-literal",
|
|
1653
1667
|
raw: expr.raw,
|
|
1654
|
-
properties: expr.properties.map((p) => ({ ...p, value: rw(p.value) })
|
|
1668
|
+
properties: expr.properties.map((p) => p.kind === "spread" ? { ...p, expr: rw(p.expr) } : { ...p, value: rw(p.value) })
|
|
1655
1669
|
};
|
|
1656
1670
|
case "arrow":
|
|
1657
1671
|
return { kind: "arrow", params: expr.params, body: rw(expr.body) };
|
|
@@ -1709,7 +1723,7 @@ function freeVarsInBody(body, params) {
|
|
|
1709
1723
|
return;
|
|
1710
1724
|
case "object-literal":
|
|
1711
1725
|
for (const p of e.properties)
|
|
1712
|
-
visit(p.value, bound);
|
|
1726
|
+
visit(p.kind === "spread" ? p.expr : p.value, bound);
|
|
1713
1727
|
return;
|
|
1714
1728
|
case "array-method":
|
|
1715
1729
|
if (e.method === "includes" || e.method === "join") {
|
|
@@ -1784,7 +1798,7 @@ function freeIdentifiers(expr) {
|
|
|
1784
1798
|
return true;
|
|
1785
1799
|
case "object-literal":
|
|
1786
1800
|
for (const p of e.properties)
|
|
1787
|
-
if (!visit(p.value, bound))
|
|
1801
|
+
if (!visit(p.kind === "spread" ? p.expr : p.value, bound))
|
|
1788
1802
|
return false;
|
|
1789
1803
|
return true;
|
|
1790
1804
|
case "arrow": {
|
|
@@ -1931,10 +1945,17 @@ function toEvalNode(e) {
|
|
|
1931
1945
|
case "object-literal": {
|
|
1932
1946
|
const properties = [];
|
|
1933
1947
|
for (const p of e.properties) {
|
|
1948
|
+
if (p.kind === "spread") {
|
|
1949
|
+
const spreadExpr = toEvalNode(p.expr);
|
|
1950
|
+
if (!spreadExpr)
|
|
1951
|
+
return null;
|
|
1952
|
+
properties.push({ kind: "spread", expr: spreadExpr });
|
|
1953
|
+
continue;
|
|
1954
|
+
}
|
|
1934
1955
|
const value = toEvalNode(p.value);
|
|
1935
1956
|
if (!value)
|
|
1936
1957
|
return null;
|
|
1937
|
-
properties.push({ key: p.key, value });
|
|
1958
|
+
properties.push({ kind: "prop", key: p.key, value });
|
|
1938
1959
|
}
|
|
1939
1960
|
return { kind: "object-literal", properties };
|
|
1940
1961
|
}
|
|
@@ -2304,6 +2325,7 @@ var ErrorCodes = {
|
|
|
2304
2325
|
MISSING_KEY_IN_LIST: "BF023",
|
|
2305
2326
|
MISSING_KEY_IN_NESTED_LIST: "BF024",
|
|
2306
2327
|
UNSUPPORTED_DESTRUCTURE_REST: "BF025",
|
|
2328
|
+
RETURN_VALUE_NOT_JSX: "BF027",
|
|
2307
2329
|
PROPS_DESTRUCTURING: "BF043",
|
|
2308
2330
|
SIGNAL_GETTER_NOT_CALLED: "BF044",
|
|
2309
2331
|
JSX_IN_LOCAL_FUNCTION: "BF045",
|
|
@@ -2335,6 +2357,7 @@ var errorMessages = {
|
|
|
2335
2357
|
[ErrorCodes.MISSING_KEY_IN_LIST]: "Missing key attribute in list rendering. Add a key prop for efficient updates",
|
|
2336
2358
|
[ErrorCodes.MISSING_KEY_IN_NESTED_LIST]: "Nested .map() loop requires key attribute for event delegation. Add a key prop to elements in the inner loop",
|
|
2337
2359
|
[ErrorCodes.UNSUPPORTED_DESTRUCTURE_REST]: "Computed property key in .map() callback destructure is not supported. Rewrite the callback to destructure explicit bindings (e.g., `({ a, b }) => ...`) so the compiler can rewrite references to per-item signal accessors.",
|
|
2360
|
+
[ErrorCodes.RETURN_VALUE_NOT_JSX]: "Component's return value is not recognized as JSX — return the JSX expression directly instead of binding it to a local variable first.",
|
|
2338
2361
|
[ErrorCodes.PROPS_DESTRUCTURING]: "Props destructuring in function parameters breaks reactivity. Use props object directly.",
|
|
2339
2362
|
[ErrorCodes.SIGNAL_GETTER_NOT_CALLED]: "Signal/memo getter passed without calling it. Use getter() to read the value.",
|
|
2340
2363
|
[ErrorCodes.JSX_IN_LOCAL_FUNCTION]: "Local function returns JSX but cannot be inlined. Extract it as a top-level PascalCase component or use a single return statement.",
|
|
@@ -2967,6 +2990,8 @@ function matchToLocaleDateStringCall(callee, args, metadata) {
|
|
|
2967
2990
|
let tz = null;
|
|
2968
2991
|
const probeOptions = {};
|
|
2969
2992
|
for (const prop of options.properties) {
|
|
2993
|
+
if (prop.kind === "spread")
|
|
2994
|
+
return null;
|
|
2970
2995
|
if (prop.value.kind !== "literal" || prop.value.literalType !== "string")
|
|
2971
2996
|
return null;
|
|
2972
2997
|
const value = String(prop.value.value);
|
|
@@ -3957,7 +3982,7 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
|
|
|
3957
3982
|
|
|
3958
3983
|
// ../jsx/src/ssr-seed-plan.ts
|
|
3959
3984
|
function classify(name, origin, expr, parsed, available) {
|
|
3960
|
-
if (!
|
|
3985
|
+
if (!isSupportedValue(parsed).supported)
|
|
3961
3986
|
return { kind: "opaque", name, origin };
|
|
3962
3987
|
const frees = freeIdentifiers(parsed);
|
|
3963
3988
|
if (frees === null)
|
|
@@ -4020,7 +4045,7 @@ function computeSsrSeedPlan(metadata) {
|
|
|
4020
4045
|
}
|
|
4021
4046
|
}
|
|
4022
4047
|
const expr = signal.initialValue.trim();
|
|
4023
|
-
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(parseExpression(expr), localConsts), available));
|
|
4048
|
+
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(signal.parsed ?? parseExpression(`(${expr})`), localConsts), available));
|
|
4024
4049
|
available.add(signal.getter);
|
|
4025
4050
|
}
|
|
4026
4051
|
for (const memo of metadata.memos) {
|
|
@@ -4706,6 +4731,17 @@ function evaluateStaticLiteral(expr, bindings) {
|
|
|
4706
4731
|
case "object-literal": {
|
|
4707
4732
|
const out = {};
|
|
4708
4733
|
for (const prop of expr.properties) {
|
|
4734
|
+
if (prop.kind === "spread") {
|
|
4735
|
+
const resolved2 = evaluateStaticLiteral(prop.expr, bindings);
|
|
4736
|
+
if (!resolved2)
|
|
4737
|
+
return null;
|
|
4738
|
+
if (resolved2.value === null || resolved2.value === undefined)
|
|
4739
|
+
continue;
|
|
4740
|
+
if (typeof resolved2.value !== "object" || Array.isArray(resolved2.value))
|
|
4741
|
+
return null;
|
|
4742
|
+
Object.assign(out, resolved2.value);
|
|
4743
|
+
continue;
|
|
4744
|
+
}
|
|
4709
4745
|
const resolved = evaluateStaticLiteral(prop.value, bindings);
|
|
4710
4746
|
if (!resolved)
|
|
4711
4747
|
return null;
|
|
@@ -4772,6 +4808,8 @@ function matchQueryHrefCall(callee, args, localNames) {
|
|
|
4772
4808
|
return null;
|
|
4773
4809
|
const triples = [];
|
|
4774
4810
|
for (const p of obj.properties) {
|
|
4811
|
+
if (p.kind === "spread")
|
|
4812
|
+
return null;
|
|
4775
4813
|
const v = p.value;
|
|
4776
4814
|
if (v.kind === "conditional" && isOmitBranch(v.alternate)) {
|
|
4777
4815
|
triples.push({ guard: v.test, key: p.key, value: v.consequent });
|
|
@@ -4959,6 +4997,8 @@ function htmlPropValue(parsed) {
|
|
|
4959
4997
|
if (parsed.properties.length !== 1)
|
|
4960
4998
|
return null;
|
|
4961
4999
|
const [prop] = parsed.properties;
|
|
5000
|
+
if (prop.kind === "spread")
|
|
5001
|
+
return null;
|
|
4962
5002
|
if (prop.key !== "__html")
|
|
4963
5003
|
return null;
|
|
4964
5004
|
return prop.value;
|
|
@@ -5860,8 +5900,22 @@ class JinjaTopLevelEmitter {
|
|
|
5860
5900
|
unsupported(_raw, _reason) {
|
|
5861
5901
|
return "''";
|
|
5862
5902
|
}
|
|
5863
|
-
objectLiteral(properties,
|
|
5864
|
-
|
|
5903
|
+
objectLiteral(properties, raw, emit) {
|
|
5904
|
+
if (properties.length === 0)
|
|
5905
|
+
return "{}";
|
|
5906
|
+
if (!properties.some((p) => p.kind === "spread")) {
|
|
5907
|
+
return `{${properties.map((p) => p.kind === "prop" ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : "").join(", ")}}`;
|
|
5908
|
+
}
|
|
5909
|
+
const [first, ...rest] = properties;
|
|
5910
|
+
const kwargSafe = (p) => p.keyKind !== "numeric" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !RESERVED_WORDS2.has(p.key);
|
|
5911
|
+
const shapeOk = first.kind === "spread" && rest.every((p) => p.kind === "prop" && kwargSafe(p));
|
|
5912
|
+
if (!shapeOk) {
|
|
5913
|
+
this.ctx._recordExprBF101(`Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`, `Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`);
|
|
5914
|
+
return "''";
|
|
5915
|
+
}
|
|
5916
|
+
const kwargs = rest.map((p) => `${p.key}=${emit(p.value)}`);
|
|
5917
|
+
const base = emit(first.expr);
|
|
5918
|
+
return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(", ")})`;
|
|
5865
5919
|
}
|
|
5866
5920
|
}
|
|
5867
5921
|
|
|
@@ -5974,6 +6028,8 @@ function objectLiteralExprToJinjaDict(ctx, expr) {
|
|
|
5974
6028
|
function objectLiteralToJinjaDict(ctx, obj) {
|
|
5975
6029
|
const entries = [];
|
|
5976
6030
|
for (const prop of obj.properties) {
|
|
6031
|
+
if (prop.kind === "spread")
|
|
6032
|
+
return null;
|
|
5977
6033
|
if (prop.shorthand)
|
|
5978
6034
|
return null;
|
|
5979
6035
|
if (prop.keyKind === "numeric")
|
|
@@ -6044,7 +6100,7 @@ function generateDerivedMemoSeed(ctx, ir) {
|
|
|
6044
6100
|
continue;
|
|
6045
6101
|
const materialized = materializeGetterCalls(step.parsed, knownGetterNames);
|
|
6046
6102
|
const errorsBefore = ctx.errors.length;
|
|
6047
|
-
const jinja = ctx.convertExpressionToJinja("", materialized);
|
|
6103
|
+
const jinja = ctx.convertExpressionToJinja("", materialized, "value");
|
|
6048
6104
|
if (ctx.errors.length > errorsBefore) {
|
|
6049
6105
|
ctx.errors.length = errorsBefore;
|
|
6050
6106
|
continue;
|
|
@@ -6871,11 +6927,11 @@ ${reason}` : "";
|
|
|
6871
6927
|
}
|
|
6872
6928
|
get memoCtx() {
|
|
6873
6929
|
return {
|
|
6874
|
-
convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
|
|
6930
|
+
convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
|
|
6875
6931
|
errors: this.errors
|
|
6876
6932
|
};
|
|
6877
6933
|
}
|
|
6878
|
-
convertExpressionToJinja(expr, preParsed) {
|
|
6934
|
+
convertExpressionToJinja(expr, preParsed, pos = "rendered") {
|
|
6879
6935
|
let parsed;
|
|
6880
6936
|
if (preParsed) {
|
|
6881
6937
|
parsed = preParsed;
|
|
@@ -6898,7 +6954,7 @@ ${reason}` : "";
|
|
|
6898
6954
|
}
|
|
6899
6955
|
}
|
|
6900
6956
|
}
|
|
6901
|
-
const support = isSupported(parsed);
|
|
6957
|
+
const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
|
|
6902
6958
|
if (!support.supported) {
|
|
6903
6959
|
this.errors.push({
|
|
6904
6960
|
code: "BF101",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/rust",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.1",
|
|
4
4
|
"description": "minijinja (Rust) adapter for BarefootJS — compiles IR to .j2 templates and ships a Rust rendering runtime (packages/adapter-rust/runtime/); runs under any Rust web framework (axum, etc.)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"directory": "packages/adapter-rust"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@barefootjs/shared": "0.
|
|
57
|
+
"@barefootjs/shared": "0.33.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@barefootjs/jsx": ">=0.2.0",
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
74
|
-
"@barefootjs/jsx": "0.
|
|
75
|
-
"@barefootjs/vite": "0.
|
|
76
|
-
"@barefootjs/client": "0.
|
|
74
|
+
"@barefootjs/jsx": "0.33.1",
|
|
75
|
+
"@barefootjs/vite": "0.33.1",
|
|
76
|
+
"@barefootjs/client": "0.33.1",
|
|
77
77
|
"typescript": "^5.0.0",
|
|
78
78
|
"vite": "^6.0.0"
|
|
79
79
|
}
|
package/runtime/src/evaluator.rs
CHANGED
|
@@ -149,9 +149,27 @@ pub fn evaluate(node: &JsonValue, env: &Env) -> JsValue {
|
|
|
149
149
|
JsValue::Array(elements)
|
|
150
150
|
}
|
|
151
151
|
"object-literal" => {
|
|
152
|
+
// Each entry carries its own "kind" ("prop" | "spread", #2696
|
|
153
|
+
// Step 2) -- the same encoding the Go/Perl/Python/Ruby/PHP
|
|
154
|
+
// evaluators and the raw ParsedExpr shape the eval-vectors.json
|
|
155
|
+
// golden corpus carry. A "spread" evaluates its "expr" and
|
|
156
|
+
// shallow-merges the result's own keys (a non-Object result --
|
|
157
|
+
// including a null/undefined JS spread source -- is a no-op);
|
|
158
|
+
// a "prop" sets one key. Later entries win on a shared key, in
|
|
159
|
+
// source order, matching JS object-spread exactly.
|
|
152
160
|
let mut out = std::collections::BTreeMap::new();
|
|
153
161
|
if let Some(props) = node.get("properties").and_then(|v| v.as_array()) {
|
|
154
162
|
for prop in props {
|
|
163
|
+
let kind = prop.get("kind").and_then(|v| v.as_str()).unwrap_or("");
|
|
164
|
+
if kind == "spread" {
|
|
165
|
+
let spread = evaluate(prop.get("expr").unwrap_or(&JsonValue::Null), env);
|
|
166
|
+
if let JsValue::Object(spread_map) = spread {
|
|
167
|
+
for (k, v) in spread_map {
|
|
168
|
+
out.insert(k, v);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
155
173
|
let key = prop.get("key").and_then(|v| v.as_str()).unwrap_or("").to_string();
|
|
156
174
|
let value = evaluate(prop.get("value").unwrap_or(&JsonValue::Null), env);
|
|
157
175
|
out.insert(key, value);
|
|
@@ -101,8 +101,11 @@ export interface JinjaMemoContext {
|
|
|
101
101
|
/**
|
|
102
102
|
* Lower a JS expression to its Jinja form (the core recursive entry). See
|
|
103
103
|
* `JinjaSpreadContext.convertExpressionToJinja` for the `preParsed` contract.
|
|
104
|
+
* `pos` (default `'rendered'`) must be `'value'` for a derived-seed RHS —
|
|
105
|
+
* an assignment, not a render — so the internal support gate matches the
|
|
106
|
+
* `isSupportedValue` classification the seed plan already used.
|
|
104
107
|
*/
|
|
105
|
-
convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string
|
|
108
|
+
convertExpressionToJinja(expr: string, preParsed?: ParsedExpr, pos?: 'rendered' | 'value'): string
|
|
106
109
|
|
|
107
110
|
/**
|
|
108
111
|
* Per-compile diagnostic list `convertExpressionToJinja` appends to on an
|
|
@@ -64,7 +64,7 @@ import { groupBinaryOperand,
|
|
|
64
64
|
|
|
65
65
|
import type { JinjaEmitContext } from '../emit-context.ts'
|
|
66
66
|
import { JINJA_TEMPLATE_PRIMITIVES } from '../lib/constants.ts'
|
|
67
|
-
import { minijinjaIdent, escapeMinijinjaSingleQuoted } from '../lib/minijinja-naming.ts'
|
|
67
|
+
import { minijinjaIdent, escapeMinijinjaSingleQuoted, minijinjaHashKey, RESERVED_WORDS as MINIJINJA_KWARG_RESERVED } from '../lib/minijinja-naming.ts'
|
|
68
68
|
import { isBooleanResultParsed } from '../boolean-result.ts'
|
|
69
69
|
import {
|
|
70
70
|
renderArrayMethod,
|
|
@@ -623,16 +623,44 @@ export class JinjaTopLevelEmitter implements ParsedExprEmitter {
|
|
|
623
623
|
return "''"
|
|
624
624
|
}
|
|
625
625
|
|
|
626
|
-
objectLiteral(properties: ObjectLiteralProperty[],
|
|
627
|
-
//
|
|
628
|
-
//
|
|
629
|
-
//
|
|
630
|
-
//
|
|
631
|
-
// literal,
|
|
632
|
-
//
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
626
|
+
objectLiteral(properties: ObjectLiteralProperty[], raw: string, emit: (e: ParsedExpr) => string): string {
|
|
627
|
+
// Reachable here in VALUE position (a `.map()` receiver/callback body, an
|
|
628
|
+
// array-literal element, …) since `isSupportedValue` admits an object
|
|
629
|
+
// literal whose every property value is itself supported
|
|
630
|
+
// (expression-parser.ts, `checkSupport`'s `pos` parameter). Emit a
|
|
631
|
+
// minijinja dict literal, keyed the same way `objectLiteralToJinjaDict`
|
|
632
|
+
// quotes the spread-path literal.
|
|
633
|
+
if (properties.length === 0) return '{}'
|
|
634
|
+
if (!properties.some(p => p.kind === 'spread')) {
|
|
635
|
+
return `{${properties.map(p => (p.kind === 'prop' ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : '')).join(', ')}}`
|
|
636
|
+
}
|
|
637
|
+
// Spread (`{ ...t, editing: false }`, #2696 Step 2). minijinja's builtin
|
|
638
|
+
// `dict(value, **kwargs)` (functions.rs) merges kwargs OVER a base value
|
|
639
|
+
// — `None`/undefined bases to an empty map (JS's null/undefined-spread
|
|
640
|
+
// no-op, for free) — but minijinja has NO `**expr` unpack at call sites
|
|
641
|
+
// (`**` lexes only as the power operator), so the override side must be
|
|
642
|
+
// STATIC named kwargs. That expresses exactly ONE shape faithfully: a
|
|
643
|
+
// single spread FIRST, followed only by plain `prop` entries whose keys
|
|
644
|
+
// are valid bareword identifiers (a reserved word can't be a kwarg name
|
|
645
|
+
// either) — the todo-app motivating shape. Any other arrangement (a
|
|
646
|
+
// spread not first, two spreads, or a non-identifier prop key sharing an
|
|
647
|
+
// object with a spread) has no minijinja spelling — self-report BF101
|
|
648
|
+
// rather than silently dropping the unmergeable keys.
|
|
649
|
+
const [first, ...rest] = properties
|
|
650
|
+
const kwargSafe = (p: Extract<ObjectLiteralProperty, { kind: 'prop' }>) =>
|
|
651
|
+
p.keyKind !== 'numeric' && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !MINIJINJA_KWARG_RESERVED.has(p.key)
|
|
652
|
+
const shapeOk =
|
|
653
|
+
first.kind === 'spread' &&
|
|
654
|
+
rest.every(p => p.kind === 'prop' && kwargSafe(p))
|
|
655
|
+
if (!shapeOk) {
|
|
656
|
+
this.ctx._recordExprBF101(
|
|
657
|
+
`Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`,
|
|
658
|
+
`Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`,
|
|
659
|
+
)
|
|
660
|
+
return "''"
|
|
661
|
+
}
|
|
662
|
+
const kwargs = (rest as Extract<ObjectLiteralProperty, { kind: 'prop' }>[]).map(p => `${p.key}=${emit(p.value)}`)
|
|
663
|
+
const base = emit(first.expr)
|
|
664
|
+
return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(', ')})`
|
|
637
665
|
}
|
|
638
666
|
}
|
|
@@ -65,7 +65,7 @@ export function minijinjaHashKey(name: string): string {
|
|
|
65
65
|
* truth, IDENTICAL to adapter-jinja's set; the Rust runtime's
|
|
66
66
|
* `mangle_ident` mirrors this exact set.
|
|
67
67
|
*/
|
|
68
|
-
const RESERVED_WORDS = new Set([
|
|
68
|
+
export const RESERVED_WORDS = new Set([
|
|
69
69
|
'if', 'else', 'for', 'in', 'is', 'not', 'and', 'or', 'none', 'true', 'false',
|
|
70
70
|
'import', 'from', 'class', 'def', 'pass', 'del', 'return', 'lambda', 'global',
|
|
71
71
|
'with', 'as', 'raise', 'try', 'except', 'finally', 'while', 'break',
|
package/src/adapter/memo/seed.ts
CHANGED
|
@@ -123,7 +123,8 @@ export function generateDerivedMemoSeed(ctx: JinjaMemoContext, ir: ComponentIR):
|
|
|
123
123
|
if (step.kind !== 'derived') continue
|
|
124
124
|
const materialized = materializeGetterCalls(step.parsed, knownGetterNames)
|
|
125
125
|
const errorsBefore = ctx.errors.length
|
|
126
|
-
|
|
126
|
+
// `'value'` — this RHS is an assignment, not a render (#2696 review).
|
|
127
|
+
const jinja = ctx.convertExpressionToJinja('', materialized, 'value')
|
|
127
128
|
if (ctx.errors.length > errorsBefore) {
|
|
128
129
|
ctx.errors.length = errorsBefore
|
|
129
130
|
continue
|
|
@@ -149,6 +149,7 @@ import {
|
|
|
149
149
|
parseProviderObjectLiteral,
|
|
150
150
|
parseStyleObjectEntries,
|
|
151
151
|
isSupported,
|
|
152
|
+
isSupportedValue,
|
|
152
153
|
emitParsedExpr,
|
|
153
154
|
emitIRNode,
|
|
154
155
|
emitAttrValue,
|
|
@@ -1789,12 +1790,12 @@ export class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitter<Jinja
|
|
|
1789
1790
|
/** Build the narrow context the extracted memo seeding depends on. */
|
|
1790
1791
|
private get memoCtx(): JinjaMemoContext {
|
|
1791
1792
|
return {
|
|
1792
|
-
convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
|
|
1793
|
+
convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
|
|
1793
1794
|
errors: this.errors,
|
|
1794
1795
|
}
|
|
1795
1796
|
}
|
|
1796
1797
|
|
|
1797
|
-
private convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string {
|
|
1798
|
+
private convertExpressionToJinja(expr: string, preParsed?: ParsedExpr, pos: 'rendered' | 'value' = 'rendered'): string {
|
|
1798
1799
|
// Parse-first lowering — parity with the Xslate adapter's
|
|
1799
1800
|
// `convertExpressionToKolon`. Parse the JS expression once, gate it on the
|
|
1800
1801
|
// shared `isSupported`, and render every supported shape through the AST
|
|
@@ -1846,7 +1847,11 @@ export class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitter<Jinja
|
|
|
1846
1847
|
}
|
|
1847
1848
|
}
|
|
1848
1849
|
|
|
1849
|
-
|
|
1850
|
+
// `pos` distinguishes a derived-seed RHS (an assignment, checked via
|
|
1851
|
+
// `isSupportedValue`) from every other, genuinely rendered call site —
|
|
1852
|
+
// the rendered gate would otherwise re-refuse a tree the seed plan
|
|
1853
|
+
// already classified `derived` at value position (#2696 review).
|
|
1854
|
+
const support = pos === 'value' ? isSupportedValue(parsed) : isSupported(parsed)
|
|
1850
1855
|
if (!support.supported) {
|
|
1851
1856
|
this.errors.push({
|
|
1852
1857
|
code: 'BF101',
|
|
@@ -82,6 +82,10 @@ export function objectLiteralToJinjaDict(
|
|
|
82
82
|
): string | null {
|
|
83
83
|
const entries: string[] = []
|
|
84
84
|
for (const prop of obj.properties) {
|
|
85
|
+
// A spread (`{ ...t }`, #2696 Step 2) isn't a per-key entry this
|
|
86
|
+
// conditional-spread inline lowering can express — bail, same as any
|
|
87
|
+
// other unsupported shape (the caller falls back to the generic path).
|
|
88
|
+
if (prop.kind === 'spread') return null
|
|
85
89
|
// Shorthand `{ a }` was a `ShorthandPropertyAssignment` (not a
|
|
86
90
|
// `PropertyAssignment`), so the former parser rejected it — keep refusing.
|
|
87
91
|
if (prop.shorthand) return null
|
package/src/conformance-pins.ts
CHANGED
|
@@ -57,4 +57,11 @@ export const conformancePins: ConformancePins = {
|
|
|
57
57
|
// above is refused.
|
|
58
58
|
'date-method-uncatalogued': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2356' }],
|
|
59
59
|
'rich-prop-client-read': [{ code: 'BF049', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2648' }],
|
|
60
|
+
// #2667: a ternary/array LITERALLY WRAPPING JSX at a non-children prop
|
|
61
|
+
// position (e.g. `header={cond ? <a/> : <b/>}`) is refused ahead of
|
|
62
|
+
// `adapter.generate()` in the shared jsx-to-ir.ts phase, so it is pinned
|
|
63
|
+
// identically on every adapter (including Hono) — same reasoning as
|
|
64
|
+
// `rich-prop-client-read` above.
|
|
65
|
+
'jsx-element-prop-ternary': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2667' }],
|
|
66
|
+
'jsx-element-prop-array': [{ code: 'BF021', severity: 'error', issue: 'https://github.com/piconic-ai/barefootjs/issues/2667' }],
|
|
60
67
|
}
|
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
|
|
12
12
|
import type { RenderDivergences } from '@barefootjs/jsx'
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
14
|
+
// #2696 graduated: `todo-app` / `todo-app-ssr` seeded `todos` opaque
|
|
15
|
+
// because their `.map(t => ({ ...t, editing: false }))` callback body's
|
|
16
|
+
// object-literal SPREAD refused (`checkSupport`). Step 2 admits a spread
|
|
17
|
+
// at value position and the runtime evaluator's `object-literal` case
|
|
18
|
+
// now merges it, so the seed classifies `derived` and SSRs identically
|
|
19
|
+
// to Hono.
|
|
20
|
+
export const renderDivergences: RenderDivergences = {}
|