@barefootjs/go-template 0.1.2 → 0.2.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/go-template-adapter.d.ts +16 -9
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +158 -90
- package/dist/build.js +158 -90
- package/dist/index.js +158 -90
- package/package.json +3 -3
- package/src/__tests__/go-template-adapter.test.ts +145 -10
- package/src/adapter/go-template-adapter.ts +191 -144
package/dist/build.js
CHANGED
|
@@ -420,9 +420,11 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
420
420
|
options;
|
|
421
421
|
inLoop = false;
|
|
422
422
|
loopParamStack = [];
|
|
423
|
+
loopVarRefCount = new Map;
|
|
423
424
|
errors = [];
|
|
424
425
|
propsObjectName = null;
|
|
425
426
|
restPropsName = null;
|
|
427
|
+
templateVarCounter = 0;
|
|
426
428
|
localTypeNames = new Set;
|
|
427
429
|
localTypeAliases = new Map;
|
|
428
430
|
usesHtmlTemplate = false;
|
|
@@ -437,6 +439,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
437
439
|
generate(ir, options) {
|
|
438
440
|
this.componentName = ir.metadata.componentName;
|
|
439
441
|
this.errors = [];
|
|
442
|
+
this.templateVarCounter = 0;
|
|
440
443
|
this.propsObjectName = ir.metadata.propsObjectName;
|
|
441
444
|
this.restPropsName = ir.metadata.restPropsName ?? null;
|
|
442
445
|
if (!options?.siblingTemplatesRegistered) {
|
|
@@ -776,7 +779,7 @@ ${goFields.join(`
|
|
|
776
779
|
lines.push("\tScopeID string // Optional: if empty, random ID is generated");
|
|
777
780
|
lines.push("\tBfParent string // Optional: parent scope id");
|
|
778
781
|
lines.push("\tBfMount string // Optional: slot id in parent");
|
|
779
|
-
const
|
|
782
|
+
const inputNested = nestedComponents.filter((n) => !n.isDynamic || n.isPropDerived);
|
|
780
783
|
const nestedArrayFields = new Set(nestedComponents.map((n) => `${n.name}s`));
|
|
781
784
|
for (const param of ir.metadata.propsParams) {
|
|
782
785
|
const fieldName = this.capitalizeFieldName(param.name);
|
|
@@ -785,7 +788,7 @@ ${goFields.join(`
|
|
|
785
788
|
const goType = propTypeOverrides.get(param.name) ?? this.typeInfoToGo(param.type, param.defaultValue);
|
|
786
789
|
lines.push(` ${fieldName} ${goType}`);
|
|
787
790
|
}
|
|
788
|
-
for (const nested of
|
|
791
|
+
for (const nested of inputNested) {
|
|
789
792
|
lines.push(` ${nested.name}s []${nested.name}Input`);
|
|
790
793
|
}
|
|
791
794
|
const restPropsName = ir.metadata.restPropsName;
|
|
@@ -861,7 +864,7 @@ ${goFields.join(`
|
|
|
861
864
|
lines.push(` ${fieldName} ${goType} \`json:"${jsonTag}"\``);
|
|
862
865
|
}
|
|
863
866
|
for (const nested of nestedComponents) {
|
|
864
|
-
if (nested.isDynamic) {
|
|
867
|
+
if (nested.isDynamic && !nested.isPropDerived) {
|
|
865
868
|
lines.push(` ${nested.name}s []${nested.name}Props \`json:"-"\``);
|
|
866
869
|
} else {
|
|
867
870
|
const jsonTag = this.toJsonTag(`${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`);
|
|
@@ -882,9 +885,9 @@ ${goFields.join(`
|
|
|
882
885
|
generateNewPropsFunction(lines, ir, componentName, nestedComponents, spreadSlots) {
|
|
883
886
|
const inputTypeName = `${componentName}Input`;
|
|
884
887
|
const propsTypeName = `${componentName}Props`;
|
|
885
|
-
const
|
|
888
|
+
const signalDynamicNested = nestedComponents.filter((n) => n.isDynamic && !n.isPropDerived);
|
|
886
889
|
lines.push(`// New${componentName}Props creates ${propsTypeName} from ${inputTypeName}.`);
|
|
887
|
-
for (const nested of
|
|
890
|
+
for (const nested of signalDynamicNested) {
|
|
888
891
|
const arrayField = `${nested.name}s`;
|
|
889
892
|
lines.push(`//`);
|
|
890
893
|
lines.push(`// NOTE: \`${arrayField}\` is populated by the route handler, not by`);
|
|
@@ -906,7 +909,7 @@ ${goFields.join(`
|
|
|
906
909
|
lines.push(` scopeID = "${componentName}_" + randomID(6)`);
|
|
907
910
|
lines.push("\t}");
|
|
908
911
|
lines.push("");
|
|
909
|
-
const staticNested = nestedComponents.filter((n) => !n.isDynamic);
|
|
912
|
+
const staticNested = nestedComponents.filter((n) => !n.isDynamic || n.isPropDerived);
|
|
910
913
|
if (staticNested.length > 0) {
|
|
911
914
|
for (const nested of staticNested) {
|
|
912
915
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
@@ -1054,7 +1057,8 @@ ${goFields.join(`
|
|
|
1054
1057
|
if (!result.some((c) => c.name === loop.childComponent.name)) {
|
|
1055
1058
|
result.push({
|
|
1056
1059
|
...loop.childComponent,
|
|
1057
|
-
isDynamic: !loop.isStaticArray
|
|
1060
|
+
isDynamic: !loop.isStaticArray,
|
|
1061
|
+
isPropDerived: !!loop.isPropDerivedArray
|
|
1058
1062
|
});
|
|
1059
1063
|
}
|
|
1060
1064
|
}
|
|
@@ -1871,13 +1875,18 @@ ${goFields.join(`
|
|
|
1871
1875
|
return emitParsedExpr(expr, this);
|
|
1872
1876
|
}
|
|
1873
1877
|
identifier(name) {
|
|
1878
|
+
const currentLoopParam = this.loopParamStack[this.loopParamStack.length - 1];
|
|
1879
|
+
if (currentLoopParam && name === currentLoopParam)
|
|
1880
|
+
return ".";
|
|
1881
|
+
if (this.loopVarRefCount.has(name))
|
|
1882
|
+
return `$${name}`;
|
|
1874
1883
|
return `.${this.capitalizeFieldName(name)}`;
|
|
1875
1884
|
}
|
|
1876
1885
|
literal(value, literalType) {
|
|
1877
1886
|
if (literalType === "string")
|
|
1878
1887
|
return `"${value}"`;
|
|
1879
1888
|
if (literalType === "null")
|
|
1880
|
-
return
|
|
1889
|
+
return "nil";
|
|
1881
1890
|
return String(value);
|
|
1882
1891
|
}
|
|
1883
1892
|
call(callee, args, emit) {
|
|
@@ -1913,7 +1922,7 @@ ${goFields.join(`
|
|
|
1913
1922
|
if (result)
|
|
1914
1923
|
return result;
|
|
1915
1924
|
}
|
|
1916
|
-
if (object.kind === "higher-order" && object.method === "find") {
|
|
1925
|
+
if (object.kind === "higher-order" && (object.method === "find" || object.method === "findLast")) {
|
|
1917
1926
|
const findResult = this.renderHigherOrderExpr(object, emit);
|
|
1918
1927
|
if (findResult) {
|
|
1919
1928
|
return `{{with ${findResult}}}{{.${this.capitalizeFieldName(property)}}}{{end}}`;
|
|
@@ -2017,7 +2026,7 @@ ${goFields.join(`
|
|
|
2017
2026
|
const result = this.renderHigherOrderExpr(reconstructed, emit);
|
|
2018
2027
|
if (result)
|
|
2019
2028
|
return result;
|
|
2020
|
-
if (method === "find" || method === "findIndex") {
|
|
2029
|
+
if (method === "find" || method === "findIndex" || method === "findLast" || method === "findLastIndex") {
|
|
2021
2030
|
const templateBlock = this.renderFindTemplateBlock(reconstructed, emit);
|
|
2022
2031
|
if (templateBlock)
|
|
2023
2032
|
return templateBlock;
|
|
@@ -2157,12 +2166,17 @@ ${goFields.join(`
|
|
|
2157
2166
|
const value = negated ? "false" : "true";
|
|
2158
2167
|
return `bf_filter ${arrayExpr} "${field}" ${value}`;
|
|
2159
2168
|
}
|
|
2160
|
-
if (expr.method === "find" || expr.method === "findIndex") {
|
|
2169
|
+
if (expr.method === "find" || expr.method === "findIndex" || expr.method === "findLast" || expr.method === "findLastIndex") {
|
|
2161
2170
|
const eqPred = this.extractEqualityPredicate(expr.predicate, expr.param, (e) => this.renderParsedExpr(e));
|
|
2162
2171
|
if (!eqPred)
|
|
2163
2172
|
return null;
|
|
2164
|
-
const
|
|
2165
|
-
|
|
2173
|
+
const funcMap = {
|
|
2174
|
+
find: "bf_find",
|
|
2175
|
+
findIndex: "bf_find_index",
|
|
2176
|
+
findLast: "bf_find_last",
|
|
2177
|
+
findLastIndex: "bf_find_last_index"
|
|
2178
|
+
};
|
|
2179
|
+
return `${funcMap[expr.method]} ${arrayExpr} "${eqPred.field}" ${eqPred.value}`;
|
|
2166
2180
|
}
|
|
2167
2181
|
return null;
|
|
2168
2182
|
}
|
|
@@ -2178,6 +2192,15 @@ ${goFields.join(`
|
|
|
2178
2192
|
if (expr.method === "findIndex") {
|
|
2179
2193
|
return `{{range $i, $_ := ${arrayExpr}}}{{if ${condition}}}{{$i}}{{break}}{{end}}{{end}}`;
|
|
2180
2194
|
}
|
|
2195
|
+
if (expr.method === "findLast") {
|
|
2196
|
+
const v = `$bf_r${this.templateVarCounter++}`;
|
|
2197
|
+
const capture = propertyAccess ? `.${propertyAccess}` : ".";
|
|
2198
|
+
return `{{${v} := ""}}{{range ${arrayExpr}}}{{if ${condition}}}{{${v} = ${capture}}}{{end}}{{end}}{{${v}}}`;
|
|
2199
|
+
}
|
|
2200
|
+
if (expr.method === "findLastIndex") {
|
|
2201
|
+
const v = `$bf_r${this.templateVarCounter++}`;
|
|
2202
|
+
return `{{${v} := -1}}{{range $i, $_ := ${arrayExpr}}}{{if ${condition}}}{{${v} = $i}}{{end}}{{end}}{{${v}}}`;
|
|
2203
|
+
}
|
|
2181
2204
|
return null;
|
|
2182
2205
|
}
|
|
2183
2206
|
renderEverySomeTemplateBlock(expr, renderArray) {
|
|
@@ -2186,11 +2209,13 @@ ${goFields.join(`
|
|
|
2186
2209
|
if (condition.includes("[UNSUPPORTED"))
|
|
2187
2210
|
return null;
|
|
2188
2211
|
if (expr.method === "every") {
|
|
2212
|
+
const v = `$bf_r${this.templateVarCounter++}`;
|
|
2189
2213
|
const negated = this.negateGoCondition(condition);
|
|
2190
|
-
return `{{$
|
|
2214
|
+
return `{{${v} := true}}{{range ${arrayExpr}}}{{if ${negated}}}{{${v} = false}}{{break}}{{end}}{{end}}{{${v}}}`;
|
|
2191
2215
|
}
|
|
2192
2216
|
if (expr.method === "some") {
|
|
2193
|
-
|
|
2217
|
+
const v = `$bf_r${this.templateVarCounter++}`;
|
|
2218
|
+
return `{{${v} := false}}{{range ${arrayExpr}}}{{if ${condition}}}{{${v} = true}}{{break}}{{end}}{{end}}{{${v}}}`;
|
|
2194
2219
|
}
|
|
2195
2220
|
return null;
|
|
2196
2221
|
}
|
|
@@ -2219,6 +2244,22 @@ ${goFields.join(`
|
|
|
2219
2244
|
needsParens(expr) {
|
|
2220
2245
|
return expr.kind === "logical" || expr.kind === "unary" || expr.kind === "conditional";
|
|
2221
2246
|
}
|
|
2247
|
+
splitPreamble(rendered) {
|
|
2248
|
+
if (!rendered.includes("{{"))
|
|
2249
|
+
return null;
|
|
2250
|
+
const lastOpen = rendered.lastIndexOf("{{");
|
|
2251
|
+
const lastClose = rendered.lastIndexOf("}}");
|
|
2252
|
+
if (lastOpen >= 0 && lastClose > lastOpen) {
|
|
2253
|
+
const candidate = rendered.substring(lastOpen + 2, lastClose);
|
|
2254
|
+
if (!candidate.startsWith("$"))
|
|
2255
|
+
return null;
|
|
2256
|
+
return {
|
|
2257
|
+
preamble: rendered.substring(0, lastOpen),
|
|
2258
|
+
expr: candidate
|
|
2259
|
+
};
|
|
2260
|
+
}
|
|
2261
|
+
return null;
|
|
2262
|
+
}
|
|
2222
2263
|
renderBlockBodyCondition(statements, param) {
|
|
2223
2264
|
const localVarMap = new Map;
|
|
2224
2265
|
const paths = this.collectReturnPaths(statements, [], localVarMap, param);
|
|
@@ -2339,7 +2380,7 @@ ${goFields.join(`
|
|
|
2339
2380
|
return `"${expr.value}"`;
|
|
2340
2381
|
}
|
|
2341
2382
|
if (expr.literalType === "null") {
|
|
2342
|
-
return
|
|
2383
|
+
return "nil";
|
|
2343
2384
|
}
|
|
2344
2385
|
return String(expr.value);
|
|
2345
2386
|
case "member": {
|
|
@@ -2616,138 +2657,141 @@ Options:
|
|
|
2616
2657
|
});
|
|
2617
2658
|
return { condition: `false`, preamble: "" };
|
|
2618
2659
|
}
|
|
2619
|
-
const
|
|
2620
|
-
|
|
2621
|
-
const lastOpen = rendered.lastIndexOf("{{");
|
|
2622
|
-
const lastClose = rendered.lastIndexOf("}}");
|
|
2623
|
-
if (lastOpen >= 0 && lastClose > lastOpen) {
|
|
2624
|
-
const preamble = rendered.substring(0, lastOpen);
|
|
2625
|
-
const condition = rendered.substring(lastOpen + 2, lastClose);
|
|
2626
|
-
return { condition, preamble };
|
|
2627
|
-
}
|
|
2628
|
-
}
|
|
2629
|
-
return { condition: rendered, preamble: "" };
|
|
2660
|
+
const { preamble, expr: condition } = this.renderConditionExpr(parsed);
|
|
2661
|
+
return { condition, preamble };
|
|
2630
2662
|
}
|
|
2631
2663
|
renderConditionExpr(expr) {
|
|
2664
|
+
const plain = (e) => ({ preamble: "", expr: e });
|
|
2632
2665
|
switch (expr.kind) {
|
|
2633
2666
|
case "identifier":
|
|
2634
2667
|
{
|
|
2635
2668
|
const currentLoopParam = this.loopParamStack[this.loopParamStack.length - 1];
|
|
2636
2669
|
if (currentLoopParam && expr.name === currentLoopParam) {
|
|
2637
|
-
return ".";
|
|
2670
|
+
return plain(".");
|
|
2671
|
+
}
|
|
2672
|
+
if (this.loopVarRefCount.has(expr.name)) {
|
|
2673
|
+
return plain(`$${expr.name}`);
|
|
2638
2674
|
}
|
|
2639
2675
|
}
|
|
2640
|
-
return `.${this.capitalizeFieldName(expr.name)}
|
|
2676
|
+
return plain(`.${this.capitalizeFieldName(expr.name)}`);
|
|
2641
2677
|
case "literal":
|
|
2642
|
-
if (expr.literalType === "string")
|
|
2643
|
-
return `"${expr.value}"
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
}
|
|
2648
|
-
return String(expr.value);
|
|
2678
|
+
if (expr.literalType === "string")
|
|
2679
|
+
return plain(`"${expr.value}"`);
|
|
2680
|
+
if (expr.literalType === "null")
|
|
2681
|
+
return plain("nil");
|
|
2682
|
+
return plain(String(expr.value));
|
|
2649
2683
|
case "call": {
|
|
2650
2684
|
if (expr.callee.kind === "identifier" && expr.args.length === 0) {
|
|
2651
|
-
return `.${this.capitalizeFieldName(expr.callee.name)}
|
|
2685
|
+
return plain(`.${this.capitalizeFieldName(expr.callee.name)}`);
|
|
2652
2686
|
}
|
|
2653
|
-
return this.renderParsedExpr(expr);
|
|
2687
|
+
return plain(this.renderParsedExpr(expr));
|
|
2654
2688
|
}
|
|
2655
2689
|
case "member": {
|
|
2656
2690
|
if (expr.property === "length" && expr.object.kind === "higher-order") {
|
|
2657
|
-
const result = this.renderFilterLengthExpr(expr.object, (e) => this.renderConditionExpr(e));
|
|
2658
|
-
if (result)
|
|
2659
|
-
return result;
|
|
2660
|
-
}
|
|
2691
|
+
const result = this.renderFilterLengthExpr(expr.object, (e) => this.renderConditionExpr(e).expr);
|
|
2692
|
+
if (result)
|
|
2693
|
+
return plain(result);
|
|
2661
2694
|
}
|
|
2662
2695
|
if (expr.object.kind === "identifier" && this.propsObjectName && expr.object.name === this.propsObjectName) {
|
|
2663
|
-
return `.${this.capitalizeFieldName(expr.property)}
|
|
2696
|
+
return plain(`.${this.capitalizeFieldName(expr.property)}`);
|
|
2664
2697
|
}
|
|
2665
2698
|
{
|
|
2666
2699
|
const currentLoopParam = this.loopParamStack[this.loopParamStack.length - 1];
|
|
2667
2700
|
if (expr.object.kind === "identifier" && currentLoopParam && expr.object.name === currentLoopParam) {
|
|
2668
|
-
return `.${this.capitalizeFieldName(expr.property)}
|
|
2701
|
+
return plain(`.${this.capitalizeFieldName(expr.property)}`);
|
|
2669
2702
|
}
|
|
2670
2703
|
}
|
|
2671
2704
|
const obj = this.renderConditionExpr(expr.object);
|
|
2672
2705
|
if (expr.property === "length") {
|
|
2673
|
-
return `len ${obj}
|
|
2706
|
+
return { preamble: obj.preamble, expr: `len ${obj.expr}` };
|
|
2674
2707
|
}
|
|
2675
|
-
return `${obj}.${this.capitalizeFieldName(expr.property)}
|
|
2708
|
+
return { preamble: obj.preamble, expr: `${obj.expr}.${this.capitalizeFieldName(expr.property)}` };
|
|
2676
2709
|
}
|
|
2677
2710
|
case "binary": {
|
|
2678
2711
|
const leftNeedsParens = this.needsParensInGoTemplate(expr.left);
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
left = `(${left})`;
|
|
2682
|
-
}
|
|
2712
|
+
const leftResult = this.renderConditionExpr(expr.left);
|
|
2713
|
+
const left = leftNeedsParens ? `(${leftResult.expr})` : leftResult.expr;
|
|
2683
2714
|
const rightNeedsParens = this.needsParensInGoTemplate(expr.right);
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2715
|
+
const rightResult = this.renderConditionExpr(expr.right);
|
|
2716
|
+
const right = rightNeedsParens ? `(${rightResult.expr})` : rightResult.expr;
|
|
2717
|
+
const preamble = leftResult.preamble + rightResult.preamble;
|
|
2718
|
+
let result;
|
|
2688
2719
|
switch (expr.op) {
|
|
2689
2720
|
case "===":
|
|
2690
2721
|
case "==":
|
|
2691
|
-
|
|
2722
|
+
result = `eq ${left} ${right}`;
|
|
2723
|
+
break;
|
|
2692
2724
|
case "!==":
|
|
2693
2725
|
case "!=":
|
|
2694
|
-
|
|
2726
|
+
result = `ne ${left} ${right}`;
|
|
2727
|
+
break;
|
|
2695
2728
|
case ">":
|
|
2696
|
-
|
|
2729
|
+
result = `gt ${left} ${right}`;
|
|
2730
|
+
break;
|
|
2697
2731
|
case "<":
|
|
2698
|
-
|
|
2732
|
+
result = `lt ${left} ${right}`;
|
|
2733
|
+
break;
|
|
2699
2734
|
case ">=":
|
|
2700
|
-
|
|
2735
|
+
result = `ge ${left} ${right}`;
|
|
2736
|
+
break;
|
|
2701
2737
|
case "<=":
|
|
2702
|
-
|
|
2738
|
+
result = `le ${left} ${right}`;
|
|
2739
|
+
break;
|
|
2703
2740
|
case "+":
|
|
2704
|
-
|
|
2741
|
+
result = `bf_add ${left} ${right}`;
|
|
2742
|
+
break;
|
|
2705
2743
|
case "-":
|
|
2706
|
-
|
|
2744
|
+
result = `bf_sub ${left} ${right}`;
|
|
2745
|
+
break;
|
|
2707
2746
|
case "*":
|
|
2708
|
-
|
|
2747
|
+
result = `bf_mul ${left} ${right}`;
|
|
2748
|
+
break;
|
|
2709
2749
|
case "/":
|
|
2710
|
-
|
|
2750
|
+
result = `bf_div ${left} ${right}`;
|
|
2751
|
+
break;
|
|
2711
2752
|
default:
|
|
2712
|
-
|
|
2753
|
+
result = `${left} ${expr.op} ${right}`;
|
|
2713
2754
|
}
|
|
2755
|
+
return { preamble, expr: result };
|
|
2714
2756
|
}
|
|
2715
2757
|
case "unary": {
|
|
2716
2758
|
const arg = this.renderConditionExpr(expr.argument);
|
|
2717
|
-
if (expr.op === "!")
|
|
2718
|
-
return `not ${arg}
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
return `bf_neg ${arg}`;
|
|
2722
|
-
}
|
|
2759
|
+
if (expr.op === "!")
|
|
2760
|
+
return { preamble: arg.preamble, expr: `not ${arg.expr}` };
|
|
2761
|
+
if (expr.op === "-")
|
|
2762
|
+
return { preamble: arg.preamble, expr: `bf_neg ${arg.expr}` };
|
|
2723
2763
|
return arg;
|
|
2724
2764
|
}
|
|
2725
2765
|
case "logical": {
|
|
2726
|
-
const
|
|
2727
|
-
const
|
|
2728
|
-
const
|
|
2729
|
-
const
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
}
|
|
2733
|
-
return `or ${wrapLeft} ${wrapRight}`;
|
|
2766
|
+
const leftResult = this.renderConditionExpr(expr.left);
|
|
2767
|
+
const rightResult = this.renderConditionExpr(expr.right);
|
|
2768
|
+
const preamble = leftResult.preamble + rightResult.preamble;
|
|
2769
|
+
const wrapLeft = this.needsParens(expr.left) ? `(${leftResult.expr})` : leftResult.expr;
|
|
2770
|
+
const wrapRight = this.needsParens(expr.right) ? `(${rightResult.expr})` : rightResult.expr;
|
|
2771
|
+
const result = expr.op === "&&" ? `and ${wrapLeft} ${wrapRight}` : `or ${wrapLeft} ${wrapRight}`;
|
|
2772
|
+
return { preamble, expr: result };
|
|
2734
2773
|
}
|
|
2735
2774
|
case "conditional": {
|
|
2736
2775
|
const test = this.renderConditionExpr(expr.test);
|
|
2737
2776
|
return test;
|
|
2738
2777
|
}
|
|
2739
2778
|
case "template-literal":
|
|
2740
|
-
return this.renderParsedExpr(expr);
|
|
2779
|
+
return plain(this.renderParsedExpr(expr));
|
|
2741
2780
|
case "arrow-fn":
|
|
2742
|
-
return "[ARROW-FN]";
|
|
2743
|
-
case "higher-order":
|
|
2744
|
-
|
|
2781
|
+
return plain("[ARROW-FN]");
|
|
2782
|
+
case "higher-order": {
|
|
2783
|
+
const rendered = this.renderParsedExpr(expr);
|
|
2784
|
+
const split = this.splitPreamble(rendered);
|
|
2785
|
+
if (split)
|
|
2786
|
+
return split;
|
|
2787
|
+
return plain(rendered);
|
|
2788
|
+
}
|
|
2745
2789
|
case "array-literal":
|
|
2746
|
-
return this.renderParsedExpr(expr);
|
|
2790
|
+
return plain(this.renderParsedExpr(expr));
|
|
2747
2791
|
case "array-method":
|
|
2748
|
-
return this.renderParsedExpr(expr);
|
|
2792
|
+
return plain(this.renderParsedExpr(expr));
|
|
2749
2793
|
case "unsupported":
|
|
2750
|
-
return expr.raw;
|
|
2794
|
+
return plain(expr.raw);
|
|
2751
2795
|
}
|
|
2752
2796
|
}
|
|
2753
2797
|
renderLoop(loop) {
|
|
@@ -2770,14 +2814,38 @@ Options:
|
|
|
2770
2814
|
}
|
|
2771
2815
|
let goArray = this.convertExpressionToGo(loop.array);
|
|
2772
2816
|
const param = loop.param;
|
|
2773
|
-
|
|
2817
|
+
let index = loop.index || "_";
|
|
2818
|
+
let rangeIndex = index;
|
|
2819
|
+
let rangeValue = param;
|
|
2820
|
+
if (loop.iterationShape === "keys") {
|
|
2821
|
+
rangeIndex = param;
|
|
2822
|
+
rangeValue = "_";
|
|
2823
|
+
}
|
|
2774
2824
|
const childComponent = this.findChildComponent(loop.children);
|
|
2775
2825
|
if (childComponent) {
|
|
2776
2826
|
goArray = `.${childComponent.name}s`;
|
|
2777
2827
|
}
|
|
2778
2828
|
this.inLoop = true;
|
|
2779
|
-
|
|
2829
|
+
const addedLoopVars = [];
|
|
2830
|
+
if (loop.iterationShape === "keys") {
|
|
2831
|
+
this.loopParamStack.push("");
|
|
2832
|
+
this.loopVarRefCount.set(param, (this.loopVarRefCount.get(param) ?? 0) + 1);
|
|
2833
|
+
addedLoopVars.push(param);
|
|
2834
|
+
} else {
|
|
2835
|
+
this.loopParamStack.push(param);
|
|
2836
|
+
if (rangeIndex !== "_") {
|
|
2837
|
+
this.loopVarRefCount.set(rangeIndex, (this.loopVarRefCount.get(rangeIndex) ?? 0) + 1);
|
|
2838
|
+
addedLoopVars.push(rangeIndex);
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2780
2841
|
const children = this.renderChildren(loop.children);
|
|
2842
|
+
for (const v of addedLoopVars) {
|
|
2843
|
+
const rc = (this.loopVarRefCount.get(v) ?? 1) - 1;
|
|
2844
|
+
if (rc <= 0)
|
|
2845
|
+
this.loopVarRefCount.delete(v);
|
|
2846
|
+
else
|
|
2847
|
+
this.loopVarRefCount.set(v, rc);
|
|
2848
|
+
}
|
|
2781
2849
|
this.loopParamStack.pop();
|
|
2782
2850
|
this.inLoop = false;
|
|
2783
2851
|
if (loop.sortComparator) {
|
|
@@ -2793,10 +2861,10 @@ Options:
|
|
|
2793
2861
|
filterCond = "true";
|
|
2794
2862
|
}
|
|
2795
2863
|
const itemMarker2 = loop.bodyIsMultiRoot ? `{{bfComment "bf-loop-i"}}` : "";
|
|
2796
|
-
return `{{bfComment "loop:${loop.markerId}"}}{{range $${
|
|
2864
|
+
return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}{{if ${filterCond}}}${itemMarker2}${children}{{end}}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
|
|
2797
2865
|
}
|
|
2798
2866
|
const itemMarker = loop.bodyIsMultiRoot ? `{{bfComment "bf-loop-i"}}` : "";
|
|
2799
|
-
return `{{bfComment "loop:${loop.markerId}"}}{{range $${
|
|
2867
|
+
return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}${itemMarker}${children}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
|
|
2800
2868
|
}
|
|
2801
2869
|
findChildComponent(nodes) {
|
|
2802
2870
|
for (const node of nodes) {
|