@barefootjs/go-template 0.33.4 → 0.34.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 +12 -0
- package/dist/adapter/emit-context.d.ts.map +1 -1
- package/dist/adapter/expr/url-builder.d.ts +53 -1
- package/dist/adapter/expr/url-builder.d.ts.map +1 -1
- package/dist/adapter/go-template-adapter.d.ts +153 -7
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +253 -99
- package/dist/adapter/lib/compile-state.d.ts +17 -0
- package/dist/adapter/lib/compile-state.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.map +1 -1
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +261 -103
- package/dist/render-divergences.d.ts +10 -0
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +420 -214
- package/package.json +5 -5
- package/src/__tests__/go-template-adapter.test.ts +333 -9
- package/src/__tests__/lowering-plugin.test.ts +38 -0
- package/src/__tests__/query-href.test.ts +126 -0
- package/src/adapter/emit-context.ts +14 -0
- package/src/adapter/expr/url-builder.ts +114 -8
- package/src/adapter/go-template-adapter.ts +514 -107
- package/src/adapter/lib/compile-state.ts +18 -0
- package/src/adapter/value/parsed-literal-to-go.ts +11 -7
- package/src/adapter/value/value-lowering.ts +17 -0
- package/src/conformance-pins.ts +19 -0
- package/src/render-divergences.ts +12 -6
- package/src/test-render.ts +32 -15
package/dist/adapter/index.js
CHANGED
|
@@ -28,7 +28,8 @@ import {
|
|
|
28
28
|
dangerousInnerHtmlDiagnostic,
|
|
29
29
|
collectLoopBoundNames as collectLoopBoundNames2,
|
|
30
30
|
evaluateStaticLiteral as evaluateStaticLiteral3,
|
|
31
|
-
BindingScope
|
|
31
|
+
BindingScope,
|
|
32
|
+
buildImportAliasMap
|
|
32
33
|
} from "@barefootjs/jsx";
|
|
33
34
|
import { findInterpolationEnd } from "@barefootjs/jsx/scanner";
|
|
34
35
|
import { BF_REGION, escapeHtml, resolveJsxChildrenProp } from "@barefootjs/shared";
|
|
@@ -303,6 +304,7 @@ class CompileState {
|
|
|
303
304
|
componentName = "";
|
|
304
305
|
errors = [];
|
|
305
306
|
referencedDerivedConsts = new Set;
|
|
307
|
+
templateReadRootFields = new Set;
|
|
306
308
|
templateVarCounter = 0;
|
|
307
309
|
pendingChildrenDefines = [];
|
|
308
310
|
propsObjectName = null;
|
|
@@ -887,9 +889,22 @@ function lowerTernaryTest(ctx, test) {
|
|
|
887
889
|
const isBoolShape = test.kind === "binary" && BOOL_COMPARISON_OPS.has(test.op) || test.kind === "unary" && test.op === "!" || test.kind === "literal" && test.literalType === "boolean";
|
|
888
890
|
return isBoolShape ? go : `(bf_truthy ${go})`;
|
|
889
891
|
}
|
|
892
|
+
function matchRegisteredCall(ctx, callee, args) {
|
|
893
|
+
for (const matcher of ctx.state.loweringMatchers) {
|
|
894
|
+
const node = matcher(callee, args);
|
|
895
|
+
if (node)
|
|
896
|
+
return node;
|
|
897
|
+
}
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
function lowerRegisteredCallNode(ctx, callee, args) {
|
|
901
|
+
if (ctx.state.loweringMatchers.length === 0)
|
|
902
|
+
return null;
|
|
903
|
+
const node = matchRegisteredCall(ctx, callee, args);
|
|
904
|
+
return node ? renderLoweringNode(ctx, node) : null;
|
|
905
|
+
}
|
|
890
906
|
function lowerRegisteredCall(ctx, jsExpr, preParsed) {
|
|
891
|
-
|
|
892
|
-
if (matchers.length === 0)
|
|
907
|
+
if (ctx.state.loweringMatchers.length === 0)
|
|
893
908
|
return null;
|
|
894
909
|
let call = preParsed?.kind === "call" ? preParsed : undefined;
|
|
895
910
|
if (!call) {
|
|
@@ -900,15 +915,32 @@ function lowerRegisteredCall(ctx, jsExpr, preParsed) {
|
|
|
900
915
|
return null;
|
|
901
916
|
call = parsed;
|
|
902
917
|
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
918
|
+
return lowerRegisteredCallNode(ctx, call.callee, call.args);
|
|
919
|
+
}
|
|
920
|
+
function lowerRegisteredAttrCall(ctx, attrName, parsed) {
|
|
921
|
+
if (parsed.kind === "conditional") {
|
|
922
|
+
if (!ternaryHasQueryBranch(ctx, parsed.consequent, parsed.alternate))
|
|
923
|
+
return null;
|
|
924
|
+
const rendered2 = lowerTernary(ctx, parsed.test, parsed.consequent, parsed.alternate);
|
|
925
|
+
return `{{bf_attr ${JSON.stringify(attrName)} ${rendered2}}}`;
|
|
910
926
|
}
|
|
911
|
-
|
|
927
|
+
if (parsed.kind !== "call")
|
|
928
|
+
return null;
|
|
929
|
+
const node = matchRegisteredCall(ctx, parsed.callee, parsed.args);
|
|
930
|
+
if (!node || node.kind !== "guard-list" || node.helper !== "query")
|
|
931
|
+
return null;
|
|
932
|
+
const rendered = renderLoweringNode(ctx, node);
|
|
933
|
+
return rendered === null ? null : `{{bf_attr ${JSON.stringify(attrName)} (${rendered})}}`;
|
|
934
|
+
}
|
|
935
|
+
function isQueryGuardListCall(ctx, node) {
|
|
936
|
+
if (node.kind !== "call")
|
|
937
|
+
return false;
|
|
938
|
+
const lowered = matchRegisteredCall(ctx, node.callee, node.args);
|
|
939
|
+
return lowered?.kind === "guard-list" && lowered.helper === "query";
|
|
940
|
+
}
|
|
941
|
+
function ternaryHasQueryBranch(ctx, consequent, alternate) {
|
|
942
|
+
const branchHasQuery = (n) => n.kind === "conditional" ? ternaryHasQueryBranch(ctx, n.consequent, n.alternate) : isQueryGuardListCall(ctx, n);
|
|
943
|
+
return branchHasQuery(consequent) || branchHasQuery(alternate);
|
|
912
944
|
}
|
|
913
945
|
function renderLoweringNode(ctx, node) {
|
|
914
946
|
const helper = goHelperName(node.helper);
|
|
@@ -1170,6 +1202,15 @@ function convertInitialValue(ctx, value, _typeInfo, propsParams, preParsed) {
|
|
|
1170
1202
|
if (param2) {
|
|
1171
1203
|
return propRef(param2);
|
|
1172
1204
|
}
|
|
1205
|
+
const inlinedStr = ctx.resolveModuleStringConst(value);
|
|
1206
|
+
if (inlinedStr !== null)
|
|
1207
|
+
return inlinedStr;
|
|
1208
|
+
const inlinedNum = ctx.resolveModuleNumericConst(value);
|
|
1209
|
+
if (inlinedNum !== null)
|
|
1210
|
+
return inlinedNum;
|
|
1211
|
+
const inlinedBool = ctx.resolveModuleBooleanConst(value);
|
|
1212
|
+
if (inlinedBool !== null)
|
|
1213
|
+
return inlinedBool;
|
|
1173
1214
|
}
|
|
1174
1215
|
const propName = ctx.extractPropNameFromInitialValue(value, preParsed);
|
|
1175
1216
|
const param = propName ? propsParams?.find((p) => p.name === propName) : undefined;
|
|
@@ -2890,7 +2931,9 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2890
2931
|
extractPropNameFromInitialValue: (initialValue, preParsed) => this.extractPropNameFromInitialValue(initialValue, preParsed),
|
|
2891
2932
|
extractPropFallback: (initialValue, preParsed) => this.extractPropFallback(initialValue, preParsed),
|
|
2892
2933
|
extractCollisionDerivation: (parsed) => this.extractCollisionDerivation(parsed),
|
|
2893
|
-
resolveModuleStringConst: (name) => this.resolveModuleStringConst(name)
|
|
2934
|
+
resolveModuleStringConst: (name) => this.resolveModuleStringConst(name),
|
|
2935
|
+
resolveModuleNumericConst: (name) => this.resolveModuleNumericConst(name),
|
|
2936
|
+
resolveModuleBooleanConst: (name) => this.resolveModuleBooleanConst(name)
|
|
2894
2937
|
};
|
|
2895
2938
|
get errors() {
|
|
2896
2939
|
return this.state.errors;
|
|
@@ -2907,6 +2950,10 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2907
2950
|
staticLoopBakeFailed = false;
|
|
2908
2951
|
childComponentShapes = new Map;
|
|
2909
2952
|
childContextConsumers = new Map;
|
|
2953
|
+
importAliases = new Map;
|
|
2954
|
+
resolveChildName(name) {
|
|
2955
|
+
return this.importAliases.get(name) ?? name;
|
|
2956
|
+
}
|
|
2910
2957
|
constructor(options = {}) {
|
|
2911
2958
|
super();
|
|
2912
2959
|
this.options = {
|
|
@@ -2918,6 +2965,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2918
2965
|
primeCompileState(ir) {
|
|
2919
2966
|
this.state.propsObjectName = ir.metadata.propsObjectName;
|
|
2920
2967
|
this.state.restPropsName = ir.metadata.restPropsName ?? null;
|
|
2968
|
+
this.importAliases = buildImportAliasMap(ir.metadata.imports ?? []);
|
|
2921
2969
|
this.state.objectTypedPropNames = new Set((ir.metadata.propsParams ?? []).filter((p) => p.type.kind === "object").map((p) => p.name));
|
|
2922
2970
|
this.state.moduleStringConsts = this.collectModuleStringConsts(ir.metadata.localConstants);
|
|
2923
2971
|
this.state.localConstants = ir.metadata.localConstants ?? [];
|
|
@@ -2952,6 +3000,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2952
3000
|
this.state.componentName = ir.metadata.componentName;
|
|
2953
3001
|
this.state.errors = [];
|
|
2954
3002
|
this.state.referencedDerivedConsts = new Set;
|
|
3003
|
+
this.state.templateReadRootFields = new Set;
|
|
2955
3004
|
this.state.templateVarCounter = 0;
|
|
2956
3005
|
this.state.pendingChildrenDefines = [];
|
|
2957
3006
|
this.scope = BindingScope.EMPTY;
|
|
@@ -2980,7 +3029,7 @@ ${scriptRegistrations}${templateBody}
|
|
|
2980
3029
|
template += `{{define "${d.name}"}}${d.content}{{end}}
|
|
2981
3030
|
`;
|
|
2982
3031
|
}
|
|
2983
|
-
const types = this.generateTypes(ir);
|
|
3032
|
+
const types = this.generateTypes(ir, true);
|
|
2984
3033
|
if (this.state.errors.length > 0) {
|
|
2985
3034
|
ir.errors.push(...this.state.errors);
|
|
2986
3035
|
}
|
|
@@ -3209,9 +3258,12 @@ ${scriptRegistrations}${templateBody}
|
|
|
3209
3258
|
taken.add(desired);
|
|
3210
3259
|
return desired;
|
|
3211
3260
|
}
|
|
3212
|
-
generateTypes(ir) {
|
|
3261
|
+
generateTypes(ir, preserveTemplateReadRootFields = false) {
|
|
3213
3262
|
this.state.usesHtmlTemplate = false;
|
|
3214
3263
|
this.state.usesFmt = false;
|
|
3264
|
+
if (!preserveTemplateReadRootFields) {
|
|
3265
|
+
this.state.templateReadRootFields = new Set;
|
|
3266
|
+
}
|
|
3215
3267
|
this.primeCompileState(ir);
|
|
3216
3268
|
const lines = [];
|
|
3217
3269
|
const componentName = ir.metadata.componentName;
|
|
@@ -3355,10 +3407,17 @@ ${goFields.join(`
|
|
|
3355
3407
|
const node = signal.parsed;
|
|
3356
3408
|
if (!node || node.kind !== "array-literal" || node.elements.length === 0)
|
|
3357
3409
|
return null;
|
|
3410
|
+
const name = `${componentName}${capitalizeFieldName(signal.getter)}Item`;
|
|
3411
|
+
return this.synthesizeStructsFromElements(node.elements, name);
|
|
3412
|
+
}
|
|
3413
|
+
synthesizeStructsFromElements(elements, name) {
|
|
3414
|
+
if (this.state.localTypeNames.has(name))
|
|
3415
|
+
return null;
|
|
3358
3416
|
const order = [];
|
|
3359
|
-
const
|
|
3360
|
-
|
|
3361
|
-
|
|
3417
|
+
const shapes = new Map;
|
|
3418
|
+
const nestedElements = new Map;
|
|
3419
|
+
for (let i = 0;i < elements.length; i++) {
|
|
3420
|
+
const el = elements[i];
|
|
3362
3421
|
if (el.kind !== "object-literal")
|
|
3363
3422
|
return null;
|
|
3364
3423
|
const seen = new Set;
|
|
@@ -3370,37 +3429,93 @@ ${goFields.join(`
|
|
|
3370
3429
|
const key = prop.key;
|
|
3371
3430
|
if (!GO_IDENTIFIER.test(key))
|
|
3372
3431
|
return null;
|
|
3432
|
+
seen.add(key);
|
|
3433
|
+
const isNestedArray = prop.value.kind === "array-literal" && prop.value.elements.every((e) => e.kind === "object-literal");
|
|
3434
|
+
if (isNestedArray) {
|
|
3435
|
+
const prevShape2 = shapes.get(key);
|
|
3436
|
+
if (prevShape2 === undefined) {
|
|
3437
|
+
if (i !== 0)
|
|
3438
|
+
return null;
|
|
3439
|
+
order.push(key);
|
|
3440
|
+
shapes.set(key, { kind: "nested-array" });
|
|
3441
|
+
nestedElements.set(key, []);
|
|
3442
|
+
} else if (prevShape2.kind !== "nested-array") {
|
|
3443
|
+
return null;
|
|
3444
|
+
}
|
|
3445
|
+
nestedElements.get(key).push(...prop.value.elements);
|
|
3446
|
+
continue;
|
|
3447
|
+
}
|
|
3373
3448
|
const goType = this.scalarParsedGoType(prop.value);
|
|
3374
3449
|
if (!goType)
|
|
3375
3450
|
return null;
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
if (prev === undefined) {
|
|
3451
|
+
const prevShape = shapes.get(key);
|
|
3452
|
+
if (prevShape === undefined) {
|
|
3379
3453
|
if (i !== 0)
|
|
3380
3454
|
return null;
|
|
3381
3455
|
order.push(key);
|
|
3382
|
-
|
|
3456
|
+
shapes.set(key, { kind: "scalar", goType });
|
|
3457
|
+
} else if (prevShape.kind !== "scalar") {
|
|
3458
|
+
return null;
|
|
3383
3459
|
} else {
|
|
3384
|
-
const merged = this.mergeScalarGoType(
|
|
3460
|
+
const merged = this.mergeScalarGoType(prevShape.goType, goType);
|
|
3385
3461
|
if (!merged)
|
|
3386
3462
|
return null;
|
|
3387
|
-
|
|
3463
|
+
shapes.set(key, { kind: "scalar", goType: merged });
|
|
3388
3464
|
}
|
|
3389
3465
|
}
|
|
3390
3466
|
if (seen.size !== order.length)
|
|
3391
3467
|
return null;
|
|
3392
3468
|
}
|
|
3393
|
-
const
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3469
|
+
const nestedStructs = [];
|
|
3470
|
+
const fields = [];
|
|
3471
|
+
const properties = [];
|
|
3472
|
+
for (const key of order) {
|
|
3473
|
+
const shape = shapes.get(key);
|
|
3474
|
+
if (shape.kind === "scalar") {
|
|
3475
|
+
fields.push({ tsName: key, goName: capitalizeFieldName(key), goType: shape.goType });
|
|
3476
|
+
properties.push({ name: key, type: this.scalarGoTypeToTypeInfo(shape.goType), optional: false, readonly: false });
|
|
3477
|
+
continue;
|
|
3478
|
+
}
|
|
3479
|
+
const nestedList = nestedElements.get(key);
|
|
3480
|
+
if (nestedList.length === 0)
|
|
3481
|
+
return null;
|
|
3482
|
+
const nestedName = `${name}${capitalizeFieldName(key)}Item`;
|
|
3483
|
+
const nested = this.synthesizeStructsFromElements(nestedList, nestedName);
|
|
3484
|
+
if (!nested)
|
|
3485
|
+
return null;
|
|
3486
|
+
nestedStructs.push(...nested);
|
|
3487
|
+
fields.push({ tsName: key, goName: capitalizeFieldName(key), goType: `[]${nestedName}` });
|
|
3488
|
+
properties.push({ name: key, type: this.synthSliceTypeInfo(nestedName), optional: false, readonly: false });
|
|
3489
|
+
}
|
|
3490
|
+
return [...nestedStructs, { name, fields, properties }];
|
|
3491
|
+
}
|
|
3492
|
+
scalarGoTypeToTypeInfo(goType) {
|
|
3493
|
+
if (goType === "string")
|
|
3494
|
+
return { kind: "primitive", raw: "string", primitive: "string" };
|
|
3495
|
+
if (goType === "bool")
|
|
3496
|
+
return { kind: "primitive", raw: "boolean", primitive: "boolean" };
|
|
3497
|
+
return { kind: "primitive", raw: "number", primitive: "number" };
|
|
3498
|
+
}
|
|
3499
|
+
synthSliceTypeInfo(name) {
|
|
3500
|
+
return { kind: "array", raw: `${name}[]`, elementType: { kind: "interface", raw: name } };
|
|
3501
|
+
}
|
|
3502
|
+
registerSynthStruct(lines, name, fields, properties, comment) {
|
|
3503
|
+
this.state.localTypeNames.add(name);
|
|
3504
|
+
this.state.localStructFields.set(name, new Map(fields.map((f) => [f.tsName, f.goName])));
|
|
3505
|
+
this.state.currentTypeDefinitions.push({
|
|
3506
|
+
kind: "type",
|
|
3397
3507
|
name,
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3508
|
+
definition: "",
|
|
3509
|
+
properties,
|
|
3510
|
+
loc: SYNTH_TYPE_LOC
|
|
3511
|
+
});
|
|
3512
|
+
const goFields = fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
3513
|
+
lines.push(comment);
|
|
3514
|
+
lines.push(`type ${name} struct {
|
|
3515
|
+
${goFields.join(`
|
|
3516
|
+
`)}
|
|
3517
|
+
}`);
|
|
3518
|
+
lines.push("");
|
|
3404
3519
|
}
|
|
3405
3520
|
scalarParsedGoType(value) {
|
|
3406
3521
|
if (value.kind === "unary" && value.op === "-" && value.argument.kind === "literal") {
|
|
@@ -3467,7 +3582,7 @@ ${goFields.join(`
|
|
|
3467
3582
|
for (const nested of inputNested) {
|
|
3468
3583
|
if (nested.loopMarkerId && this.getBakedStaticChildLoop(nested.loopMarkerId, nested, nested.loopArrayParsed, nested.loopParam, nested.loopKey))
|
|
3469
3584
|
continue;
|
|
3470
|
-
lines.push(` ${nested.name}s []${nested.name}Input`);
|
|
3585
|
+
lines.push(` ${nested.name}s []${this.resolveChildName(nested.name)}Input`);
|
|
3471
3586
|
}
|
|
3472
3587
|
const takenInput = new Set(this.propParamFieldNamesUnion(ir.metadata.propsParams));
|
|
3473
3588
|
for (const c of this.nonCollidingContextConsumers(takenInput)) {
|
|
@@ -3503,10 +3618,11 @@ ${goFields.join(`
|
|
|
3503
3618
|
const wrapperName = this.loopBodyWrapperName(parentComponentName, nested);
|
|
3504
3619
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
3505
3620
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren);
|
|
3506
|
-
|
|
3621
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3622
|
+
lines.push(`// ${wrapperName} wraps ${declaredName}Props with per-row loop datum`);
|
|
3507
3623
|
lines.push(`// fields and child component slots for the loop body children. (#1897)`);
|
|
3508
3624
|
lines.push(`type ${wrapperName} struct {`);
|
|
3509
|
-
lines.push(` ${
|
|
3625
|
+
lines.push(` ${declaredName}Props`);
|
|
3510
3626
|
for (const f of datumFields) {
|
|
3511
3627
|
lines.push(` ${f.goName} ${f.goType} \`json:"-"\``);
|
|
3512
3628
|
}
|
|
@@ -3515,7 +3631,7 @@ ${goFields.join(`
|
|
|
3515
3631
|
lines.push(` BfLoopItem ${scalarLoopType} \`json:"-"\``);
|
|
3516
3632
|
}
|
|
3517
3633
|
for (const child of bodyChildInstances) {
|
|
3518
|
-
lines.push(` ${child.fieldName} ${child.name}Props \`json:"-"\``);
|
|
3634
|
+
lines.push(` ${child.fieldName} ${this.resolveChildName(child.name)}Props \`json:"-"\``);
|
|
3519
3635
|
}
|
|
3520
3636
|
lines.push("}");
|
|
3521
3637
|
lines.push("");
|
|
@@ -3599,12 +3715,13 @@ ${goFields.join(`
|
|
|
3599
3715
|
const staticWithoutBody = staticNested.filter((n) => !n.bodyChildren || n.bodyChildren.length === 0);
|
|
3600
3716
|
for (const nested of staticWithoutBody) {
|
|
3601
3717
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
3718
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3602
3719
|
const baked = nested.loopMarkerId ? this.getBakedStaticChildLoop(nested.loopMarkerId, nested, nested.loopArrayParsed, nested.loopParam, nested.loopKey) : null;
|
|
3603
3720
|
if (baked) {
|
|
3604
|
-
lines.push(` ${varName} := make([]${
|
|
3721
|
+
lines.push(` ${varName} := make([]${declaredName}Props, ${baked.items.length})`);
|
|
3605
3722
|
baked.items.forEach((item, i) => {
|
|
3606
3723
|
const fields = item.inputFields.map((f) => `${f.goField}: ${f.goValue}`).join(", ");
|
|
3607
|
-
lines.push(` ${varName}[${i}] = New${
|
|
3724
|
+
lines.push(` ${varName}[${i}] = New${declaredName}Props(${declaredName}Input{${fields}})`);
|
|
3608
3725
|
lines.push(` ${varName}[${i}].BfParent = scopeID`);
|
|
3609
3726
|
lines.push(` ${varName}[${i}].BfMount = "${nested.slotId}"`);
|
|
3610
3727
|
if (item.dataKey !== null) {
|
|
@@ -3614,9 +3731,9 @@ ${goFields.join(`
|
|
|
3614
3731
|
lines.push("");
|
|
3615
3732
|
continue;
|
|
3616
3733
|
}
|
|
3617
|
-
lines.push(` ${varName} := make([]${
|
|
3734
|
+
lines.push(` ${varName} := make([]${declaredName}Props, len(in.${nested.name}s))`);
|
|
3618
3735
|
lines.push(` for i, item := range in.${nested.name}s {`);
|
|
3619
|
-
lines.push(` ${varName}[i] = New${
|
|
3736
|
+
lines.push(` ${varName}[i] = New${declaredName}Props(item)`);
|
|
3620
3737
|
lines.push(` ${varName}[i].BfParent = scopeID`);
|
|
3621
3738
|
lines.push(` ${varName}[i].BfMount = "${nested.slotId}"`);
|
|
3622
3739
|
const keyField = loopKeyToGoFieldPath(nested.loopKey, nested.loopParam);
|
|
@@ -3731,8 +3848,14 @@ ${goFields.join(`
|
|
|
3731
3848
|
lines.push(` ${fieldName}: ${hoisted.varName},`);
|
|
3732
3849
|
} else {
|
|
3733
3850
|
const bakeType = this.state.synthStructTypes.get(signal.getter) ?? signal.type;
|
|
3851
|
+
const resolvedParsed = this.resolvedSignalParsed(signal);
|
|
3734
3852
|
const initialValue = convertInitialValue(this.emitCtx, signal.initialValue, bakeType, ir.metadata.propsParams, signal.parsed);
|
|
3735
3853
|
lines.push(` ${fieldName}: ${initialValue},`);
|
|
3854
|
+
if (resolvedParsed?.kind === "object-literal" && jsLiteralToGo(this.emitCtx, bakeType, resolvedParsed) === null) {
|
|
3855
|
+
const step = this.state.ssrSeedPlan.steps.find((s) => s.kind === "derived" && s.origin === "signal" && s.name === signal.getter);
|
|
3856
|
+
if (step?.kind === "derived")
|
|
3857
|
+
this.refuseUnbakeableDerivedObjectLiteral(signal.getter, signal.loc, step.frees);
|
|
3858
|
+
}
|
|
3736
3859
|
}
|
|
3737
3860
|
}
|
|
3738
3861
|
for (const nested of staticWithoutBody) {
|
|
@@ -3832,19 +3955,20 @@ ${goFields.join(`
|
|
|
3832
3955
|
emitStaticChildInstances(lines, ir) {
|
|
3833
3956
|
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
3834
3957
|
for (const child of staticChildren) {
|
|
3835
|
-
|
|
3958
|
+
const declaredName = this.resolveChildName(child.name);
|
|
3959
|
+
lines.push(` ${child.fieldName}: New${declaredName}Props(${declaredName}Input{`);
|
|
3836
3960
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
3837
3961
|
lines.push(` BfParent: scopeID,`);
|
|
3838
3962
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
3839
3963
|
if (child.contextBindings) {
|
|
3840
|
-
for (const consumer of this.childContextConsumers.get(
|
|
3964
|
+
for (const consumer of this.childContextConsumers.get(declaredName) ?? []) {
|
|
3841
3965
|
const goVal = child.contextBindings.get(consumer.contextName);
|
|
3842
3966
|
if (goVal !== undefined) {
|
|
3843
3967
|
lines.push(` ${this.contextFieldName(consumer)}: ${goVal},`);
|
|
3844
3968
|
}
|
|
3845
3969
|
}
|
|
3846
3970
|
}
|
|
3847
|
-
const childShape = this.childComponentShapes.get(
|
|
3971
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
3848
3972
|
const restBagEntries = [];
|
|
3849
3973
|
const emitChildField = (jsxName, goValue) => {
|
|
3850
3974
|
if (childShape && childShape.restBagField && !childShape.paramNames.has(jsxName)) {
|
|
@@ -3941,6 +4065,7 @@ ${goFields.join(`
|
|
|
3941
4065
|
lines.push(`// New${componentName}Props creates ${propsTypeName} from ${inputTypeName}.`);
|
|
3942
4066
|
for (const nested of signalDynamicNested) {
|
|
3943
4067
|
const arrayField = `${nested.name}s`;
|
|
4068
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3944
4069
|
lines.push(`//`);
|
|
3945
4070
|
lines.push(`// NOTE: \`${arrayField}\` is populated by the route handler, not by`);
|
|
3946
4071
|
lines.push(`// New${componentName}Props — the SSR template iterates over it`);
|
|
@@ -3948,9 +4073,9 @@ ${goFields.join(`
|
|
|
3948
4073
|
lines.push(`// assign it before passing the props to your renderer. Example:`);
|
|
3949
4074
|
lines.push(`//`);
|
|
3950
4075
|
lines.push(`// props := New${componentName}Props(${inputTypeName}{ /* ... */ })`);
|
|
3951
|
-
lines.push(`// props.${arrayField} = make([]${
|
|
4076
|
+
lines.push(`// props.${arrayField} = make([]${declaredName}Props, len(items))`);
|
|
3952
4077
|
lines.push(`// for i, item := range items {`);
|
|
3953
|
-
lines.push(`// props.${arrayField}[i] = New${
|
|
4078
|
+
lines.push(`// props.${arrayField}[i] = New${declaredName}Props(${declaredName}Input{ /* fields */ })`);
|
|
3954
4079
|
lines.push(`// props.${arrayField}[i].BfParent = props.ScopeID`);
|
|
3955
4080
|
lines.push(`// props.${arrayField}[i].BfMount = "${nested.slotId}"`);
|
|
3956
4081
|
lines.push(`// }`);
|
|
@@ -3989,9 +4114,11 @@ ${goFields.join(`
|
|
|
3989
4114
|
const wrapperType = this.loopBodyWrapperName(componentName, nested);
|
|
3990
4115
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
3991
4116
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
4117
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
3992
4118
|
for (const child of bodyChildInstances) {
|
|
3993
4119
|
const childVar = `child_${child.fieldName}`;
|
|
3994
|
-
|
|
4120
|
+
const childDeclaredName = this.resolveChildName(child.name);
|
|
4121
|
+
lines.push(` ${childVar} := New${childDeclaredName}Props(${childDeclaredName}Input{`);
|
|
3995
4122
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
3996
4123
|
lines.push(` BfParent: scopeID,`);
|
|
3997
4124
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
@@ -4011,7 +4138,7 @@ ${goFields.join(`
|
|
|
4011
4138
|
lines.push(` ${varName} := make([]${wrapperType}, len(${dataVar}))`);
|
|
4012
4139
|
lines.push(` for i, item := range ${dataVar} {`);
|
|
4013
4140
|
lines.push(` ${varName}[i] = ${wrapperType}{`);
|
|
4014
|
-
lines.push(` ${
|
|
4141
|
+
lines.push(` ${declaredName}Props: New${declaredName}Props(${declaredName}Input{`);
|
|
4015
4142
|
lines.push(` BfParent: scopeID,`);
|
|
4016
4143
|
lines.push(` BfMount: "${nested.slotId}",`);
|
|
4017
4144
|
for (const prop of nested.props ?? []) {
|
|
@@ -4066,9 +4193,11 @@ ${goFields.join(`
|
|
|
4066
4193
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
4067
4194
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
4068
4195
|
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
4196
|
+
const declaredName = this.resolveChildName(nested.name);
|
|
4069
4197
|
for (const child of bodyChildInstances) {
|
|
4070
4198
|
const childVar = `child_${child.fieldName}`;
|
|
4071
|
-
|
|
4199
|
+
const childDeclaredName = this.resolveChildName(child.name);
|
|
4200
|
+
lines.push(` ${childVar} := New${childDeclaredName}Props(${childDeclaredName}Input{`);
|
|
4072
4201
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
4073
4202
|
lines.push(` BfParent: scopeID,`);
|
|
4074
4203
|
lines.push(` BfMount: "${child.slotId}",`);
|
|
@@ -4087,7 +4216,7 @@ ${goFields.join(`
|
|
|
4087
4216
|
lines.push(` ${varName} := make([]${wrapperType}, len(bakedData))`);
|
|
4088
4217
|
lines.push(` for i, item := range bakedData {`);
|
|
4089
4218
|
lines.push(` ${varName}[i] = ${wrapperType}{`);
|
|
4090
|
-
lines.push(` ${
|
|
4219
|
+
lines.push(` ${declaredName}Props: New${declaredName}Props(${declaredName}Input{`);
|
|
4091
4220
|
lines.push(` BfParent: scopeID,`);
|
|
4092
4221
|
lines.push(` BfMount: "${nested.slotId}",`);
|
|
4093
4222
|
lines.push(` }),`);
|
|
@@ -4142,21 +4271,7 @@ ${goFields.join(`
|
|
|
4142
4271
|
visit(prop.type, desiredName, prop.name);
|
|
4143
4272
|
}
|
|
4144
4273
|
const fields = this.structFieldsFor(typeInfo);
|
|
4145
|
-
this.
|
|
4146
|
-
this.state.currentTypeDefinitions.push({
|
|
4147
|
-
kind: "type",
|
|
4148
|
-
name: desiredName,
|
|
4149
|
-
definition: "",
|
|
4150
|
-
properties: typeInfo.properties ?? [],
|
|
4151
|
-
loc: SYNTH_TYPE_LOC
|
|
4152
|
-
});
|
|
4153
|
-
const goFields = fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
4154
|
-
lines.push(`// ${desiredName} is a synthesised type for an anonymous object type (#2674).`);
|
|
4155
|
-
lines.push(`type ${desiredName} struct {
|
|
4156
|
-
${goFields.join(`
|
|
4157
|
-
`)}
|
|
4158
|
-
}`);
|
|
4159
|
-
lines.push("");
|
|
4274
|
+
this.registerSynthStruct(lines, desiredName, fields, typeInfo.properties ?? [], `// ${desiredName} is a synthesised type for an anonymous object type (#2674).`);
|
|
4160
4275
|
};
|
|
4161
4276
|
const visitArrayElem = (elemType, parentName, propName) => {
|
|
4162
4277
|
if (!elemType)
|
|
@@ -4208,20 +4323,11 @@ ${goFields.join(`
|
|
|
4208
4323
|
const synth = this.synthesizeStructFromSignal(signal, componentName);
|
|
4209
4324
|
if (!synth)
|
|
4210
4325
|
continue;
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
elementType: { kind: "interface", raw: synth.name }
|
|
4217
|
-
});
|
|
4218
|
-
const goFields = synth.fields.map((f) => ` ${f.goName} ${f.goType} \`json:"${this.toJsonTag(f.tsName)}"\``);
|
|
4219
|
-
lines.push(`// ${synth.name} is a synthesised element type for the ${signal.getter} signal.`);
|
|
4220
|
-
lines.push(`type ${synth.name} struct {
|
|
4221
|
-
${goFields.join(`
|
|
4222
|
-
`)}
|
|
4223
|
-
}`);
|
|
4224
|
-
lines.push("");
|
|
4326
|
+
for (const s of synth) {
|
|
4327
|
+
this.registerSynthStruct(lines, s.name, s.fields, s.properties, `// ${s.name} is a synthesised element type for the ${signal.getter} signal.`);
|
|
4328
|
+
}
|
|
4329
|
+
const top = synth[synth.length - 1];
|
|
4330
|
+
this.state.synthStructTypes.set(signal.getter, this.synthSliceTypeInfo(top.name));
|
|
4225
4331
|
}
|
|
4226
4332
|
}
|
|
4227
4333
|
resolveNestedLoopItemTypes(ir, nestedComponents) {
|
|
@@ -4364,7 +4470,7 @@ ${goFields.join(`
|
|
|
4364
4470
|
for (const nested of nestedComponents) {
|
|
4365
4471
|
if (this.isOrphanedClientOnlyNested(nested))
|
|
4366
4472
|
continue;
|
|
4367
|
-
const elemType = nested.bodyChildren?.length ? this.loopBodyWrapperName(componentName, nested) : `${nested.name}Props`;
|
|
4473
|
+
const elemType = nested.bodyChildren?.length ? this.loopBodyWrapperName(componentName, nested) : `${this.resolveChildName(nested.name)}Props`;
|
|
4368
4474
|
if (nested.isDynamic && !nested.isPropDerived) {
|
|
4369
4475
|
lines.push(` ${nested.name}s []${elemType} \`json:"-"\``);
|
|
4370
4476
|
} else if (nested.isDynamic && nested.isPropDerived && !propDrivingFieldNames.has(`${nested.name}s`)) {
|
|
@@ -4376,7 +4482,7 @@ ${goFields.join(`
|
|
|
4376
4482
|
}
|
|
4377
4483
|
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
4378
4484
|
for (const child of staticChildren) {
|
|
4379
|
-
lines.push(` ${child.fieldName} ${child.name}Props \`json:"-"\``);
|
|
4485
|
+
lines.push(` ${child.fieldName} ${this.resolveChildName(child.name)}Props \`json:"-"\``);
|
|
4380
4486
|
}
|
|
4381
4487
|
for (const slot of spreadSlots) {
|
|
4382
4488
|
const jsonTag = "-";
|
|
@@ -4755,6 +4861,22 @@ ${goFields.join(`
|
|
|
4755
4861
|
resolvedSignalParsed(signal) {
|
|
4756
4862
|
return resolveSignalParsedThroughSeedPlan(this.state, signal);
|
|
4757
4863
|
}
|
|
4864
|
+
refuseUnbakeableDerivedObjectLiteral(name, loc, frees) {
|
|
4865
|
+
if (frees.length === 0)
|
|
4866
|
+
return;
|
|
4867
|
+
if (!this.state.templateReadRootFields.has(name))
|
|
4868
|
+
return;
|
|
4869
|
+
this.state.errors.push({
|
|
4870
|
+
code: "BF101",
|
|
4871
|
+
severity: "error",
|
|
4872
|
+
message: `Signal '${name}' is seeded from an object literal that references live value(s) (${frees.join(", ")}) — the Go template adapter bakes object-typed signal values into Go source at New${this.state.componentName}Props time, and that baker is static-only (identifier/member/call operands defer), so the SSR template's read of it would see the Go zero value instead of the derived object.`,
|
|
4873
|
+
loc,
|
|
4874
|
+
suggestion: {
|
|
4875
|
+
message: `Wrap each SSR read of '${name}()' in /* @client */ so it renders on the client instead, or pass the already-derived object in as a prop.`,
|
|
4876
|
+
escape: [{ kind: "client-directive" }]
|
|
4877
|
+
}
|
|
4878
|
+
});
|
|
4879
|
+
}
|
|
4758
4880
|
extractPropFallback(initialValue, preParsed) {
|
|
4759
4881
|
const structural = preParsed ? this.extractPropFallbackFromParsed(preParsed) : null;
|
|
4760
4882
|
if (structural)
|
|
@@ -5083,6 +5205,7 @@ ${goFields.join(`
|
|
|
5083
5205
|
return hit !== null && hit.depth > 0 && hit.binding.source === "item";
|
|
5084
5206
|
}
|
|
5085
5207
|
rootFieldRef(name) {
|
|
5208
|
+
this.state.templateReadRootFields.add(name);
|
|
5086
5209
|
const prefix = this.inLoop ? "$." : ".";
|
|
5087
5210
|
return `${prefix}${capitalizeFieldName(name)}`;
|
|
5088
5211
|
}
|
|
@@ -5104,6 +5227,9 @@ ${goFields.join(`
|
|
|
5104
5227
|
return null;
|
|
5105
5228
|
return `"${escapeGoString(value)}"`;
|
|
5106
5229
|
}
|
|
5230
|
+
findModuleConst(name) {
|
|
5231
|
+
return this.state.localConstants.find((k) => k.name === name && k.isModule && !k.containsArrow);
|
|
5232
|
+
}
|
|
5107
5233
|
resolveModuleNumericConst(name) {
|
|
5108
5234
|
if (this.isCurrentLoopItem(name))
|
|
5109
5235
|
return null;
|
|
@@ -5111,12 +5237,25 @@ ${goFields.join(`
|
|
|
5111
5237
|
return null;
|
|
5112
5238
|
if (this.isOuterLoopParam(name))
|
|
5113
5239
|
return null;
|
|
5114
|
-
const c = this.
|
|
5240
|
+
const c = this.findModuleConst(name);
|
|
5115
5241
|
if (!c || c.value === undefined)
|
|
5116
5242
|
return null;
|
|
5117
5243
|
const v = c.value.trim().replace(/(?<=\d)_(?=\d)/g, "");
|
|
5118
5244
|
return /^-?\d+(\.\d+)?$/.test(v) ? v : null;
|
|
5119
5245
|
}
|
|
5246
|
+
resolveModuleBooleanConst(name) {
|
|
5247
|
+
if (this.isCurrentLoopItem(name))
|
|
5248
|
+
return null;
|
|
5249
|
+
if (this.loopVarRefCount.has(name))
|
|
5250
|
+
return null;
|
|
5251
|
+
if (this.isOuterLoopParam(name))
|
|
5252
|
+
return null;
|
|
5253
|
+
const c = this.findModuleConst(name);
|
|
5254
|
+
if (!c || c.value === undefined)
|
|
5255
|
+
return null;
|
|
5256
|
+
const v = c.value.trim();
|
|
5257
|
+
return v === "true" || v === "false" ? v : null;
|
|
5258
|
+
}
|
|
5120
5259
|
literal(value, literalType) {
|
|
5121
5260
|
if (literalType === "string")
|
|
5122
5261
|
return `"${value}"`;
|
|
@@ -5125,6 +5264,9 @@ ${goFields.join(`
|
|
|
5125
5264
|
return String(value);
|
|
5126
5265
|
}
|
|
5127
5266
|
call(callee, args, emit) {
|
|
5267
|
+
const lowered = lowerRegisteredCallNode(this.emitCtx, callee, args);
|
|
5268
|
+
if (lowered !== null)
|
|
5269
|
+
return lowered;
|
|
5128
5270
|
if (callee.kind === "identifier" && args.length === 0) {
|
|
5129
5271
|
return this.searchParamsFieldRef(callee.name) ?? this.rootFieldRef(callee.name);
|
|
5130
5272
|
}
|
|
@@ -5754,8 +5896,10 @@ ${goFields.join(`
|
|
|
5754
5896
|
}
|
|
5755
5897
|
const signal = localVarMap.get(expr.name);
|
|
5756
5898
|
if (signal) {
|
|
5899
|
+
this.rootFieldRef(signal);
|
|
5757
5900
|
return `$.${capitalizeFieldName(signal)}`;
|
|
5758
5901
|
}
|
|
5902
|
+
this.rootFieldRef(expr.name);
|
|
5759
5903
|
return `.${capitalizeFieldName(expr.name)}`;
|
|
5760
5904
|
}
|
|
5761
5905
|
case "literal":
|
|
@@ -5788,6 +5932,7 @@ ${goFields.join(`
|
|
|
5788
5932
|
return `${paramPrefix}.${capitalizeFieldName(expr.callee.property)}`;
|
|
5789
5933
|
}
|
|
5790
5934
|
if (expr.callee.kind === "identifier" && expr.args.length === 0) {
|
|
5935
|
+
this.rootFieldRef(expr.callee.name);
|
|
5791
5936
|
return `$.${capitalizeFieldName(expr.callee.name)}`;
|
|
5792
5937
|
}
|
|
5793
5938
|
if (asCallbackMethodCall4(expr) !== null) {
|
|
@@ -5960,7 +6105,8 @@ ${goFields.join(`
|
|
|
5960
6105
|
return this.scope.isBound(name) || this.loopVarRefCount.has(name);
|
|
5961
6106
|
}
|
|
5962
6107
|
loopRowChildPropOverrides(comp) {
|
|
5963
|
-
const
|
|
6108
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
6109
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
5964
6110
|
const args = [];
|
|
5965
6111
|
let needsRebuild = false;
|
|
5966
6112
|
for (const prop of comp.props) {
|
|
@@ -5980,10 +6126,10 @@ ${goFields.join(`
|
|
|
5980
6126
|
if (!free || ![...free].some((name) => this.isLoopShadowedName(name)))
|
|
5981
6127
|
continue;
|
|
5982
6128
|
{
|
|
5983
|
-
const derived = this.childDerivedFieldDeps.get(
|
|
6129
|
+
const derived = this.childDerivedFieldDeps.get(declaredName);
|
|
5984
6130
|
const overriddenField = capitalizeFieldName(prop.name);
|
|
5985
6131
|
const staleField = derived ? [...derived].find(([, deps]) => deps.has(overriddenField))?.[0] : undefined;
|
|
5986
|
-
if (staleField && !this.childRepropsReady.has(
|
|
6132
|
+
if (staleField && !this.childRepropsReady.has(declaredName)) {
|
|
5987
6133
|
this.state.errors.push({
|
|
5988
6134
|
code: "BF101",
|
|
5989
6135
|
severity: "error",
|
|
@@ -5997,8 +6143,8 @@ ${goFields.join(`
|
|
|
5997
6143
|
}
|
|
5998
6144
|
if (staleField) {
|
|
5999
6145
|
needsRebuild = true;
|
|
6000
|
-
if (!this.repropsOwner.has(
|
|
6001
|
-
this.repropsOwner.set(
|
|
6146
|
+
if (!this.repropsOwner.has(declaredName)) {
|
|
6147
|
+
this.repropsOwner.set(declaredName, this.state.componentName);
|
|
6002
6148
|
}
|
|
6003
6149
|
}
|
|
6004
6150
|
}
|
|
@@ -6024,7 +6170,7 @@ ${goFields.join(`
|
|
|
6024
6170
|
});
|
|
6025
6171
|
continue;
|
|
6026
6172
|
}
|
|
6027
|
-
const fieldName = this.childPropFieldNames.get(
|
|
6173
|
+
const fieldName = this.childPropFieldNames.get(declaredName)?.get(prop.name) ?? capitalizeFieldName(prop.name);
|
|
6028
6174
|
args.push(`${JSON.stringify(fieldName)} ${wrapIfMultiToken(go)}`);
|
|
6029
6175
|
}
|
|
6030
6176
|
if (args.length === 0)
|
|
@@ -6570,7 +6716,8 @@ ${goFields.join(`
|
|
|
6570
6716
|
}
|
|
6571
6717
|
queueDynamicPropDefine(comp) {
|
|
6572
6718
|
const args = [];
|
|
6573
|
-
const
|
|
6719
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
6720
|
+
const childShape = this.childComponentShapes.get(declaredName);
|
|
6574
6721
|
for (const prop of comp.props) {
|
|
6575
6722
|
if (prop.value.kind !== "jsx-children" || prop.name === "children")
|
|
6576
6723
|
continue;
|
|
@@ -6597,7 +6744,7 @@ ${goFields.join(`
|
|
|
6597
6744
|
content: this.renderChildren(children)
|
|
6598
6745
|
});
|
|
6599
6746
|
}
|
|
6600
|
-
const fieldName = this.childPropFieldNames.get(
|
|
6747
|
+
const fieldName = this.childPropFieldNames.get(declaredName)?.get(prop.name) ?? capitalizeFieldName(prop.name);
|
|
6601
6748
|
args.push(`${JSON.stringify(fieldName)} (bf_tmpl ${JSON.stringify(name)} .)`);
|
|
6602
6749
|
}
|
|
6603
6750
|
return args.length > 0 ? args.join(" ") : null;
|
|
@@ -6629,31 +6776,32 @@ ${goFields.join(`
|
|
|
6629
6776
|
if (comp.dynamicTag) {
|
|
6630
6777
|
return this.renderChildren(comp.children);
|
|
6631
6778
|
}
|
|
6779
|
+
const declaredName = this.resolveChildName(comp.name);
|
|
6632
6780
|
let templateCall;
|
|
6633
6781
|
if (this.inLoop && (this.loopWrapperStack[this.loopWrapperStack.length - 1] ?? false)) {
|
|
6634
6782
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
6635
6783
|
if (loopBodyDefine) {
|
|
6636
6784
|
const bodyData = this.loopScalarItemStack[this.loopScalarItemStack.length - 1] ? ".BfLoopItem" : ".";
|
|
6637
|
-
templateCall = `{{template "${
|
|
6785
|
+
templateCall = `{{template "${declaredName}" (bf_with_children . (bf_tmpl "${loopBodyDefine}" ${bodyData}))}}`;
|
|
6638
6786
|
} else {
|
|
6639
|
-
templateCall = `{{template "${
|
|
6787
|
+
templateCall = `{{template "${declaredName}" .}}`;
|
|
6640
6788
|
}
|
|
6641
6789
|
} else if (this.inLoop && comp.slotId) {
|
|
6642
6790
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
6643
6791
|
const overrides = this.loopRowChildPropOverrides(comp);
|
|
6644
6792
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
6645
|
-
const base = overrides ? overrides.helper === "bf_reprops" ? `(bf_reprops ${JSON.stringify(
|
|
6646
|
-
templateCall = loopBodyDefine ? `{{template "${
|
|
6793
|
+
const base = overrides ? overrides.helper === "bf_reprops" ? `(bf_reprops ${JSON.stringify(declaredName)} $.${comp.name}${suffix} ${overrides.args})` : `(bf_with_props $.${comp.name}${suffix} ${overrides.args})` : `$.${comp.name}${suffix}`;
|
|
6794
|
+
templateCall = loopBodyDefine ? `{{template "${declaredName}" (bf_with_children ${base} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${declaredName}" ${base}}}`;
|
|
6647
6795
|
} else if (this.inLoop) {
|
|
6648
|
-
templateCall = `{{template "${
|
|
6796
|
+
templateCall = `{{template "${declaredName}" .}}`;
|
|
6649
6797
|
} else if (comp.slotId) {
|
|
6650
6798
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
6651
6799
|
const childrenDefine = this.queueDynamicChildrenDefine(comp);
|
|
6652
6800
|
const propArgs = this.queueDynamicPropDefine(comp);
|
|
6653
6801
|
const base = propArgs ? `(bf_with_props .${comp.name}${suffix} ${propArgs})` : `.${comp.name}${suffix}`;
|
|
6654
|
-
templateCall = childrenDefine ? `{{template "${
|
|
6802
|
+
templateCall = childrenDefine ? `{{template "${declaredName}" (bf_with_children ${base} (bf_tmpl "${childrenDefine}" .))}}` : `{{template "${declaredName}" ${base}}}`;
|
|
6655
6803
|
} else {
|
|
6656
|
-
templateCall = `{{template "${
|
|
6804
|
+
templateCall = `{{template "${declaredName}" .${comp.name}}}`;
|
|
6657
6805
|
}
|
|
6658
6806
|
if (ctx?.isRootOfClientComponent) {
|
|
6659
6807
|
return `{{bfScopeComment .}}${templateCall}`;
|
|
@@ -6704,15 +6852,21 @@ ${children}`;
|
|
|
6704
6852
|
const test = parsed.test;
|
|
6705
6853
|
if (undef(parsed.alternate) && !undef(parsed.consequent)) {
|
|
6706
6854
|
const { condition: goCond, preamble } = this.convertConditionToGo(this.isTemplateFragment(this.renderParsedExpr(test), test.kind) ? value.expr : value.expr.slice(0, value.expr.indexOf("?")).trim());
|
|
6707
|
-
const
|
|
6708
|
-
const body = `${name}="{{${
|
|
6855
|
+
const attrConsequent = lowerRegisteredAttrCall(this.emitCtx, name, parsed.consequent);
|
|
6856
|
+
const body = attrConsequent !== null ? attrConsequent : `${name}="{{${this.renderParsedExpr(parsed.consequent)}}}"`;
|
|
6709
6857
|
return `${preamble}{{if ${goCond}}}${body}{{end}}`;
|
|
6710
6858
|
}
|
|
6859
|
+
const attrTernary = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
|
|
6860
|
+
if (attrTernary !== null)
|
|
6861
|
+
return attrTernary;
|
|
6711
6862
|
return `${name}="{{${this.renderParsedExpr(parsed)}}}"`;
|
|
6712
6863
|
}
|
|
6713
6864
|
if (parsed.kind === "template-literal") {
|
|
6714
6865
|
return `${name}="${this.renderParsedExpr(parsed)}"`;
|
|
6715
6866
|
}
|
|
6867
|
+
const attrAction = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
|
|
6868
|
+
if (attrAction !== null)
|
|
6869
|
+
return attrAction;
|
|
6716
6870
|
const bareId = value.expr.trim();
|
|
6717
6871
|
const propName = this.state.propsObjectName && bareId.startsWith(`${this.state.propsObjectName}.`) ? bareId.slice(this.state.propsObjectName.length + 1) : bareId;
|
|
6718
6872
|
if (/^[A-Za-z_$][\w$]*$/.test(propName) && this.state.nillablePropNames.has(propName)) {
|