Skip to content

Commit 9b44c6d

Browse files
fix: take other snippets into account when checking for hoistability (#2668)
Closes #2664
1 parent 2f46701 commit 9b44c6d

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed

packages/svelte2tsx/src/htmlxtojsx_v2/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export interface TemplateProcessResult {
5454
scriptTag: BaseNode;
5555
moduleScriptTag: BaseNode;
5656
/** Start/end positions of snippets that should be moved to the instance script or possibly even module script */
57-
rootSnippets: Array<[start: number, end: number, globals: Map<string, any>]>;
57+
rootSnippets: Array<[start: number, end: number, globals: Map<string, any>, string]>;
5858
/** To be added later as a comment on the default class export */
5959
componentDocumentation: ComponentDocumentation;
6060
events: ComponentEvents;
@@ -93,7 +93,7 @@ export function convertHtmlxToJsx(
9393

9494
stripDoctype(str);
9595

96-
const rootSnippets: Array<[number, number, Map<string, any>]> = [];
96+
const rootSnippets: Array<[number, number, Map<string, any>, string]> = [];
9797
let element: Element | InlineComponent | undefined;
9898

9999
const pendingSnippetHoistCheck = new Set<BaseNode>();
@@ -264,7 +264,12 @@ export function convertHtmlxToJsx(
264264
}
265265
});
266266

267-
rootSnippets.push([node.start, node.end, result.globals]);
267+
rootSnippets.push([
268+
node.start,
269+
node.end,
270+
result.globals,
271+
node.expression.name
272+
]);
268273
} else {
269274
pendingSnippetHoistCheck.add(parent);
270275
}

packages/svelte2tsx/src/svelte2tsx/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ export function svelte2tsx(
165165
}
166166
}
167167

168+
if (moduleScriptTag && rootSnippets.length > 0) {
169+
exportedNames.hoistableInterfaces.analyzeSnippets(rootSnippets);
170+
}
171+
168172
if (moduleScriptTag || scriptTag) {
169173
for (const [start, end, globals] of rootSnippets) {
170174
const hoist_to_module =

packages/svelte2tsx/src/svelte2tsx/nodes/HoistableInterfaces.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,28 @@ export class HoistableInterfaces {
1919
value_deps: new Set<string>()
2020
};
2121

22+
analyzeSnippets(
23+
rootSnippets: [start: number, end: number, globals: Map<string, any>, string][]
24+
) {
25+
let prev_disallowed_values_size;
26+
// we need to recalculate the disallowed values until they are stable because
27+
// one snippet might depend on another snippet which was previously hoistable
28+
while (
29+
prev_disallowed_values_size == null ||
30+
this.disallowed_values.size !== prev_disallowed_values_size
31+
) {
32+
prev_disallowed_values_size = this.disallowed_values.size;
33+
for (const [, , globals, name] of rootSnippets) {
34+
const hoist_to_module =
35+
globals.size === 0 ||
36+
[...globals.keys()].every((id) => this.isAllowedReference(id));
37+
if (!hoist_to_module) {
38+
this.disallowed_values.add(name);
39+
}
40+
}
41+
}
42+
}
43+
2244
/** should be called before analyzeInstanceScriptNode */
2345
analyzeModuleScriptNode(node: ts.Node) {
2446
// Handle Import Declarations
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
///<reference types="svelte" />
2+
;
3+
4+
;; const hoistable/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
5+
{ svelteHTML.createElement("h1", {}); }
6+
};return __sveltets_2_any(0)};function render() {
7+
const chain/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
8+
{ svelteHTML.createElement("div", {});foo; }
9+
};return __sveltets_2_any(0)}; const chain2/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
10+
;__sveltets_2_ensureSnippet(chain());
11+
};return __sveltets_2_any(0)}; const chain3/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
12+
;__sveltets_2_ensureSnippet(chain2());
13+
};return __sveltets_2_any(0)};
14+
let foo = true;
15+
;
16+
async () => {
17+
18+
19+
20+
21+
22+
23+
24+
25+
26+
};
27+
return { props: /** @type {Record<string, never>} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }}
28+
const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render())));
29+
/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType<typeof Input__SvelteComponent_>;
30+
/*Ωignore_endΩ*/export default Input__SvelteComponent_;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<script module lang="ts">
2+
3+
</script>
4+
5+
<script>
6+
let foo = true;
7+
</script>
8+
9+
{#snippet chain()}
10+
<div>{foo}</div>
11+
{/snippet}
12+
13+
{#snippet chain2()}
14+
{@render chain()}
15+
{/snippet}
16+
17+
{#snippet chain3()}
18+
{@render chain2()}
19+
{/snippet}
20+
21+
{#snippet hoistable()}
22+
<h1>hoist me</h1>
23+
{/snippet}

0 commit comments

Comments
 (0)
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