From 5659b7a2ac1f854362d4c3b06f5fe9a89b45bfeb Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:38:15 -0500 Subject: [PATCH 1/6] feat(tsx): Return interesting ranges for TSX output --- cmd/astro-wasm/astro-wasm.go | 2 ++ internal/loc/loc.go | 5 +++++ internal/printer/print-to-tsx.go | 16 ++++++++++++++++ internal/printer/printer.go | 13 +++++++++++++ packages/compiler/src/shared/types.ts | 10 ++++++++++ 5 files changed, 46 insertions(+) diff --git a/cmd/astro-wasm/astro-wasm.go b/cmd/astro-wasm/astro-wasm.go index dda3bdd00..ce652b850 100644 --- a/cmd/astro-wasm/astro-wasm.go +++ b/cmd/astro-wasm/astro-wasm.go @@ -173,6 +173,7 @@ type TSXResult struct { Code string `js:"code"` Map string `js:"map"` Diagnostics []loc.DiagnosticMessage `js:"diagnostics"` + Ranges printer.TSXRanges `js:"metaRanges"` } type TransformResult struct { @@ -269,6 +270,7 @@ func ConvertToTSX() any { Code: code, Map: sourcemapString, Diagnostics: h.Diagnostics(), + Ranges: result.TSXRanges, }).Value }) } diff --git a/internal/loc/loc.go b/internal/loc/loc.go index b2a6603a9..7168c32f9 100644 --- a/internal/loc/loc.go +++ b/internal/loc/loc.go @@ -20,6 +20,11 @@ type Span struct { Start, End int } +type TSXRange struct { + Start int `js:"start"` + End int `js:"end"` +} + // A NodeType is the type of a Node. type DiagnosticSeverity int diff --git a/internal/printer/print-to-tsx.go b/internal/printer/print-to-tsx.go index 678d1d922..7b276243b 100644 --- a/internal/printer/print-to-tsx.go +++ b/internal/printer/print-to-tsx.go @@ -31,9 +31,15 @@ func PrintToTSX(sourcetext string, n *Node, opts transform.TransformOptions, h * return PrintResult{ Output: p.output, SourceMapChunk: p.builder.GenerateChunk(p.output), + TSXRanges: p.ranges, } } +type TSXRanges struct { + Frontmatter loc.TSXRange `js:"frontmatter"` + Body loc.TSXRange `js:"body"` +} + func isScript(p *astro.Node) bool { return p.DataAtom == atom.Script } @@ -106,6 +112,7 @@ func renderTsx(p *printer, n *Node) { props := js_scanner.GetPropsType(source) hasGetStaticPaths := js_scanner.HasGetStaticPaths(source) hasChildren := false + startLoc := len(p.output) for c := n.FirstChild; c != nil; c = c.NextSibling { // This checks for the first node that comes *after* the frontmatter // to ensure that the statement is properly closed with a `;`. @@ -150,6 +157,10 @@ func renderTsx(p *printer, n *Node) { } } + p.setTSXBodyRange(loc.TSXRange{ + Start: startLoc, + End: len(p.output), + }) p.print(fmt.Sprintf("export default function %s%s(_props: %s%s): any {}\n", componentName, props.Statement, propsIdent, props.Generics)) if hasGetStaticPaths { p.printf(`type ASTRO__ArrayElement = ArrayType extends readonly (infer ElementType)[] ? ElementType : never; @@ -176,6 +187,7 @@ declare const Astro: Readonly 0 { @@ -192,6 +204,10 @@ declare const Astro: Readonly Date: Tue, 2 Jan 2024 08:48:57 -0500 Subject: [PATCH 2/6] test: add test --- internal/printer/print-to-tsx.go | 16 ++++++++++++---- packages/compiler/test/tsx/basic.ts | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/internal/printer/print-to-tsx.go b/internal/printer/print-to-tsx.go index 7b276243b..9aa55043c 100644 --- a/internal/printer/print-to-tsx.go +++ b/internal/printer/print-to-tsx.go @@ -130,11 +130,18 @@ func renderTsx(p *printer, n *Node) { // We always need to start the body with `` p.addNilSourceMapping() p.print("\n") + + // Update the start location of the body to the start of the first child + startLoc = len(p.output) + hasChildren = true } if c.PrevSibling == nil && c.Type != FrontmatterNode { p.addNilSourceMapping() p.print("\n") + + startLoc = len(p.output) + hasChildren = true } renderTsx(p, c) @@ -143,6 +150,11 @@ func renderTsx(p *printer, n *Node) { p.print("\n") p.addNilSourceMapping() + p.setTSXBodyRange(loc.TSXRange{ + Start: startLoc, + End: len(p.output), + }) + // Only close the body with `` if we printed a body if hasChildren { p.print("\n") @@ -157,10 +169,6 @@ func renderTsx(p *printer, n *Node) { } } - p.setTSXBodyRange(loc.TSXRange{ - Start: startLoc, - End: len(p.output), - }) p.print(fmt.Sprintf("export default function %s%s(_props: %s%s): any {}\n", componentName, props.Statement, propsIdent, props.Generics)) if hasGetStaticPaths { p.printf(`type ASTRO__ArrayElement = ArrayType extends readonly (infer ElementType)[] ? ElementType : never; diff --git a/packages/compiler/test/tsx/basic.ts b/packages/compiler/test/tsx/basic.ts index 69ac8f44b..d16b69adc 100644 --- a/packages/compiler/test/tsx/basic.ts +++ b/packages/compiler/test/tsx/basic.ts @@ -245,4 +245,20 @@ export default function __AstroComponent_(_props: Record): any {}\n assert.snapshot(code, output, `expected code to match snapshot`); }); +test('return ranges', async () => { + const input = `---\nconsole.log("Hello!")\n---\n\n
`; + const { metaRanges } = await convertToTSX(input, { sourcemap: 'external' }); + + assert.equal(metaRanges, { + frontmatter: { + start: 31, + end: 55, + }, + body: { + start: 69, + end: 81, + }, + }); +}); + test.run(); From d234f5d440cc365207a1d0090286c0d851cdbd06 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:50:04 -0500 Subject: [PATCH 3/6] chore: changeset --- .changeset/fair-windows-wave.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fair-windows-wave.md diff --git a/.changeset/fair-windows-wave.md b/.changeset/fair-windows-wave.md new file mode 100644 index 000000000..f752d3be8 --- /dev/null +++ b/.changeset/fair-windows-wave.md @@ -0,0 +1,5 @@ +--- +'@astrojs/compiler': minor +--- + +Return generated frontmatter and body ranges in TSX output From ab7d918bbd52c82674f2d8782812ff46a60b1ee9 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:53:52 -0500 Subject: [PATCH 4/6] fix: wait a minute, this is not JavaScript! --- internal/printer/print-to-tsx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/printer/print-to-tsx.go b/internal/printer/print-to-tsx.go index 9aa55043c..5249af1ff 100644 --- a/internal/printer/print-to-tsx.go +++ b/internal/printer/print-to-tsx.go @@ -195,7 +195,7 @@ declare const Astro: Readonly 0 { From 3421ee8160d29f00b0ef21684377f41f1b4f281a Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Tue, 2 Jan 2024 10:47:50 -0500 Subject: [PATCH 5/6] test: add test for no frontmatter --- packages/compiler/test/tsx/basic.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/compiler/test/tsx/basic.ts b/packages/compiler/test/tsx/basic.ts index d16b69adc..3ac6ab2ec 100644 --- a/packages/compiler/test/tsx/basic.ts +++ b/packages/compiler/test/tsx/basic.ts @@ -261,4 +261,20 @@ test('return ranges', async () => { }); }); +test('return ranges - no frontmatter', async () => { + const input = `
`; + const { metaRanges } = await convertToTSX(input, { sourcemap: 'external' }); + + assert.equal(metaRanges, { + frontmatter: { + start: 31, + end: 31, + }, + body: { + start: 42, + end: 54, + }, + }); +}); + test.run(); From 9bb68490203414c0998297e17bc26840fb7f1863 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Tue, 2 Jan 2024 10:52:07 -0500 Subject: [PATCH 6/6] test: update new tests --- packages/compiler/test/tsx/escape.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/compiler/test/tsx/escape.ts b/packages/compiler/test/tsx/escape.ts index e0702a739..d8d47f662 100644 --- a/packages/compiler/test/tsx/escape.ts +++ b/packages/compiler/test/tsx/escape.ts @@ -1,10 +1,11 @@ import { convertToTSX } from '@astrojs/compiler'; import { test } from 'uvu'; import * as assert from 'uvu/assert'; +import { TSXPrefix } from '../utils'; test('escapes braces in comment', async () => { const input = ``; - const output = ` + const output = `${TSXPrefix} {/** \\\\{
Not JSX!
\\\\}*/} export default function __AstroComponent_(_props: Record): any {}\n`; @@ -14,7 +15,7 @@ export default function __AstroComponent_(_props: Record): any {}\n test('always inserts space before comment', async () => { const input = ``; - const output = ` + const output = `${TSXPrefix} {/** /
Error?
*/} export default function __AstroComponent_(_props: Record): any {}\n`; @@ -24,7 +25,7 @@ export default function __AstroComponent_(_props: Record): any {}\n test('simple escapes star slashes (*/)', async () => { const input = ``; - const output = ` + const output = `${TSXPrefix} {/** *\\/
Evil comment
*/} export default function __AstroComponent_(_props: Record): any {}\n`; @@ -34,7 +35,7 @@ export default function __AstroComponent_(_props: Record): any {}\n test('multiple escapes star slashes (*/)', async () => { const input = ``; - const output = ` + const output = `${TSXPrefix} {/** ***\\/*\\/**\\/*\\/*\\/*\\/
Even more evil comment
*/} export default function __AstroComponent_(_props: Record): any {}\n`;