From 20dac2ae1219b2aca663e0007c94e361a9d358c4 Mon Sep 17 00:00:00 2001 From: gtmnayan <50981692+gtm-nayan@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:47:46 +0545 Subject: [PATCH] fix: handle patterns in destructured literals (#8871) fixes #8863 --------- Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- .changeset/lucky-knives-crash.md | 5 ++++ packages/playground/README.md | 4 ++- packages/playground/compile.js | 6 +++++ .../svelte/src/compiler/compile/Component.js | 26 ++++++++----------- .../test/js/samples/hoisted-const/expected.js | 3 ++- .../js/samples/hoisted-const/input.svelte | 3 ++- 6 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 .changeset/lucky-knives-crash.md create mode 100644 packages/playground/compile.js diff --git a/.changeset/lucky-knives-crash.md b/.changeset/lucky-knives-crash.md new file mode 100644 index 0000000000..b3506ecc4f --- /dev/null +++ b/.changeset/lucky-knives-crash.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle destructured primitive literals diff --git a/packages/playground/README.md b/packages/playground/README.md index 6ac0393720..e86c6b2da0 100644 --- a/packages/playground/README.md +++ b/packages/playground/README.md @@ -4,4 +4,6 @@ To prevent any changes you make in this directory from being accidentally commit If you would actually like to make some changes to the files here for everyone then run `git update-index --no-skip-worktree ./**/*.*` before committing. -If you're using VS Code, you can use the "Playground: Full" launch configuration to run the playground and attach the debugger to both the compiler and the browser. +If you're using VS Code, you can use the "Playground: Full" launch configuration to run the playground and attach the debugger to both the compiler and the browser. This will SSR the component and then also hydrate it on the client side using rollup to bundle any other imports. + +You can also just compile the `App.svelte` file by running `node compile.js` if you'd like to check some compiler behaviour in isolation. diff --git a/packages/playground/compile.js b/packages/playground/compile.js new file mode 100644 index 0000000000..8b6dac9f1a --- /dev/null +++ b/packages/playground/compile.js @@ -0,0 +1,6 @@ +import { readFileSync } from 'node:fs'; +import { compile } from '../svelte/src/compiler/index.js'; + +const code = readFileSync('src/App.svelte', 'utf8'); + +console.log(compile(code)); diff --git a/packages/svelte/src/compiler/compile/Component.js b/packages/svelte/src/compiler/compile/Component.js index 384bf06726..06e849fe13 100644 --- a/packages/svelte/src/compiler/compile/Component.js +++ b/packages/svelte/src/compiler/compile/Component.js @@ -1292,26 +1292,22 @@ export default class Component { // everything except const values can be changed by e.g. svelte devtools // which means we can't hoist it if (node.kind !== 'const' && this.compile_options.dev) return false; - const { name } = /** @type {import('estree').Identifier} */ (d.id); - const v = this.var_lookup.get(name); - if (v.reassigned) return false; - if (v.export_name) return false; - if (this.var_lookup.get(name).reassigned) return false; - if ( - this.vars.find( - /** @param {any} variable */ (variable) => variable.name === name && variable.module - ) - ) { - return false; + for (const name of extract_names(d.id)) { + const v = this.var_lookup.get(name); + if (v.reassigned) return false; + if (v.export_name) return false; + + if (this.vars.find((variable) => variable.name === name && variable.module)) { + return false; + } } return true; }); if (all_hoistable) { node.declarations.forEach((d) => { - const variable = this.var_lookup.get( - /** @type {import('estree').Identifier} */ (d.id).name - ); - variable.hoistable = true; + for (const name of extract_names(d.id)) { + this.var_lookup.get(name).hoistable = true; + } }); hoistable_nodes.add(node); body.splice(i--, 1); diff --git a/packages/svelte/test/js/samples/hoisted-const/expected.js b/packages/svelte/test/js/samples/hoisted-const/expected.js index 33005b121d..48bdf1f28b 100644 --- a/packages/svelte/test/js/samples/hoisted-const/expected.js +++ b/packages/svelte/test/js/samples/hoisted-const/expected.js @@ -15,7 +15,7 @@ function create_fragment(ctx) { return { c() { b = element("b"); - b.textContent = `${get_answer()}`; + b.textContent = `${get_answer()} ${length}`; }, m(target, anchor) { insert(target, b, anchor); @@ -32,6 +32,7 @@ function create_fragment(ctx) { } const ANSWER = 42; +const { length } = 'abc'; function get_answer() { return ANSWER; diff --git a/packages/svelte/test/js/samples/hoisted-const/input.svelte b/packages/svelte/test/js/samples/hoisted-const/input.svelte index d248a83154..4553a1952e 100644 --- a/packages/svelte/test/js/samples/hoisted-const/input.svelte +++ b/packages/svelte/test/js/samples/hoisted-const/input.svelte @@ -1,6 +1,7 @@ -{get_answer()} \ No newline at end of file +{get_answer()} {length} \ No newline at end of file