@barefootjs/go-template 0.35.2 → 0.35.3

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.
@@ -32,7 +32,7 @@ import {
32
32
  buildImportAliasMap,
33
33
  resolveGetterAliases,
34
34
  collectAliasableGetterNames,
35
- resolveBodyDestructuredPropAliases
35
+ resolveBodyDestructuredPropAliases as resolveBodyDestructuredPropAliases2
36
36
  } from "@barefootjs/jsx";
37
37
  import { findInterpolationEnd } from "@barefootjs/jsx/scanner";
38
38
  import { BF_REGION, escapeHtml, resolveJsxChildrenProp } from "@barefootjs/shared";
@@ -2877,7 +2877,7 @@ function collectNillablePropNames(ctx, ir) {
2877
2877
  }
2878
2878
 
2879
2879
  // src/adapter/props/prop-classes.ts
2880
- import { collectLoopBoundNames } from "@barefootjs/jsx";
2880
+ import { collectLoopBoundNames, resolveBodyDestructuredPropAliases } from "@barefootjs/jsx";
2881
2881
  function isStringTypeInfo(type) {
2882
2882
  return type.kind === "primitive" && type.primitive === "string";
2883
2883
  }
@@ -2898,6 +2898,10 @@ function collectStringValueNames(ir) {
2898
2898
  if (isStringTypeInfo(p.type))
2899
2899
  names.add(p.name);
2900
2900
  }
2901
+ for (const [local, callerKey] of resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName)) {
2902
+ if (names.has(callerKey))
2903
+ names.add(local);
2904
+ }
2901
2905
  for (const c of ir.metadata.localConstants) {
2902
2906
  if (c.type !== null && isStringTypeInfo(c.type) || isBareStringLiteral(c.value)) {
2903
2907
  names.add(c.name);
@@ -2989,7 +2993,7 @@ class GoTemplateAdapter extends BaseAdapter {
2989
2993
  const getterNames = collectAliasableGetterNames(ir.metadata.signals ?? [], ir.metadata.memos ?? []);
2990
2994
  this.state.getterAliases = resolveGetterAliases(ir.metadata.localConstants ?? [], (n) => getterNames.has(n));
2991
2995
  }
2992
- this.state.propDestructureAliases = resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName);
2996
+ this.state.propDestructureAliases = resolveBodyDestructuredPropAliases2(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName);
2993
2997
  this.state.staticLoopSourceBoundNames = collectLoopBoundNames2(ir);
2994
2998
  this.bakedStaticChildLoopCache = new Map;
2995
2999
  this.state.localHelperNames = new Set(this.state.localConstants.filter((c) => !c.isModule && c.containsArrow).map((c) => c.name));
@@ -35,6 +35,19 @@ import { type ComponentIR } from '@barefootjs/jsx';
35
35
  * string elsewhere in the component) but safe: the suppressed case just
36
36
  * falls back to today's numeric `bf_add` — the same, already-accepted
37
37
  * residual as an unresolvable operand — never silently-wrong output.
38
+ *
39
+ * A bare-props-form component's BODY-destructured, RENAMED prop (`const {
40
+ * fallbackLabel: skipLabel } = props`, the #2788 alias family) has no
41
+ * `propsParams` entry of its own — `propsParams` only carries the TYPE-level,
42
+ * caller-facing names, and the local alias never appears there. Without the
43
+ * alias resolved here too, a string-typed prop referenced only under its
44
+ * local rename in a `+` concat (`greeting + skipLabel`) is invisible to this
45
+ * witness, so `isStringConcatBinary` falls through to numeric `bf_add`
46
+ * instead of `bf_concat_str` (#2894, the go-template sibling of #2883's
47
+ * Mojolicious fix). `resolveBodyDestructuredPropAliases` already recognizes
48
+ * this exact destructuring shape; reusing it here keeps this one witness the
49
+ * single source of truth `_isStringValueName` reads, rather than growing a
50
+ * second, adapter-local alias lookup.
38
51
  */
39
52
  export declare function collectStringValueNames(ir: ComponentIR): Set<string>;
40
53
  //# sourceMappingURL=prop-classes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prop-classes.d.ts","sourceRoot":"","sources":["../../../src/adapter/props/prop-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAyB,KAAK,WAAW,EAAiB,MAAM,iBAAiB,CAAA;AAcxF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBpE"}
1
+ {"version":3,"file":"prop-classes.d.ts","sourceRoot":"","sources":["../../../src/adapter/props/prop-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAA6D,KAAK,WAAW,EAAiB,MAAM,iBAAiB,CAAA;AAc5H;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAuBpE"}
@@ -1 +1 @@
1
- {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eA4F7B,CAAA"}
1
+ {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eA2G7B,CAAA"}
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  buildImportAliasMap,
33
33
  resolveGetterAliases,
34
34
  collectAliasableGetterNames,
35
- resolveBodyDestructuredPropAliases
35
+ resolveBodyDestructuredPropAliases as resolveBodyDestructuredPropAliases2
36
36
  } from "@barefootjs/jsx";
37
37
  import { findInterpolationEnd } from "@barefootjs/jsx/scanner";
38
38
  import { BF_REGION, escapeHtml, resolveJsxChildrenProp } from "@barefootjs/shared";
@@ -2877,7 +2877,7 @@ function collectNillablePropNames(ctx, ir) {
2877
2877
  }
2878
2878
 
2879
2879
  // src/adapter/props/prop-classes.ts
2880
- import { collectLoopBoundNames } from "@barefootjs/jsx";
2880
+ import { collectLoopBoundNames, resolveBodyDestructuredPropAliases } from "@barefootjs/jsx";
2881
2881
  function isStringTypeInfo(type) {
2882
2882
  return type.kind === "primitive" && type.primitive === "string";
2883
2883
  }
@@ -2898,6 +2898,10 @@ function collectStringValueNames(ir) {
2898
2898
  if (isStringTypeInfo(p.type))
2899
2899
  names.add(p.name);
2900
2900
  }
2901
+ for (const [local, callerKey] of resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName)) {
2902
+ if (names.has(callerKey))
2903
+ names.add(local);
2904
+ }
2901
2905
  for (const c of ir.metadata.localConstants) {
2902
2906
  if (c.type !== null && isStringTypeInfo(c.type) || isBareStringLiteral(c.value)) {
2903
2907
  names.add(c.name);
@@ -2989,7 +2993,7 @@ class GoTemplateAdapter extends BaseAdapter {
2989
2993
  const getterNames = collectAliasableGetterNames(ir.metadata.signals ?? [], ir.metadata.memos ?? []);
2990
2994
  this.state.getterAliases = resolveGetterAliases(ir.metadata.localConstants ?? [], (n) => getterNames.has(n));
2991
2995
  }
2992
- this.state.propDestructureAliases = resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName);
2996
+ this.state.propDestructureAliases = resolveBodyDestructuredPropAliases2(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName);
2993
2997
  this.state.staticLoopSourceBoundNames = collectLoopBoundNames2(ir);
2994
2998
  this.bakedStaticChildLoopCache = new Map;
2995
2999
  this.state.localHelperNames = new Set(this.state.localConstants.filter((c) => !c.isModule && c.containsArrow).map((c) => c.name));
@@ -7109,7 +7113,12 @@ var conformancePins = {
7109
7113
  severity: "error",
7110
7114
  issue: "https://github.com/piconic-ai/barefootjs/issues/2700"
7111
7115
  }],
7112
- "namespace-import-primitive": [{ code: "BF013", severity: "error" }]
7116
+ "namespace-import-primitive": [{ code: "BF013", severity: "error" }],
7117
+ "static-nested-loop-ref": [{
7118
+ code: "BF101",
7119
+ severity: "error",
7120
+ issue: "https://github.com/piconic-ai/barefootjs/issues/2893"
7121
+ }]
7113
7122
  };
7114
7123
  // src/render-divergences.ts
7115
7124
  var renderDivergences = {};
package/dist/vite.js CHANGED
@@ -3525,8 +3525,11 @@ function formatDateLocalNames(metadata) {
3525
3525
  // ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
3526
3526
  import ts19 from "typescript";
3527
3527
 
3528
- // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
3528
+ // ../jsx/src/ir-to-client-js/emit-reactive.ts
3529
3529
  import ts20 from "typescript";
3530
+
3531
+ // ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
3532
+ import ts21 from "typescript";
3530
3533
  var NO_PREAMBLE = {
3531
3534
  lazySafe: true,
3532
3535
  facts: { declaredNames: new Set, freeNames: new Set }
@@ -3575,9 +3578,6 @@ var INERT_BINDING_GLOBALS = new Set([
3575
3578
  "decodeURI"
3576
3579
  ]);
3577
3580
 
3578
- // ../jsx/src/ir-to-client-js/emit-reactive.ts
3579
- import ts21 from "typescript";
3580
-
3581
3581
  // ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
3582
3582
  var NON_BUBBLING_EVENTS = new Set([
3583
3583
  "blur",
@@ -8184,6 +8184,10 @@ function collectStringValueNames(ir) {
8184
8184
  if (isStringTypeInfo(p.type))
8185
8185
  names.add(p.name);
8186
8186
  }
8187
+ for (const [local, callerKey] of resolveBodyDestructuredPropAliases(ir.metadata.localConstants ?? [], ir.metadata.propsObjectName)) {
8188
+ if (names.has(callerKey))
8189
+ names.add(local);
8190
+ }
8187
8191
  for (const c of ir.metadata.localConstants) {
8188
8192
  if (c.type !== null && isStringTypeInfo(c.type) || isBareStringLiteral(c.value)) {
8189
8193
  names.add(c.name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/go-template",
3
- "version": "0.35.2",
3
+ "version": "0.35.3",
4
4
  "description": "Go html/template adapter for BarefootJS - generates Go template files from IR",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -49,7 +49,7 @@
49
49
  "directory": "packages/adapter-go-template"
50
50
  },
51
51
  "dependencies": {
52
- "@barefootjs/shared": "0.35.2"
52
+ "@barefootjs/shared": "0.35.3"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@barefootjs/jsx": ">=0.2.0",
@@ -67,9 +67,9 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@barefootjs/adapter-tests": "0.1.0",
70
- "@barefootjs/client": "0.35.2",
71
- "@barefootjs/jsx": "0.35.2",
72
- "@barefootjs/vite": "0.35.2",
70
+ "@barefootjs/client": "0.35.3",
71
+ "@barefootjs/jsx": "0.35.3",
72
+ "@barefootjs/vite": "0.35.3",
73
73
  "vite": "^6.0.0"
74
74
  }
75
75
  }
@@ -6909,3 +6909,34 @@ export { C }
6909
6909
  expect(decode(htmlExplicitZero)).toEqual({ name: 'Ada', label: '', x: 0 })
6910
6910
  })
6911
6911
  })
6912
+
6913
+ describe('GoTemplateAdapter - collectStringValueNames resolves renamed body-destructured prop aliases (#2894)', () => {
6914
+ // Sibling gap to #2883 (Mojolicious): a `+` concat against a bare-props-form
6915
+ // BODY-destructured, RENAMED prop (`const { fallbackLabel: skipLabel } =
6916
+ // props`, the #2788 alias family) previously had no witness in
6917
+ // `collectStringValueNames`, so `isStringConcatBinary` fell through to
6918
+ // numeric `bf_add` instead of `bf_concat_str` — Go's `bf_add` coerces both
6919
+ // operands through `toFloat64`, so a string operand silently becomes `0`.
6920
+ test('a `+` concat against a renamed body-destructured prop lowers to bf_concat_str, not bf_add', () => {
6921
+ const result = compileAndGenerate(`
6922
+ 'use client'
6923
+ import { createSignal } from '@barefootjs/client'
6924
+
6925
+ type Todo = { id: number; label: string }
6926
+
6927
+ export function ConcatRenamedProp(props: { fallbackLabel: string }) {
6928
+ const { fallbackLabel: skipLabel } = props
6929
+ const [todos] = createSignal<Todo[]>([{ id: 1, label: 'Alpha' }])
6930
+ return (
6931
+ <ul>
6932
+ {todos().map(t => (
6933
+ <li key={t.id}>{t.label + skipLabel}</li>
6934
+ ))}
6935
+ </ul>
6936
+ )
6937
+ }
6938
+ `)
6939
+ expect(result.template).toContain('bf_concat_str .Label $.FallbackLabel')
6940
+ expect(result.template).not.toContain('bf_add .Label $.FallbackLabel')
6941
+ })
6942
+ })
@@ -7,7 +7,7 @@
7
7
  * function over `ir.metadata`; no adapter instance state.
8
8
  */
9
9
 
10
- import { collectLoopBoundNames, type ComponentIR, type TypeInfo } from '@barefootjs/jsx'
10
+ import { collectLoopBoundNames, resolveBodyDestructuredPropAliases, type ComponentIR, type TypeInfo } from '@barefootjs/jsx'
11
11
 
12
12
  /** True when `type` is the `string` primitive. */
13
13
  function isStringTypeInfo(type: TypeInfo): boolean {
@@ -49,6 +49,19 @@ function isBareStringLiteral(initialValue: string | undefined): boolean {
49
49
  * string elsewhere in the component) but safe: the suppressed case just
50
50
  * falls back to today's numeric `bf_add` — the same, already-accepted
51
51
  * residual as an unresolvable operand — never silently-wrong output.
52
+ *
53
+ * A bare-props-form component's BODY-destructured, RENAMED prop (`const {
54
+ * fallbackLabel: skipLabel } = props`, the #2788 alias family) has no
55
+ * `propsParams` entry of its own — `propsParams` only carries the TYPE-level,
56
+ * caller-facing names, and the local alias never appears there. Without the
57
+ * alias resolved here too, a string-typed prop referenced only under its
58
+ * local rename in a `+` concat (`greeting + skipLabel`) is invisible to this
59
+ * witness, so `isStringConcatBinary` falls through to numeric `bf_add`
60
+ * instead of `bf_concat_str` (#2894, the go-template sibling of #2883's
61
+ * Mojolicious fix). `resolveBodyDestructuredPropAliases` already recognizes
62
+ * this exact destructuring shape; reusing it here keeps this one witness the
63
+ * single source of truth `_isStringValueName` reads, rather than growing a
64
+ * second, adapter-local alias lookup.
52
65
  */
53
66
  export function collectStringValueNames(ir: ComponentIR): Set<string> {
54
67
  const names = new Set<string>()
@@ -60,6 +73,12 @@ export function collectStringValueNames(ir: ComponentIR): Set<string> {
60
73
  for (const p of ir.metadata.propsParams) {
61
74
  if (isStringTypeInfo(p.type)) names.add(p.name)
62
75
  }
76
+ for (const [local, callerKey] of resolveBodyDestructuredPropAliases(
77
+ ir.metadata.localConstants ?? [],
78
+ ir.metadata.propsObjectName,
79
+ )) {
80
+ if (names.has(callerKey)) names.add(local)
81
+ }
63
82
  for (const c of ir.metadata.localConstants) {
64
83
  if ((c.type !== null && isStringTypeInfo(c.type)) || isBareStringLiteral(c.value)) {
65
84
  names.add(c.name)
@@ -101,4 +101,19 @@ export const conformancePins: ConformancePins = {
101
101
  // resolves the primitive normally and never reaches this refusal (formerly
102
102
  // tracked as #2771, closed) — no open issue tracks further work.
103
103
  'namespace-import-primitive': [{ code: 'BF013', severity: 'error' }],
104
+ // #2893: `analyzeBakeableStaticElementLoop`'s static-array bake (Go's only
105
+ // path to bind a static/non-signal array as a loop source — `html/template`
106
+ // has no slice literal syntax) bails the WHOLE loop when the body contains
107
+ // a nested `loop` node (module docstring, `static-element-loop-bake.ts`).
108
+ // This fixture's outer static array's row has a nested `.map()` over
109
+ // `item.children`, so it falls through to the generic "computed loop
110
+ // array" BF101 refusal. Unrelated to #2798's own fix (a client-JS-only
111
+ // ref/reactive-binding gap) — this is a pre-existing Go-adapter SSR
112
+ // static-loop-baking scope boundary the new fixture happened to be the
113
+ // first to exercise.
114
+ 'static-nested-loop-ref': [{
115
+ code: 'BF101',
116
+ severity: 'error',
117
+ issue: 'https://github.com/piconic-ai/barefootjs/issues/2893',
118
+ }],
104
119
  }