From d12a9ae276c9f4c6a62964bbdca074424cbab123 Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Thu, 15 May 2025 15:57:51 +0200 Subject: [PATCH] feat: support generics on snippets (#2761) * feat: support generics on snippets * chore: remove log * adjust grammar (holy shit that was fucked up) --------- Co-authored-by: Simon Holthausen --- .../syntaxes/svelte.tmLanguage.src.yaml | 29 ++++++++++++++++++- .../src/htmlxtojsx_v2/nodes/SnippetBlock.ts | 2 +- .../samples/snippet-generics.v5/expectedv2.ts | 17 +++++++++++ .../samples/snippet-generics.v5/input.svelte | 10 +++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/input.svelte diff --git a/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml b/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml index e2c689077..e925ff2f2 100644 --- a/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml +++ b/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml @@ -234,11 +234,38 @@ repository: special-tags-modes: patterns: # Expressions or simple values. - - begin: (?<=(if|key|then|catch|snippet|html|render).*?)\G + - begin: (?<=(if|key|then|catch|html|render).*?)\G end: (?=}) name: meta.embedded.expression.svelte source.ts patterns: [ include: source.ts ] + # Snippet blocks - special because of how source.ts will parse generics: If it realizes "oh this is a function definition" it will + # go into arrow function parsing mode and not stop until it finds a `=>`, which means it will go past the `}` snippet open boundary + # and fuck up the rest of the file syntax highlighting + - begin: (?<=snippet.*?)\G + end: (?=}) + name: meta.embedded.expression.svelte source.ts + patterns: + # Match an identifier, but only if it is before a generic + - match: \G\s*([_$[:alpha:]][_$[:alnum:]]*)\s*(?=<) + captures: + 1: { name: entity.name.function.ts } + # Match optional `<` ... `>` with inner as source.ts + - begin: (?<=<) + end: (?=>) + contentName: meta.type.parameters.ts + patterns: [ include: source.ts ] + # Match the `(...)` but not starting at `(` because then TS would see it as an arrow function and parse past our snippet open boundary + - begin: (?<=>\s*\() + end: (?=}) + name: meta.embedded.expression.svelte source.ts + patterns: [ include: source.ts ] + # If the above three don't match (because there's no generic) then this one kicks in + - begin: \G + end: (?=}) + name: meta.embedded.expression.svelte source.ts + patterns: [ include: source.ts ] + # Const. - begin: (?<=const.*?)\G end: (?=}) diff --git a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts index 7dd6633a8..f08e8c960 100644 --- a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts +++ b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts @@ -116,7 +116,7 @@ export function handleSnippet( 'const ', [snippetBlock.expression.start, snippetBlock.expression.end], IGNORE_POSITION_COMMENT, - ' = (' + ` = ${snippetBlock.typeParams ? `<${snippetBlock.typeParams}>` : ''}(` ]; if (parameters) { diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/expectedv2.ts new file mode 100644 index 000000000..460b114ba --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/expectedv2.ts @@ -0,0 +1,17 @@ +/// +;function $$render() { + const generic/*Ωignore_positionΩ*/ = (val: T)/*Ωignore_startΩ*/: ReturnType/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => { + val; +};return __sveltets_2_any(0)}; const complex_generic/*Ωignore_positionΩ*/ = ">>(val: T)/*Ωignore_startΩ*/: ReturnType/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => { + val; +};return __sveltets_2_any(0)}; +; +async () => { + + + +}; +return { props: /** @type {Record} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event($$render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/input.svelte new file mode 100644 index 000000000..4ee619728 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/snippet-generics.v5/input.svelte @@ -0,0 +1,10 @@ + + +{#snippet generic(val: T)} + {val} +{/snippet} + +{#snippet complex_generic">>(val: T)} + {val} +{/snippet} \ No newline at end of file pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy