Skip to content

Commit d12a9ae

Browse files
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 <[email protected]>
1 parent 7a13025 commit d12a9ae

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,38 @@ repository:
234234
special-tags-modes:
235235
patterns:
236236
# Expressions or simple values.
237-
- begin: (?<=(if|key|then|catch|snippet|html|render).*?)\G
237+
- begin: (?<=(if|key|then|catch|html|render).*?)\G
238238
end: (?=})
239239
name: meta.embedded.expression.svelte source.ts
240240
patterns: [ include: source.ts ]
241241

242+
# Snippet blocks - special because of how source.ts will parse generics: If it realizes "oh this is a function definition" it will
243+
# go into arrow function parsing mode and not stop until it finds a `=>`, which means it will go past the `}` snippet open boundary
244+
# and fuck up the rest of the file syntax highlighting
245+
- begin: (?<=snippet.*?)\G
246+
end: (?=})
247+
name: meta.embedded.expression.svelte source.ts
248+
patterns:
249+
# Match an identifier, but only if it is before a generic
250+
- match: \G\s*([_$[:alpha:]][_$[:alnum:]]*)\s*(?=<)
251+
captures:
252+
1: { name: entity.name.function.ts }
253+
# Match optional `<` ... `>` with inner as source.ts
254+
- begin: (?<=<)
255+
end: (?=>)
256+
contentName: meta.type.parameters.ts
257+
patterns: [ include: source.ts ]
258+
# Match the `(...)` but not starting at `(` because then TS would see it as an arrow function and parse past our snippet open boundary
259+
- begin: (?<=>\s*\()
260+
end: (?=})
261+
name: meta.embedded.expression.svelte source.ts
262+
patterns: [ include: source.ts ]
263+
# If the above three don't match (because there's no generic) then this one kicks in
264+
- begin: \G
265+
end: (?=})
266+
name: meta.embedded.expression.svelte source.ts
267+
patterns: [ include: source.ts ]
268+
242269
# Const.
243270
- begin: (?<=const.*?)\G
244271
end: (?=})

packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export function handleSnippet(
116116
'const ',
117117
[snippetBlock.expression.start, snippetBlock.expression.end],
118118
IGNORE_POSITION_COMMENT,
119-
' = ('
119+
` = ${snippetBlock.typeParams ? `<${snippetBlock.typeParams}>` : ''}(`
120120
];
121121

122122
if (parameters) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
///<reference types="svelte" />
2+
;function $$render() {
3+
const generic/*Ωignore_positionΩ*/ = <T extends string>(val: T)/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
4+
val;
5+
};return __sveltets_2_any(0)}; const complex_generic/*Ωignore_positionΩ*/ = <T extends { bracket: "<" } | "<" | Set<"<>">>(val: T)/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
6+
val;
7+
};return __sveltets_2_any(0)};
8+
;
9+
async () => {
10+
11+
12+
13+
};
14+
return { props: /** @type {Record<string, never>} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }}
15+
const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event($$render())));
16+
/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType<typeof Input__SvelteComponent_>;
17+
/*Ωignore_endΩ*/export default Input__SvelteComponent_;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script lang="ts">
2+
</script>
3+
4+
{#snippet generic<T extends string>(val: T)}
5+
{val}
6+
{/snippet}
7+
8+
{#snippet complex_generic<T extends { bracket: "<" } | "<" | Set<"<>">>(val: T)}
9+
{val}
10+
{/snippet}

0 commit comments

Comments
 (0)