@barefootjs/go-template 0.32.0 → 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/expr/helper-inline.d.ts.map +1 -1
- package/dist/adapter/go-template-adapter.d.ts +1 -1
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +65 -11
- 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/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 +68 -12
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +159 -48
- package/package.json +5 -5
- package/src/adapter/expr/helper-inline.ts +4 -2
- package/src/adapter/go-template-adapter.ts +42 -7
- 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/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 +4 -1
package/dist/vite.js
CHANGED
|
@@ -209,7 +209,7 @@ function convertNode(node, raw) {
|
|
|
209
209
|
}
|
|
210
210
|
if (n === undefined || Number.isNaN(n)) {
|
|
211
211
|
const parsedDepth = convertNode(depthNode, raw);
|
|
212
|
-
if (checkSupport(parsedDepth).supported) {
|
|
212
|
+
if (checkSupport(parsedDepth, "rendered").supported) {
|
|
213
213
|
depthExpr = parsedDepth;
|
|
214
214
|
flatDepth = 1;
|
|
215
215
|
} else {
|
|
@@ -303,10 +303,12 @@ function convertNode(node, raw) {
|
|
|
303
303
|
const k = objectLiteralKeyName(prop.name);
|
|
304
304
|
if (k === null)
|
|
305
305
|
return { kind: "unsupported", raw, reason: `Unsupported syntax: ${ts.SyntaxKind[node.kind]}` };
|
|
306
|
-
properties.push({ key: k.key, keyKind: k.keyKind, shorthand: false, value: convertNode(prop.initializer, raw) });
|
|
306
|
+
properties.push({ kind: "prop", key: k.key, keyKind: k.keyKind, shorthand: false, value: convertNode(prop.initializer, raw) });
|
|
307
307
|
} else if (ts.isShorthandPropertyAssignment(prop)) {
|
|
308
308
|
const key = prop.name.text;
|
|
309
|
-
properties.push({ key, keyKind: "identifier", shorthand: true, value: { kind: "identifier", name: key } });
|
|
309
|
+
properties.push({ kind: "prop", key, keyKind: "identifier", shorthand: true, value: { kind: "identifier", name: key } });
|
|
310
|
+
} else if (ts.isSpreadAssignment(prop)) {
|
|
311
|
+
properties.push({ kind: "spread", expr: convertNode(prop.expression, raw) });
|
|
310
312
|
} else {
|
|
311
313
|
return { kind: "unsupported", raw, reason: `Unsupported syntax: ${ts.SyntaxKind[node.kind]}` };
|
|
312
314
|
}
|
|
@@ -986,14 +988,26 @@ function getUnaryOperatorString(op) {
|
|
|
986
988
|
}
|
|
987
989
|
}
|
|
988
990
|
function isSupported(expr) {
|
|
989
|
-
return checkSupport(expr);
|
|
991
|
+
return checkSupport(expr, "rendered");
|
|
990
992
|
}
|
|
991
|
-
function
|
|
993
|
+
function isSupportedValue(expr) {
|
|
994
|
+
return checkSupport(expr, "value");
|
|
995
|
+
}
|
|
996
|
+
function checkSupport(expr, pos) {
|
|
992
997
|
switch (expr.kind) {
|
|
993
998
|
case "unsupported":
|
|
994
999
|
return { supported: false, reason: expr.reason };
|
|
995
|
-
case "object-literal":
|
|
996
|
-
|
|
1000
|
+
case "object-literal": {
|
|
1001
|
+
if (pos !== "value") {
|
|
1002
|
+
return { supported: false, reason: "Unsupported syntax: ObjectLiteralExpression" };
|
|
1003
|
+
}
|
|
1004
|
+
for (const prop of expr.properties) {
|
|
1005
|
+
const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos);
|
|
1006
|
+
if (!propSupport.supported)
|
|
1007
|
+
return propSupport;
|
|
1008
|
+
}
|
|
1009
|
+
return { supported: true, level: "L2" };
|
|
1010
|
+
}
|
|
997
1011
|
case "identifier":
|
|
998
1012
|
return { supported: true, level: "L1" };
|
|
999
1013
|
case "literal":
|
|
@@ -1003,7 +1017,7 @@ function checkSupport(expr) {
|
|
|
1003
1017
|
return { supported: false, reason: "Standalone arrow functions / regex literals are not supported" };
|
|
1004
1018
|
case "array-literal": {
|
|
1005
1019
|
for (const el of expr.elements) {
|
|
1006
|
-
const elSupport = checkSupport(el);
|
|
1020
|
+
const elSupport = checkSupport(el, pos);
|
|
1007
1021
|
if (!elSupport.supported)
|
|
1008
1022
|
return elSupport;
|
|
1009
1023
|
}
|
|
@@ -1016,16 +1030,16 @@ function checkSupport(expr) {
|
|
|
1016
1030
|
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 */`
|
|
1017
1031
|
};
|
|
1018
1032
|
}
|
|
1019
|
-
const objSupport = checkSupport(expr.object);
|
|
1033
|
+
const objSupport = checkSupport(expr.object, pos);
|
|
1020
1034
|
if (!objSupport.supported)
|
|
1021
1035
|
return objSupport;
|
|
1022
1036
|
for (const arg of expr.args) {
|
|
1023
|
-
const argSupport = checkSupport(arg);
|
|
1037
|
+
const argSupport = checkSupport(arg, pos);
|
|
1024
1038
|
if (!argSupport.supported)
|
|
1025
1039
|
return argSupport;
|
|
1026
1040
|
}
|
|
1027
1041
|
if (expr.method === "flat" && expr.depthExpr) {
|
|
1028
|
-
const depthSupport = checkSupport(expr.depthExpr);
|
|
1042
|
+
const depthSupport = checkSupport(expr.depthExpr, pos);
|
|
1029
1043
|
if (!depthSupport.supported)
|
|
1030
1044
|
return depthSupport;
|
|
1031
1045
|
}
|
|
@@ -1034,10 +1048,10 @@ function checkSupport(expr) {
|
|
|
1034
1048
|
case "call": {
|
|
1035
1049
|
const cb = asCallbackMethodCall(expr);
|
|
1036
1050
|
if (cb) {
|
|
1037
|
-
const objSupport = checkSupport(cb.object);
|
|
1051
|
+
const objSupport = checkSupport(cb.object, pos);
|
|
1038
1052
|
if (!objSupport.supported)
|
|
1039
1053
|
return objSupport;
|
|
1040
|
-
const bodySupport = checkSupport(cb.arrow.body);
|
|
1054
|
+
const bodySupport = checkSupport(cb.arrow.body, pos);
|
|
1041
1055
|
if (!bodySupport.supported) {
|
|
1042
1056
|
return {
|
|
1043
1057
|
supported: false,
|
|
@@ -1046,13 +1060,13 @@ function checkSupport(expr) {
|
|
|
1046
1060
|
};
|
|
1047
1061
|
}
|
|
1048
1062
|
for (const rest of cb.args) {
|
|
1049
|
-
const restSupport = checkSupport(rest);
|
|
1063
|
+
const restSupport = checkSupport(rest, pos);
|
|
1050
1064
|
if (!restSupport.supported)
|
|
1051
1065
|
return restSupport;
|
|
1052
1066
|
}
|
|
1053
1067
|
return { supported: true, level: "L5" };
|
|
1054
1068
|
}
|
|
1055
|
-
const calleeSupport = checkSupport(expr.callee);
|
|
1069
|
+
const calleeSupport = checkSupport(expr.callee, pos);
|
|
1056
1070
|
if (!calleeSupport.supported) {
|
|
1057
1071
|
return calleeSupport;
|
|
1058
1072
|
}
|
|
@@ -1071,7 +1085,7 @@ function checkSupport(expr) {
|
|
|
1071
1085
|
return { supported: true, level: "L1" };
|
|
1072
1086
|
}
|
|
1073
1087
|
for (const arg of expr.args) {
|
|
1074
|
-
const argSupport = checkSupport(arg);
|
|
1088
|
+
const argSupport = checkSupport(arg, pos);
|
|
1075
1089
|
if (!argSupport.supported) {
|
|
1076
1090
|
return argSupport;
|
|
1077
1091
|
}
|
|
@@ -1079,7 +1093,7 @@ function checkSupport(expr) {
|
|
|
1079
1093
|
return { supported: true, level: "L2" };
|
|
1080
1094
|
}
|
|
1081
1095
|
case "member": {
|
|
1082
|
-
const objSupport = checkSupport(expr.object);
|
|
1096
|
+
const objSupport = checkSupport(expr.object, pos);
|
|
1083
1097
|
if (!objSupport.supported) {
|
|
1084
1098
|
return objSupport;
|
|
1085
1099
|
}
|
|
@@ -1089,19 +1103,19 @@ function checkSupport(expr) {
|
|
|
1089
1103
|
return { supported: true, level: "L2" };
|
|
1090
1104
|
}
|
|
1091
1105
|
case "index-access": {
|
|
1092
|
-
const objSupport = checkSupport(expr.object);
|
|
1106
|
+
const objSupport = checkSupport(expr.object, pos);
|
|
1093
1107
|
if (!objSupport.supported)
|
|
1094
1108
|
return objSupport;
|
|
1095
|
-
const indexSupport = checkSupport(expr.index);
|
|
1109
|
+
const indexSupport = checkSupport(expr.index, pos);
|
|
1096
1110
|
if (!indexSupport.supported)
|
|
1097
1111
|
return indexSupport;
|
|
1098
1112
|
return { supported: true, level: "L2" };
|
|
1099
1113
|
}
|
|
1100
1114
|
case "binary": {
|
|
1101
|
-
const leftSupport = checkSupport(expr.left);
|
|
1115
|
+
const leftSupport = checkSupport(expr.left, pos);
|
|
1102
1116
|
if (!leftSupport.supported)
|
|
1103
1117
|
return leftSupport;
|
|
1104
|
-
const rightSupport = checkSupport(expr.right);
|
|
1118
|
+
const rightSupport = checkSupport(expr.right, pos);
|
|
1105
1119
|
if (!rightSupport.supported)
|
|
1106
1120
|
return rightSupport;
|
|
1107
1121
|
if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].includes(expr.op)) {
|
|
@@ -1113,7 +1127,7 @@ function checkSupport(expr) {
|
|
|
1113
1127
|
return { supported: false, reason: `Unknown operator: ${expr.op}` };
|
|
1114
1128
|
}
|
|
1115
1129
|
case "unary": {
|
|
1116
|
-
const argSupport = checkSupport(expr.argument);
|
|
1130
|
+
const argSupport = checkSupport(expr.argument, pos);
|
|
1117
1131
|
if (!argSupport.supported)
|
|
1118
1132
|
return argSupport;
|
|
1119
1133
|
if (expr.op === "!") {
|
|
@@ -1125,25 +1139,25 @@ function checkSupport(expr) {
|
|
|
1125
1139
|
return { supported: false, reason: `Unsupported unary operator: ${expr.op}` };
|
|
1126
1140
|
}
|
|
1127
1141
|
case "logical": {
|
|
1128
|
-
const leftSupport = checkSupport(expr.left);
|
|
1142
|
+
const leftSupport = checkSupport(expr.left, pos);
|
|
1129
1143
|
if (!leftSupport.supported)
|
|
1130
1144
|
return leftSupport;
|
|
1131
1145
|
if (expr.op === "??" && expr.right.kind === "object-literal" && expr.right.properties.length === 0) {
|
|
1132
1146
|
return { supported: true, level: "L4" };
|
|
1133
1147
|
}
|
|
1134
|
-
const rightSupport = checkSupport(expr.right);
|
|
1148
|
+
const rightSupport = checkSupport(expr.right, pos);
|
|
1135
1149
|
if (!rightSupport.supported)
|
|
1136
1150
|
return rightSupport;
|
|
1137
1151
|
return { supported: true, level: "L4" };
|
|
1138
1152
|
}
|
|
1139
1153
|
case "conditional": {
|
|
1140
|
-
const testSupport = checkSupport(expr.test);
|
|
1154
|
+
const testSupport = checkSupport(expr.test, pos);
|
|
1141
1155
|
if (!testSupport.supported)
|
|
1142
1156
|
return testSupport;
|
|
1143
|
-
const consSupport = checkSupport(expr.consequent);
|
|
1157
|
+
const consSupport = checkSupport(expr.consequent, pos);
|
|
1144
1158
|
if (!consSupport.supported)
|
|
1145
1159
|
return consSupport;
|
|
1146
|
-
const altSupport = checkSupport(expr.alternate);
|
|
1160
|
+
const altSupport = checkSupport(expr.alternate, pos);
|
|
1147
1161
|
if (!altSupport.supported)
|
|
1148
1162
|
return altSupport;
|
|
1149
1163
|
return { supported: true, level: "L4" };
|
|
@@ -1151,7 +1165,7 @@ function checkSupport(expr) {
|
|
|
1151
1165
|
case "template-literal": {
|
|
1152
1166
|
for (const part of expr.parts) {
|
|
1153
1167
|
if (part.type === "expression") {
|
|
1154
|
-
const partSupport = checkSupport(part.expr);
|
|
1168
|
+
const partSupport = checkSupport(part.expr, pos);
|
|
1155
1169
|
if (!partSupport.supported)
|
|
1156
1170
|
return partSupport;
|
|
1157
1171
|
}
|
|
@@ -1267,7 +1281,7 @@ function isPureInit(e, pureCallNames) {
|
|
|
1267
1281
|
case "array-literal":
|
|
1268
1282
|
return e.elements.every(pure);
|
|
1269
1283
|
case "object-literal":
|
|
1270
|
-
return e.properties.every((p) => pure(p.value));
|
|
1284
|
+
return e.properties.every((p) => pure(p.kind === "spread" ? p.expr : p.value));
|
|
1271
1285
|
case "call":
|
|
1272
1286
|
return e.callee.kind === "identifier" && e.args.length === 0 && pureCallNames !== undefined && pureCallNames.has(e.callee.name);
|
|
1273
1287
|
case "array-method":
|
|
@@ -1321,7 +1335,7 @@ function usesPerPath(name, expr) {
|
|
|
1321
1335
|
}
|
|
1322
1336
|
return add(walk(e.object), sum(e.args));
|
|
1323
1337
|
case "object-literal":
|
|
1324
|
-
return sum(e.properties.map((p) => p.value));
|
|
1338
|
+
return sum(e.properties.map((p) => p.kind === "spread" ? p.expr : p.value));
|
|
1325
1339
|
case "arrow":
|
|
1326
1340
|
return walk(e.body).max > 0 ? { min: 0, max: Number.POSITIVE_INFINITY } : { min: 0, max: 0 };
|
|
1327
1341
|
}
|
|
@@ -1387,7 +1401,7 @@ function inlineBinding(expr, name, value) {
|
|
|
1387
1401
|
case "object-literal":
|
|
1388
1402
|
return {
|
|
1389
1403
|
kind: "object-literal",
|
|
1390
|
-
properties: e.properties.map((p) => ({ ...p, value: walk(p.value, enclosing) })
|
|
1404
|
+
properties: e.properties.map((p) => p.kind === "spread" ? { ...p, expr: walk(p.expr, enclosing) } : { ...p, value: walk(p.value, enclosing) }),
|
|
1391
1405
|
raw: e.raw
|
|
1392
1406
|
};
|
|
1393
1407
|
case "literal":
|
|
@@ -1597,7 +1611,7 @@ function materializeGetterCalls(expr, names) {
|
|
|
1597
1611
|
return {
|
|
1598
1612
|
kind: "object-literal",
|
|
1599
1613
|
raw: expr.raw,
|
|
1600
|
-
properties: expr.properties.map((p) => ({ ...p, value: rw(p.value) })
|
|
1614
|
+
properties: expr.properties.map((p) => p.kind === "spread" ? { ...p, expr: rw(p.expr) } : { ...p, value: rw(p.value) })
|
|
1601
1615
|
};
|
|
1602
1616
|
case "arrow":
|
|
1603
1617
|
return { kind: "arrow", params: expr.params, body: rw(expr.body) };
|
|
@@ -1655,7 +1669,7 @@ function freeVarsInBody(body, params) {
|
|
|
1655
1669
|
return;
|
|
1656
1670
|
case "object-literal":
|
|
1657
1671
|
for (const p of e.properties)
|
|
1658
|
-
visit(p.value, bound);
|
|
1672
|
+
visit(p.kind === "spread" ? p.expr : p.value, bound);
|
|
1659
1673
|
return;
|
|
1660
1674
|
case "array-method":
|
|
1661
1675
|
if (e.method === "includes" || e.method === "join") {
|
|
@@ -1730,7 +1744,7 @@ function freeIdentifiers(expr) {
|
|
|
1730
1744
|
return true;
|
|
1731
1745
|
case "object-literal":
|
|
1732
1746
|
for (const p of e.properties)
|
|
1733
|
-
if (!visit(p.value, bound))
|
|
1747
|
+
if (!visit(p.kind === "spread" ? p.expr : p.value, bound))
|
|
1734
1748
|
return false;
|
|
1735
1749
|
return true;
|
|
1736
1750
|
case "arrow": {
|
|
@@ -1877,10 +1891,17 @@ function toEvalNode(e) {
|
|
|
1877
1891
|
case "object-literal": {
|
|
1878
1892
|
const properties = [];
|
|
1879
1893
|
for (const p of e.properties) {
|
|
1894
|
+
if (p.kind === "spread") {
|
|
1895
|
+
const spreadExpr = toEvalNode(p.expr);
|
|
1896
|
+
if (!spreadExpr)
|
|
1897
|
+
return null;
|
|
1898
|
+
properties.push({ kind: "spread", expr: spreadExpr });
|
|
1899
|
+
continue;
|
|
1900
|
+
}
|
|
1880
1901
|
const value = toEvalNode(p.value);
|
|
1881
1902
|
if (!value)
|
|
1882
1903
|
return null;
|
|
1883
|
-
properties.push({ key: p.key, value });
|
|
1904
|
+
properties.push({ kind: "prop", key: p.key, value });
|
|
1884
1905
|
}
|
|
1885
1906
|
return { kind: "object-literal", properties };
|
|
1886
1907
|
}
|
|
@@ -2985,6 +3006,8 @@ function matchToLocaleDateStringCall(callee, args, metadata) {
|
|
|
2985
3006
|
let tz = null;
|
|
2986
3007
|
const probeOptions = {};
|
|
2987
3008
|
for (const prop of options.properties) {
|
|
3009
|
+
if (prop.kind === "spread")
|
|
3010
|
+
return null;
|
|
2988
3011
|
if (prop.value.kind !== "literal" || prop.value.literalType !== "string")
|
|
2989
3012
|
return null;
|
|
2990
3013
|
const value = String(prop.value.value);
|
|
@@ -3918,7 +3941,7 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
|
|
|
3918
3941
|
|
|
3919
3942
|
// ../jsx/src/ssr-seed-plan.ts
|
|
3920
3943
|
function classify(name, origin, expr, parsed, available) {
|
|
3921
|
-
if (!
|
|
3944
|
+
if (!isSupportedValue(parsed).supported)
|
|
3922
3945
|
return { kind: "opaque", name, origin };
|
|
3923
3946
|
const frees = freeIdentifiers(parsed);
|
|
3924
3947
|
if (frees === null)
|
|
@@ -3981,7 +4004,7 @@ function computeSsrSeedPlan(metadata) {
|
|
|
3981
4004
|
}
|
|
3982
4005
|
}
|
|
3983
4006
|
const expr = signal.initialValue.trim();
|
|
3984
|
-
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(parseExpression(expr), localConsts), available));
|
|
4007
|
+
steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(signal.parsed ?? parseExpression(`(${expr})`), localConsts), available));
|
|
3985
4008
|
available.add(signal.getter);
|
|
3986
4009
|
}
|
|
3987
4010
|
for (const memo of metadata.memos) {
|
|
@@ -4605,6 +4628,26 @@ function isStringTypedOperand(expr, isStringName) {
|
|
|
4605
4628
|
function isStringConcatBinary(op, left, right, isStringName) {
|
|
4606
4629
|
return op === "+" && (isStringTypedOperand(left, isStringName) || isStringTypedOperand(right, isStringName));
|
|
4607
4630
|
}
|
|
4631
|
+
function groupObjectLiteralSegments(properties, literalOf, emit) {
|
|
4632
|
+
const segments = [];
|
|
4633
|
+
let run = [];
|
|
4634
|
+
const flushRun = () => {
|
|
4635
|
+
if (run.length > 0) {
|
|
4636
|
+
segments.push(literalOf(run));
|
|
4637
|
+
run = [];
|
|
4638
|
+
}
|
|
4639
|
+
};
|
|
4640
|
+
for (const p of properties) {
|
|
4641
|
+
if (p.kind === "spread") {
|
|
4642
|
+
flushRun();
|
|
4643
|
+
segments.push(emit(p.expr));
|
|
4644
|
+
} else {
|
|
4645
|
+
run.push(p);
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
4648
|
+
flushRun();
|
|
4649
|
+
return segments;
|
|
4650
|
+
}
|
|
4608
4651
|
function emitParsedExpr(expr, emitter) {
|
|
4609
4652
|
const emit = (child) => emitParsedExpr(child, emitter);
|
|
4610
4653
|
switch (expr.kind) {
|
|
@@ -4751,6 +4794,17 @@ function evaluateStaticLiteral(expr, bindings) {
|
|
|
4751
4794
|
case "object-literal": {
|
|
4752
4795
|
const out = {};
|
|
4753
4796
|
for (const prop of expr.properties) {
|
|
4797
|
+
if (prop.kind === "spread") {
|
|
4798
|
+
const resolved2 = evaluateStaticLiteral(prop.expr, bindings);
|
|
4799
|
+
if (!resolved2)
|
|
4800
|
+
return null;
|
|
4801
|
+
if (resolved2.value === null || resolved2.value === undefined)
|
|
4802
|
+
continue;
|
|
4803
|
+
if (typeof resolved2.value !== "object" || Array.isArray(resolved2.value))
|
|
4804
|
+
return null;
|
|
4805
|
+
Object.assign(out, resolved2.value);
|
|
4806
|
+
continue;
|
|
4807
|
+
}
|
|
4754
4808
|
const resolved = evaluateStaticLiteral(prop.value, bindings);
|
|
4755
4809
|
if (!resolved)
|
|
4756
4810
|
return null;
|
|
@@ -4817,6 +4871,8 @@ function matchQueryHrefCall(callee, args, localNames) {
|
|
|
4817
4871
|
return null;
|
|
4818
4872
|
const triples = [];
|
|
4819
4873
|
for (const p of obj.properties) {
|
|
4874
|
+
if (p.kind === "spread")
|
|
4875
|
+
return null;
|
|
4820
4876
|
const v = p.value;
|
|
4821
4877
|
if (v.kind === "conditional" && isOmitBranch(v.alternate)) {
|
|
4822
4878
|
triples.push({ guard: v.test, key: p.key, value: v.consequent });
|
|
@@ -4980,6 +5036,8 @@ function htmlPropValue(parsed) {
|
|
|
4980
5036
|
if (parsed.properties.length !== 1)
|
|
4981
5037
|
return null;
|
|
4982
5038
|
const [prop] = parsed.properties;
|
|
5039
|
+
if (prop.kind === "spread")
|
|
5040
|
+
return null;
|
|
4983
5041
|
if (prop.key !== "__html")
|
|
4984
5042
|
return null;
|
|
4985
5043
|
return prop.value;
|
|
@@ -5849,7 +5907,7 @@ function isSubstituteSafeBody(body, paramNames) {
|
|
|
5849
5907
|
if (n.kind === "identifier")
|
|
5850
5908
|
return paramNames.has(n.name);
|
|
5851
5909
|
if (n.kind === "object-literal") {
|
|
5852
|
-
return n.properties.some((p) => p.shorthand && paramNames.has(p.key) || referencesParam(p.value));
|
|
5910
|
+
return n.properties.some((p) => p.kind === "spread" ? referencesParam(p.expr) : p.shorthand && paramNames.has(p.key) || referencesParam(p.value));
|
|
5853
5911
|
}
|
|
5854
5912
|
let hit = false;
|
|
5855
5913
|
forEachValueChild(n, (c) => {
|
|
@@ -6204,6 +6262,8 @@ function bakeInlineObjectAsGoMap(ctx, expr) {
|
|
|
6204
6262
|
return null;
|
|
6205
6263
|
const entries = [];
|
|
6206
6264
|
for (const prop of expr.properties) {
|
|
6265
|
+
if (prop.kind === "spread")
|
|
6266
|
+
return null;
|
|
6207
6267
|
if (prop.shorthand)
|
|
6208
6268
|
return null;
|
|
6209
6269
|
const go = prop.value.kind === "object-literal" ? bakeInlineObjectAsGoMap(ctx, prop.value) : parsedLiteralToGo(ctx, prop.value);
|
|
@@ -6259,6 +6319,8 @@ function parsedLiteralToGo(ctx, expr, typeInfo) {
|
|
|
6259
6319
|
return null;
|
|
6260
6320
|
const entries = [];
|
|
6261
6321
|
for (const prop of expr.properties) {
|
|
6322
|
+
if (prop.kind === "spread")
|
|
6323
|
+
return null;
|
|
6262
6324
|
const goField = structFields.get(prop.key);
|
|
6263
6325
|
if (!goField)
|
|
6264
6326
|
return null;
|
|
@@ -6380,6 +6442,8 @@ function objectLiteralToGoMap(ctx, expr) {
|
|
|
6380
6442
|
return null;
|
|
6381
6443
|
const entries = [];
|
|
6382
6444
|
for (const prop of expr.properties) {
|
|
6445
|
+
if (prop.kind === "spread")
|
|
6446
|
+
return null;
|
|
6383
6447
|
if (prop.shorthand)
|
|
6384
6448
|
return null;
|
|
6385
6449
|
const val = parsedLiteralToGo(ctx, prop.value);
|
|
@@ -6458,17 +6522,18 @@ function resolveMapJoinBaseAsGo(ctx, object, signals, propsParams) {
|
|
|
6458
6522
|
}
|
|
6459
6523
|
return null;
|
|
6460
6524
|
}
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6525
|
+
var CALLBACK_EVAL_FUNC = { map: "bf.MapEval", filter: "bf.FilterEval" };
|
|
6526
|
+
function callbackStepToGo(ctx, method, itemsGo, arrow, signals, propsParams, propFallbackVars) {
|
|
6527
|
+
const evalFunc = CALLBACK_EVAL_FUNC[method];
|
|
6528
|
+
if (!evalFunc)
|
|
6464
6529
|
return null;
|
|
6465
6530
|
const knownGetterNames = new Set(signals.map((s) => s.getter));
|
|
6466
|
-
const materialized = materializeGetterCalls(
|
|
6531
|
+
const materialized = materializeGetterCalls(arrow.body, knownGetterNames);
|
|
6467
6532
|
const projJSON = serializeParsedExpr(materialized);
|
|
6468
6533
|
if (projJSON === null)
|
|
6469
6534
|
return null;
|
|
6470
|
-
const paramName =
|
|
6471
|
-
const freeVars = freeVarsInBody(materialized, new Set(
|
|
6535
|
+
const paramName = arrow.params[0] ?? "_";
|
|
6536
|
+
const freeVars = freeVarsInBody(materialized, new Set(arrow.params));
|
|
6472
6537
|
const envEntries = [];
|
|
6473
6538
|
for (const name of freeVars) {
|
|
6474
6539
|
const sig = signals.find((s) => s.getter === name);
|
|
@@ -6485,6 +6550,25 @@ function mapJoinChainToGo(ctx, chain, signals, propsParams, propFallbackVars) {
|
|
|
6485
6550
|
envEntries.push(`${JSON.stringify(name)}: ${goExpr}`);
|
|
6486
6551
|
}
|
|
6487
6552
|
const envMap = `map[string]any{${envEntries.join(", ")}}`;
|
|
6553
|
+
return `${evalFunc}(${itemsGo}, "${escapeGoString(projJSON)}", ${JSON.stringify(paramName)}, ${envMap})`;
|
|
6554
|
+
}
|
|
6555
|
+
function resolveMapChainAsGo(ctx, expr, signals, propsParams, propFallbackVars) {
|
|
6556
|
+
const cb = asCallbackMethodCall(expr);
|
|
6557
|
+
if (cb && cb.method in CALLBACK_EVAL_FUNC) {
|
|
6558
|
+
const innerGo = resolveMapChainAsGo(ctx, cb.object, signals, propsParams, propFallbackVars);
|
|
6559
|
+
if (innerGo === null)
|
|
6560
|
+
return null;
|
|
6561
|
+
return callbackStepToGo(ctx, cb.method, innerGo, cb.arrow, signals, propsParams, propFallbackVars);
|
|
6562
|
+
}
|
|
6563
|
+
return resolveMapJoinBaseAsGo(ctx, expr, signals, propsParams);
|
|
6564
|
+
}
|
|
6565
|
+
function mapJoinChainToGo(ctx, chain, signals, propsParams, propFallbackVars) {
|
|
6566
|
+
const itemsGo = resolveMapChainAsGo(ctx, chain.object, signals, propsParams, propFallbackVars);
|
|
6567
|
+
if (itemsGo === null)
|
|
6568
|
+
return null;
|
|
6569
|
+
const mapGo = callbackStepToGo(ctx, "map", itemsGo, chain.arrow, signals, propsParams, propFallbackVars);
|
|
6570
|
+
if (mapGo === null)
|
|
6571
|
+
return null;
|
|
6488
6572
|
let sepGo;
|
|
6489
6573
|
if (!chain.sepArg) {
|
|
6490
6574
|
sepGo = JSON.stringify(",");
|
|
@@ -6493,7 +6577,7 @@ function mapJoinChainToGo(ctx, chain, signals, propsParams, propFallbackVars) {
|
|
|
6493
6577
|
} else {
|
|
6494
6578
|
return null;
|
|
6495
6579
|
}
|
|
6496
|
-
return `bf.Join(
|
|
6580
|
+
return `bf.Join(${mapGo}, ${sepGo})`;
|
|
6497
6581
|
}
|
|
6498
6582
|
|
|
6499
6583
|
// src/adapter/memo/memo-type.ts
|
|
@@ -6780,6 +6864,8 @@ function computeObjectMemoInitialValue(ctx, memo) {
|
|
|
6780
6864
|
const env = { searchParamsVars: new Set, params: new Map };
|
|
6781
6865
|
const entries = [];
|
|
6782
6866
|
for (const prop of retObj.properties) {
|
|
6867
|
+
if (prop.kind === "spread")
|
|
6868
|
+
return null;
|
|
6783
6869
|
if (prop.shorthand)
|
|
6784
6870
|
return null;
|
|
6785
6871
|
if (prop.keyKind !== undefined && prop.keyKind !== "identifier" && prop.keyKind !== "string") {
|
|
@@ -6903,6 +6989,8 @@ function recordIndexInterpolationToGo(ctx, node, propNames, localKeyBindings) {
|
|
|
6903
6989
|
return null;
|
|
6904
6990
|
const entries = [];
|
|
6905
6991
|
for (const prop of parsedConst.properties) {
|
|
6992
|
+
if (prop.kind === "spread")
|
|
6993
|
+
return null;
|
|
6906
6994
|
const v = prop.value;
|
|
6907
6995
|
if (v.kind === "literal" && v.literalType === "number") {
|
|
6908
6996
|
entries.push({ key: prop.key, value: { kind: "number", text: v.raw ?? String(v.value) } });
|
|
@@ -7229,6 +7317,12 @@ function memoInitialFromParsedBody(ctx, body, signals, propsParams, propFallback
|
|
|
7229
7317
|
if (concatGo !== null)
|
|
7230
7318
|
return concatGo;
|
|
7231
7319
|
}
|
|
7320
|
+
const bareChain = matchMapJoinChain(body);
|
|
7321
|
+
if (bareChain) {
|
|
7322
|
+
const chainGo = mapJoinChainToGo(ctx, bareChain, signals, propsParams, propFallbackVars);
|
|
7323
|
+
if (chainGo !== null)
|
|
7324
|
+
return chainGo;
|
|
7325
|
+
}
|
|
7232
7326
|
return null;
|
|
7233
7327
|
}
|
|
7234
7328
|
function resolveStringConcatChainGo(ctx, expr, signals, propsParams, propFallbackVars, propRef) {
|
|
@@ -7400,7 +7494,7 @@ function collectPropsReadByCtorInit(body, propsObjectName, propNames) {
|
|
|
7400
7494
|
return;
|
|
7401
7495
|
case "object-literal":
|
|
7402
7496
|
for (const p of e.properties)
|
|
7403
|
-
visit(p.value, bound);
|
|
7497
|
+
visit(p.kind === "spread" ? p.expr : p.value, bound);
|
|
7404
7498
|
return;
|
|
7405
7499
|
case "array-method":
|
|
7406
7500
|
visit(e.object, bound);
|
|
@@ -7511,6 +7605,8 @@ function parsedObjectLiteralToGoMap(parsed) {
|
|
|
7511
7605
|
return null;
|
|
7512
7606
|
const entries = [];
|
|
7513
7607
|
for (const prop of parsed.properties) {
|
|
7608
|
+
if (prop.kind === "spread")
|
|
7609
|
+
return null;
|
|
7514
7610
|
if (prop.keyKind === "numeric")
|
|
7515
7611
|
return null;
|
|
7516
7612
|
const v = prop.value;
|
|
@@ -7635,6 +7731,8 @@ function conditionToGoBool(condition, ir) {
|
|
|
7635
7731
|
function objectLiteralToGoSpreadMap(ctx, obj, ir) {
|
|
7636
7732
|
const entries = [];
|
|
7637
7733
|
for (const prop of obj.properties) {
|
|
7734
|
+
if (prop.kind === "spread")
|
|
7735
|
+
return null;
|
|
7638
7736
|
if (prop.shorthand)
|
|
7639
7737
|
return null;
|
|
7640
7738
|
if (prop.keyKind === "numeric")
|
|
@@ -8449,6 +8547,8 @@ ${goFields.join(`
|
|
|
8449
8547
|
return null;
|
|
8450
8548
|
const seen = new Set;
|
|
8451
8549
|
for (const prop of el.properties) {
|
|
8550
|
+
if (prop.kind === "spread")
|
|
8551
|
+
return null;
|
|
8452
8552
|
if (prop.shorthand)
|
|
8453
8553
|
return null;
|
|
8454
8554
|
const key = prop.key;
|
|
@@ -9620,6 +9720,8 @@ ${goFields.join(`
|
|
|
9620
9720
|
return null;
|
|
9621
9721
|
const entries = [];
|
|
9622
9722
|
for (const prop of parsed.properties) {
|
|
9723
|
+
if (prop.kind === "spread")
|
|
9724
|
+
return null;
|
|
9623
9725
|
if (prop.shorthand)
|
|
9624
9726
|
return null;
|
|
9625
9727
|
const goVal = this.lowerProviderMapMemberValue(prop.value, propsParams);
|
|
@@ -10386,7 +10488,16 @@ ${goFields.join(`
|
|
|
10386
10488
|
});
|
|
10387
10489
|
return `bf_arr ${parts.join(" ")}`;
|
|
10388
10490
|
}
|
|
10389
|
-
objectLiteral(
|
|
10491
|
+
objectLiteral(properties, raw, emit) {
|
|
10492
|
+
if (properties.length > 0) {
|
|
10493
|
+
const wrap = (rendered) => rendered.includes(" ") ? `(${rendered})` : rendered;
|
|
10494
|
+
const literalOf = (run) => `bf_map ${run.map((p) => `"${escapeGoString(p.key)}" ${wrap(emit(p.value))}`).join(" ")}`;
|
|
10495
|
+
if (!properties.some((p) => p.kind === "spread")) {
|
|
10496
|
+
return literalOf(properties);
|
|
10497
|
+
}
|
|
10498
|
+
const segments = groupObjectLiteralSegments(properties, literalOf, (e) => wrap(emit(e)));
|
|
10499
|
+
return `bf_merge ${segments.join(" ")}`;
|
|
10500
|
+
}
|
|
10390
10501
|
this.state.errors.push({
|
|
10391
10502
|
code: "BF101",
|
|
10392
10503
|
severity: "error",
|
|
@@ -11109,7 +11220,7 @@ ${goFields.join(`
|
|
|
11109
11220
|
return null;
|
|
11110
11221
|
const carried = constInfo.parsed;
|
|
11111
11222
|
if (carried?.kind === "object-literal") {
|
|
11112
|
-
const hit = carried.properties.find((prop) => prop.key === key);
|
|
11223
|
+
const hit = carried.properties.find((prop) => prop.kind === "prop" && prop.key === key);
|
|
11113
11224
|
if (hit && hit.value.kind === "literal") {
|
|
11114
11225
|
if (hit.value.literalType === "string")
|
|
11115
11226
|
return JSON.stringify(hit.value.value);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/go-template",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "Go html/template adapter for BarefootJS - generates Go template files from IR",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"directory": "packages/adapter-go-template"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@barefootjs/shared": "0.
|
|
52
|
+
"@barefootjs/shared": "0.33.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@barefootjs/jsx": ">=0.2.0",
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
70
|
-
"@barefootjs/client": "0.
|
|
71
|
-
"@barefootjs/jsx": "0.
|
|
72
|
-
"@barefootjs/vite": "0.
|
|
70
|
+
"@barefootjs/client": "0.33.0",
|
|
71
|
+
"@barefootjs/jsx": "0.33.0",
|
|
72
|
+
"@barefootjs/vite": "0.33.0",
|
|
73
73
|
"vite": "^6.0.0"
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -86,8 +86,10 @@ function isSubstituteSafeBody(body: ParsedExpr, paramNames: ReadonlySet<string>)
|
|
|
86
86
|
const referencesParam = (n: ParsedExpr): boolean => {
|
|
87
87
|
if (n.kind === 'identifier') return paramNames.has(n.name)
|
|
88
88
|
if (n.kind === 'object-literal') {
|
|
89
|
-
return n.properties.some(
|
|
90
|
-
p
|
|
89
|
+
return n.properties.some(p =>
|
|
90
|
+
p.kind === 'spread'
|
|
91
|
+
? referencesParam(p.expr)
|
|
92
|
+
: (p.shorthand && paramNames.has(p.key)) || referencesParam(p.value),
|
|
91
93
|
)
|
|
92
94
|
}
|
|
93
95
|
let hit = false
|