From 2b33a09f31cc9991a9a061ea079cd634d57cf916 Mon Sep 17 00:00:00 2001 From: Nguyen Tran Date: Fri, 26 May 2023 18:56:29 -0400 Subject: [PATCH 1/5] Simple fix to var declarations in brackets issue --- src/compiler/compile/Component.js | 38 +++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/compiler/compile/Component.js b/src/compiler/compile/Component.js index 894cb9b787b9..7ba1ed8e7510 100644 --- a/src/compiler/compile/Component.js +++ b/src/compiler/compile/Component.js @@ -17,7 +17,7 @@ import fuzzymatch from '../utils/fuzzymatch.js'; import get_object from './utils/get_object.js'; import add_to_set from './utils/add_to_set.js'; import check_graph_for_cycles from './utils/check_graph_for_cycles.js'; -import { print, b } from 'code-red'; +import { print, b, x } from 'code-red'; import { is_reserved_keyword } from './utils/reserved_keywords.js'; import { apply_preprocessor_sourcemap } from '../utils/mapped_code.js'; import { clone } from '../utils/clone.js'; @@ -1146,7 +1146,9 @@ export default class Component { if (node.type === 'VariableDeclaration') { // NOTE: `var` does not follow block scoping if (node.kind === 'var' || scope === instance_scope) { + /** @type {import('estree').Node[][]} */ const inserts = []; + /** @type {import('estree').AssignmentProperty[]} */ const props = []; /** @@ -1177,8 +1179,7 @@ export default class Component { // ``` // into // ``` - // let { x: x$, y: y$ = 123 } = OBJ; - // let { x = x$, y = y$, z = 456 } = $$props; + // let { x: x$, y: y$ = 123 } = OBJ, { x = x$, y = y$, z = 456 } = $$props; // ``` for (let index = 0; index < node.declarations.length; index++) { const declarator = node.declarations[index]; @@ -1273,15 +1274,28 @@ export default class Component { } } } - this.replace( - /** @type {any} */ ( - b` - ${node.declarations.length ? node : null} - ${props.length > 0 && b`let { ${props} } = $$props;`} - ${inserts} - ` - ) - ); + + if (props.length > 0) { + node.declarations.push({ + type: 'VariableDeclarator', + id: { + type: 'ObjectPattern', + properties: props + }, + init: x`$$props` + }); + } + + if (inserts.length > 0) { + node.declarations.push({ + type: 'VariableDeclarator', + id: component.get_unique_name('$$subscriptions'), + init: x`(() => { + ${inserts} + })()` + }); + } + return this.skip(); } } From 82fd18939c24f59d9605b9fcdf0a1396eb7e396b Mon Sep 17 00:00:00 2001 From: Nguyen Tran Date: Fri, 26 May 2023 18:58:05 -0400 Subject: [PATCH 2/5] Tests for vars not in outer level --- .../samples/capture-inject-state/expected.js | 12 +++-- .../expected.js | 8 +++- .../expected.js | 8 +++- test/js/samples/var-in-block/expected.js | 46 +++++++++++++++++++ test/js/samples/var-in-block/input.svelte | 7 +++ .../expected.js | 20 ++++++++ .../input.svelte | 7 +++ test/runtime/samples/var-in-block/_config.js | 3 ++ test/runtime/samples/var-in-block/main.svelte | 9 ++++ .../samples/var-in-do-while-block/_config.js | 7 +++ .../samples/var-in-do-while-block/main.svelte | 9 ++++ .../samples/var-in-for-in-loop/_config.js | 3 ++ .../samples/var-in-for-in-loop/main.svelte | 10 ++++ .../samples/var-in-for-loop/_config.js | 3 ++ .../samples/var-in-for-loop/main.svelte | 10 ++++ .../samples/var-in-function/_config.js | 11 +++++ .../samples/var-in-function/main.svelte | 10 ++++ .../samples/var-in-if-block/_config.js | 13 ++++++ .../samples/var-in-if-block/main.svelte | 15 ++++++ .../samples/var-in-while-block/_config.js | 7 +++ .../samples/var-in-while-block/main.svelte | 9 ++++ .../_config.js | 3 ++ .../main.svelte | 19 ++++++++ .../var-store-destructured-in-if/_config.js | 3 ++ .../var-store-destructured-in-if/main.svelte | 20 ++++++++ .../var-store-different-brackets/_config.js | 3 ++ .../var-store-different-brackets/main.svelte | 24 ++++++++++ .../var-store-in-do-while-loop/_config.js | 3 ++ .../var-store-in-do-while-loop/main.svelte | 15 ++++++ .../_config.js | 3 ++ .../main.svelte | 10 ++++ .../samples/var-store-in-for-init/_config.js | 3 ++ .../samples/var-store-in-for-init/main.svelte | 12 +++++ .../samples/var-store-in-for-loop/_config.js | 3 ++ .../samples/var-store-in-for-loop/main.svelte | 16 +++++++ .../samples/var-store-in-if/_config.js | 3 ++ .../samples/var-store-in-if/main.svelte | 20 ++++++++ .../var-store-in-labeled-statement/_config.js | 3 ++ .../main.svelte | 15 ++++++ .../var-store-in-switch-statement/_config.js | 3 ++ .../var-store-in-switch-statement/main.svelte | 39 ++++++++++++++++ .../var-store-in-while-loop/_config.js | 3 ++ .../var-store-in-while-loop/main.svelte | 16 +++++++ .../_config.js | 3 ++ .../main.svelte | 23 ++++++++++ 45 files changed, 484 insertions(+), 8 deletions(-) create mode 100644 test/js/samples/var-in-block/expected.js create mode 100644 test/js/samples/var-in-block/input.svelte create mode 100644 test/js/samples/variable-declaration-in-switch-case/expected.js create mode 100644 test/js/samples/variable-declaration-in-switch-case/input.svelte create mode 100644 test/runtime/samples/var-in-block/_config.js create mode 100644 test/runtime/samples/var-in-block/main.svelte create mode 100644 test/runtime/samples/var-in-do-while-block/_config.js create mode 100644 test/runtime/samples/var-in-do-while-block/main.svelte create mode 100644 test/runtime/samples/var-in-for-in-loop/_config.js create mode 100644 test/runtime/samples/var-in-for-in-loop/main.svelte create mode 100644 test/runtime/samples/var-in-for-loop/_config.js create mode 100644 test/runtime/samples/var-in-for-loop/main.svelte create mode 100644 test/runtime/samples/var-in-function/_config.js create mode 100644 test/runtime/samples/var-in-function/main.svelte create mode 100644 test/runtime/samples/var-in-if-block/_config.js create mode 100644 test/runtime/samples/var-in-if-block/main.svelte create mode 100644 test/runtime/samples/var-in-while-block/_config.js create mode 100644 test/runtime/samples/var-in-while-block/main.svelte create mode 100644 test/runtime/samples/var-store-destructured-in-do-while/_config.js create mode 100644 test/runtime/samples/var-store-destructured-in-do-while/main.svelte create mode 100644 test/runtime/samples/var-store-destructured-in-if/_config.js create mode 100644 test/runtime/samples/var-store-destructured-in-if/main.svelte create mode 100644 test/runtime/samples/var-store-different-brackets/_config.js create mode 100644 test/runtime/samples/var-store-different-brackets/main.svelte create mode 100644 test/runtime/samples/var-store-in-do-while-loop/_config.js create mode 100644 test/runtime/samples/var-store-in-do-while-loop/main.svelte create mode 100644 test/runtime/samples/var-store-in-for-init-destructured/_config.js create mode 100644 test/runtime/samples/var-store-in-for-init-destructured/main.svelte create mode 100644 test/runtime/samples/var-store-in-for-init/_config.js create mode 100644 test/runtime/samples/var-store-in-for-init/main.svelte create mode 100644 test/runtime/samples/var-store-in-for-loop/_config.js create mode 100644 test/runtime/samples/var-store-in-for-loop/main.svelte create mode 100644 test/runtime/samples/var-store-in-if/_config.js create mode 100644 test/runtime/samples/var-store-in-if/main.svelte create mode 100644 test/runtime/samples/var-store-in-labeled-statement/_config.js create mode 100644 test/runtime/samples/var-store-in-labeled-statement/main.svelte create mode 100644 test/runtime/samples/var-store-in-switch-statement/_config.js create mode 100644 test/runtime/samples/var-store-in-switch-statement/main.svelte create mode 100644 test/runtime/samples/var-store-in-while-loop/_config.js create mode 100644 test/runtime/samples/var-store-in-while-loop/main.svelte create mode 100644 test/runtime/samples/variable-declarations-in-switch-no-brackets/_config.js create mode 100644 test/runtime/samples/variable-declarations-in-switch-no-brackets/main.svelte diff --git a/test/js/samples/capture-inject-state/expected.js b/test/js/samples/capture-inject-state/expected.js index 41f9b966b02b..56f7f9b381c4 100644 --- a/test/js/samples/capture-inject-state/expected.js +++ b/test/js/samples/capture-inject-state/expected.js @@ -107,9 +107,13 @@ function instance($$self, $$props, $$invalidate) { $$self.$$.on_destroy.push(() => $$unsubscribe_prop()); let { $$slots: slots = {}, $$scope } = $$props; validate_slots('Component', slots, []); - let { prop } = $$props; - validate_store(prop, 'prop'); - $$subscribe_prop(); + + let { prop } = $$props, + $$subscriptions = (() => { + validate_store(prop, 'prop'); + $$subscribe_prop(); + })(); + let { alias: realName } = $$props; let local; let shadowedByModule; @@ -197,4 +201,4 @@ class Component extends SvelteComponentDev { } export default Component; -export { moduleLiveBinding, moduleConstantProps }; +export { moduleLiveBinding, moduleConstantProps }; \ No newline at end of file diff --git a/test/js/samples/component-store-access-invalidate/expected.js b/test/js/samples/component-store-access-invalidate/expected.js index 2742481aef10..1ea3011b5ce5 100644 --- a/test/js/samples/component-store-access-invalidate/expected.js +++ b/test/js/samples/component-store-access-invalidate/expected.js @@ -41,8 +41,12 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let $foo; - const foo = writable(0); - component_subscribe($$self, foo, value => $$invalidate(0, $foo = value)); + + const foo = writable(0), + $$subscriptions = (() => { + component_subscribe($$self, foo, value => $$invalidate(0, $foo = value)); + })(); + return [$foo, foo]; } diff --git a/test/js/samples/component-store-reassign-invalidate/expected.js b/test/js/samples/component-store-reassign-invalidate/expected.js index 9047316cef92..9edc5f2db294 100644 --- a/test/js/samples/component-store-reassign-invalidate/expected.js +++ b/test/js/samples/component-store-reassign-invalidate/expected.js @@ -65,8 +65,12 @@ function instance($$self, $$props, $$invalidate) { $$subscribe_foo = () => ($$unsubscribe_foo(), $$unsubscribe_foo = subscribe(foo, $$value => $$invalidate(1, $foo = $$value)), foo); $$self.$$.on_destroy.push(() => $$unsubscribe_foo()); - let foo = writable(0); - $$subscribe_foo(); + + let foo = writable(0), + $$subscriptions = (() => { + $$subscribe_foo(); + })(); + const click_handler = () => $$subscribe_foo($$invalidate(0, foo = writable(0))); return [foo, $foo, click_handler]; } diff --git a/test/js/samples/var-in-block/expected.js b/test/js/samples/var-in-block/expected.js new file mode 100644 index 000000000000..53e0e43530ae --- /dev/null +++ b/test/js/samples/var-in-block/expected.js @@ -0,0 +1,46 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + detach, + init, + insert, + noop, + safe_not_equal, + text +} from "svelte/internal"; + +function create_fragment(ctx) { + let t; + + return { + c() { + t = text(/*one*/ ctx[0]); + }, + m(target, anchor) { + insert(target, t, anchor); + }, + p: noop, + i: noop, + o: noop, + d(detaching) { + if (detaching) detach(t); + } + }; +} + +function instance($$self) { + { + var one = 1; + } + + return [one]; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, {}); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/var-in-block/input.svelte b/test/js/samples/var-in-block/input.svelte new file mode 100644 index 000000000000..5aa45f0aa4ec --- /dev/null +++ b/test/js/samples/var-in-block/input.svelte @@ -0,0 +1,7 @@ + + +{one} diff --git a/test/js/samples/variable-declaration-in-switch-case/expected.js b/test/js/samples/variable-declaration-in-switch-case/expected.js new file mode 100644 index 000000000000..71fbab6a3468 --- /dev/null +++ b/test/js/samples/variable-declaration-in-switch-case/expected.js @@ -0,0 +1,20 @@ +/* generated by Svelte vX.Y.Z */ +import { SvelteComponent, init, safe_not_equal } from "svelte/internal"; + +function instance($$self) { + switch (1) { + case 1: + const value = Math.random(); + } + + return []; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, null, safe_not_equal, {}); + } +} + +export default Component; diff --git a/test/js/samples/variable-declaration-in-switch-case/input.svelte b/test/js/samples/variable-declaration-in-switch-case/input.svelte new file mode 100644 index 000000000000..bef86a4967c0 --- /dev/null +++ b/test/js/samples/variable-declaration-in-switch-case/input.svelte @@ -0,0 +1,7 @@ + + diff --git a/test/runtime/samples/var-in-block/_config.js b/test/runtime/samples/var-in-block/_config.js new file mode 100644 index 000000000000..273d728e2762 --- /dev/null +++ b/test/runtime/samples/var-in-block/_config.js @@ -0,0 +1,3 @@ +export default { + html: '

12345

67890

' +}; diff --git a/test/runtime/samples/var-in-block/main.svelte b/test/runtime/samples/var-in-block/main.svelte new file mode 100644 index 000000000000..ee3ca575a9aa --- /dev/null +++ b/test/runtime/samples/var-in-block/main.svelte @@ -0,0 +1,9 @@ + + +

{foo}

+

{bar}

diff --git a/test/runtime/samples/var-in-do-while-block/_config.js b/test/runtime/samples/var-in-do-while-block/_config.js new file mode 100644 index 000000000000..1ba2c535ec4a --- /dev/null +++ b/test/runtime/samples/var-in-do-while-block/_config.js @@ -0,0 +1,7 @@ +export default { + props: { + a: 13 + }, + + html: '

169

' +}; diff --git a/test/runtime/samples/var-in-do-while-block/main.svelte b/test/runtime/samples/var-in-do-while-block/main.svelte new file mode 100644 index 000000000000..cb4d4ff93e2c --- /dev/null +++ b/test/runtime/samples/var-in-do-while-block/main.svelte @@ -0,0 +1,9 @@ + + +

{b}

diff --git a/test/runtime/samples/var-in-for-in-loop/_config.js b/test/runtime/samples/var-in-for-in-loop/_config.js new file mode 100644 index 000000000000..fc3f1797c417 --- /dev/null +++ b/test/runtime/samples/var-in-for-in-loop/_config.js @@ -0,0 +1,3 @@ +export default { + html: '

0

2

4

6

8

' +}; diff --git a/test/runtime/samples/var-in-for-in-loop/main.svelte b/test/runtime/samples/var-in-for-in-loop/main.svelte new file mode 100644 index 000000000000..8cc83d9305c7 --- /dev/null +++ b/test/runtime/samples/var-in-for-in-loop/main.svelte @@ -0,0 +1,10 @@ + + +{#each array as a} +

{a}

+{/each} diff --git a/test/runtime/samples/var-in-for-loop/_config.js b/test/runtime/samples/var-in-for-loop/_config.js new file mode 100644 index 000000000000..fd54cb4f85dd --- /dev/null +++ b/test/runtime/samples/var-in-for-loop/_config.js @@ -0,0 +1,3 @@ +export default { + html: '

0

1

2

3

4

' +}; diff --git a/test/runtime/samples/var-in-for-loop/main.svelte b/test/runtime/samples/var-in-for-loop/main.svelte new file mode 100644 index 000000000000..acf38eecaefe --- /dev/null +++ b/test/runtime/samples/var-in-for-loop/main.svelte @@ -0,0 +1,10 @@ + + +{#each array as a} +

{a}

+{/each} diff --git a/test/runtime/samples/var-in-function/_config.js b/test/runtime/samples/var-in-function/_config.js new file mode 100644 index 000000000000..f5c4a16cc046 --- /dev/null +++ b/test/runtime/samples/var-in-function/_config.js @@ -0,0 +1,11 @@ +export default { + html: '

0

', + + async test({ assert, target, window }) { + const button = target.querySelector('button'); + const clickEvent = new window.MouseEvent('click'); + + await button.dispatchEvent(clickEvent); + assert.htmlEqual(target.innerHTML, '

4

'); + } +}; diff --git a/test/runtime/samples/var-in-function/main.svelte b/test/runtime/samples/var-in-function/main.svelte new file mode 100644 index 000000000000..1dab3ff6b607 --- /dev/null +++ b/test/runtime/samples/var-in-function/main.svelte @@ -0,0 +1,10 @@ + + +

0

', + html: '

0

', - async test({ assert, target, window }) { - const button = target.querySelector('button'); - const clickEvent = new window.MouseEvent('click'); + async test({ assert, target, window }) { + const button = target.querySelector('button'); + const clickEvent = new window.MouseEvent('click'); - await button.dispatchEvent(clickEvent); - assert.htmlEqual(target.innerHTML, '

4

'); - } + await button.dispatchEvent(clickEvent); + assert.htmlEqual(target.innerHTML, '

4

'); + } }; diff --git a/packages/svelte/test/runtime/samples/var-in-function/main.svelte b/packages/svelte/test/runtime/samples/var-in-function/main.svelte index 1dab3ff6b607..d81a2ee781b1 100644 --- a/packages/svelte/test/runtime/samples/var-in-function/main.svelte +++ b/packages/svelte/test/runtime/samples/var-in-function/main.svelte @@ -1,9 +1,9 @@