diff --git a/.changeset/poor-cheetahs-talk.md b/.changeset/poor-cheetahs-talk.md new file mode 100644 index 000000000..c144128bf --- /dev/null +++ b/.changeset/poor-cheetahs-talk.md @@ -0,0 +1,5 @@ +--- +'@astrojs/compiler': patch +--- + +Preserve whitespace in expressions diff --git a/internal/parser.go b/internal/parser.go index 70b00fdff..ff9d783fa 100644 --- a/internal/parser.go +++ b/internal/parser.go @@ -342,11 +342,6 @@ func (p *parser) addText(text string) { return } - // Inside of expressions we can skip whitespace - if p.top().Expression && strings.TrimSpace(text) == "" { - return - } - t := p.top() if n := t.LastChild; n != nil && n.Type == TextNode { n.Data += text diff --git a/internal/printer/print-to-js.go b/internal/printer/print-to-js.go index 8fe72fe91..5bcf082cb 100644 --- a/internal/printer/print-to-js.go +++ b/internal/printer/print-to-js.go @@ -316,7 +316,11 @@ func render1(p *printer, n *Node, opts RenderOptions) { // Tip! Comment this block out to debug expressions if n.Expression { - if n.FirstChild == nil { + clean := "" + if n.FirstChild != nil { + clean = strings.TrimSpace(n.FirstChild.Data) + } + if n.FirstChild == nil || clean == "" { p.print("${(void 0)") } else if expressionOnlyHasComment(n) { // we do not print expressions that only contain comment blocks diff --git a/internal/printer/print-to-tsx.go b/internal/printer/print-to-tsx.go index 0a45a0577..1ea42e436 100644 --- a/internal/printer/print-to-tsx.go +++ b/internal/printer/print-to-tsx.go @@ -230,9 +230,6 @@ declare const Astro: Readonly { return %s
  • ${item}
  • %s; }) - }%s})} + }%s + })} `, "$$render"+BACKTICK, "$$render"+BACKTICK, BACKTICK, BACKTICK), }, }, @@ -871,7 +872,7 @@ const groups = [[0, 1, 2], [3, 4, 5]]; name: "nested expressions IV", source: `
    {() => { if (value > 0.25) { return Default } else if (value > 0.5) { return Another } else if (value > 0.75) { return Other } return Yet Other }}
    `, want: want{ - code: "${$$maybeRenderHead($$result)}
    ${() => { if (value > 0.25) { return $$render`Default`} else if (value > 0.5) { return $$render`Another`} else if (value > 0.75) { return $$render`Other`} return $$render`Yet Other`}}
    ", + code: "${$$maybeRenderHead($$result)}
    ${() => { if (value > 0.25) { return $$render`Default` } else if (value > 0.5) { return $$render`Another` } else if (value > 0.75) { return $$render`Other` } return $$render`Yet Other` }}
    ", }, }, { @@ -921,10 +922,10 @@ const items = ['red', 'yellow', 'blue']; code: `${$$maybeRenderHead($$result)}
    ${items.map((item) => ( // foo < > < } -$$render` + "`" + `color
    ` + "`" + ` + $$render` + "`" + `color` + "`" + ` ))} ${items.map((item) => ( - /* foo < > < } */$$render` + "`" + `color` + "`" + ` + /* foo < > < } */ $$render` + "`" + `color` + "`" + ` ))} `, }, @@ -2311,6 +2312,13 @@ const items = ["Dog", "Cat", "Platipus"]; code: `${$$maybeRenderHead($$result)}(${(void 0)})`, }, }, + { + name: "Empty expression with whitespace", + source: "({ })", + want: want{ + code: `${$$maybeRenderHead($$result)}(${(void 0) })`, + }, + }, { name: "Empty attribute expression", source: "", diff --git a/packages/compiler/test/basic/expression-then-node.ts b/packages/compiler/test/basic/expression-then-node.ts index dd29f7d5e..c90e9caf5 100644 --- a/packages/compiler/test/basic/expression-then-node.ts +++ b/packages/compiler/test/basic/expression-then-node.ts @@ -38,7 +38,7 @@ test('expression followed by node', () => { result.code, `yield ' '; -}`, + }`, 'Expected output to properly handle expression!' ); }); diff --git a/packages/compiler/test/tsx/comment-whitespace.ts b/packages/compiler/test/tsx/comment-whitespace.ts new file mode 100644 index 000000000..78cb3a0a4 --- /dev/null +++ b/packages/compiler/test/tsx/comment-whitespace.ts @@ -0,0 +1,47 @@ +import { convertToTSX } from '@astrojs/compiler'; +import { test } from 'uvu'; +import * as assert from 'uvu/assert'; + +test('preverve whitespace around jsx comments', async () => { + const input = `{/* @ts-expect-error */} + + +{ +// @ts-expect-error +} + + +{ +/* @ts-expect-error */ + +} + +{ +// @ts-expect-error + +}`; + const output = ` +{/* @ts-expect-error */} + + +{ +// @ts-expect-error +} + + +{ +/* @ts-expect-error */ + +} + +{ +// @ts-expect-error + +} + +export default function __AstroComponent_(_props: Record): any {}\n`; + const { code } = await convertToTSX(input, { sourcemap: 'external' }); + assert.snapshot(code, output, `expected code to match snapshot`); +}); + +test.run();