@barefootjs/go-template 0.31.10 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/emit-context.d.ts +16 -0
- package/dist/adapter/emit-context.d.ts.map +1 -1
- package/dist/adapter/expr/helper-inline.d.ts.map +1 -1
- package/dist/adapter/go-template-adapter.d.ts +75 -1
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +165 -15
- package/dist/adapter/lib/types.d.ts +13 -0
- package/dist/adapter/lib/types.d.ts.map +1 -1
- package/dist/adapter/memo/memo-compute.d.ts.map +1 -1
- package/dist/adapter/memo/memo-value.d.ts.map +1 -1
- package/dist/adapter/memo/template-interp.d.ts.map +1 -1
- package/dist/adapter/props/prop-types.d.ts.map +1 -1
- package/dist/adapter/spread/spread-codegen.d.ts.map +1 -1
- package/dist/adapter/value/parsed-literal-to-go.d.ts.map +1 -1
- package/dist/adapter/value/value-lowering.d.ts +15 -12
- package/dist/adapter/value/value-lowering.d.ts.map +1 -1
- package/dist/index.js +166 -17
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +259 -52
- package/package.json +5 -5
- package/src/__tests__/go-template-adapter.test.ts +246 -6
- package/src/adapter/emit-context.ts +14 -0
- package/src/adapter/expr/helper-inline.ts +4 -2
- package/src/adapter/go-template-adapter.ts +296 -9
- package/src/adapter/lib/types.ts +10 -0
- package/src/adapter/memo/memo-compute.ts +12 -1
- package/src/adapter/memo/memo-value.ts +3 -0
- package/src/adapter/memo/template-interp.ts +5 -0
- package/src/adapter/props/prop-types.ts +26 -1
- package/src/adapter/spread/spread-codegen.ts +8 -0
- package/src/adapter/value/parsed-literal-to-go.ts +7 -0
- package/src/adapter/value/value-lowering.ts +96 -22
- package/src/render-divergences.ts +2 -23
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spread-codegen.d.ts","sourceRoot":"","sources":["../../../src/adapter/spread/spread-codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EAQN,UAAU,EACX,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGrD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAIrF;
|
|
1
|
+
{"version":3,"file":"spread-codegen.d.ts","sourceRoot":"","sources":["../../../src/adapter/spread/spread-codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EAQN,UAAU,EACX,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGrD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAIrF;AA2ID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,WAAW,EACf,MAAM,CAAC,EAAE,UAAU,GAClB,MAAM,GAAG,IAAI,CA6Ef"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed-literal-to-go.d.ts","sourceRoot":"","sources":["../../../src/adapter/value/parsed-literal-to-go.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAkB,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"parsed-literal-to-go.d.ts","sourceRoot":"","sources":["../../../src/adapter/value/parsed-literal-to-go.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAkB,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAsDvD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAalE;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,EAChB,QAAQ,CAAC,EAAE,QAAQ,GAClB,MAAM,GAAG,IAAI,CAkFf"}
|
|
@@ -74,20 +74,23 @@ export declare function matchMapJoinChain(expr: ParsedExpr): {
|
|
|
74
74
|
} | null;
|
|
75
75
|
/**
|
|
76
76
|
* Lower a `.map(cb).join(sep)` chain (matched by {@link matchMapJoinChain})
|
|
77
|
-
* to a `bf.Join(
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
77
|
+
* to a `bf.Join(<chain>, <sep>)` Go expression, where `<chain>` is the
|
|
78
|
+
* chain's OWN `.map()` step composed by {@link callbackStepToGo} over
|
|
79
|
+
* whatever {@link resolveMapChainAsGo} resolves its receiver to (a base
|
|
80
|
+
* shape, or one or more nested `.map()`/`.filter()` layers) — the
|
|
81
|
+
* constructor-source analogue of `matchFilterArmMemo`'s `bf.FilterEval`
|
|
82
|
+
* emit (`memo-compute.ts`), reusing the SAME runtime evaluator functions
|
|
83
|
+
* (`MapEval`/`FilterEval`, `eval.go`; `Join`, `bf.go`) the template-position
|
|
84
|
+
* `bf_map_eval`/`bf_join` lowering already calls. Shared by a memo's
|
|
85
|
+
* derived value (`memoInitialFromParsedBody`'s concatenation-chain arm and
|
|
86
|
+
* bare-chain arm) and a SIGNAL's own initializer (`convertInitialValue`'s
|
|
87
|
+
* `string` branch, #2492).
|
|
85
88
|
*
|
|
86
89
|
* @returns the Go expression, or null when the receiver doesn't resolve
|
|
87
|
-
* ({@link
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
90
|
+
* ({@link resolveMapChainAsGo}), the projection body isn't representable
|
|
91
|
+
* to the runtime evaluator (`serializeParsedExpr` refusal), a captured
|
|
92
|
+
* free variable doesn't resolve, or the separator isn't a string literal
|
|
93
|
+
* (a dynamic separator — out of scope for this arm).
|
|
91
94
|
*/
|
|
92
95
|
export declare function mapJoinChainToGo(ctx: GoEmitContext, chain: {
|
|
93
96
|
object: ParsedExpr;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-lowering.d.ts","sourceRoot":"","sources":["../../../src/adapter/value/value-lowering.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAQ3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAyDtD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,QAAQ,EACnB,WAAW,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EACrD,SAAS,CAAC,EAAE,UAAU,GACrB,MAAM,CAkHR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,QAAQ,EAClB,SAAS,CAAC,EAAE,UAAU,GACrB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"value-lowering.d.ts","sourceRoot":"","sources":["../../../src/adapter/value/value-lowering.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAQ3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAyDtD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,QAAQ,EACnB,WAAW,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EACrD,SAAS,CAAC,EAAE,UAAU,GACrB,MAAM,CAkHR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,QAAQ,EAClB,SAAS,CAAC,EAAE,UAAU,GACrB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAcxF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,aAAa,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EACpD,gBAAgB,GAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAA4B,EACjF,UAAU,CAAC,EAAE,QAAQ,GACpB,MAAM,CAqCR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG;IACnD,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;IAC7C,MAAM,CAAC,EAAE,UAAU,CAAA;CACpB,GAAG,IAAI,CAKP;AA8JD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAE,EACjG,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAE,EAAE,EACzF,WAAW,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EACpD,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GACrD,MAAM,GAAG,IAAI,CAiBf"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
asCallbackMethodCall as asCallbackMethodCall4,
|
|
12
12
|
sortComparatorFromArrow,
|
|
13
13
|
emitParsedExpr,
|
|
14
|
+
groupObjectLiteralSegments,
|
|
14
15
|
emitIRNode,
|
|
15
16
|
emitAttrValue,
|
|
16
17
|
augmentInheritedPropAccesses,
|
|
@@ -724,7 +725,7 @@ function isSubstituteSafeBody(body, paramNames) {
|
|
|
724
725
|
if (n.kind === "identifier")
|
|
725
726
|
return paramNames.has(n.name);
|
|
726
727
|
if (n.kind === "object-literal") {
|
|
727
|
-
return n.properties.some((p) => p.shorthand && paramNames.has(p.key) || referencesParam(p.value));
|
|
728
|
+
return n.properties.some((p) => p.kind === "spread" ? referencesParam(p.expr) : p.shorthand && paramNames.has(p.key) || referencesParam(p.value));
|
|
728
729
|
}
|
|
729
730
|
let hit = false;
|
|
730
731
|
forEachValueChild(n, (c) => {
|
|
@@ -1092,6 +1093,8 @@ function bakeInlineObjectAsGoMap(ctx, expr) {
|
|
|
1092
1093
|
return null;
|
|
1093
1094
|
const entries = [];
|
|
1094
1095
|
for (const prop of expr.properties) {
|
|
1096
|
+
if (prop.kind === "spread")
|
|
1097
|
+
return null;
|
|
1095
1098
|
if (prop.shorthand)
|
|
1096
1099
|
return null;
|
|
1097
1100
|
const go = prop.value.kind === "object-literal" ? bakeInlineObjectAsGoMap(ctx, prop.value) : parsedLiteralToGo(ctx, prop.value);
|
|
@@ -1147,6 +1150,8 @@ function parsedLiteralToGo(ctx, expr, typeInfo) {
|
|
|
1147
1150
|
return null;
|
|
1148
1151
|
const entries = [];
|
|
1149
1152
|
for (const prop of expr.properties) {
|
|
1153
|
+
if (prop.kind === "spread")
|
|
1154
|
+
return null;
|
|
1150
1155
|
const goField = structFields.get(prop.key);
|
|
1151
1156
|
if (!goField)
|
|
1152
1157
|
return null;
|
|
@@ -1268,6 +1273,8 @@ function objectLiteralToGoMap(ctx, expr) {
|
|
|
1268
1273
|
return null;
|
|
1269
1274
|
const entries = [];
|
|
1270
1275
|
for (const prop of expr.properties) {
|
|
1276
|
+
if (prop.kind === "spread")
|
|
1277
|
+
return null;
|
|
1271
1278
|
if (prop.shorthand)
|
|
1272
1279
|
return null;
|
|
1273
1280
|
const val = parsedLiteralToGo(ctx, prop.value);
|
|
@@ -1346,17 +1353,18 @@ function resolveMapJoinBaseAsGo(ctx, object, signals, propsParams) {
|
|
|
1346
1353
|
}
|
|
1347
1354
|
return null;
|
|
1348
1355
|
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1356
|
+
var CALLBACK_EVAL_FUNC = { map: "bf.MapEval", filter: "bf.FilterEval" };
|
|
1357
|
+
function callbackStepToGo(ctx, method, itemsGo, arrow, signals, propsParams, propFallbackVars) {
|
|
1358
|
+
const evalFunc = CALLBACK_EVAL_FUNC[method];
|
|
1359
|
+
if (!evalFunc)
|
|
1352
1360
|
return null;
|
|
1353
1361
|
const knownGetterNames = new Set(signals.map((s) => s.getter));
|
|
1354
|
-
const materialized = materializeGetterCalls(
|
|
1362
|
+
const materialized = materializeGetterCalls(arrow.body, knownGetterNames);
|
|
1355
1363
|
const projJSON = serializeParsedExpr2(materialized);
|
|
1356
1364
|
if (projJSON === null)
|
|
1357
1365
|
return null;
|
|
1358
|
-
const paramName =
|
|
1359
|
-
const freeVars = freeVarsInBody2(materialized, new Set(
|
|
1366
|
+
const paramName = arrow.params[0] ?? "_";
|
|
1367
|
+
const freeVars = freeVarsInBody2(materialized, new Set(arrow.params));
|
|
1360
1368
|
const envEntries = [];
|
|
1361
1369
|
for (const name of freeVars) {
|
|
1362
1370
|
const sig = signals.find((s) => s.getter === name);
|
|
@@ -1373,6 +1381,25 @@ function mapJoinChainToGo(ctx, chain, signals, propsParams, propFallbackVars) {
|
|
|
1373
1381
|
envEntries.push(`${JSON.stringify(name)}: ${goExpr}`);
|
|
1374
1382
|
}
|
|
1375
1383
|
const envMap = `map[string]any{${envEntries.join(", ")}}`;
|
|
1384
|
+
return `${evalFunc}(${itemsGo}, "${escapeGoString(projJSON)}", ${JSON.stringify(paramName)}, ${envMap})`;
|
|
1385
|
+
}
|
|
1386
|
+
function resolveMapChainAsGo(ctx, expr, signals, propsParams, propFallbackVars) {
|
|
1387
|
+
const cb = asCallbackMethodCall(expr);
|
|
1388
|
+
if (cb && cb.method in CALLBACK_EVAL_FUNC) {
|
|
1389
|
+
const innerGo = resolveMapChainAsGo(ctx, cb.object, signals, propsParams, propFallbackVars);
|
|
1390
|
+
if (innerGo === null)
|
|
1391
|
+
return null;
|
|
1392
|
+
return callbackStepToGo(ctx, cb.method, innerGo, cb.arrow, signals, propsParams, propFallbackVars);
|
|
1393
|
+
}
|
|
1394
|
+
return resolveMapJoinBaseAsGo(ctx, expr, signals, propsParams);
|
|
1395
|
+
}
|
|
1396
|
+
function mapJoinChainToGo(ctx, chain, signals, propsParams, propFallbackVars) {
|
|
1397
|
+
const itemsGo = resolveMapChainAsGo(ctx, chain.object, signals, propsParams, propFallbackVars);
|
|
1398
|
+
if (itemsGo === null)
|
|
1399
|
+
return null;
|
|
1400
|
+
const mapGo = callbackStepToGo(ctx, "map", itemsGo, chain.arrow, signals, propsParams, propFallbackVars);
|
|
1401
|
+
if (mapGo === null)
|
|
1402
|
+
return null;
|
|
1376
1403
|
let sepGo;
|
|
1377
1404
|
if (!chain.sepArg) {
|
|
1378
1405
|
sepGo = JSON.stringify(",");
|
|
@@ -1381,7 +1408,7 @@ function mapJoinChainToGo(ctx, chain, signals, propsParams, propFallbackVars) {
|
|
|
1381
1408
|
} else {
|
|
1382
1409
|
return null;
|
|
1383
1410
|
}
|
|
1384
|
-
return `bf.Join(
|
|
1411
|
+
return `bf.Join(${mapGo}, ${sepGo})`;
|
|
1385
1412
|
}
|
|
1386
1413
|
|
|
1387
1414
|
// src/adapter/memo/memo-type.ts
|
|
@@ -1670,6 +1697,8 @@ function computeObjectMemoInitialValue(ctx, memo) {
|
|
|
1670
1697
|
const env = { searchParamsVars: new Set, params: new Map };
|
|
1671
1698
|
const entries = [];
|
|
1672
1699
|
for (const prop of retObj.properties) {
|
|
1700
|
+
if (prop.kind === "spread")
|
|
1701
|
+
return null;
|
|
1673
1702
|
if (prop.shorthand)
|
|
1674
1703
|
return null;
|
|
1675
1704
|
if (prop.keyKind !== undefined && prop.keyKind !== "identifier" && prop.keyKind !== "string") {
|
|
@@ -1801,6 +1830,8 @@ function recordIndexInterpolationToGo(ctx, node, propNames, localKeyBindings) {
|
|
|
1801
1830
|
return null;
|
|
1802
1831
|
const entries = [];
|
|
1803
1832
|
for (const prop of parsedConst.properties) {
|
|
1833
|
+
if (prop.kind === "spread")
|
|
1834
|
+
return null;
|
|
1804
1835
|
const v = prop.value;
|
|
1805
1836
|
if (v.kind === "literal" && v.literalType === "number") {
|
|
1806
1837
|
entries.push({ key: prop.key, value: { kind: "number", text: v.raw ?? String(v.value) } });
|
|
@@ -2127,6 +2158,12 @@ function memoInitialFromParsedBody(ctx, body, signals, propsParams, propFallback
|
|
|
2127
2158
|
if (concatGo !== null)
|
|
2128
2159
|
return concatGo;
|
|
2129
2160
|
}
|
|
2161
|
+
const bareChain = matchMapJoinChain(body);
|
|
2162
|
+
if (bareChain) {
|
|
2163
|
+
const chainGo = mapJoinChainToGo(ctx, bareChain, signals, propsParams, propFallbackVars);
|
|
2164
|
+
if (chainGo !== null)
|
|
2165
|
+
return chainGo;
|
|
2166
|
+
}
|
|
2130
2167
|
return null;
|
|
2131
2168
|
}
|
|
2132
2169
|
function resolveStringConcatChainGo(ctx, expr, signals, propsParams, propFallbackVars, propRef) {
|
|
@@ -2298,7 +2335,7 @@ function collectPropsReadByCtorInit(body, propsObjectName, propNames) {
|
|
|
2298
2335
|
return;
|
|
2299
2336
|
case "object-literal":
|
|
2300
2337
|
for (const p of e.properties)
|
|
2301
|
-
visit(p.value, bound);
|
|
2338
|
+
visit(p.kind === "spread" ? p.expr : p.value, bound);
|
|
2302
2339
|
return;
|
|
2303
2340
|
case "array-method":
|
|
2304
2341
|
visit(e.object, bound);
|
|
@@ -2410,6 +2447,8 @@ function parsedObjectLiteralToGoMap(parsed) {
|
|
|
2410
2447
|
return null;
|
|
2411
2448
|
const entries = [];
|
|
2412
2449
|
for (const prop of parsed.properties) {
|
|
2450
|
+
if (prop.kind === "spread")
|
|
2451
|
+
return null;
|
|
2413
2452
|
if (prop.keyKind === "numeric")
|
|
2414
2453
|
return null;
|
|
2415
2454
|
const v = prop.value;
|
|
@@ -2534,6 +2573,8 @@ function conditionToGoBool(condition, ir) {
|
|
|
2534
2573
|
function objectLiteralToGoSpreadMap(ctx, obj, ir) {
|
|
2535
2574
|
const entries = [];
|
|
2536
2575
|
for (const prop of obj.properties) {
|
|
2576
|
+
if (prop.kind === "spread")
|
|
2577
|
+
return null;
|
|
2537
2578
|
if (prop.shorthand)
|
|
2538
2579
|
return null;
|
|
2539
2580
|
if (prop.keyKind === "numeric")
|
|
@@ -2677,7 +2718,18 @@ function collectNullishConsumedPropNames(ctx, ir) {
|
|
|
2677
2718
|
};
|
|
2678
2719
|
walk(ir.root);
|
|
2679
2720
|
for (const signal of ir.metadata.signals) {
|
|
2680
|
-
const
|
|
2721
|
+
const resolvedParsed = resolveSignalParsedThroughSeedPlan(ctx.state, signal);
|
|
2722
|
+
let match = ctx.extractPropFallback(signal.initialValue, resolvedParsed);
|
|
2723
|
+
if (!match) {
|
|
2724
|
+
const collision = ctx.extractCollisionDerivation(resolvedParsed);
|
|
2725
|
+
if (collision) {
|
|
2726
|
+
const collisionParam = ir.metadata.propsParams.find((p) => p.name === collision.propName);
|
|
2727
|
+
const collisionField = collisionParam ? capitalizeFieldName(collisionParam.sourceName ?? collision.propName) : null;
|
|
2728
|
+
if (collisionField && capitalizeFieldName(signal.getter) === collisionField) {
|
|
2729
|
+
match = { propName: collision.propName, goFallback: collision.goFallback };
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2681
2733
|
if (!match || !optionalParams.has(match.propName))
|
|
2682
2734
|
continue;
|
|
2683
2735
|
const f = match.goFallback;
|
|
@@ -2863,6 +2915,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2863
2915
|
convertConditionToGo: (jsCondition, preParsed) => this.convertConditionToGo(jsCondition, preParsed),
|
|
2864
2916
|
extractPropNameFromInitialValue: (initialValue, preParsed) => this.extractPropNameFromInitialValue(initialValue, preParsed),
|
|
2865
2917
|
extractPropFallback: (initialValue, preParsed) => this.extractPropFallback(initialValue, preParsed),
|
|
2918
|
+
extractCollisionDerivation: (parsed) => this.extractCollisionDerivation(parsed),
|
|
2866
2919
|
resolveModuleStringConst: (name) => this.resolveModuleStringConst(name)
|
|
2867
2920
|
};
|
|
2868
2921
|
get errors() {
|
|
@@ -3338,6 +3391,8 @@ ${goFields.join(`
|
|
|
3338
3391
|
return null;
|
|
3339
3392
|
const seen = new Set;
|
|
3340
3393
|
for (const prop of el.properties) {
|
|
3394
|
+
if (prop.kind === "spread")
|
|
3395
|
+
return null;
|
|
3341
3396
|
if (prop.shorthand)
|
|
3342
3397
|
return null;
|
|
3343
3398
|
const key = prop.key;
|
|
@@ -3641,6 +3696,7 @@ ${goFields.join(`
|
|
|
3641
3696
|
}
|
|
3642
3697
|
lines.push("");
|
|
3643
3698
|
}
|
|
3699
|
+
this.emitCallerPropsInit(lines, ir, nestedComponents, staticWithoutBody, staticWithBody, dynamicWithBody, emittedWrapperVars, propTypeOverrides);
|
|
3644
3700
|
lines.push(` return ${propsTypeName}{`);
|
|
3645
3701
|
lines.push("\t\tScopeID: scopeID,");
|
|
3646
3702
|
lines.push("\t\tBfParent: in.BfParent,");
|
|
@@ -3648,6 +3704,7 @@ ${goFields.join(`
|
|
|
3648
3704
|
if (this.usesSearchParams(ir)) {
|
|
3649
3705
|
lines.push("\t\tSearchParams: in.SearchParams,");
|
|
3650
3706
|
}
|
|
3707
|
+
lines.push("\t\tBfCallerProps: bfCallerProps,");
|
|
3651
3708
|
const nestedArrayFields = this.propDerivedNestedArrayFields(nestedComponents);
|
|
3652
3709
|
const memoFallbacks = new Map;
|
|
3653
3710
|
for (const memo of ir.metadata.memos) {
|
|
@@ -3673,7 +3730,8 @@ ${goFields.join(`
|
|
|
3673
3730
|
continue;
|
|
3674
3731
|
const hoisted = propFallbackVars.get(param.name);
|
|
3675
3732
|
if (hoisted) {
|
|
3676
|
-
|
|
3733
|
+
const value = hoisted.collisionWrap ? `${hoisted.varName} ${hoisted.collisionWrap.operator} ${hoisted.collisionWrap.operand}` : hoisted.varName;
|
|
3734
|
+
lines.push(` ${fieldName}: ${value},`);
|
|
3677
3735
|
} else {
|
|
3678
3736
|
const paramDefault = goPropDefault(param.defaultValue);
|
|
3679
3737
|
const memoFold = memoFallbacks.get(fieldName);
|
|
@@ -3752,6 +3810,53 @@ ${goFields.join(`
|
|
|
3752
3810
|
lines.push("\t}");
|
|
3753
3811
|
lines.push("}");
|
|
3754
3812
|
}
|
|
3813
|
+
emitCallerPropsInit(lines, ir, nestedComponents, staticWithoutBody, staticWithBody, dynamicWithBody, emittedWrapperVars, propTypeOverrides) {
|
|
3814
|
+
lines.push("\tbfCallerProps := map[string]interface{}{}");
|
|
3815
|
+
const bfCallerPropsTakenTags = new Set;
|
|
3816
|
+
const nestedArrayFields = this.propDerivedNestedArrayFields(nestedComponents);
|
|
3817
|
+
for (const param of ir.metadata.propsParams) {
|
|
3818
|
+
if (param.name === "children")
|
|
3819
|
+
continue;
|
|
3820
|
+
if (this.isNestedArrayShadowed(param, nestedArrayFields))
|
|
3821
|
+
continue;
|
|
3822
|
+
const callerKey = this.claimJsonTag(this.toJsonTag(param.sourceName ?? param.name), bfCallerPropsTakenTags);
|
|
3823
|
+
if (callerKey === "-")
|
|
3824
|
+
continue;
|
|
3825
|
+
const inputField = `in.${capitalizeFieldName(param.sourceName ?? param.name)}`;
|
|
3826
|
+
const goType = resolvePropGoType(this.emitCtx, param, propTypeOverrides);
|
|
3827
|
+
const isNillable = goType === "interface{}" || goType === "map[string]interface{}" || goType.startsWith("[]");
|
|
3828
|
+
if (param.optional && isNillable) {
|
|
3829
|
+
lines.push(` if ${inputField} != nil {`);
|
|
3830
|
+
lines.push(` bfCallerProps["${callerKey}"] = ${inputField}`);
|
|
3831
|
+
lines.push(` }`);
|
|
3832
|
+
} else {
|
|
3833
|
+
lines.push(` bfCallerProps["${callerKey}"] = ${inputField}`);
|
|
3834
|
+
}
|
|
3835
|
+
}
|
|
3836
|
+
for (const nested of [...staticWithoutBody, ...staticWithBody, ...dynamicWithBody]) {
|
|
3837
|
+
if (!nested.isPropDerived)
|
|
3838
|
+
continue;
|
|
3839
|
+
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
3840
|
+
const isBuilt = staticWithoutBody.includes(nested) || emittedWrapperVars.has(varName);
|
|
3841
|
+
if (!isBuilt)
|
|
3842
|
+
continue;
|
|
3843
|
+
const arrayFieldName = capitalizeFieldName(`${nested.name}s`);
|
|
3844
|
+
const param = ir.metadata.propsParams.find((p) => capitalizeFieldName(p.name) === arrayFieldName || capitalizeFieldName(p.sourceName ?? p.name) === arrayFieldName);
|
|
3845
|
+
if (!param || !this.isNestedArrayShadowed(param, nestedArrayFields))
|
|
3846
|
+
continue;
|
|
3847
|
+
const callerKey = this.claimJsonTag(this.toJsonTag(param.sourceName ?? param.name), bfCallerPropsTakenTags);
|
|
3848
|
+
if (callerKey === "-")
|
|
3849
|
+
continue;
|
|
3850
|
+
if (param.optional) {
|
|
3851
|
+
lines.push(` if in.${nested.name}s != nil {`);
|
|
3852
|
+
lines.push(` bfCallerProps["${callerKey}"] = ${varName}`);
|
|
3853
|
+
lines.push(` }`);
|
|
3854
|
+
} else {
|
|
3855
|
+
lines.push(` bfCallerProps["${callerKey}"] = ${varName}`);
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
lines.push("");
|
|
3859
|
+
}
|
|
3755
3860
|
emitStaticChildInstances(lines, ir) {
|
|
3756
3861
|
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
3757
3862
|
for (const child of staticChildren) {
|
|
@@ -4203,6 +4308,7 @@ ${goFields.join(`
|
|
|
4203
4308
|
if (this.usesSearchParams(ir)) {
|
|
4204
4309
|
lines.push('\tSearchParams bf.SearchParams `json:"-"`');
|
|
4205
4310
|
}
|
|
4311
|
+
lines.push('\tBfCallerProps map[string]interface{} `json:"-"`');
|
|
4206
4312
|
}
|
|
4207
4313
|
emitPropsDataFields(lines, ir, nestedComponents, propTypeOverrides, takenJsonTags) {
|
|
4208
4314
|
const nestedArrayFields = this.propDerivedNestedArrayFields(nestedComponents);
|
|
@@ -4458,6 +4564,8 @@ ${goFields.join(`
|
|
|
4458
4564
|
return null;
|
|
4459
4565
|
const entries = [];
|
|
4460
4566
|
for (const prop of parsed.properties) {
|
|
4567
|
+
if (prop.kind === "spread")
|
|
4568
|
+
return null;
|
|
4461
4569
|
if (prop.shorthand)
|
|
4462
4570
|
return null;
|
|
4463
4571
|
const goVal = this.lowerProviderMapMemberValue(prop.value, propsParams);
|
|
@@ -4614,7 +4722,19 @@ ${goFields.join(`
|
|
|
4614
4722
|
}
|
|
4615
4723
|
const propTypeOverrides = buildPropTypeOverrides(this.emitCtx, ir);
|
|
4616
4724
|
for (const signal of ir.metadata.signals) {
|
|
4617
|
-
|
|
4725
|
+
let match = this.extractPropFallback(signal.initialValue, this.resolvedSignalParsed(signal));
|
|
4726
|
+
let collisionWrap;
|
|
4727
|
+
if (!match) {
|
|
4728
|
+
const collision = this.extractCollisionDerivation(this.resolvedSignalParsed(signal));
|
|
4729
|
+
if (collision) {
|
|
4730
|
+
const collisionParam = ir.metadata.propsParams.find((p) => p.name === collision.propName);
|
|
4731
|
+
const collisionField = collisionParam ? capitalizeFieldName(collisionParam.sourceName ?? collision.propName) : null;
|
|
4732
|
+
if (collisionField && capitalizeFieldName(signal.getter) === collisionField) {
|
|
4733
|
+
match = { propName: collision.propName, goFallback: collision.goFallback };
|
|
4734
|
+
collisionWrap = { operator: collision.operator, operand: collision.operand };
|
|
4735
|
+
}
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
4618
4738
|
if (!match)
|
|
4619
4739
|
continue;
|
|
4620
4740
|
if (result.has(match.propName))
|
|
@@ -4653,7 +4773,8 @@ ${goFields.join(`
|
|
|
4653
4773
|
fieldName,
|
|
4654
4774
|
goFallback: match.goFallback,
|
|
4655
4775
|
zeroLiteral,
|
|
4656
|
-
...nullishLowered ? { assertType: concreteType } : {}
|
|
4776
|
+
...nullishLowered ? { assertType: concreteType } : {},
|
|
4777
|
+
...collisionWrap ? { collisionWrap } : {}
|
|
4657
4778
|
});
|
|
4658
4779
|
}
|
|
4659
4780
|
return result;
|
|
@@ -4703,6 +4824,26 @@ ${goFields.join(`
|
|
|
4703
4824
|
return null;
|
|
4704
4825
|
return { propName, goFallback };
|
|
4705
4826
|
}
|
|
4827
|
+
extractCollisionDerivation(parsed) {
|
|
4828
|
+
if (!parsed || parsed.kind !== "binary")
|
|
4829
|
+
return null;
|
|
4830
|
+
if (!["*", "+", "-", "/"].includes(parsed.op))
|
|
4831
|
+
return null;
|
|
4832
|
+
const { right } = parsed;
|
|
4833
|
+
if (right.kind !== "literal" || right.literalType !== "number" || typeof right.value !== "number" || !Number.isInteger(right.value) || right.value < 0) {
|
|
4834
|
+
return null;
|
|
4835
|
+
}
|
|
4836
|
+
if (parsed.op === "/" && right.value === 0)
|
|
4837
|
+
return null;
|
|
4838
|
+
const coalesce = parsed.left;
|
|
4839
|
+
if (coalesce.kind !== "logical" || coalesce.op !== "??" || coalesce.right.kind !== "literal" || coalesce.right.literalType !== "number") {
|
|
4840
|
+
return null;
|
|
4841
|
+
}
|
|
4842
|
+
const inner = this.extractPropFallbackFromParsed(parsed.left);
|
|
4843
|
+
if (!inner)
|
|
4844
|
+
return null;
|
|
4845
|
+
return { ...inner, operator: parsed.op, operand: String(right.value) };
|
|
4846
|
+
}
|
|
4706
4847
|
extractPropNameFromInitialValue(initialValue, preParsed) {
|
|
4707
4848
|
if (!this.state.propsObjectName) {
|
|
4708
4849
|
if (preParsed?.kind === "logical" && (preParsed.op === "??" || preParsed.op === "||") && preParsed.left.kind === "identifier") {
|
|
@@ -5191,7 +5332,16 @@ ${goFields.join(`
|
|
|
5191
5332
|
});
|
|
5192
5333
|
return `bf_arr ${parts.join(" ")}`;
|
|
5193
5334
|
}
|
|
5194
|
-
objectLiteral(
|
|
5335
|
+
objectLiteral(properties, raw, emit) {
|
|
5336
|
+
if (properties.length > 0) {
|
|
5337
|
+
const wrap = (rendered) => rendered.includes(" ") ? `(${rendered})` : rendered;
|
|
5338
|
+
const literalOf = (run) => `bf_map ${run.map((p) => `"${escapeGoString(p.key)}" ${wrap(emit(p.value))}`).join(" ")}`;
|
|
5339
|
+
if (!properties.some((p) => p.kind === "spread")) {
|
|
5340
|
+
return literalOf(properties);
|
|
5341
|
+
}
|
|
5342
|
+
const segments = groupObjectLiteralSegments(properties, literalOf, (e) => wrap(emit(e)));
|
|
5343
|
+
return `bf_merge ${segments.join(" ")}`;
|
|
5344
|
+
}
|
|
5195
5345
|
this.state.errors.push({
|
|
5196
5346
|
code: "BF101",
|
|
5197
5347
|
severity: "error",
|
|
@@ -5914,7 +6064,7 @@ ${goFields.join(`
|
|
|
5914
6064
|
return null;
|
|
5915
6065
|
const carried = constInfo.parsed;
|
|
5916
6066
|
if (carried?.kind === "object-literal") {
|
|
5917
|
-
const hit = carried.properties.find((prop) => prop.key === key);
|
|
6067
|
+
const hit = carried.properties.find((prop) => prop.kind === "prop" && prop.key === key);
|
|
5918
6068
|
if (hit && hit.value.kind === "literal") {
|
|
5919
6069
|
if (hit.value.literalType === "string")
|
|
5920
6070
|
return JSON.stringify(hit.value.value);
|
|
@@ -6758,8 +6908,7 @@ var conformancePins = {
|
|
|
6758
6908
|
};
|
|
6759
6909
|
// src/render-divergences.ts
|
|
6760
6910
|
var renderDivergences = {
|
|
6761
|
-
"signal-
|
|
6762
|
-
"signal-prop-same-name-via-const-derived": "self-derived signal (reached through a component-scope const) collides with its prop field name in the generated Go props struct — the non-idempotent `* 2` derivation is dropped and the signal renders the raw prop value instead (https://github.com/piconic-ai/barefootjs/issues/2683)"
|
|
6911
|
+
"signal-object-spread-init": "PRE-EXISTING, unrelated to the #2696 Step 2 spread work this fixture pins: a `derived`-classified signal/memo whose value is an OBJECT literal has no live-template-expression lowering on Go — unlike the other six template-stash backends (e.g. minijinja emits `{% set merged = dict(base, done=true) %}`), Go always bakes an object-typed signal/memo field into Go SOURCE at `NewXxxProps` constructor time (`convertInitialValue`/`parsedLiteralToGo`), and that baker is STATIC-only (identifier/call/member operands defer, `parsed-literal-to-go.ts`'s own docstring) — it cannot reference a live prop at all. Reproduced identically with the spread REMOVED (`createSignal({ id: base.id, done: true })`), confirming the gap predates and is independent of spread: the signal seeds `nil` and every field read (`.Merged.ID`/`.Merged.Done`) reads the Go zero value regardless of `initialTodos`. Graduate by teaching the baker to emit prop-referencing Go expressions (https://github.com/piconic-ai/barefootjs/issues/2700)."
|
|
6763
6912
|
};
|
|
6764
6913
|
export {
|
|
6765
6914
|
renderDivergences,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAG/B,CAAA"}
|