fix: preserve whitespace around empty JSX expressions - #4032
fix: preserve whitespace around empty JSX expressions#4032raisulchowdhury wants to merge 4 commits into
Conversation
Do not remove an empty JSX expression when the surrounding multiline text and JSX elements rely on it to preserve rendered whitespace. Add the reported regression and a safe inline control. Assisted-by: OpenAI Codex Signed-off-by: raisulchowdhury <34920788+raisulchowdhury@users.noreply.github.com>
haimuhaimu
left a comment
There was a problem hiding this comment.
The whitespace-preservation guard misses the equivalent empty no-substitution template literal case.
I reproduced this on head 178859e73e3c81165b73696a363e00fa9f314ed6 with ESLint 9.39.5 and verifyAndFix:
<span>
<span>The braces</span>
{``} matter here.
</span>The rule still reports/fixes the empty template expression and produces:
<span>
<span>The braces</span>
matter here.
</span>That is the same whitespace-sensitive output shape as #3995. lintUnnecessaryCurly explicitly handles a TemplateLiteral with zero expressions and the fixer replaces it with its empty cooked value, but isEmptyStringExpression only checks child.expression.value === ""; a TemplateLiteral has no value, so the new bailout never runs.
Could isEmptyStringExpression also recognize a zero-expression template whose sole quasi has an empty cooked/raw value? A multiline valid regression using {``} plus the existing safe inline invalid/control case would cover both branches.
haimuhaimu
left a comment
There was a problem hiding this comment.
Verified the follow-up on d0a5dedeff02e86ba09b089e877e192c4f292a82 with ESLint 9.39.4. The multiline empty-template reproducer now remains unchanged with no diagnostic, the inline control still fixes to plain text, and the existing empty-string multiline case remains protected. The added regression file is included by the project unit-test glob, and all four reported checks pass. My previous concern is resolved; thanks for covering both branches.
haimuhaimu
left a comment
There was a problem hiding this comment.
Re-verified the latest head 3e26b04c39cde640062ec5719434abf488f2cf74, including the new no-children guard added after my previous approval. With ESLint 9.39.4, the JSX attribute control now fixes <App prop={foo} /> to <App prop="foo" /> without throwing; the multiline empty-template and empty-string cases remain protected, and the inline template control still fixes normally. All four reported checks pass. This approval covers the current head.
Summary
Fixes #3995.
Validation
npx mocha tests/lib/rules/jsx-curly-brace-presence.js --grep 'The braces'(2passing)Linterverification of the reported case and inline controlnpx eslint lib/rules/jsx-curly-brace-presence.js tests/lib/rules/jsx-curly-brace-presence.js(0 errors; 7 pre-existing warnings in the test file)git diff --checkThe full legacy parser matrix is not a reliable signal in this environment because its TypeScript 3.9 parser stack is incompatible with the installed Node 25 runtime; the focused rule tests and direct behavior checks pass.
Assisted-by: OpenAI Codex. The contributor reviewed the implementation and validation before publication.