@barefootjs/jsx 0.18.2 → 0.18.4

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.
@@ -103,6 +103,45 @@ export interface ParsedExprEmitter {
103
103
  }, emit: (e: ParsedExpr) => string): string;
104
104
  unsupported(raw: string, reason: string): string;
105
105
  }
106
+ /**
107
+ * Whether an operand is string-typed, as far as the ParsedExpr tree can
108
+ * tell: a string literal, a template literal, a zero-arg getter call /
109
+ * `props.x` member whose name the adapter knows to be string-valued
110
+ * (`isStringName`, from adapter state), or a `+` chain that is itself a
111
+ * string concatenation. Promoted from the Mojo/Xslate adapters' local
112
+ * copies (their file header marked it a shared candidate) and extended
113
+ * with the template-literal and nested-`+` arms.
114
+ *
115
+ * Consumed by `===`/`!==` lowering on backends whose `==` is numeric
116
+ * (Perl `eq`/`ne`) and by `isStringConcatBinary` below.
117
+ */
118
+ export declare function isStringTypedOperand(expr: ParsedExpr, isStringName: (n: string) => boolean): boolean;
119
+ /**
120
+ * Whether a `binary` node is JS STRING concatenation rather than numeric
121
+ * addition: `+` with at least one string-typed operand (#2176). JS `+`
122
+ * overloads on operand type; backends whose `+` is numeric-only coerce
123
+ * the strings — Perl renders `'Hello, ' + name` as 0, PHP fatals with
124
+ * "Unsupported operand types" — so their emitters must pick the
125
+ * language's concat operator (`.` / `~`) when this returns true. The
126
+ * decision is shared-layer semantics; each adapter only maps true to
127
+ * its own operator.
128
+ */
129
+ export declare function isStringConcatBinary(op: string, left: ParsedExpr, right: ParsedExpr, isStringName: (n: string) => boolean): boolean;
130
+ /**
131
+ * Wrap an emitted binary/logical/ternary OPERAND in parentheses so the
132
+ * source grouping the `ParsedExpr` tree encodes survives infix
133
+ * re-emission (#2173). `(count() + 2) * 3` parses as
134
+ * `binary{*, binary{+}, 3}` — the tree is unambiguous, but an emitter
135
+ * that joins operands textually (`${l} ${op} ${r}`) re-exposes the
136
+ * text to the TARGET language's precedence, silently computing
137
+ * `count + 2 * 3`. Grouping is decided here, in the shared layer
138
+ * (the semantics), so adapters just call this on each operand — no
139
+ * per-language precedence table needed: parenthesizing a compound
140
+ * operand is universally valid, and leaf operands (identifiers,
141
+ * literals, calls, members) stay unwrapped so simple emissions remain
142
+ * byte-identical.
143
+ */
144
+ export declare function groupBinaryOperand(operand: ParsedExpr, emitted: string): string;
106
145
  /**
107
146
  * Single point of dispatch from `ParsedExpr.kind` to the adapter's
108
147
  * method. Adapters call this once at their entry point; the recursion
@@ -1 +1 @@
1
- {"version":3,"file":"parsed-expr-emitter.d.ts","sourceRoot":"","sources":["../../src/adapters/parsed-expr-emitter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parsed-expr-emitter.d.ts","sourceRoot":"","sources":["../../src/adapters/parsed-expr-emitter.ts"],"names":[],"mappings":"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"}
@@ -37,5 +37,15 @@ export interface BindingEnvironment {
37
37
  * through a local constant are recursively expanded so the consumer sees
38
38
  * the constant's *kind composition*, not just the local name.
39
39
  */
40
+ /**
41
+ * Whether `name` is bound by anything in the environment — an import, a
42
+ * local const/function, a prop param, a signal/memo, or an active loop
43
+ * param. Used by Phase 1's render-nothing-literal fold to distinguish
44
+ * the global `undefined` (renders nothing per JSX semantics) from a
45
+ * shadowed local binding named `undefined` (legal, if inadvisable — the
46
+ * shadowed VALUE must render). Cheap: the binding map is memoized per
47
+ * environment.
48
+ */
49
+ export declare function isNameBound(name: string, env: BindingEnvironment): boolean;
40
50
  export declare function resolveFreeRefs(node: ts.Node, env: BindingEnvironment): FreeReference[];
41
51
  //# sourceMappingURL=free-refs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"free-refs.d.ts","sourceRoot":"","sources":["../src/free-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,KAAK,EAEV,aAAa,EAEb,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAA;AAInB;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IAC9B,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;IAC1B,WAAW,EAAE,SAAS,SAAS,EAAE,CAAA;IACjC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,cAAc,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,cAAc,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACnC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAChC,OAAO,EAAE,EAAE,CAAC,WAAW,GAAG,IAAI,CAAA;CAC/B;AA2VD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,GAAG,EAAE,kBAAkB,GACtB,aAAa,EAAE,CAEjB"}
1
+ {"version":3,"file":"free-refs.d.ts","sourceRoot":"","sources":["../src/free-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,KAAK,EAEV,aAAa,EAEb,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAA;AAInB;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IAC9B,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;IAC1B,WAAW,EAAE,SAAS,SAAS,EAAE,CAAA;IACjC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,cAAc,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,cAAc,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACnC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAChC,OAAO,EAAE,EAAE,CAAC,WAAW,GAAG,IAAI,CAAA;CAC/B;AA2VD;;;;;GAKG;AACH;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAE1E;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,GAAG,EAAE,kBAAkB,GACtB,aAAa,EAAE,CAEjB"}
package/dist/index.d.ts CHANGED
@@ -20,7 +20,7 @@ export type { TemplateAdapter, AdapterOutput, AdapterGenerateOptions, TemplateSe
20
20
  export { JsxAdapter } from './adapters/jsx-adapter.ts';
21
21
  export type { JsxAdapterConfig } from './adapters/jsx-adapter.ts';
22
22
  export { rewriteImportsForTemplate } from './adapters/template-imports.ts';
23
- export { emitParsedExpr } from './adapters/parsed-expr-emitter.ts';
23
+ export { emitParsedExpr, groupBinaryOperand, isStringTypedOperand, isStringConcatBinary } from './adapters/parsed-expr-emitter.ts';
24
24
  export type { ParsedExprEmitter, HigherOrderMethod, ArrayMethod, SortMethod, LiteralType } from './adapters/parsed-expr-emitter.ts';
25
25
  export { importsSearchParams, searchParamsLocalNames, envSignalLocalNames, envSignalReaderFor, ENV_SIGNAL_READERS, queryHrefLocalNames, matchSearchParamsMethodCall } from './adapters/env-signal.ts';
26
26
  export type { EnvSignalReader } from './adapters/env-signal.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8026,11 +8026,15 @@ function resolveFreeRefsInternal(node, env, visited) {
8026
8026
  }
8027
8027
  return out;
8028
8028
  }
8029
+ function isNameBound(name, env) {
8030
+ return buildBindingMap(env).has(name);
8031
+ }
8029
8032
  function resolveFreeRefs(node, env) {
8030
8033
  return resolveFreeRefsInternal(node, env, new Set);
8031
8034
  }
8032
8035
 
8033
8036
  // src/jsx-to-ir.ts
8037
+ import { toHTMLAttrName } from "@barefootjs/shared";
8034
8038
  var CLIENT_DIRECTIVE_INTERIOR_RE2 = /^\s*@client\s*$/;
8035
8039
  var BLOCK_COMMENT_RE2 = /\/\*([\s\S]*?)\*\//g;
8036
8040
  function hasLeadingClientDirective(expr, sourceFile) {
@@ -8468,7 +8472,7 @@ function clientBuiltinTags(ctx) {
8468
8472
  ctx._clientBuiltinTags = map;
8469
8473
  return map;
8470
8474
  }
8471
- function isNameBound(ctx, name) {
8475
+ function isNameBound2(ctx, name) {
8472
8476
  const a = ctx.analyzer;
8473
8477
  if (a.ambientGlobals.has(name))
8474
8478
  return true;
@@ -8503,7 +8507,7 @@ function dispatchClientBuiltin(tagName, ctx, diagNode, transformAsync, transform
8503
8507
  return transformAsync();
8504
8508
  if (builtin === "Region")
8505
8509
  return transformRegion();
8506
- if (isClientBuiltinName(tagName) && !isNameBound(ctx, tagName)) {
8510
+ if (isClientBuiltinName(tagName) && !isNameBound2(ctx, tagName)) {
8507
8511
  reportBuiltinNotImported(ctx, diagNode, tagName);
8508
8512
  }
8509
8513
  return null;
@@ -8818,6 +8822,13 @@ function transformChildren(children, ctx) {
8818
8822
  }
8819
8823
  return result;
8820
8824
  }
8825
+ function isRenderNothingLiteral(expr, ctx) {
8826
+ let e = expr;
8827
+ while (ts11.isParenthesizedExpression(e) || ts11.isAsExpression(e) || ts11.isSatisfiesExpression(e) || ts11.isNonNullExpression(e)) {
8828
+ e = e.expression;
8829
+ }
8830
+ return e.kind === ts11.SyntaxKind.NullKeyword || e.kind === ts11.SyntaxKind.TrueKeyword || e.kind === ts11.SyntaxKind.FalseKeyword || ts11.isIdentifier(e) && e.text === "undefined" && !isNameBound("undefined", makeBindingEnv(ctx));
8831
+ }
8821
8832
  function transformText(node, ctx) {
8822
8833
  const text = node.text.replace(/\s+/g, " ");
8823
8834
  if (text.trim() === "") {
@@ -8838,6 +8849,9 @@ function transformExpression(node, ctx) {
8838
8849
  }
8839
8850
  function transformExpressionInner(expr, ctx, node, isClientOnly) {
8840
8851
  expr = tryDesugarInterleaveTaggedTemplate(expr, ctx);
8852
+ if (isRenderNothingLiteral(expr, ctx)) {
8853
+ return null;
8854
+ }
8841
8855
  checkBareSignalOrMemoIdentifier(expr, ctx);
8842
8856
  if (ts11.isIdentifier(expr)) {
8843
8857
  const jsxNode = ctx.analyzer.jsxConstants.get(expr.text);
@@ -10297,27 +10311,28 @@ function processAttributes(attributes, ctx) {
10297
10311
  }
10298
10312
  if (!ts11.isJsxAttribute(attr))
10299
10313
  continue;
10300
- const name = attr.name.getText(ctx.sourceFile);
10301
- if (name === "ref") {
10314
+ const rawName = attr.name.getText(ctx.sourceFile);
10315
+ if (rawName === "ref") {
10302
10316
  if (attr.initializer && ts11.isJsxExpression(attr.initializer) && attr.initializer.expression) {
10303
10317
  reportJsxBranchLocalInCallback(attr.initializer.expression, ctx);
10304
10318
  ref = ctx.getJS(attr.initializer.expression);
10305
10319
  }
10306
10320
  continue;
10307
10321
  }
10308
- if (/^on[A-Z]/.test(name)) {
10322
+ if (/^on[A-Z]/.test(rawName)) {
10309
10323
  if (attr.initializer && ts11.isJsxExpression(attr.initializer) && attr.initializer.expression) {
10310
- const eventName = name.slice(2).toLowerCase();
10324
+ const eventName = rawName.slice(2).toLowerCase();
10311
10325
  reportJsxBranchLocalInCallback(attr.initializer.expression, ctx);
10312
10326
  events.push({
10313
10327
  name: eventName,
10314
- originalAttr: name,
10328
+ originalAttr: rawName,
10315
10329
  handler: ctx.getJS(attr.initializer.expression),
10316
10330
  loc: getSourceLocation(attr, ctx.sourceFile, ctx.filePath)
10317
10331
  });
10318
10332
  }
10319
10333
  continue;
10320
10334
  }
10335
+ const name = toHTMLAttrName(rawName);
10321
10336
  let value = getAttributeValue(attr, ctx);
10322
10337
  let clientOnly;
10323
10338
  if (attr.initializer && ts11.isJsxExpression(attr.initializer) && attr.initializer.expression) {
@@ -19993,6 +20008,28 @@ export default ${this.componentName}` : "";
19993
20008
  }
19994
20009
  var testAdapter = new TestAdapter;
19995
20010
  // src/adapters/parsed-expr-emitter.ts
20011
+ function isStringTypedOperand(expr, isStringName) {
20012
+ if (expr.kind === "literal" && expr.literalType === "string")
20013
+ return true;
20014
+ if (expr.kind === "template-literal")
20015
+ return true;
20016
+ if (expr.kind === "call" && expr.callee.kind === "identifier" && expr.args.length === 0) {
20017
+ return isStringName(expr.callee.name);
20018
+ }
20019
+ if (expr.kind === "member" && expr.object.kind === "identifier" && expr.object.name === "props") {
20020
+ return isStringName(expr.property);
20021
+ }
20022
+ if (expr.kind === "binary" && expr.op === "+") {
20023
+ return isStringTypedOperand(expr.left, isStringName) || isStringTypedOperand(expr.right, isStringName);
20024
+ }
20025
+ return false;
20026
+ }
20027
+ function isStringConcatBinary(op, left, right, isStringName) {
20028
+ return op === "+" && (isStringTypedOperand(left, isStringName) || isStringTypedOperand(right, isStringName));
20029
+ }
20030
+ function groupBinaryOperand(operand, emitted) {
20031
+ return operand.kind === "binary" || operand.kind === "logical" || operand.kind === "conditional" ? `(${emitted})` : emitted;
20032
+ }
19996
20033
  function emitParsedExpr(expr, emitter) {
19997
20034
  const emit = (child) => emitParsedExpr(child, emitter);
19998
20035
  switch (expr.kind) {
@@ -23055,11 +23092,14 @@ export {
23055
23092
  joinProfilerEvents,
23056
23093
  isValidHelperId,
23057
23094
  isSupported,
23095
+ isStringTypedOperand,
23096
+ isStringConcatBinary,
23058
23097
  isLowerableObjectRestDestructure,
23059
23098
  isLowerableLoopDestructure,
23060
23099
  isBooleanAttr,
23061
23100
  importsSearchParams,
23062
23101
  identifierPath,
23102
+ groupBinaryOperand,
23063
23103
  graphToJSON,
23064
23104
  getLoweringPlugins,
23065
23105
  getCompilerCounters,
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-to-ir.d.ts","sourceRoot":"","sources":["../src/jsx-to-ir.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,KAAK,MAAM,EA0BZ,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,KAAK,eAAe,EAA0E,MAAM,uBAAuB,CAAA;AAsnBpI,wBAAgB,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAIhE"}
1
+ {"version":3,"file":"jsx-to-ir.d.ts","sourceRoot":"","sources":["../src/jsx-to-ir.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,KAAK,MAAM,EA0BZ,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,KAAK,eAAe,EAA0E,MAAM,uBAAuB,CAAA;AAunBpI,wBAAgB,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAIhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/jsx",
3
- "version": "0.18.2",
3
+ "version": "0.18.4",
4
4
  "description": "JSX compiler for BarefootJS - transforms JSX to server HTML + client JS",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -53,7 +53,7 @@
53
53
  "directory": "packages/jsx"
54
54
  },
55
55
  "dependencies": {
56
- "@barefootjs/shared": "0.18.2"
56
+ "@barefootjs/shared": "0.18.4"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@barefootjs/client": ">=0.2.0",
@@ -3090,7 +3090,7 @@ export function initExample(__scope, _p = {}) {
3090
3090
  initChild('DialogTrigger', _s0, { asChild: true })
3091
3091
  }
3092
3092
 
3093
- hydrate('Example', { init: initExample, template: (_p) => \`<div>\${renderChild('DialogTrigger', {asChild: true, children: \`<span role="button" \${(0) != null ? 'tabIndex="' + escapeAttr(0) + '"' : ''}>Open</span>\`}, undefined, 's0')}</div>\` })
3093
+ hydrate('Example', { init: initExample, template: (_p) => \`<div>\${renderChild('DialogTrigger', {asChild: true, children: \`<span role="button" \${(0) != null ? 'tabindex="' + escapeAttr(0) + '"' : ''}>Open</span>\`}, undefined, 's0')}</div>\` })
3094
3094
  export function Example(_p, __bfKey) { return createComponent('Example', _p, __bfKey) }"
3095
3095
  `;
3096
3096
 
@@ -26,7 +26,7 @@ function findClassNameValue(node: IRNode): AttrValue | null {
26
26
  if (node.type === 'element') {
27
27
  const el = node as IRElement
28
28
  for (const attr of el.attrs) {
29
- if (attr.name === 'className') return attr.value
29
+ if (attr.name === 'class') return attr.value
30
30
  }
31
31
  for (const child of el.children) {
32
32
  const v = findClassNameValue(child)
@@ -83,8 +83,8 @@ describe('Context.Provider JSX', () => {
83
83
  contextName: 'Ctx',
84
84
  valueProp: { name: 'value', value: { kind: 'expression', expr: '{ active, setActive }' } },
85
85
  children: [
86
- { type: 'element', tag: 'div', attrs: [{ name: 'className', value: { kind: 'literal', value: 'tabs-header' } }] },
87
- { type: 'element', tag: 'div', attrs: [{ name: 'className', value: { kind: 'literal', value: 'tabs-body' } }] },
86
+ { type: 'element', tag: 'div', attrs: [{ name: 'class', value: { kind: 'literal', value: 'tabs-header' } }] },
87
+ { type: 'element', tag: 'div', attrs: [{ name: 'class', value: { kind: 'literal', value: 'tabs-body' } }] },
88
88
  ],
89
89
  })
90
90
  })
@@ -0,0 +1,108 @@
1
+ /**
2
+ * JSX render-nothing literal folding (#2171).
3
+ *
4
+ * Per JSX semantics, `{null}` / `{undefined}` / `{true}` / `{false}` in
5
+ * child position render NOTHING, while `{0}` renders "0" and `{''}`
6
+ * renders the empty string. Historically the literals fell through to
7
+ * the scalar IRExpression fallback and each adapter stringified them
8
+ * its own way (Hono emitted the text "null" for `{null}`; the template
9
+ * adapters emitted "false" for `{false}`) — the Priority-12 sweep's
10
+ * `falsy-text-values` fixture pinned that three-way divergence. Folding
11
+ * in Phase 1 means the IR simply carries no node for these children,
12
+ * so every adapter agrees by construction.
13
+ */
14
+
15
+ import { describe, expect, test } from 'bun:test'
16
+ import { analyzeComponent } from '../analyzer'
17
+ import { jsxToIR } from '../jsx-to-ir'
18
+ import type { IRElement, IRNode } from '../types'
19
+
20
+ function irFor(source: string): IRNode {
21
+ const analyzer = analyzeComponent(source, 'test.tsx')
22
+ const ir = jsxToIR(analyzer)
23
+ if (!ir) throw new Error('no IR produced')
24
+ return ir
25
+ }
26
+
27
+ function childrenOf(ir: IRNode): IRNode[] {
28
+ return (ir as IRElement).children ?? []
29
+ }
30
+
31
+ describe('render-nothing literal children fold in Phase 1', () => {
32
+ test.each(['null', 'undefined', 'true', 'false'])(
33
+ '{%s} child produces no IR node',
34
+ (literal) => {
35
+ const ir = irFor(`
36
+ export function C() {
37
+ return <div><span>a</span>{${literal}}<span>b</span></div>
38
+ }
39
+ `)
40
+ const children = childrenOf(ir)
41
+ expect(children).toHaveLength(2)
42
+ expect(children.every(c => c.type === 'element')).toBe(true)
43
+ },
44
+ )
45
+
46
+ test('transparently wrapped spellings fold too', () => {
47
+ for (const wrapped of ['(null)', 'null as unknown', 'undefined!']) {
48
+ const ir = irFor(`
49
+ export function C() {
50
+ return <div>{${wrapped}}</div>
51
+ }
52
+ `)
53
+ expect(childrenOf(ir)).toHaveLength(0)
54
+ }
55
+ })
56
+
57
+ test('{0} and {""} still produce expression children', () => {
58
+ const ir = irFor(`
59
+ export function C() {
60
+ return <div>{0}{''}</div>
61
+ }
62
+ `)
63
+ const children = childrenOf(ir)
64
+ expect(children).toHaveLength(2)
65
+ expect(children.every(c => c.type === 'expression')).toBe(true)
66
+ })
67
+
68
+ test('a dynamic expression that may evaluate to null is NOT folded', () => {
69
+ const ir = irFor(`
70
+ export function C(props: { name?: string }) {
71
+ return <div>{props.name}</div>
72
+ }
73
+ `)
74
+ expect(childrenOf(ir)).toHaveLength(1)
75
+ expect(childrenOf(ir)[0].type).toBe('expression')
76
+ })
77
+
78
+ test('a SHADOWED `undefined` binding is not folded (renders the value)', () => {
79
+ // `const undefined = …` is lint-hostile but legal JS — the shadowed
80
+ // binding's value must render, so the fold checks the binding
81
+ // environment before treating the identifier as the global.
82
+ const ir = irFor(`
83
+ export function C() {
84
+ const undefined = 'shadowed'
85
+ return <div>{undefined}</div>
86
+ }
87
+ `)
88
+ const children = childrenOf(ir)
89
+ expect(children).toHaveLength(1)
90
+ expect(children[0].type).toBe('expression')
91
+ })
92
+
93
+ test('conditional null branches keep their existing handling', () => {
94
+ // `cond ? <a/> : null` routes through the conditional transformer,
95
+ // not the JSX-child scalar path — the fold must not disturb it.
96
+ const ir = irFor(`
97
+ 'use client'
98
+ import { createSignal } from '@barefootjs/client'
99
+ export function C() {
100
+ const [show] = createSignal(false)
101
+ return <div>{show() ? <span>on</span> : null}</div>
102
+ }
103
+ `)
104
+ const children = childrenOf(ir)
105
+ expect(children).toHaveLength(1)
106
+ expect(children[0].type).toBe('conditional')
107
+ })
108
+ })
@@ -41,7 +41,7 @@ function classAttrValue(source: string, filename = 'TagDemo.tsx') {
41
41
  expect(ir).not.toBeNull()
42
42
  expect(ir!.type).toBe('element')
43
43
  const el = ir as IRElement
44
- const attr = el.attrs.find(a => a.name === 'className')
44
+ const attr = el.attrs.find(a => a.name === 'class')
45
45
  expect(attr).toBeDefined()
46
46
  return attr!.value
47
47
  }
@@ -256,7 +256,7 @@ describe('tagged-template interleave-tag recognition (#2092)', () => {
256
256
  const ir = jsxToIR(ctx)
257
257
  expect(ir).not.toBeNull()
258
258
  const el = ir as IRElement
259
- const attr = el.attrs.find(a => a.name === 'className')
259
+ const attr = el.attrs.find(a => a.name === 'class')
260
260
  expect(attr).toBeDefined()
261
261
  // The desugar still applies (the client-only directive doesn't block
262
262
  // recognition — it's read independently from the original node), and
@@ -198,6 +198,72 @@ export interface ParsedExprEmitter {
198
198
  unsupported(raw: string, reason: string): string
199
199
  }
200
200
 
201
+ /**
202
+ * Whether an operand is string-typed, as far as the ParsedExpr tree can
203
+ * tell: a string literal, a template literal, a zero-arg getter call /
204
+ * `props.x` member whose name the adapter knows to be string-valued
205
+ * (`isStringName`, from adapter state), or a `+` chain that is itself a
206
+ * string concatenation. Promoted from the Mojo/Xslate adapters' local
207
+ * copies (their file header marked it a shared candidate) and extended
208
+ * with the template-literal and nested-`+` arms.
209
+ *
210
+ * Consumed by `===`/`!==` lowering on backends whose `==` is numeric
211
+ * (Perl `eq`/`ne`) and by `isStringConcatBinary` below.
212
+ */
213
+ export function isStringTypedOperand(expr: ParsedExpr, isStringName: (n: string) => boolean): boolean {
214
+ if (expr.kind === 'literal' && expr.literalType === 'string') return true
215
+ if (expr.kind === 'template-literal') return true
216
+ if (expr.kind === 'call' && expr.callee.kind === 'identifier' && expr.args.length === 0) {
217
+ return isStringName(expr.callee.name)
218
+ }
219
+ if (expr.kind === 'member' && expr.object.kind === 'identifier' && expr.object.name === 'props') {
220
+ return isStringName(expr.property)
221
+ }
222
+ if (expr.kind === 'binary' && expr.op === '+') {
223
+ return isStringTypedOperand(expr.left, isStringName) || isStringTypedOperand(expr.right, isStringName)
224
+ }
225
+ return false
226
+ }
227
+
228
+ /**
229
+ * Whether a `binary` node is JS STRING concatenation rather than numeric
230
+ * addition: `+` with at least one string-typed operand (#2176). JS `+`
231
+ * overloads on operand type; backends whose `+` is numeric-only coerce
232
+ * the strings — Perl renders `'Hello, ' + name` as 0, PHP fatals with
233
+ * "Unsupported operand types" — so their emitters must pick the
234
+ * language's concat operator (`.` / `~`) when this returns true. The
235
+ * decision is shared-layer semantics; each adapter only maps true to
236
+ * its own operator.
237
+ */
238
+ export function isStringConcatBinary(
239
+ op: string,
240
+ left: ParsedExpr,
241
+ right: ParsedExpr,
242
+ isStringName: (n: string) => boolean,
243
+ ): boolean {
244
+ return op === '+' && (isStringTypedOperand(left, isStringName) || isStringTypedOperand(right, isStringName))
245
+ }
246
+
247
+ /**
248
+ * Wrap an emitted binary/logical/ternary OPERAND in parentheses so the
249
+ * source grouping the `ParsedExpr` tree encodes survives infix
250
+ * re-emission (#2173). `(count() + 2) * 3` parses as
251
+ * `binary{*, binary{+}, 3}` — the tree is unambiguous, but an emitter
252
+ * that joins operands textually (`${l} ${op} ${r}`) re-exposes the
253
+ * text to the TARGET language's precedence, silently computing
254
+ * `count + 2 * 3`. Grouping is decided here, in the shared layer
255
+ * (the semantics), so adapters just call this on each operand — no
256
+ * per-language precedence table needed: parenthesizing a compound
257
+ * operand is universally valid, and leaf operands (identifiers,
258
+ * literals, calls, members) stay unwrapped so simple emissions remain
259
+ * byte-identical.
260
+ */
261
+ export function groupBinaryOperand(operand: ParsedExpr, emitted: string): string {
262
+ return operand.kind === 'binary' || operand.kind === 'logical' || operand.kind === 'conditional'
263
+ ? `(${emitted})`
264
+ : emitted
265
+ }
266
+
201
267
  /**
202
268
  * Single point of dispatch from `ParsedExpr.kind` to the adapter's
203
269
  * method. Adapters call this once at their entry point; the recursion
package/src/free-refs.ts CHANGED
@@ -397,6 +397,19 @@ function resolveFreeRefsInternal(
397
397
  * through a local constant are recursively expanded so the consumer sees
398
398
  * the constant's *kind composition*, not just the local name.
399
399
  */
400
+ /**
401
+ * Whether `name` is bound by anything in the environment — an import, a
402
+ * local const/function, a prop param, a signal/memo, or an active loop
403
+ * param. Used by Phase 1's render-nothing-literal fold to distinguish
404
+ * the global `undefined` (renders nothing per JSX semantics) from a
405
+ * shadowed local binding named `undefined` (legal, if inadvisable — the
406
+ * shadowed VALUE must render). Cheap: the binding map is memoized per
407
+ * environment.
408
+ */
409
+ export function isNameBound(name: string, env: BindingEnvironment): boolean {
410
+ return buildBindingMap(env).has(name)
411
+ }
412
+
400
413
  export function resolveFreeRefs(
401
414
  node: ts.Node,
402
415
  env: BindingEnvironment
package/src/index.ts CHANGED
@@ -85,7 +85,7 @@ export type {
85
85
  export { JsxAdapter } from './adapters/jsx-adapter.ts'
86
86
  export type { JsxAdapterConfig } from './adapters/jsx-adapter.ts'
87
87
  export { rewriteImportsForTemplate } from './adapters/template-imports.ts'
88
- export { emitParsedExpr } from './adapters/parsed-expr-emitter.ts'
88
+ export { emitParsedExpr, groupBinaryOperand, isStringTypedOperand, isStringConcatBinary } from './adapters/parsed-expr-emitter.ts'
89
89
  export type { ParsedExprEmitter, HigherOrderMethod, ArrayMethod, SortMethod, LiteralType } from './adapters/parsed-expr-emitter.ts'
90
90
  export { importsSearchParams, searchParamsLocalNames, envSignalLocalNames, envSignalReaderFor, ENV_SIGNAL_READERS, queryHrefLocalNames, matchSearchParamsMethodCall } from './adapters/env-signal.ts'
91
91
  export type { EnvSignalReader } from './adapters/env-signal.ts'
package/src/jsx-to-ir.ts CHANGED
@@ -44,10 +44,11 @@ import {
44
44
  rewriteBarePropRefs as rewriteBarePropRefsCore,
45
45
  collectAstPropRefs,
46
46
  } from './prop-rewrite.ts'
47
- import { resolveFreeRefs, type BindingEnvironment } from './free-refs.ts'
47
+ import { resolveFreeRefs, isNameBound as isNameBoundInEnv, type BindingEnvironment } from './free-refs.ts'
48
48
  import { computeFileScope } from './ir-to-client-js/component-scope.ts'
49
49
  import { extractFreeIdentifiersFromNode, initializerShapeContainsJsx } from './analyzer.ts'
50
50
  import { iterateJsTokens, replaceInExprContexts } from './scanner/js-scanner.ts'
51
+ import { toHTMLAttrName } from '@barefootjs/shared'
51
52
 
52
53
  // =============================================================================
53
54
  // Transform Context
@@ -1517,6 +1518,41 @@ function transformChildren(
1517
1518
  // Text Transformation
1518
1519
  // =============================================================================
1519
1520
 
1521
+ /**
1522
+ * True for the literals that render NOTHING in JSX child position per
1523
+ * JSX semantics: `null`, `undefined`, `true`, `false` — including
1524
+ * transparently wrapped spellings (`{(null)}`, `{null as any}`,
1525
+ * `{undefined!}`). Deliberately narrow: `0`, `NaN`, and `''` are NOT
1526
+ * here (`0` renders "0"; `''` renders empty by stringification), and a
1527
+ * dynamic expression that EVALUATES to null is a runtime concern the
1528
+ * client runtime / adapters own, not a compile-time fold.
1529
+ *
1530
+ * `undefined` is an Identifier, not a keyword, and CAN be legally
1531
+ * shadowed (`const undefined = 1` — lint-hostile but valid JS); the
1532
+ * shadowed binding's VALUE must render, so the identifier only folds
1533
+ * when nothing in the binding environment (imports, locals, props,
1534
+ * signals, memos, active loop params) binds the name.
1535
+ */
1536
+ function isRenderNothingLiteral(expr: ts.Expression, ctx: TransformContext): boolean {
1537
+ let e = expr
1538
+ while (
1539
+ ts.isParenthesizedExpression(e) ||
1540
+ ts.isAsExpression(e) ||
1541
+ ts.isSatisfiesExpression(e) ||
1542
+ ts.isNonNullExpression(e)
1543
+ ) {
1544
+ e = e.expression
1545
+ }
1546
+ return (
1547
+ e.kind === ts.SyntaxKind.NullKeyword ||
1548
+ e.kind === ts.SyntaxKind.TrueKeyword ||
1549
+ e.kind === ts.SyntaxKind.FalseKeyword ||
1550
+ (ts.isIdentifier(e) &&
1551
+ e.text === 'undefined' &&
1552
+ !isNameBoundInEnv('undefined', makeBindingEnv(ctx)))
1553
+ )
1554
+ }
1555
+
1520
1556
  function transformText(node: ts.JsxText, ctx: TransformContext): IRText | null {
1521
1557
  // Normalize whitespace (React-like behavior)
1522
1558
  const text = node.text.replace(/\s+/g, ' ')
@@ -1576,6 +1612,20 @@ function transformExpressionInner(
1576
1612
  // scalar fallback's `ctx.getJS`) sees the untagged template literal.
1577
1613
  expr = tryDesugarInterleaveTaggedTemplate(expr, ctx)
1578
1614
 
1615
+ // JSX render-nothing literals (#2171): `{null}` / `{undefined}` /
1616
+ // `{true}` / `{false}` in child position render NOTHING per JSX
1617
+ // semantics (`{0}` and `{''}` still render their stringification).
1618
+ // Folding here — Phase 1, before any adapter sees the node — is what
1619
+ // makes every backend agree: previously the literal fell through to
1620
+ // the scalar IRExpression fallback and each adapter stringified it
1621
+ // its own way (the Hono reference emitted the text "null" for
1622
+ // `{null}`, template adapters emitted "false" for `{false}`). The
1623
+ // conditional-branch path (`cond ? <a/> : null`) is NOT routed
1624
+ // through here and keeps its own null-branch handling.
1625
+ if (isRenderNothingLiteral(expr, ctx)) {
1626
+ return null
1627
+ }
1628
+
1579
1629
  // Check for bare signal/memo identifier (BF044)
1580
1630
  checkBareSignalOrMemoIdentifier(expr, ctx)
1581
1631
 
@@ -4017,13 +4067,13 @@ function processAttributes(
4017
4067
 
4018
4068
  if (!ts.isJsxAttribute(attr)) continue
4019
4069
 
4020
- const name = attr.name.getText(ctx.sourceFile)
4070
+ const rawName = attr.name.getText(ctx.sourceFile)
4021
4071
 
4022
4072
  // ref is captured separately (not pushed into `attrs`) because it never
4023
4073
  // appears in the rendered HTML — it's a compile-time binding from the
4024
4074
  // JSX call site to the runtime DOM element, surfaced via the IRElement
4025
4075
  // `ref` field for the client-JS emitter.
4026
- if (name === 'ref') {
4076
+ if (rawName === 'ref') {
4027
4077
  if (attr.initializer && ts.isJsxExpression(attr.initializer) && attr.initializer.expression) {
4028
4078
  reportJsxBranchLocalInCallback(attr.initializer.expression, ctx)
4029
4079
  ref = ctx.getJS(attr.initializer.expression)
@@ -4035,13 +4085,13 @@ function processAttributes(
4035
4085
  // they're wired up at hydration time (delegated event registration) and
4036
4086
  // must not leak into rendered HTML. The DOM event name is lowercase
4037
4087
  // (`click`, not `Click`), so strip the `on` prefix and downcase.
4038
- if (/^on[A-Z]/.test(name)) {
4088
+ if (/^on[A-Z]/.test(rawName)) {
4039
4089
  if (attr.initializer && ts.isJsxExpression(attr.initializer) && attr.initializer.expression) {
4040
- const eventName = name.slice(2).toLowerCase()
4090
+ const eventName = rawName.slice(2).toLowerCase()
4041
4091
  reportJsxBranchLocalInCallback(attr.initializer.expression, ctx)
4042
4092
  events.push({
4043
4093
  name: eventName,
4044
- originalAttr: name,
4094
+ originalAttr: rawName,
4045
4095
  handler: ctx.getJS(attr.initializer.expression),
4046
4096
  loc: getSourceLocation(attr, ctx.sourceFile, ctx.filePath),
4047
4097
  })
@@ -4049,6 +4099,19 @@ function processAttributes(
4049
4099
  continue
4050
4100
  }
4051
4101
 
4102
+ // Normalize the JSX prop spelling to the HTML/SVG attribute name ONCE,
4103
+ // here in Phase 1, so IRAttribute.name is already the name every
4104
+ // adapter emits verbatim (#2172): React-style HTML camelCase aliases
4105
+ // lower (`htmlFor` → `for`, `tabIndex` → `tabindex`, `readOnly` →
4106
+ // the BOOLEAN_ATTRS member `readonly`), SVG presentation attrs
4107
+ // kebab-case (`strokeWidth` → `stroke-width`), case-sensitive SVG XML
4108
+ // names (`viewBox`) and everything unknown (`data-*`, custom-element
4109
+ // attrs) pass through. Previously each adapter re-derived (at most)
4110
+ // `className` → `class` itself and every other alias leaked into the
4111
+ // emitted HTML as an unknown attribute the browser ignores. Intrinsic
4112
+ // elements only — component props (IRProp) keep the user's API names.
4113
+ const name = toHTMLAttrName(rawName)
4114
+
4052
4115
  let value = getAttributeValue(attr, ctx)
4053
4116
  let clientOnly: boolean | undefined
4054
4117
  if (attr.initializer && ts.isJsxExpression(attr.initializer) && attr.initializer.expression) {