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: handle patterns in destructured literals #8871

Merged
merged 11 commits into from
Jul 11, 2023
5 changes: 5 additions & 0 deletions .changeset/lucky-knives-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: handle destructured primitive literals
4 changes: 3 additions & 1 deletion packages/playground/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
6 changes: 6 additions & 0 deletions packages/playground/compile.js
Original file line number Diff line number Diff line change
@@ -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));
26 changes: 11 additions & 15 deletions packages/svelte/src/compiler/compile/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/test/js/samples/hoisted-const/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -32,6 +32,7 @@ function create_fragment(ctx) {
}

const ANSWER = 42;
const { length } = 'abc';

function get_answer() {
return ANSWER;
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/test/js/samples/hoisted-const/input.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script>
const ANSWER = 42;
const { length } = 'abc';
benmccann marked this conversation as resolved.
Show resolved Hide resolved
function get_answer() { return ANSWER; }
</script>

<b>{get_answer()}</b>
<b>{get_answer()} {length}</b>