@barefootjs/go-template 0.17.1 → 0.18.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/url-builder.d.ts.map +1 -1
- package/dist/adapter/go-template-adapter.d.ts +134 -14
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +228 -82
- package/dist/adapter/lib/go-naming.d.ts +23 -0
- package/dist/adapter/lib/go-naming.d.ts.map +1 -1
- package/dist/adapter/type/type-codegen.d.ts +5 -1
- package/dist/adapter/type/type-codegen.d.ts.map +1 -1
- package/dist/adapter/value/parsed-literal-to-go.d.ts +13 -4
- package/dist/adapter/value/parsed-literal-to-go.d.ts.map +1 -1
- package/dist/build.js +228 -82
- package/dist/conformance-pins.d.ts +12 -0
- package/dist/conformance-pins.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +247 -82
- package/package.json +3 -3
- package/src/__tests__/go-template-adapter.test.ts +388 -145
- package/src/__tests__/lowering-plugin.test.ts +56 -0
- package/src/adapter/expr/url-builder.ts +14 -3
- package/src/adapter/go-template-adapter.ts +511 -109
- package/src/adapter/lib/go-naming.ts +29 -0
- package/src/adapter/type/type-codegen.ts +22 -3
- package/src/adapter/value/parsed-literal-to-go.ts +82 -9
- package/src/conformance-pins.ts +135 -0
- package/src/index.ts +1 -0
package/dist/adapter/index.js
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
emitAttrValue,
|
|
39
39
|
augmentInheritedPropAccesses,
|
|
40
40
|
collectContextConsumers,
|
|
41
|
-
|
|
41
|
+
isLowerableLoopDestructure,
|
|
42
42
|
collectModuleStringConsts as collectModuleStringConstsShared,
|
|
43
43
|
prepareLoweringMatchers,
|
|
44
44
|
envSignalReaderFor,
|
|
@@ -123,6 +123,13 @@ function capitalizeFieldName(name) {
|
|
|
123
123
|
}
|
|
124
124
|
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
125
125
|
}
|
|
126
|
+
function goFieldNameForKey(key) {
|
|
127
|
+
const parts = key.split(/[^A-Za-z0-9_]+/).filter(Boolean);
|
|
128
|
+
if (parts.length === 0)
|
|
129
|
+
return "Field";
|
|
130
|
+
const name = parts.map(capitalizeFieldName).join("");
|
|
131
|
+
return /^[0-9]/.test(name) ? `Field${name}` : name;
|
|
132
|
+
}
|
|
126
133
|
function slotIdToFieldSuffix(slotId) {
|
|
127
134
|
const cleanId = slotId.startsWith("^") ? slotId.slice(1) : slotId;
|
|
128
135
|
const match = cleanId.match(/^s(\d+)$/);
|
|
@@ -695,9 +702,12 @@ function forEachValueChild(n, visit) {
|
|
|
695
702
|
// src/adapter/expr/url-builder.ts
|
|
696
703
|
import {
|
|
697
704
|
parseExpression,
|
|
698
|
-
stringifyParsedExpr
|
|
705
|
+
stringifyParsedExpr,
|
|
706
|
+
isValidHelperId
|
|
699
707
|
} from "@barefootjs/jsx";
|
|
700
|
-
|
|
708
|
+
function goHelperName(helper) {
|
|
709
|
+
return isValidHelperId(helper) ? `bf_${helper}` : null;
|
|
710
|
+
}
|
|
701
711
|
var BOOL_COMPARISON_OPS = new Set([
|
|
702
712
|
"==",
|
|
703
713
|
"===",
|
|
@@ -740,7 +750,7 @@ function lowerRegisteredCall(ctx, jsExpr, preParsed) {
|
|
|
740
750
|
return null;
|
|
741
751
|
}
|
|
742
752
|
function renderLoweringNode(ctx, node) {
|
|
743
|
-
const helper =
|
|
753
|
+
const helper = goHelperName(node.helper);
|
|
744
754
|
if (!helper)
|
|
745
755
|
return null;
|
|
746
756
|
const lowerExpr = (n) => ctx.convertExpressionToGo(stringifyParsedExpr(n), undefined, n);
|
|
@@ -780,7 +790,7 @@ function typeInfoToGo(ctx, typeInfo, defaultValue) {
|
|
|
780
790
|
case "object":
|
|
781
791
|
return "map[string]interface{}";
|
|
782
792
|
case "interface":
|
|
783
|
-
if (typeInfo.raw && ctx.state.
|
|
793
|
+
if (typeInfo.raw && (ctx.state.localStructFields.has(typeInfo.raw) || ctx.state.localTypeAliases.has(typeInfo.raw))) {
|
|
784
794
|
return typeInfo.raw;
|
|
785
795
|
}
|
|
786
796
|
if (typeInfo.raw) {
|
|
@@ -813,7 +823,7 @@ function tsTypeStringToGo(ctx, tsType) {
|
|
|
813
823
|
const arrayMatch = t.match(/^Array<(.+)>$/);
|
|
814
824
|
if (arrayMatch)
|
|
815
825
|
return `[]${tsTypeStringToGo(ctx, arrayMatch[1])}`;
|
|
816
|
-
if (ctx.state.
|
|
826
|
+
if (ctx.state.localStructFields.has(t) || ctx.state.localTypeAliases.has(t))
|
|
817
827
|
return t;
|
|
818
828
|
return "interface{}";
|
|
819
829
|
}
|
|
@@ -835,6 +845,24 @@ function inferTypeFromValue(value) {
|
|
|
835
845
|
}
|
|
836
846
|
|
|
837
847
|
// src/adapter/value/parsed-literal-to-go.ts
|
|
848
|
+
function structPropertyType(ctx, structGoType, key) {
|
|
849
|
+
const td = ctx.state.currentTypeDefinitions.find((t) => t.name === structGoType);
|
|
850
|
+
return td?.properties?.find((p) => p.name === key)?.type;
|
|
851
|
+
}
|
|
852
|
+
function bakeInlineObjectAsGoMap(ctx, expr) {
|
|
853
|
+
if (expr.kind !== "object-literal")
|
|
854
|
+
return null;
|
|
855
|
+
const entries = [];
|
|
856
|
+
for (const prop of expr.properties) {
|
|
857
|
+
if (prop.shorthand)
|
|
858
|
+
return null;
|
|
859
|
+
const go = prop.value.kind === "object-literal" ? bakeInlineObjectAsGoMap(ctx, prop.value) : parsedLiteralToGo(ctx, prop.value);
|
|
860
|
+
if (go === null)
|
|
861
|
+
return null;
|
|
862
|
+
entries.push(`${JSON.stringify(goFieldNameForKey(prop.key))}: ${go}`);
|
|
863
|
+
}
|
|
864
|
+
return `map[string]interface{}{${entries.join(", ")}}`;
|
|
865
|
+
}
|
|
838
866
|
function parsedLiteralToGo(ctx, expr, typeInfo) {
|
|
839
867
|
if (expr.kind === "unary" && expr.op === "-" && expr.argument.kind === "literal" && expr.argument.literalType === "number") {
|
|
840
868
|
return expr.argument.raw !== undefined ? `-${expr.argument.raw}` : null;
|
|
@@ -875,9 +903,16 @@ function parsedLiteralToGo(ctx, expr, typeInfo) {
|
|
|
875
903
|
const goField = structFields.get(prop.key);
|
|
876
904
|
if (!goField)
|
|
877
905
|
return null;
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
906
|
+
const propType = structPropertyType(ctx, goType, prop.key);
|
|
907
|
+
let go;
|
|
908
|
+
if (prop.value.kind === "array-literal") {
|
|
909
|
+
go = parsedLiteralToGo(ctx, prop.value, propType);
|
|
910
|
+
} else if (prop.value.kind === "object-literal") {
|
|
911
|
+
const nestedGoType = propType ? typeInfoToGo(ctx, propType) : undefined;
|
|
912
|
+
go = nestedGoType && ctx.state.localStructFields.has(nestedGoType) ? parsedLiteralToGo(ctx, prop.value, propType) : bakeInlineObjectAsGoMap(ctx, prop.value);
|
|
913
|
+
} else {
|
|
914
|
+
go = parsedLiteralToGo(ctx, prop.value);
|
|
915
|
+
}
|
|
881
916
|
if (go === null)
|
|
882
917
|
return null;
|
|
883
918
|
entries.push(`${goField}: ${go}`);
|
|
@@ -2115,8 +2150,10 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
2115
2150
|
inLoop = false;
|
|
2116
2151
|
loopParamStack = [];
|
|
2117
2152
|
loopScalarItemStack = [];
|
|
2153
|
+
loopWrapperStack = [];
|
|
2118
2154
|
loopVarRefCount = new Map;
|
|
2119
2155
|
loopBindingStack = [];
|
|
2156
|
+
loopRestExcludeStack = [];
|
|
2120
2157
|
childComponentShapes = new Map;
|
|
2121
2158
|
childContextConsumers = new Map;
|
|
2122
2159
|
constructor(options = {}) {
|
|
@@ -2309,11 +2346,22 @@ ${scriptRegistrations}${templateBody}
|
|
|
2309
2346
|
contextFieldName(c) {
|
|
2310
2347
|
return capitalizeFieldName(c.localName);
|
|
2311
2348
|
}
|
|
2349
|
+
isMapRootedContextChain(node) {
|
|
2350
|
+
if (node.kind === "identifier") {
|
|
2351
|
+
return this.state.contextConsumers.some((c) => c.localName === node.name && c.defaultKind === "object");
|
|
2352
|
+
}
|
|
2353
|
+
if (node.kind === "member" && !node.computed) {
|
|
2354
|
+
return this.isMapRootedContextChain(node.object);
|
|
2355
|
+
}
|
|
2356
|
+
return false;
|
|
2357
|
+
}
|
|
2312
2358
|
contextConsumerGoType(c) {
|
|
2313
2359
|
if (typeof c.defaultValue === "number")
|
|
2314
2360
|
return "int";
|
|
2315
2361
|
if (typeof c.defaultValue === "boolean")
|
|
2316
2362
|
return "bool";
|
|
2363
|
+
if (c.defaultKind === "object")
|
|
2364
|
+
return "map[string]interface{}";
|
|
2317
2365
|
return "string";
|
|
2318
2366
|
}
|
|
2319
2367
|
contextConsumerGoDefault(c) {
|
|
@@ -2323,6 +2371,8 @@ ${scriptRegistrations}${templateBody}
|
|
|
2323
2371
|
return String(c.defaultValue);
|
|
2324
2372
|
if (typeof c.defaultValue === "string")
|
|
2325
2373
|
return `"${escapeGoString(c.defaultValue)}"`;
|
|
2374
|
+
if (c.defaultKind === "object")
|
|
2375
|
+
return "map[string]interface{}{}";
|
|
2326
2376
|
return '""';
|
|
2327
2377
|
}
|
|
2328
2378
|
nonCollidingContextConsumers(taken) {
|
|
@@ -2369,12 +2419,15 @@ ${goFields.join(`
|
|
|
2369
2419
|
}
|
|
2370
2420
|
structFieldsFor(td) {
|
|
2371
2421
|
const fields = [];
|
|
2422
|
+
const seenGoNames = new Set;
|
|
2372
2423
|
for (const prop of td.properties ?? []) {
|
|
2373
|
-
|
|
2424
|
+
const goName = goFieldNameForKey(prop.name);
|
|
2425
|
+
if (seenGoNames.has(goName))
|
|
2374
2426
|
continue;
|
|
2427
|
+
seenGoNames.add(goName);
|
|
2375
2428
|
fields.push({
|
|
2376
2429
|
tsName: prop.name,
|
|
2377
|
-
goName
|
|
2430
|
+
goName,
|
|
2378
2431
|
goType: typeInfoToGo(this.emitCtx, prop.type)
|
|
2379
2432
|
});
|
|
2380
2433
|
}
|
|
@@ -2602,10 +2655,10 @@ ${goFields.join(`
|
|
|
2602
2655
|
}
|
|
2603
2656
|
return "interface{}";
|
|
2604
2657
|
}
|
|
2605
|
-
collectBodyChildInstances(bodyChildren) {
|
|
2658
|
+
collectBodyChildInstances(bodyChildren, propsParams = []) {
|
|
2606
2659
|
const result = [];
|
|
2607
2660
|
for (const child of bodyChildren) {
|
|
2608
|
-
this.collectStaticChildInstancesRecursive(child, result, false, new Map);
|
|
2661
|
+
this.collectStaticChildInstancesRecursive(child, result, false, new Map, propsParams);
|
|
2609
2662
|
}
|
|
2610
2663
|
return result;
|
|
2611
2664
|
}
|
|
@@ -2775,7 +2828,7 @@ ${goFields.join(`
|
|
|
2775
2828
|
for (const c of this.nonCollidingContextConsumers(takenInit)) {
|
|
2776
2829
|
const field = this.contextFieldName(c);
|
|
2777
2830
|
const def = this.contextConsumerGoDefault(c);
|
|
2778
|
-
const defaulted = c.defaultValue === null || def === '""' || def === "0" || def === "false" ? `in.${field}` : applyGoFallback(`in.${field}`, def);
|
|
2831
|
+
const defaulted = c.defaultValue === null || def === '""' || def === "0" || def === "false" || def === "map[string]interface{}{}" ? `in.${field}` : applyGoFallback(`in.${field}`, def);
|
|
2779
2832
|
lines.push(` ${field}: ${defaulted},`);
|
|
2780
2833
|
}
|
|
2781
2834
|
this.emitStaticChildInstances(lines, ir);
|
|
@@ -2784,7 +2837,7 @@ ${goFields.join(`
|
|
|
2784
2837
|
lines.push("}");
|
|
2785
2838
|
}
|
|
2786
2839
|
emitStaticChildInstances(lines, ir) {
|
|
2787
|
-
const staticChildren = this.collectStaticChildInstances(ir.root);
|
|
2840
|
+
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
2788
2841
|
for (const child of staticChildren) {
|
|
2789
2842
|
lines.push(` ${child.fieldName}: New${child.name}Props(${child.name}Input{`);
|
|
2790
2843
|
lines.push(` ScopeID: scopeID + "_${child.slotId}",`);
|
|
@@ -2916,7 +2969,7 @@ ${goFields.join(`
|
|
|
2916
2969
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
2917
2970
|
const wrapperType = this.loopBodyWrapperName(componentName, nested);
|
|
2918
2971
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
2919
|
-
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren);
|
|
2972
|
+
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
2920
2973
|
for (const child of bodyChildInstances) {
|
|
2921
2974
|
const childVar = `child_${child.fieldName}`;
|
|
2922
2975
|
lines.push(` ${childVar} := New${child.name}Props(${child.name}Input{`);
|
|
@@ -2993,7 +3046,7 @@ ${goFields.join(`
|
|
|
2993
3046
|
const wrapperType = this.loopBodyWrapperName(componentName, nested);
|
|
2994
3047
|
const varName = `${nested.name.charAt(0).toLowerCase()}${nested.name.slice(1)}s`;
|
|
2995
3048
|
const datumFields = this.resolveLoopDatumFields(nested.loopItemType);
|
|
2996
|
-
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren);
|
|
3049
|
+
const bodyChildInstances = this.collectBodyChildInstances(nested.bodyChildren, ir.metadata.propsParams);
|
|
2997
3050
|
for (const child of bodyChildInstances) {
|
|
2998
3051
|
const childVar = `child_${child.fieldName}`;
|
|
2999
3052
|
lines.push(` ${childVar} := New${child.name}Props(${child.name}Input{`);
|
|
@@ -3233,7 +3286,7 @@ ${goFields.join(`
|
|
|
3233
3286
|
lines.push(` ${nested.name}s []${elemType} \`json:"${jsonTag}"\``);
|
|
3234
3287
|
}
|
|
3235
3288
|
}
|
|
3236
|
-
const staticChildren = this.collectStaticChildInstances(ir.root);
|
|
3289
|
+
const staticChildren = this.collectStaticChildInstances(ir.root, ir.metadata.propsParams);
|
|
3237
3290
|
for (const child of staticChildren) {
|
|
3238
3291
|
lines.push(` ${child.fieldName} ${child.name}Props \`json:"-"\``);
|
|
3239
3292
|
}
|
|
@@ -3245,9 +3298,9 @@ ${goFields.join(`
|
|
|
3245
3298
|
toJsonTag(name) {
|
|
3246
3299
|
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
3247
3300
|
}
|
|
3248
|
-
collectStaticChildInstances(node) {
|
|
3301
|
+
collectStaticChildInstances(node, propsParams = []) {
|
|
3249
3302
|
const result = [];
|
|
3250
|
-
this.collectStaticChildInstancesRecursive(node, result, false, new Map);
|
|
3303
|
+
this.collectStaticChildInstancesRecursive(node, result, false, new Map, propsParams);
|
|
3251
3304
|
return result;
|
|
3252
3305
|
}
|
|
3253
3306
|
extractTextChildren(children) {
|
|
@@ -3292,12 +3345,12 @@ ${goFields.join(`
|
|
|
3292
3345
|
return null;
|
|
3293
3346
|
return withSentinel.split(GoTemplateAdapter.SCOPE_SENTINEL).map((seg) => JSON.stringify(seg)).join(" + scopeID + ");
|
|
3294
3347
|
}
|
|
3295
|
-
collectStaticChildInstancesRecursive(node, result, inLoop, providerCtx) {
|
|
3348
|
+
collectStaticChildInstancesRecursive(node, result, inLoop, providerCtx, propsParams = []) {
|
|
3296
3349
|
if (node.type === "component") {
|
|
3297
3350
|
const comp = node;
|
|
3298
3351
|
if (comp.dynamicTag) {
|
|
3299
3352
|
for (const child of comp.children) {
|
|
3300
|
-
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx);
|
|
3353
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx, propsParams);
|
|
3301
3354
|
}
|
|
3302
3355
|
return;
|
|
3303
3356
|
}
|
|
@@ -3315,69 +3368,111 @@ ${goFields.join(`
|
|
|
3315
3368
|
contextBindings: providerCtx.size > 0 ? providerCtx : undefined
|
|
3316
3369
|
});
|
|
3317
3370
|
for (const child of effectiveChildren) {
|
|
3318
|
-
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx);
|
|
3371
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx, propsParams);
|
|
3319
3372
|
}
|
|
3320
3373
|
}
|
|
3321
3374
|
if (comp.name === "Portal" && comp.children) {
|
|
3322
3375
|
for (const child of comp.children) {
|
|
3323
|
-
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx);
|
|
3376
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx, propsParams);
|
|
3324
3377
|
}
|
|
3325
3378
|
}
|
|
3326
3379
|
} else if (node.type === "loop") {
|
|
3327
3380
|
const loop = node;
|
|
3328
3381
|
for (const child of loop.children) {
|
|
3329
|
-
this.collectStaticChildInstancesRecursive(child, result,
|
|
3382
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop || !!loop.childComponent, providerCtx, propsParams);
|
|
3330
3383
|
}
|
|
3331
3384
|
} else if (node.type === "element") {
|
|
3332
3385
|
const element = node;
|
|
3333
3386
|
for (const child of element.children) {
|
|
3334
|
-
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx);
|
|
3387
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx, propsParams);
|
|
3335
3388
|
}
|
|
3336
3389
|
} else if (node.type === "fragment") {
|
|
3337
3390
|
const fragment = node;
|
|
3338
3391
|
for (const child of fragment.children) {
|
|
3339
|
-
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx);
|
|
3392
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx, propsParams);
|
|
3340
3393
|
}
|
|
3341
3394
|
} else if (node.type === "conditional") {
|
|
3342
3395
|
const cond = node;
|
|
3343
|
-
this.collectStaticChildInstancesRecursive(cond.whenTrue, result, inLoop, providerCtx);
|
|
3396
|
+
this.collectStaticChildInstancesRecursive(cond.whenTrue, result, inLoop, providerCtx, propsParams);
|
|
3344
3397
|
if (cond.whenFalse) {
|
|
3345
|
-
this.collectStaticChildInstancesRecursive(cond.whenFalse, result, inLoop, providerCtx);
|
|
3398
|
+
this.collectStaticChildInstancesRecursive(cond.whenFalse, result, inLoop, providerCtx, propsParams);
|
|
3346
3399
|
}
|
|
3347
3400
|
} else if (node.type === "if-statement") {
|
|
3348
3401
|
const stmt = node;
|
|
3349
|
-
this.collectStaticChildInstancesRecursive(stmt.consequent, result, inLoop, providerCtx);
|
|
3402
|
+
this.collectStaticChildInstancesRecursive(stmt.consequent, result, inLoop, providerCtx, propsParams);
|
|
3350
3403
|
if (stmt.alternate) {
|
|
3351
|
-
this.collectStaticChildInstancesRecursive(stmt.alternate, result, inLoop, providerCtx);
|
|
3404
|
+
this.collectStaticChildInstancesRecursive(stmt.alternate, result, inLoop, providerCtx, propsParams);
|
|
3352
3405
|
}
|
|
3353
3406
|
} else if (node.type === "provider") {
|
|
3354
3407
|
const p = node;
|
|
3355
|
-
const childCtx = this.extendProviderContext(providerCtx, p);
|
|
3408
|
+
const childCtx = this.extendProviderContext(providerCtx, p, propsParams);
|
|
3356
3409
|
for (const child of p.children) {
|
|
3357
|
-
this.collectStaticChildInstancesRecursive(child, result, inLoop, childCtx);
|
|
3410
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop, childCtx, propsParams);
|
|
3358
3411
|
}
|
|
3359
3412
|
} else if (node.type === "async") {
|
|
3360
3413
|
const a = node;
|
|
3361
|
-
this.collectStaticChildInstancesRecursive(a.fallback, result, inLoop, providerCtx);
|
|
3414
|
+
this.collectStaticChildInstancesRecursive(a.fallback, result, inLoop, providerCtx, propsParams);
|
|
3362
3415
|
for (const child of a.children) {
|
|
3363
|
-
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx);
|
|
3416
|
+
this.collectStaticChildInstancesRecursive(child, result, inLoop, providerCtx, propsParams);
|
|
3364
3417
|
}
|
|
3365
3418
|
}
|
|
3366
3419
|
}
|
|
3367
|
-
extendProviderContext(current, p) {
|
|
3420
|
+
extendProviderContext(current, p, propsParams) {
|
|
3368
3421
|
const v = p.valueProp?.value;
|
|
3369
|
-
if (!v
|
|
3370
|
-
return current;
|
|
3371
|
-
let goLit = null;
|
|
3372
|
-
if (typeof v.value === "string")
|
|
3373
|
-
goLit = `"${escapeGoString(v.value)}"`;
|
|
3374
|
-
else if (typeof v.value === "number" || typeof v.value === "boolean")
|
|
3375
|
-
goLit = String(v.value);
|
|
3376
|
-
if (goLit === null)
|
|
3422
|
+
if (!v)
|
|
3377
3423
|
return current;
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3424
|
+
if (v.kind === "literal") {
|
|
3425
|
+
let goLit = null;
|
|
3426
|
+
if (typeof v.value === "string")
|
|
3427
|
+
goLit = `"${escapeGoString(v.value)}"`;
|
|
3428
|
+
else if (typeof v.value === "number" || typeof v.value === "boolean")
|
|
3429
|
+
goLit = String(v.value);
|
|
3430
|
+
if (goLit === null)
|
|
3431
|
+
return current;
|
|
3432
|
+
const next = new Map(current);
|
|
3433
|
+
next.set(p.contextName, goLit);
|
|
3434
|
+
return next;
|
|
3435
|
+
}
|
|
3436
|
+
if (v.kind === "expression" && v.parsed) {
|
|
3437
|
+
const goMap = this.providerObjectValueToGoMap(v.parsed, propsParams);
|
|
3438
|
+
if (goMap !== null) {
|
|
3439
|
+
const next = new Map(current);
|
|
3440
|
+
next.set(p.contextName, goMap);
|
|
3441
|
+
return next;
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
return current;
|
|
3445
|
+
}
|
|
3446
|
+
providerObjectValueToGoMap(parsed, propsParams) {
|
|
3447
|
+
if (parsed.kind !== "object-literal")
|
|
3448
|
+
return null;
|
|
3449
|
+
const entries = [];
|
|
3450
|
+
for (const prop of parsed.properties) {
|
|
3451
|
+
if (prop.shorthand)
|
|
3452
|
+
return null;
|
|
3453
|
+
const goVal = this.lowerProviderMapMemberValue(prop.value, propsParams);
|
|
3454
|
+
if (goVal === null)
|
|
3455
|
+
return null;
|
|
3456
|
+
entries.push(`${JSON.stringify(prop.key)}: ${goVal}`);
|
|
3457
|
+
}
|
|
3458
|
+
if (entries.length === 0)
|
|
3459
|
+
return null;
|
|
3460
|
+
return `map[string]interface{}{${entries.join(", ")}}`;
|
|
3461
|
+
}
|
|
3462
|
+
lowerProviderMapMemberValue(node, propsParams) {
|
|
3463
|
+
if (node.kind === "object-literal")
|
|
3464
|
+
return objectLiteralToGoMap(this.emitCtx, node);
|
|
3465
|
+
const literal = parsedLiteralToGo(this.emitCtx, node);
|
|
3466
|
+
if (literal !== null)
|
|
3467
|
+
return literal;
|
|
3468
|
+
if (node.kind === "logical" && node.op === "??" && node.right.kind === "object-literal" && node.right.properties.length === 0 && node.left.kind === "member" && !node.left.computed && node.left.object.kind === "identifier" && node.left.object.name === this.state.propsObjectName) {
|
|
3469
|
+
const propName = node.left.property;
|
|
3470
|
+
if (propsParams.some((param) => param.name === propName)) {
|
|
3471
|
+
const fieldRef = `in.${capitalizeFieldName(propName)}`;
|
|
3472
|
+
return `func() map[string]interface{} { ` + `if m := bf.AsMap(${fieldRef}); m != nil { return m }; ` + `return map[string]interface{}{} }()`;
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
return null;
|
|
3381
3476
|
}
|
|
3382
3477
|
templatePartsToGoCode(parts, propsParams) {
|
|
3383
3478
|
const segments = [];
|
|
@@ -3847,15 +3942,19 @@ ${goFields.join(`
|
|
|
3847
3942
|
if (objHO && (objHO.method === "find" || objHO.method === "findLast")) {
|
|
3848
3943
|
const findResult = this.renderHigherOrderExpr(objHO, emit);
|
|
3849
3944
|
if (findResult) {
|
|
3850
|
-
return `{{with ${findResult}}}{{.${
|
|
3945
|
+
return `{{with ${findResult}}}{{.${goFieldNameForKey(property)}}}{{end}}`;
|
|
3851
3946
|
}
|
|
3852
|
-
const templateBlock = this.renderFindTemplateBlock(objHO, emit,
|
|
3947
|
+
const templateBlock = this.renderFindTemplateBlock(objHO, emit, goFieldNameForKey(property));
|
|
3853
3948
|
if (templateBlock)
|
|
3854
3949
|
return templateBlock;
|
|
3855
3950
|
}
|
|
3856
3951
|
if (object.kind === "identifier" && this.state.propsObjectName && object.name === this.state.propsObjectName) {
|
|
3857
3952
|
return this.rootFieldRef(property);
|
|
3858
3953
|
}
|
|
3954
|
+
if (this.isMapRootedContextChain(object)) {
|
|
3955
|
+
const objGo = emit(object);
|
|
3956
|
+
return `bf_get ${wrapIfMultiToken(objGo)} ${JSON.stringify(property)}`;
|
|
3957
|
+
}
|
|
3859
3958
|
if (object.kind === "identifier") {
|
|
3860
3959
|
const staticValue = this.resolveStaticRecordLiteralIndex(`${object.name}.${property}`);
|
|
3861
3960
|
if (staticValue !== null)
|
|
@@ -3863,12 +3962,12 @@ ${goFields.join(`
|
|
|
3863
3962
|
}
|
|
3864
3963
|
const currentLoopParam = this.loopParamStack[this.loopParamStack.length - 1];
|
|
3865
3964
|
if (object.kind === "identifier" && currentLoopParam && object.name === currentLoopParam) {
|
|
3866
|
-
return `.${
|
|
3965
|
+
return `.${goFieldNameForKey(property)}`;
|
|
3867
3966
|
}
|
|
3868
3967
|
const obj = emit(object);
|
|
3869
3968
|
if (property === "length")
|
|
3870
3969
|
return `len ${obj}`;
|
|
3871
|
-
return `${obj}.${
|
|
3970
|
+
return `${obj}.${goFieldNameForKey(property)}`;
|
|
3872
3971
|
}
|
|
3873
3972
|
indexAccess(object, index, emit) {
|
|
3874
3973
|
return `index ${wrapIfMultiToken(emit(object))} ${wrapIfMultiToken(emit(index))}`;
|
|
@@ -3960,7 +4059,16 @@ ${goFields.join(`
|
|
|
3960
4059
|
return `bf_arr ${parts.join(" ")}`;
|
|
3961
4060
|
}
|
|
3962
4061
|
objectLiteral(_properties, raw, _emit) {
|
|
3963
|
-
|
|
4062
|
+
this.state.errors.push({
|
|
4063
|
+
code: "BF101",
|
|
4064
|
+
severity: "error",
|
|
4065
|
+
message: `Expression not supported: ${raw}`,
|
|
4066
|
+
loc: this.makeLoc(),
|
|
4067
|
+
suggestion: {
|
|
4068
|
+
message: `Go templates have no object/map literal syntax, so the \`?? {}\` fallback can't render server-side. ${GO_REMEDIATION_OPTIONS}`
|
|
4069
|
+
}
|
|
4070
|
+
});
|
|
4071
|
+
return `""`;
|
|
3964
4072
|
}
|
|
3965
4073
|
static PREDICATE_METHODS = new Set([
|
|
3966
4074
|
"filter",
|
|
@@ -4173,6 +4281,9 @@ ${goFields.join(`
|
|
|
4173
4281
|
}
|
|
4174
4282
|
}
|
|
4175
4283
|
flatMethod(object, depth, emit) {
|
|
4284
|
+
if (typeof depth === "object") {
|
|
4285
|
+
return `bf_flat_dynamic ${wrapIfMultiToken(emit(object))} ${wrapIfMultiToken(emit(depth.expr))}`;
|
|
4286
|
+
}
|
|
4176
4287
|
const d = depth === "infinity" ? -1 : depth;
|
|
4177
4288
|
return `bf_flat ${wrapIfMultiToken(emit(object))} ${d}`;
|
|
4178
4289
|
}
|
|
@@ -4871,23 +4982,44 @@ ${goFields.join(`
|
|
|
4871
4982
|
return plain(expr.raw);
|
|
4872
4983
|
}
|
|
4873
4984
|
}
|
|
4985
|
+
buildSegmentAccessor(base, segments) {
|
|
4986
|
+
let acc = base;
|
|
4987
|
+
for (const seg of segments) {
|
|
4988
|
+
acc = seg.kind === "field" ? `${acc}.${goFieldNameForKey(seg.key)}` : `(index ${acc} ${seg.index})`;
|
|
4989
|
+
}
|
|
4990
|
+
return acc;
|
|
4991
|
+
}
|
|
4874
4992
|
buildDestructureBindingMap(loop, rangeVar) {
|
|
4875
|
-
const
|
|
4993
|
+
const bindings = new Map;
|
|
4994
|
+
const restExcludes = new Map;
|
|
4995
|
+
const base = `$${rangeVar}`;
|
|
4876
4996
|
for (const b of loop.paramBindings ?? []) {
|
|
4877
|
-
|
|
4878
|
-
|
|
4997
|
+
const parent = this.buildSegmentAccessor(base, b.segments ?? []);
|
|
4998
|
+
if (!b.rest) {
|
|
4999
|
+
bindings.set(b.name, parent);
|
|
5000
|
+
} else if (b.rest.kind === "array") {
|
|
5001
|
+
bindings.set(b.name, `(bf_slice ${parent} ${b.rest.from})`);
|
|
4879
5002
|
} else {
|
|
4880
|
-
|
|
5003
|
+
bindings.set(b.name, parent);
|
|
5004
|
+
restExcludes.set(b.name, { parent, excludeKeys: b.rest.exclude.map((k) => k.key) });
|
|
4881
5005
|
}
|
|
4882
5006
|
}
|
|
4883
|
-
return
|
|
5007
|
+
return { bindings, restExcludes };
|
|
5008
|
+
}
|
|
5009
|
+
lookupRestExclude(name) {
|
|
5010
|
+
for (let i = this.loopRestExcludeStack.length - 1;i >= 0; i--) {
|
|
5011
|
+
const info = this.loopRestExcludeStack[i].get(name);
|
|
5012
|
+
if (info)
|
|
5013
|
+
return info;
|
|
5014
|
+
}
|
|
5015
|
+
return;
|
|
4884
5016
|
}
|
|
4885
5017
|
renderLoop(loop) {
|
|
4886
5018
|
if (loop.clientOnly) {
|
|
4887
5019
|
return `{{bfComment "loop:${loop.markerId}"}}{{bfComment "/loop:${loop.markerId}"}}`;
|
|
4888
5020
|
}
|
|
4889
5021
|
const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
|
|
4890
|
-
const supportableDestructure = destructure &&
|
|
5022
|
+
const supportableDestructure = destructure && isLowerableLoopDestructure(loop);
|
|
4891
5023
|
if (destructure && !supportableDestructure) {
|
|
4892
5024
|
this.state.errors.push({
|
|
4893
5025
|
code: "BF104",
|
|
@@ -4902,6 +5034,21 @@ ${goFields.join(`
|
|
|
4902
5034
|
}
|
|
4903
5035
|
});
|
|
4904
5036
|
}
|
|
5037
|
+
const arrayName = loop.array.trim();
|
|
5038
|
+
if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
|
|
5039
|
+
const arrayConst = this.state.localConstants.find((c) => c.name === arrayName);
|
|
5040
|
+
if (arrayConst && !arrayConst.isModule && arrayConst.parsed && !this.isStringExpr(arrayConst.parsed, new Set)) {
|
|
5041
|
+
this.state.errors.push({
|
|
5042
|
+
code: "BF101",
|
|
5043
|
+
severity: "error",
|
|
5044
|
+
message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the Go template adapter cannot bind as a template variable — only a string-derived local resolves to a generated struct field.`,
|
|
5045
|
+
loc: loop.loc ?? this.makeLoc(),
|
|
5046
|
+
suggestion: {
|
|
5047
|
+
message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client."
|
|
5048
|
+
}
|
|
5049
|
+
});
|
|
5050
|
+
}
|
|
5051
|
+
}
|
|
4905
5052
|
let goArray = this.convertExpressionToGo(loop.array);
|
|
4906
5053
|
const param = loop.param;
|
|
4907
5054
|
let index = loop.index || "_";
|
|
@@ -4911,15 +5058,16 @@ ${goFields.join(`
|
|
|
4911
5058
|
rangeIndex = param;
|
|
4912
5059
|
rangeValue = "_";
|
|
4913
5060
|
}
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
goArray = `.${childComponent.name}s`;
|
|
5061
|
+
if (loop.childComponent) {
|
|
5062
|
+
goArray = `.${loop.childComponent.name}s`;
|
|
4917
5063
|
}
|
|
4918
5064
|
this.inLoop = true;
|
|
4919
5065
|
const addedLoopVars = [];
|
|
4920
5066
|
let pushedBindingMap = false;
|
|
4921
5067
|
if (supportableDestructure) {
|
|
4922
|
-
this.
|
|
5068
|
+
const built = this.buildDestructureBindingMap(loop, rangeValue);
|
|
5069
|
+
this.loopBindingStack.push(built.bindings);
|
|
5070
|
+
this.loopRestExcludeStack.push(built.restExcludes);
|
|
4923
5071
|
pushedBindingMap = true;
|
|
4924
5072
|
this.loopParamStack.push("");
|
|
4925
5073
|
if (rangeIndex !== "_") {
|
|
@@ -4938,7 +5086,9 @@ ${goFields.join(`
|
|
|
4938
5086
|
}
|
|
4939
5087
|
}
|
|
4940
5088
|
this.loopScalarItemStack.push(this.scalarLiteralLoopGoType(loop.arrayParsed, loop.itemType) !== null);
|
|
5089
|
+
this.loopWrapperStack.push(!!loop.childComponent);
|
|
4941
5090
|
const children = this.renderChildren(loop.children);
|
|
5091
|
+
this.loopWrapperStack.pop();
|
|
4942
5092
|
this.loopScalarItemStack.pop();
|
|
4943
5093
|
const itemMarker = this.loopItemMarker(loop);
|
|
4944
5094
|
for (const v of addedLoopVars) {
|
|
@@ -4949,8 +5099,10 @@ ${goFields.join(`
|
|
|
4949
5099
|
this.loopVarRefCount.set(v, rc);
|
|
4950
5100
|
}
|
|
4951
5101
|
this.loopParamStack.pop();
|
|
4952
|
-
if (pushedBindingMap)
|
|
5102
|
+
if (pushedBindingMap) {
|
|
4953
5103
|
this.loopBindingStack.pop();
|
|
5104
|
+
this.loopRestExcludeStack.pop();
|
|
5105
|
+
}
|
|
4954
5106
|
this.inLoop = false;
|
|
4955
5107
|
if (loop.sortComparator) {
|
|
4956
5108
|
const sortEmit = (e) => this.renderParsedExpr(e);
|
|
@@ -4979,24 +5131,6 @@ ${goFields.join(`
|
|
|
4979
5131
|
}
|
|
4980
5132
|
return "";
|
|
4981
5133
|
}
|
|
4982
|
-
findChildComponent(nodes) {
|
|
4983
|
-
for (const node of nodes) {
|
|
4984
|
-
if (node.type === "component") {
|
|
4985
|
-
return node;
|
|
4986
|
-
}
|
|
4987
|
-
if (node.type === "element" && node.children) {
|
|
4988
|
-
const found = this.findChildComponent(node.children);
|
|
4989
|
-
if (found)
|
|
4990
|
-
return found;
|
|
4991
|
-
}
|
|
4992
|
-
if (node.type === "fragment" && node.children) {
|
|
4993
|
-
const found = this.findChildComponent(node.children);
|
|
4994
|
-
if (found)
|
|
4995
|
-
return found;
|
|
4996
|
-
}
|
|
4997
|
-
}
|
|
4998
|
-
return null;
|
|
4999
|
-
}
|
|
5000
5134
|
queueDynamicChildrenDefine(comp) {
|
|
5001
5135
|
const effectiveChildren = comp.children.length > 0 ? comp.children : this.jsxChildrenPropNodes(comp.props);
|
|
5002
5136
|
if (effectiveChildren.length === 0)
|
|
@@ -5044,7 +5178,7 @@ ${goFields.join(`
|
|
|
5044
5178
|
return this.renderChildren(comp.children);
|
|
5045
5179
|
}
|
|
5046
5180
|
let templateCall;
|
|
5047
|
-
if (this.inLoop) {
|
|
5181
|
+
if (this.inLoop && (this.loopWrapperStack[this.loopWrapperStack.length - 1] ?? false)) {
|
|
5048
5182
|
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
5049
5183
|
if (loopBodyDefine) {
|
|
5050
5184
|
const bodyData = this.loopScalarItemStack[this.loopScalarItemStack.length - 1] ? ".BfLoopItem" : ".";
|
|
@@ -5052,6 +5186,12 @@ ${goFields.join(`
|
|
|
5052
5186
|
} else {
|
|
5053
5187
|
templateCall = `{{template "${comp.name}" .}}`;
|
|
5054
5188
|
}
|
|
5189
|
+
} else if (this.inLoop && comp.slotId) {
|
|
5190
|
+
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
5191
|
+
const loopBodyDefine = this.queueLoopBodyChildrenDefine(comp);
|
|
5192
|
+
templateCall = loopBodyDefine ? `{{template "${comp.name}" (bf_with_children $.${comp.name}${suffix} (bf_tmpl "${loopBodyDefine}" .))}}` : `{{template "${comp.name}" $.${comp.name}${suffix}}}`;
|
|
5193
|
+
} else if (this.inLoop) {
|
|
5194
|
+
templateCall = `{{template "${comp.name}" .}}`;
|
|
5055
5195
|
} else if (comp.slotId) {
|
|
5056
5196
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
5057
5197
|
const childrenDefine = this.queueDynamicChildrenDefine(comp);
|
|
@@ -5147,6 +5287,12 @@ ${children}`;
|
|
|
5147
5287
|
if (currentLoopParam && trimmed === currentLoopParam) {
|
|
5148
5288
|
return `{{bf_spread_attrs .}}`;
|
|
5149
5289
|
}
|
|
5290
|
+
const restInfo = this.lookupRestExclude(trimmed);
|
|
5291
|
+
if (restInfo) {
|
|
5292
|
+
const excludeArgs = restInfo.excludeKeys.map((k) => JSON.stringify(k)).join(" ");
|
|
5293
|
+
const omitArgs = excludeArgs ? `${restInfo.parent} ${excludeArgs}` : restInfo.parent;
|
|
5294
|
+
return `{{bf_spread_attrs (bf_omit ${omitArgs})}}`;
|
|
5295
|
+
}
|
|
5150
5296
|
const goExpr = this.convertExpressionToGo(value.expr);
|
|
5151
5297
|
return `{{bf_spread_attrs ${goExpr}}}`;
|
|
5152
5298
|
}
|
|
@@ -21,6 +21,29 @@ export declare const GO_KEYWORDS: Set<string>;
|
|
|
21
21
|
export declare function capitalize(s: string): string;
|
|
22
22
|
/** Capitalise a JSX prop / field name to its exported Go struct field name. */
|
|
23
23
|
export declare function capitalizeFieldName(name: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve ANY source property key — identifier or not (`data-priority`,
|
|
26
|
+
* `aria-label`, a numeric key) — to a valid Go struct field name. Splits on
|
|
27
|
+
* runs of characters that are invalid in a Go identifier (underscores are
|
|
28
|
+
* VALID and preserved, so a snake_case key round-trips to the exact same
|
|
29
|
+
* name `capitalizeFieldName` alone has always produced — `foo_bar` →
|
|
30
|
+
* `Foo_bar`, never `FooBar`; renaming it would break both existing member
|
|
31
|
+
* emission and consumers' hand-written constructors against generated
|
|
32
|
+
* types) and PascalCases each segment through `capitalizeFieldName`, so a
|
|
33
|
+
* hyphenated key gets a real field instead of being silently dropped
|
|
34
|
+
* (`data-priority` → `DataPriority`). A result that would start with a
|
|
35
|
+
* digit (numeric key `0`) is prefixed with `Field` (`Field0`), and a key
|
|
36
|
+
* with no usable characters at all falls back to `Field` — both keep the
|
|
37
|
+
* emitted struct compiling (not expected from real TS property names, but
|
|
38
|
+
* keeps the function total).
|
|
39
|
+
*
|
|
40
|
+
* Single source of truth for the source-key → Go-name mapping: used for
|
|
41
|
+
* struct-field generation (#2087 Phase B — `structFieldsFor`), inline-map
|
|
42
|
+
* baking (`bakeInlineObjectAsGoMap`), and the `member()` dot-access
|
|
43
|
+
* emitter, so the baked side and the accessor side can never disagree
|
|
44
|
+
* (PR #2089 review).
|
|
45
|
+
*/
|
|
46
|
+
export declare function goFieldNameForKey(key: string): string;
|
|
24
47
|
/**
|
|
25
48
|
* Convert a slot ID (e.g., 's6') to a Go struct field suffix (e.g., 'Slot6').
|
|
26
49
|
* Keeps field names human-readable regardless of the internal slot ID format.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"go-naming.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/go-naming.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,aAAa,QAA6B,CAAA;AAEvD,iHAAiH;AACjH,eAAO,MAAM,cAAc,aAIzB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,aAKtB,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAS1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAQtG"}
|
|
1
|
+
{"version":3,"file":"go-naming.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/go-naming.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,aAAa,QAA6B,CAAA;AAEvD,iHAAiH;AACjH,eAAO,MAAM,cAAc,aAIzB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,aAKtB,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAS1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAQtG"}
|
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
* Free functions over a {@link GoEmitContext}. They resolve a prop/signal/const's
|
|
5
5
|
* type (`TypeInfo`, a raw type string, or — as a last resort — an inferred shape
|
|
6
6
|
* from a literal value) into the Go type used for its struct field. They read
|
|
7
|
-
*
|
|
7
|
+
* `state.localStructFields` / `state.localTypeAliases` (an ACTUAL Go-backed
|
|
8
|
+
* local type — a generated struct or a string-union alias) rather than the
|
|
9
|
+
* broader `state.localTypeNames` (every type definition, including a tuple
|
|
10
|
+
* alias no struct was ever emitted for — #2087); `inferTypeFromValue` is fully
|
|
11
|
+
* pure.
|
|
8
12
|
*/
|
|
9
13
|
import type { TypeInfo } from '@barefootjs/jsx';
|
|
10
14
|
import type { GoEmitContext } from '../emit-context.ts';
|