@barefootjs/go-template 0.29.0 → 0.30.2
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 +224 -0
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +294 -8
- package/dist/adapter/memo/memo-compute.d.ts +36 -0
- package/dist/adapter/memo/memo-compute.d.ts.map +1 -1
- package/dist/adapter/type/type-codegen.d.ts +21 -1
- package/dist/adapter/type/type-codegen.d.ts.map +1 -1
- package/dist/adapter/value/value-lowering.d.ts +1 -1
- package/dist/adapter/value/value-lowering.d.ts.map +1 -1
- package/dist/build.js +294 -8
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +300 -10
- package/dist/render-divergences.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/go-template-adapter.test.ts +626 -6
- package/src/adapter/go-template-adapter.ts +597 -13
- package/src/adapter/memo/memo-compute.ts +125 -0
- package/src/adapter/type/type-codegen.ts +44 -1
- package/src/adapter/value/value-lowering.ts +6 -1
- package/src/conformance-pins.ts +0 -5
- package/src/render-divergences.ts +24 -9
package/dist/build.js
CHANGED
|
@@ -1312,7 +1312,26 @@ function renderLoweringNode(ctx, node) {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
|
|
1314
1314
|
// src/adapter/type/type-codegen.ts
|
|
1315
|
-
function
|
|
1315
|
+
function collapseLiteralUnion(typeInfo) {
|
|
1316
|
+
if (typeInfo.kind !== "union" || !typeInfo.unionTypes || typeInfo.unionTypes.length === 0) {
|
|
1317
|
+
return typeInfo;
|
|
1318
|
+
}
|
|
1319
|
+
const familyOf = (m) => {
|
|
1320
|
+
if (m.kind !== "primitive")
|
|
1321
|
+
return null;
|
|
1322
|
+
return m.primitive === "string" || m.primitive === "number" || m.primitive === "boolean" ? m.primitive : null;
|
|
1323
|
+
};
|
|
1324
|
+
const first = familyOf(typeInfo.unionTypes[0]);
|
|
1325
|
+
if (!first)
|
|
1326
|
+
return typeInfo;
|
|
1327
|
+
for (const m of typeInfo.unionTypes) {
|
|
1328
|
+
if (familyOf(m) !== first)
|
|
1329
|
+
return typeInfo;
|
|
1330
|
+
}
|
|
1331
|
+
return { kind: "primitive", raw: typeInfo.raw, primitive: first };
|
|
1332
|
+
}
|
|
1333
|
+
function typeInfoToGo(ctx, _typeInfo, defaultValue) {
|
|
1334
|
+
const typeInfo = collapseLiteralUnion(_typeInfo);
|
|
1316
1335
|
switch (typeInfo.kind) {
|
|
1317
1336
|
case "primitive":
|
|
1318
1337
|
switch (typeInfo.primitive) {
|
|
@@ -1482,7 +1501,8 @@ function nillableAwarePropRef(ctx, propName, expectedType) {
|
|
|
1482
1501
|
}
|
|
1483
1502
|
return fieldRef;
|
|
1484
1503
|
}
|
|
1485
|
-
function convertInitialValue(ctx, value,
|
|
1504
|
+
function convertInitialValue(ctx, value, _typeInfo, propsParams, preParsed) {
|
|
1505
|
+
const typeInfo = collapseLiteralUnion(_typeInfo);
|
|
1486
1506
|
const propRef = (propName2) => nillableAwarePropRef(ctx, propName2, typeInfo);
|
|
1487
1507
|
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(value)) {
|
|
1488
1508
|
if (propsParams?.some((p) => p.name === value)) {
|
|
@@ -2430,6 +2450,78 @@ function propsAccessNameFromParsed2(ctx, node) {
|
|
|
2430
2450
|
return null;
|
|
2431
2451
|
return node.property;
|
|
2432
2452
|
}
|
|
2453
|
+
function collectPropsReadByCtorInit(body, propsObjectName, propNames) {
|
|
2454
|
+
const found = new Set;
|
|
2455
|
+
const visit = (e, bound) => {
|
|
2456
|
+
switch (e.kind) {
|
|
2457
|
+
case "identifier":
|
|
2458
|
+
if (!propsObjectName && propNames.has(e.name) && !bound.has(e.name))
|
|
2459
|
+
found.add(e.name);
|
|
2460
|
+
return;
|
|
2461
|
+
case "member":
|
|
2462
|
+
if (propsObjectName && !e.computed && e.object.kind === "identifier" && e.object.name === propsObjectName) {
|
|
2463
|
+
found.add(e.property);
|
|
2464
|
+
return;
|
|
2465
|
+
}
|
|
2466
|
+
visit(e.object, bound);
|
|
2467
|
+
return;
|
|
2468
|
+
case "index-access":
|
|
2469
|
+
visit(e.object, bound);
|
|
2470
|
+
visit(e.index, bound);
|
|
2471
|
+
return;
|
|
2472
|
+
case "binary":
|
|
2473
|
+
case "logical":
|
|
2474
|
+
visit(e.left, bound);
|
|
2475
|
+
visit(e.right, bound);
|
|
2476
|
+
return;
|
|
2477
|
+
case "unary":
|
|
2478
|
+
visit(e.argument, bound);
|
|
2479
|
+
return;
|
|
2480
|
+
case "conditional":
|
|
2481
|
+
visit(e.test, bound);
|
|
2482
|
+
visit(e.consequent, bound);
|
|
2483
|
+
visit(e.alternate, bound);
|
|
2484
|
+
return;
|
|
2485
|
+
case "call":
|
|
2486
|
+
visit(e.callee, bound);
|
|
2487
|
+
e.args.forEach((a) => visit(a, bound));
|
|
2488
|
+
return;
|
|
2489
|
+
case "template-literal":
|
|
2490
|
+
for (const p of e.parts)
|
|
2491
|
+
if (p.type === "expression")
|
|
2492
|
+
visit(p.expr, bound);
|
|
2493
|
+
return;
|
|
2494
|
+
case "array-literal":
|
|
2495
|
+
e.elements.forEach((el) => visit(el, bound));
|
|
2496
|
+
return;
|
|
2497
|
+
case "object-literal":
|
|
2498
|
+
for (const p of e.properties)
|
|
2499
|
+
visit(p.value, bound);
|
|
2500
|
+
return;
|
|
2501
|
+
case "array-method":
|
|
2502
|
+
visit(e.object, bound);
|
|
2503
|
+
e.args.forEach((a) => visit(a, bound));
|
|
2504
|
+
if (e.method === "flat" && e.depthExpr)
|
|
2505
|
+
visit(e.depthExpr, bound);
|
|
2506
|
+
return;
|
|
2507
|
+
case "arrow": {
|
|
2508
|
+
const inner = e.params.length === 0 ? bound : new Set([...bound, ...e.params]);
|
|
2509
|
+
visit(e.body, inner);
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
case "literal":
|
|
2513
|
+
case "regex":
|
|
2514
|
+
case "unsupported":
|
|
2515
|
+
return;
|
|
2516
|
+
default: {
|
|
2517
|
+
const _exhaustive = e;
|
|
2518
|
+
return;
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
};
|
|
2522
|
+
visit(body, new Set);
|
|
2523
|
+
return found;
|
|
2524
|
+
}
|
|
2433
2525
|
|
|
2434
2526
|
// src/adapter/spread/spread-codegen.ts
|
|
2435
2527
|
import ts2 from "typescript";
|
|
@@ -3031,6 +3123,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
3031
3123
|
this.state.pendingChildrenDefines = [];
|
|
3032
3124
|
this.primeCompileState(ir);
|
|
3033
3125
|
this.state.stringValueNames = collectStringValueNames(ir);
|
|
3126
|
+
this.recordDerivedFieldDeps(ir, new Set((ir.metadata.propsParams ?? []).map((p) => p.name)));
|
|
3034
3127
|
if (!options?.siblingTemplatesRegistered) {
|
|
3035
3128
|
this.checkImportedLoopChildComponents(ir);
|
|
3036
3129
|
}
|
|
@@ -3167,15 +3260,50 @@ ${scriptRegistrations}${templateBody}
|
|
|
3167
3260
|
return `{{if .Scripts}}${registrations.join("")}{{end}}
|
|
3168
3261
|
`;
|
|
3169
3262
|
}
|
|
3263
|
+
childDerivedFieldDeps = new Map;
|
|
3264
|
+
childPropFieldNames = new Map;
|
|
3265
|
+
childRepropsReady = new Map;
|
|
3266
|
+
repropsOwner = new Map;
|
|
3267
|
+
recordDerivedFieldDeps(ir, paramNames) {
|
|
3268
|
+
const name = ir.metadata.componentName;
|
|
3269
|
+
if (!name)
|
|
3270
|
+
return;
|
|
3271
|
+
const sourceOf = new Map((ir.metadata.propsParams ?? []).map((p) => [p.name, p.sourceName ?? p.name]));
|
|
3272
|
+
const canonical = (local) => capitalizeFieldName(sourceOf.get(local) ?? local);
|
|
3273
|
+
const propFieldNames = new Set([...paramNames].map(canonical));
|
|
3274
|
+
const fieldNames = new Map;
|
|
3275
|
+
for (const p of ir.metadata.propsParams ?? []) {
|
|
3276
|
+
fieldNames.set(p.sourceName ?? p.name, capitalizeFieldName(p.name));
|
|
3277
|
+
}
|
|
3278
|
+
this.childPropFieldNames.set(name, fieldNames);
|
|
3279
|
+
const deps = new Map;
|
|
3280
|
+
const ctorInits = [
|
|
3281
|
+
...(ir.metadata.memos ?? []).map((m) => ({ field: m.name, init: m.parsed })),
|
|
3282
|
+
...(ir.metadata.signals ?? []).map((s) => ({ field: s.getter, init: s.parsed }))
|
|
3283
|
+
];
|
|
3284
|
+
for (const { field, init } of ctorInits) {
|
|
3285
|
+
if (propFieldNames.has(capitalizeFieldName(field)))
|
|
3286
|
+
continue;
|
|
3287
|
+
if (!init)
|
|
3288
|
+
continue;
|
|
3289
|
+
const read = collectPropsReadByCtorInit(init, ir.metadata.propsObjectName ?? null, paramNames);
|
|
3290
|
+
if (read.size === 0)
|
|
3291
|
+
continue;
|
|
3292
|
+
deps.set(field, new Set([...read].map(canonical)));
|
|
3293
|
+
}
|
|
3294
|
+
if (deps.size > 0)
|
|
3295
|
+
this.childDerivedFieldDeps.set(name, deps);
|
|
3296
|
+
}
|
|
3170
3297
|
registerChildComponentShape(ir) {
|
|
3171
3298
|
const name = ir.metadata.componentName;
|
|
3172
3299
|
if (!name)
|
|
3173
3300
|
return;
|
|
3174
|
-
const paramNames = new Set((ir.metadata.propsParams ?? []).map((p) => p.name));
|
|
3301
|
+
const paramNames = new Set((ir.metadata.propsParams ?? []).map((p) => p.sourceName ?? p.name));
|
|
3175
3302
|
const restPropsName = ir.metadata.restPropsName ?? null;
|
|
3176
3303
|
const restBagField = restPropsName ? capitalizeFieldName(restPropsName) : null;
|
|
3177
|
-
const mapTypedParamNames = new Set((ir.metadata.propsParams ?? []).filter((p) => p.optional && (p.type.kind === "object" || p.type.kind === "interface" && !!p.type.raw)).map((p) => p.name));
|
|
3304
|
+
const mapTypedParamNames = new Set((ir.metadata.propsParams ?? []).filter((p) => p.optional && (p.type.kind === "object" || p.type.kind === "interface" && !!p.type.raw)).map((p) => p.sourceName ?? p.name));
|
|
3178
3305
|
this.childComponentShapes.set(name, { paramNames, restBagField, mapTypedParamNames });
|
|
3306
|
+
this.recordDerivedFieldDeps(ir, new Set((ir.metadata.propsParams ?? []).map((p) => p.name)));
|
|
3179
3307
|
this.childContextConsumers.set(name, collectContextConsumers(ir.metadata));
|
|
3180
3308
|
}
|
|
3181
3309
|
contextFieldName(c) {
|
|
@@ -3244,8 +3372,86 @@ ${scriptRegistrations}${templateBody}
|
|
|
3244
3372
|
this.state.needsStringsImport = false;
|
|
3245
3373
|
this.generatePropsStruct(lines, ir, componentName, nestedComponents, propTypeOverrides, spreadSlots);
|
|
3246
3374
|
this.generateNewPropsFunction(lines, ir, componentName, nestedComponents, spreadSlots, propTypeOverrides);
|
|
3375
|
+
this.recordRepropsSpec(ir, componentName, nestedComponents, spreadSlots);
|
|
3376
|
+
this.emitOwnedReprops(lines, componentName);
|
|
3247
3377
|
return this.composeFileHeader(lines);
|
|
3248
3378
|
}
|
|
3379
|
+
recordRepropsSpec(ir, componentName, nestedComponents, spreadSlots) {
|
|
3380
|
+
if (!this.childDerivedFieldDeps.has(componentName))
|
|
3381
|
+
return;
|
|
3382
|
+
const nestedArrayFields = new Set(nestedComponents.map((n) => `${n.name}s`));
|
|
3383
|
+
const params = (ir.metadata.propsParams ?? []).filter((p) => !nestedArrayFields.has(capitalizeFieldName(p.name)));
|
|
3384
|
+
const takenInput = new Set((ir.metadata.propsParams ?? []).map((p) => capitalizeFieldName(p.name)));
|
|
3385
|
+
const eligible = nestedComponents.every((n) => n.isDynamic && !n.isPropDerived) && spreadSlots.length === 0 && !ir.metadata.restPropsName && this.nonCollidingContextConsumers(takenInput).length === 0;
|
|
3386
|
+
if (!eligible)
|
|
3387
|
+
return;
|
|
3388
|
+
this.childRepropsReady.set(componentName, {
|
|
3389
|
+
params: params.map((p) => capitalizeFieldName(p.name)),
|
|
3390
|
+
usesSearchParams: this.usesSearchParams(ir)
|
|
3391
|
+
});
|
|
3392
|
+
}
|
|
3393
|
+
emitOwnedReprops(lines, owner) {
|
|
3394
|
+
for (const [childName, ownerName] of this.repropsOwner) {
|
|
3395
|
+
if (ownerName !== owner)
|
|
3396
|
+
continue;
|
|
3397
|
+
const spec = this.childRepropsReady.get(childName);
|
|
3398
|
+
if (!spec)
|
|
3399
|
+
continue;
|
|
3400
|
+
this.emitRepropsRegistration(lines, childName, spec);
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
emitRepropsRegistration(lines, componentName, spec) {
|
|
3404
|
+
const { params, usesSearchParams } = spec;
|
|
3405
|
+
const inputTypeName = `${componentName}Input`;
|
|
3406
|
+
const q = JSON.stringify(componentName);
|
|
3407
|
+
lines.push(`// ${componentName} computes at least one field from an input prop when its`);
|
|
3408
|
+
lines.push("// props are constructed, so a per-row override inside a composite loop row");
|
|
3409
|
+
lines.push("// cannot be applied by patching fields — the derived field would keep the");
|
|
3410
|
+
lines.push("// shared instance's one-shot value on every row (#2448). This rebuilder");
|
|
3411
|
+
lines.push(`// re-runs New${componentName}Props with the row's overrides folded into the`);
|
|
3412
|
+
lines.push("// Input; the parent calls it through bf_reprops.");
|
|
3413
|
+
lines.push("func init() {");
|
|
3414
|
+
lines.push(` bf.RegisterReprops(${q}, func(base interface{}, kv ...interface{}) (interface{}, error) {`);
|
|
3415
|
+
lines.push(` b, ok := base.(${componentName}Props)`);
|
|
3416
|
+
lines.push("\t\tif !ok {");
|
|
3417
|
+
lines.push(` return nil, bf.RepropsTypeError(${q}, base)`);
|
|
3418
|
+
lines.push("\t\t}");
|
|
3419
|
+
lines.push(` in := ${inputTypeName}{`);
|
|
3420
|
+
lines.push("\t\t\tScopeID: b.ScopeID,");
|
|
3421
|
+
lines.push("\t\t\tBfParent: b.BfParent,");
|
|
3422
|
+
lines.push("\t\t\tBfMount: b.BfMount,");
|
|
3423
|
+
if (usesSearchParams)
|
|
3424
|
+
lines.push("\t\t\tSearchParams: b.SearchParams,");
|
|
3425
|
+
for (const field of params) {
|
|
3426
|
+
lines.push(` ${field}: b.${field},`);
|
|
3427
|
+
}
|
|
3428
|
+
lines.push("\t\t}");
|
|
3429
|
+
lines.push("\t\tfor i := 0; i < len(kv); i += 2 {");
|
|
3430
|
+
lines.push("\t\t\tname, _ := kv[i].(string)");
|
|
3431
|
+
lines.push("\t\t\tvar err error");
|
|
3432
|
+
lines.push("\t\t\tswitch name {");
|
|
3433
|
+
for (const field of params) {
|
|
3434
|
+
lines.push(` case ${JSON.stringify(field)}:`);
|
|
3435
|
+
lines.push(` err = bf.RepropsAssign(${q}, ${JSON.stringify(field)}, &in.${field}, kv[i+1])`);
|
|
3436
|
+
}
|
|
3437
|
+
lines.push("\t\t\tdefault:");
|
|
3438
|
+
lines.push(` err = bf.RepropsUnknownFieldError(${q}, name)`);
|
|
3439
|
+
lines.push("\t\t\t}");
|
|
3440
|
+
lines.push("\t\t\tif err != nil {");
|
|
3441
|
+
lines.push("\t\t\t\treturn nil, err");
|
|
3442
|
+
lines.push("\t\t\t}");
|
|
3443
|
+
lines.push("\t\t}");
|
|
3444
|
+
lines.push(` p := New${componentName}Props(in)`);
|
|
3445
|
+
lines.push("\t\t// Props-only state, absent from Input and therefore not rebuilt.");
|
|
3446
|
+
lines.push("\t\tp.Scripts = b.Scripts");
|
|
3447
|
+
lines.push("\t\tp.BfIsRoot = b.BfIsRoot");
|
|
3448
|
+
lines.push("\t\tp.BfIsChild = b.BfIsChild");
|
|
3449
|
+
lines.push("\t\tp.BfDataKey = b.BfDataKey");
|
|
3450
|
+
lines.push("\t\treturn p, nil");
|
|
3451
|
+
lines.push("\t})");
|
|
3452
|
+
lines.push("}");
|
|
3453
|
+
lines.push("");
|
|
3454
|
+
}
|
|
3249
3455
|
typeDefinitionToGo(td) {
|
|
3250
3456
|
if (td.definition.match(/^type \w+ = ('[^']*'(\s*\|\s*'[^']*')*)/)) {
|
|
3251
3457
|
return `// ${td.name} is a string type.
|
|
@@ -3729,7 +3935,8 @@ ${goFields.join(`
|
|
|
3729
3935
|
}
|
|
3730
3936
|
if (jsxName.includes("-"))
|
|
3731
3937
|
return;
|
|
3732
|
-
|
|
3938
|
+
const fieldName = this.childPropFieldNames.get(child.name)?.get(jsxName) ?? capitalizeFieldName(jsxName);
|
|
3939
|
+
lines.push(` ${fieldName}: ${goValue},`);
|
|
3733
3940
|
};
|
|
3734
3941
|
for (const prop of child.props) {
|
|
3735
3942
|
switch (prop.value.kind) {
|
|
@@ -5713,6 +5920,78 @@ ${goFields.join(`
|
|
|
5713
5920
|
isLoopShadowedName(name) {
|
|
5714
5921
|
return this.loopParamStack.length > 0 && this.loopParamStack[this.loopParamStack.length - 1] === name || this.loopVarRefCount.has(name) || this.isOuterLoopParam(name) || this.loopBindingStack.some((bindings) => bindings.has(name));
|
|
5715
5922
|
}
|
|
5923
|
+
loopRowChildPropOverrides(comp) {
|
|
5924
|
+
const childShape = this.childComponentShapes.get(comp.name);
|
|
5925
|
+
const args = [];
|
|
5926
|
+
let needsRebuild = false;
|
|
5927
|
+
for (const prop of comp.props) {
|
|
5928
|
+
if (prop.clientOnly)
|
|
5929
|
+
continue;
|
|
5930
|
+
if (prop.name === "key" || prop.name === "children")
|
|
5931
|
+
continue;
|
|
5932
|
+
if (prop.name.startsWith("on") && prop.name.length > 2)
|
|
5933
|
+
continue;
|
|
5934
|
+
if (prop.name.includes("-"))
|
|
5935
|
+
continue;
|
|
5936
|
+
if (childShape?.restBagField && !childShape.paramNames.has(prop.name))
|
|
5937
|
+
continue;
|
|
5938
|
+
if (prop.value.kind !== "expression")
|
|
5939
|
+
continue;
|
|
5940
|
+
const free = prop.freeIdentifiers;
|
|
5941
|
+
if (!free || ![...free].some((name) => this.isLoopShadowedName(name)))
|
|
5942
|
+
continue;
|
|
5943
|
+
{
|
|
5944
|
+
const derived = this.childDerivedFieldDeps.get(comp.name);
|
|
5945
|
+
const overriddenField = capitalizeFieldName(prop.name);
|
|
5946
|
+
const staleField = derived ? [...derived].find(([, deps]) => deps.has(overriddenField))?.[0] : undefined;
|
|
5947
|
+
if (staleField && !this.childRepropsReady.has(comp.name)) {
|
|
5948
|
+
this.state.errors.push({
|
|
5949
|
+
code: "BF101",
|
|
5950
|
+
severity: "error",
|
|
5951
|
+
message: `Prop '${prop.name}' on <${comp.name}> nested inside a dynamic loop row is overridden per row, but <${comp.name}>'s '${staleField}' field is computed from '${prop.name}' when the shared instance is first constructed and won't recompute per row — it would keep the first row's value on every row.`,
|
|
5952
|
+
loc: prop.loc,
|
|
5953
|
+
suggestion: {
|
|
5954
|
+
message: `Mark this loop position '@client' to render <${comp.name}> client-side, or compute '${staleField}' in the parent and pass it to <${comp.name}> as a plain prop instead of deriving it inside <${comp.name}>.`
|
|
5955
|
+
}
|
|
5956
|
+
});
|
|
5957
|
+
continue;
|
|
5958
|
+
}
|
|
5959
|
+
if (staleField) {
|
|
5960
|
+
needsRebuild = true;
|
|
5961
|
+
if (!this.repropsOwner.has(comp.name)) {
|
|
5962
|
+
this.repropsOwner.set(comp.name, this.state.componentName);
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5966
|
+
const exprOut = {};
|
|
5967
|
+
const errorCountBefore = this.state.errors.length;
|
|
5968
|
+
let go = this.convertExpressionToGo(prop.value.expr, exprOut, prop.value.parsed);
|
|
5969
|
+
if (this.state.errors.length > errorCountBefore) {
|
|
5970
|
+
for (let i = errorCountBefore;i < this.state.errors.length; i++) {
|
|
5971
|
+
this.state.errors[i].loc = prop.loc;
|
|
5972
|
+
}
|
|
5973
|
+
continue;
|
|
5974
|
+
}
|
|
5975
|
+
const singlePartTemplateLiteral = exprOut.parsed?.kind === "template-literal" && exprOut.parsed.parts.length === 1 && exprOut.parsed.parts[0].type !== "string" && go.startsWith("{{") && go.endsWith("}}");
|
|
5976
|
+
if (singlePartTemplateLiteral) {
|
|
5977
|
+
go = go.slice(2, -2);
|
|
5978
|
+
}
|
|
5979
|
+
if (!singlePartTemplateLiteral && this.isTemplateFragment(go, exprOut.parsed?.kind)) {
|
|
5980
|
+
this.state.errors.push({
|
|
5981
|
+
code: "BF101",
|
|
5982
|
+
severity: "error",
|
|
5983
|
+
message: `Prop '${prop.name}' on <${comp.name}> nested inside a dynamic loop row reads the row but can't be lowered to a Go template pipeline argument`,
|
|
5984
|
+
loc: prop.loc
|
|
5985
|
+
});
|
|
5986
|
+
continue;
|
|
5987
|
+
}
|
|
5988
|
+
const fieldName = this.childPropFieldNames.get(comp.name)?.get(prop.name) ?? capitalizeFieldName(prop.name);
|
|
5989
|
+
args.push(`${JSON.stringify(fieldName)} ${wrapIfMultiToken(go)}`);
|
|
5990
|
+
}
|
|
5991
|
+
if (args.length === 0)
|
|
5992
|
+
return null;
|
|
5993
|
+
return { args: args.join(" "), helper: needsRebuild ? "bf_reprops" : "bf_with_props" };
|
|
5994
|
+
}
|
|
5716
5995
|
resolveStaticRecordLiteralIndex(jsExpr) {
|
|
5717
5996
|
const m = /^([A-Za-z_$][\w$]*)\[\s*(?:'([^']*)'|"([^"]*)")\s*\]$/.exec(jsExpr) ?? /^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/.exec(jsExpr);
|
|
5718
5997
|
if (!m)
|
|
@@ -6122,6 +6401,10 @@ ${goFields.join(`
|
|
|
6122
6401
|
}
|
|
6123
6402
|
this.inLoop = true;
|
|
6124
6403
|
const addedLoopVars = [];
|
|
6404
|
+
for (const d of loop.preamble?.declarations ?? []) {
|
|
6405
|
+
this.loopVarRefCount.set(d.name, (this.loopVarRefCount.get(d.name) ?? 0) + 1);
|
|
6406
|
+
addedLoopVars.push(d.name);
|
|
6407
|
+
}
|
|
6125
6408
|
let pushedBindingMap = false;
|
|
6126
6409
|
if (supportableDestructure) {
|
|
6127
6410
|
const built = this.buildDestructureBindingMap(loop, rangeValue);
|
|
@@ -6147,6 +6430,7 @@ ${goFields.join(`
|
|
|
6147
6430
|
this.loopScalarItemStack.push(this.scalarLiteralLoopGoType(loop.arrayParsed, loop.itemType) !== null);
|
|
6148
6431
|
this.loopWrapperStack.push(!!loop.childComponent);
|
|
6149
6432
|
this.loopKeyDepthStack.push(loop.depth);
|
|
6433
|
+
const preambleAssignments = (loop.preamble?.declarations ?? []).map((d) => `{{$${d.name} := ${this.renderParsedExpr(d.valueParsed)}}}`).join("");
|
|
6150
6434
|
const children = this.renderChildren(loop.children);
|
|
6151
6435
|
this.loopKeyDepthStack.pop();
|
|
6152
6436
|
this.loopWrapperStack.pop();
|
|
@@ -6181,9 +6465,9 @@ ${goFields.join(`
|
|
|
6181
6465
|
} else {
|
|
6182
6466
|
filterCond = "true";
|
|
6183
6467
|
}
|
|
6184
|
-
return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}{{if ${filterCond}}}${itemMarker}${children}{{end}}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
|
|
6468
|
+
return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}{{if ${filterCond}}}${preambleAssignments}${itemMarker}${children}{{end}}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
|
|
6185
6469
|
}
|
|
6186
|
-
return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}${itemMarker}${children}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
|
|
6470
|
+
return `{{bfComment "loop:${loop.markerId}"}}{{range $${rangeIndex}, $${rangeValue} := ${goArray}}}${preambleAssignments}${itemMarker}${children}{{end}}{{bfComment "/loop:${loop.markerId}"}}`;
|
|
6187
6471
|
}
|
|
6188
6472
|
renderUnrolledStaticElementLoop(loop, items) {
|
|
6189
6473
|
this.inLoop = true;
|
|
@@ -6282,8 +6566,10 @@ ${goFields.join(`
|
|
|
6282
6566
|
}
|
|
6283
6567
|
} else if (this.inLoop && comp.slotId) {
|
|
6284
6568
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
6569
|
+
const overrides = this.loopRowChildPropOverrides(comp);
|
|
6285
6570
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
6286
|
-
|
|
6571
|
+
const base = overrides ? overrides.helper === "bf_reprops" ? `(bf_reprops ${JSON.stringify(comp.name)} $.${comp.name}${suffix} ${overrides.args})` : `(bf_with_props $.${comp.name}${suffix} ${overrides.args})` : `$.${comp.name}${suffix}`;
|
|
6572
|
+
templateCall = loopBodyDefine ? `{{template "${comp.name}" (bf_with_children ${base} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${comp.name}" ${base}}}`;
|
|
6287
6573
|
} else if (this.inLoop) {
|
|
6288
6574
|
templateCall = `{{template "${comp.name}" .}}`;
|
|
6289
6575
|
} else if (comp.slotId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;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;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAgL7B,CAAA"}
|