From 2cf037e3eaf9fe30c1fc76eb1d3252480edc7b54 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:31:10 +0100 Subject: [PATCH] fix: adjust snippet code generation for new AST shape (#2282) Snippets can now take one or more parameters, and their AST shape has changed as a consequence. Adjust it accordingly. #2281 --- .../src/htmlxtojsx_v2/nodes/EachBlock.ts | 10 ++--- .../src/htmlxtojsx_v2/nodes/SnippetBlock.ts | 41 ++++++++++++++----- .../samples/snippet.v5/expected-svelte5.js | 2 +- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/EachBlock.ts b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/EachBlock.ts index 8eae569ca..8eb2eb501 100644 --- a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/EachBlock.ts +++ b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/EachBlock.ts @@ -27,8 +27,8 @@ export function handleEach(str: MagicString, eachBlock: BaseNode): void { const containsComma = str.original .substring(eachBlock.expression.start, eachBlock.expression.end) .includes(','); - const expressionEnd = getEnd(eachBlock.expression, str); - const contextEnd = getEnd(eachBlock.context, str); + const expressionEnd = getEnd(eachBlock.expression); + const contextEnd = getEnd(eachBlock.context); const arrayAndItemVarTheSame = str.original.substring(eachBlock.expression.start, expressionEnd) === str.original.substring(eachBlock.context.start, contextEnd); @@ -78,8 +78,6 @@ export function handleEach(str: MagicString, eachBlock: BaseNode): void { /** * Get the end of the node, excluding the type annotation */ -function getEnd(node: any, str: MagicString) { - return node.typeAnnotation - ? str.original.lastIndexOf(':', node.typeAnnotation.start) - : node.end; +function getEnd(node: any) { + return node.typeAnnotation?.start ?? node.end; } diff --git a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts index dcbb5f559..a33209870 100644 --- a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts +++ b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts @@ -43,17 +43,26 @@ export function handleSnippet( ); const startEnd = - str.original.indexOf('}', snippetBlock.context?.end || snippetBlock.expression.end) + 1; + str.original.indexOf( + '}', + // context was the first iteration in a .next release, remove at some point + snippetBlock.context?.end || + snippetBlock.parameters?.at(-1)?.end || + snippetBlock.expression.end + ) + 1; if (isImplicitProp) { str.overwrite(snippetBlock.start, snippetBlock.expression.start, '', { contentOnly: true }); const transforms: TransformationArray = ['(']; - if (snippetBlock.context) { - transforms.push([snippetBlock.context.start, snippetBlock.context.end]); - str.overwrite(snippetBlock.expression.end, snippetBlock.context.start, '', { + if (snippetBlock.context || snippetBlock.parameters?.length) { + // context was the first iteration in a .next release, remove at some point + const start = snippetBlock.context?.start || snippetBlock.parameters?.[0].start; + const end = snippetBlock.context?.end || snippetBlock.parameters.at(-1).end; + transforms.push([start, end]); + str.overwrite(snippetBlock.expression.end, start, '', { contentOnly: true }); - str.overwrite(snippetBlock.context.end, startEnd, '', { contentOnly: true }); + str.overwrite(end, startEnd, '', { contentOnly: true }); } else { str.overwrite(snippetBlock.expression.end, startEnd, '', { contentOnly: true }); } @@ -64,15 +73,27 @@ export function handleSnippet( transforms ); } else { - const generic = snippetBlock.context - ? snippetBlock.context.typeAnnotation + let generic = ''; + // context was the first iteration in a .next release, remove at some point + if (snippetBlock.context) { + generic = snippetBlock.context.typeAnnotation ? `<${str.original.slice( - snippetBlock.context.typeAnnotation.start, + snippetBlock.context.typeAnnotation.start + 1, snippetBlock.context.typeAnnotation.end )}>` : // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets - '' - : ''; + ''; + } else if (snippetBlock.parameters?.length) { + generic = `<[${snippetBlock.parameters + .map((p) => + p.typeAnnotation + ? str.original.slice(p.typeAnnotation.start + 1, p.typeAnnotation.end) + : // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets + 'any' + ) + .join(', ')}]>`; + } + const typeAnnotation = surroundWithIgnoreComments(`: import('svelte').Snippet${generic}`); const transforms: TransformationArray = [ 'var ', diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/snippet.v5/expected-svelte5.js b/packages/svelte2tsx/test/htmlx2jsx/samples/snippet.v5/expected-svelte5.js index 67299d4f2..00a0c0a47 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/snippet.v5/expected-svelte5.js +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/snippet.v5/expected-svelte5.js @@ -1,4 +1,4 @@ - var foo/*Ωignore_startΩ*/: import('svelte').Snippet/*Ωignore_endΩ*/ = (x) => { + var foo/*Ωignore_startΩ*/: import('svelte').Snippet<[any]>/*Ωignore_endΩ*/ = (x) => { { svelteHTML.createElement("div", {}); x; } return __sveltets_2_any(0)};