Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: take other snippets into account when checking for hoistability #2668

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions packages/svelte2tsx/src/htmlxtojsx_v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export interface TemplateProcessResult {
scriptTag: BaseNode;
moduleScriptTag: BaseNode;
/** Start/end positions of snippets that should be moved to the instance script or possibly even module script */
rootSnippets: Array<[start: number, end: number, globals: Map<string, any>]>;
rootSnippets: Array<[start: number, end: number, globals: Map<string, any>, string]>;
/** To be added later as a comment on the default class export */
componentDocumentation: ComponentDocumentation;
events: ComponentEvents;
Expand Down Expand Up @@ -93,7 +93,7 @@ export function convertHtmlxToJsx(

stripDoctype(str);

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

const pendingSnippetHoistCheck = new Set<BaseNode>();
Expand Down Expand Up @@ -264,7 +264,12 @@ export function convertHtmlxToJsx(
}
});

rootSnippets.push([node.start, node.end, result.globals]);
rootSnippets.push([
node.start,
node.end,
result.globals,
node.expression.name
]);
} else {
pendingSnippetHoistCheck.add(parent);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/svelte2tsx/src/svelte2tsx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ export function svelte2tsx(
}
}

if (moduleScriptTag && rootSnippets.length > 0) {
exportedNames.hoistableInterfaces.analyzeSnippets(rootSnippets);
}

if (moduleScriptTag || scriptTag) {
for (const [start, end, globals] of rootSnippets) {
const hoist_to_module =
Expand Down
22 changes: 22 additions & 0 deletions packages/svelte2tsx/src/svelte2tsx/nodes/HoistableInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,28 @@ export class HoistableInterfaces {
value_deps: new Set<string>()
};

analyzeSnippets(
rootSnippets: [start: number, end: number, globals: Map<string, any>, string][]
) {
let prev_disallowed_values_size;
// we need to recalculate the disallowed values until they are stable because
// one snippet might depend on another snippet which was previously hoistable
while (
prev_disallowed_values_size == null ||
this.disallowed_values.size !== prev_disallowed_values_size
) {
prev_disallowed_values_size = this.disallowed_values.size;
for (const [, , globals, name] of rootSnippets) {
const hoist_to_module =
globals.size === 0 ||
[...globals.keys()].every((id) => this.isAllowedReference(id));
if (!hoist_to_module) {
this.disallowed_values.add(name);
}
}
}
}

/** should be called before analyzeInstanceScriptNode */
analyzeModuleScriptNode(node: ts.Node) {
// Handle Import Declarations
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
///<reference types="svelte" />
;

;; const hoistable/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
{ svelteHTML.createElement("h1", {}); }
};return __sveltets_2_any(0)};function render() {
const chain/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
{ svelteHTML.createElement("div", {});foo; }
};return __sveltets_2_any(0)}; const chain2/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
;__sveltets_2_ensureSnippet(chain());
};return __sveltets_2_any(0)}; const chain3/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
;__sveltets_2_ensureSnippet(chain2());
};return __sveltets_2_any(0)};
let foo = true;
;
async () => {









};
return { props: /** @type {Record<string, never>} */ ({}), 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<typeof Input__SvelteComponent_>;
/*Ωignore_endΩ*/export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script module lang="ts">

</script>

<script>
let foo = true;
</script>

{#snippet chain()}
<div>{foo}</div>
{/snippet}

{#snippet chain2()}
{@render chain()}
{/snippet}

{#snippet chain3()}
{@render chain2()}
{/snippet}

{#snippet hoistable()}
<h1>hoist me</h1>
{/snippet}
Loading