diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index 98fb2f1e3acf..751b73956434 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -254,11 +254,17 @@ export default class Expression { const declaration = b`const ${id} = ${node}`; if (owner.type === 'ConstTag') { + let child_scope = scope; walk(node, { - enter(node: Node) { - if (node.type === 'Identifier') { + enter(node: Node, parent: any) { + if (map.has(node)) child_scope = map.get(node); + if (node.type === 'Identifier' && is_reference(node, parent)) { + if (child_scope.has(node.name)) return; this.replace(block.renderer.reference(node, ctx)); } + }, + leave(node: Node) { + if (map.has(node)) child_scope = child_scope.parent; } }); } else if (dependencies.size === 0 && contextual_dependencies.size === 0) { diff --git a/test/runtime/samples/const-tag-each-const/_config.js b/test/runtime/samples/const-tag-each-const/_config.js new file mode 100644 index 000000000000..cde4226a2530 --- /dev/null +++ b/test/runtime/samples/const-tag-each-const/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +
0
+bar: 1,2,3,1,1,2,3,2, num: 1
+bar: 0,2,4,1,0,2,4,2, num: 2
+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +0
+bar: 1,2,3,1,1,2,3,2, num: 1
+bar: 0,2,4,1,0,2,4,2, num: 2
+ ` + ); + + component.nums = [1, 2, 3]; + + assert.htmlEqual( + target.innerHTML, + ` +0
+bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1
+bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2
+bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3
+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-const/main.svelte b/test/runtime/samples/const-tag-each-const/main.svelte new file mode 100644 index 000000000000..182ea3cfc649 --- /dev/null +++ b/test/runtime/samples/const-tag-each-const/main.svelte @@ -0,0 +1,26 @@ + + +{foo}
+{#each nums as num, index} + {@const bar = nums.map((num) => { + const func = (foos, num) => { + return [...foos.map((foo) => foo), num]; + } + return func(foos[index].nums, num); + })} +bar: {bar}, num: {num}
+{/each} diff --git a/test/runtime/samples/const-tag-each-duplicated-variable1/_config.js b/test/runtime/samples/const-tag-each-duplicated-variable1/_config.js new file mode 100644 index 000000000000..1f3e5856f286 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable1/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +bar: 1,2,3,0,2,4,-100,0,100, num: 1
+bar: 1,2,3,0,2,4,-100,0,100, num: 2
+bar: 1,2,3,0,2,4,-100,0,100, num: 3
+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +bar: 1,2,3,0,2,4,-100,0,100, num: 1
+bar: 1,2,3,0,2,4,-100,0,100, num: 2
+bar: 1,2,3,0,2,4,-100,0,100, num: 3
+ ` + ); + + component.nums = [1, 2, 3, 4]; + + assert.htmlEqual( + target.innerHTML, + ` +bar: 1,2,3,0,2,4,-100,0,100, num: 1
+bar: 1,2,3,0,2,4,-100,0,100, num: 2
+bar: 1,2,3,0,2,4,-100,0,100, num: 3
+bar: 1,2,3,0,2,4,-100,0,100, num: 4
+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-duplicated-variable1/main.svelte b/test/runtime/samples/const-tag-each-duplicated-variable1/main.svelte new file mode 100644 index 000000000000..00c53dd4ff69 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable1/main.svelte @@ -0,0 +1,19 @@ + + +{#each nums as num} + {@const bar = foos.map((foos) => foos.nums)} +bar: {bar}, num: {num}
+{/each} diff --git a/test/runtime/samples/const-tag-each-duplicated-variable2/_config.js b/test/runtime/samples/const-tag-each-duplicated-variable2/_config.js new file mode 100644 index 000000000000..16f48218f18a --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable2/_config.js @@ -0,0 +1,32 @@ +export default { + html: ` +foo: dummy-foo, num: dummy-num
+bar: 1,2,3,2,, num: 1
+bar: 1,2,3,2,, num: 2
+bar: 1,2,3,2,, num: 3
+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +foo: dummy-foo, num: dummy-num
+bar: 1,2,3,2,, num: 1
+bar: 1,2,3,2,, num: 2
+bar: 1,2,3,2,, num: 3
+ ` + ); + + component.nums = [1, 2, 3, 4]; + + assert.htmlEqual( + target.innerHTML, + ` +foo: dummy-foo, num: dummy-num
+bar: 1,2,3,2,4,, num: 1
+bar: 1,2,3,2,4,, num: 2
+bar: 1,2,3,2,4,, num: 3
+bar: 1,2,3,2,4,, num: 4
+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-duplicated-variable2/main.svelte b/test/runtime/samples/const-tag-each-duplicated-variable2/main.svelte new file mode 100644 index 000000000000..1f7afd92fd67 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable2/main.svelte @@ -0,0 +1,33 @@ + + +foo: {foo}, num: {num}
+{#each nums as num} + {@const bar = foos.map((foo) => + foo.nums.filter((num) => { + if (Object.keys($$slots).length) { + return false; + } else if (Object.keys(foo).length) { + return nums.includes(num) || default_nums.includes(num); + } else { + return false; + } + }) || num + )} +bar: {bar}, num: {num}
+{/each} diff --git a/test/runtime/samples/const-tag-each-duplicated-variable3/_config.js b/test/runtime/samples/const-tag-each-duplicated-variable3/_config.js new file mode 100644 index 000000000000..cde4226a2530 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable3/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +0
+bar: 1,2,3,1,1,2,3,2, num: 1
+bar: 0,2,4,1,0,2,4,2, num: 2
+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +0
+bar: 1,2,3,1,1,2,3,2, num: 1
+bar: 0,2,4,1,0,2,4,2, num: 2
+ ` + ); + + component.nums = [1, 2, 3]; + + assert.htmlEqual( + target.innerHTML, + ` +0
+bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1
+bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2
+bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3
+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-duplicated-variable3/main.svelte b/test/runtime/samples/const-tag-each-duplicated-variable3/main.svelte new file mode 100644 index 000000000000..f559627d2399 --- /dev/null +++ b/test/runtime/samples/const-tag-each-duplicated-variable3/main.svelte @@ -0,0 +1,25 @@ + + +{foo}
+{#each nums as num, index} + {@const bar = nums.map((num) => { + return (function (foos, num) { + return [...foos.map((foo) => foo), num]; + })(foos[index].nums, num); + })} +bar: {bar}, num: {num}
+{/each} diff --git a/test/runtime/samples/const-tag-each-function/_config.js b/test/runtime/samples/const-tag-each-function/_config.js new file mode 100644 index 000000000000..cde4226a2530 --- /dev/null +++ b/test/runtime/samples/const-tag-each-function/_config.js @@ -0,0 +1,29 @@ +export default { + html: ` +0
+bar: 1,2,3,1,1,2,3,2, num: 1
+bar: 0,2,4,1,0,2,4,2, num: 2
+ `, + async test({ component, target, assert }) { + assert.htmlEqual( + target.innerHTML, + ` +0
+bar: 1,2,3,1,1,2,3,2, num: 1
+bar: 0,2,4,1,0,2,4,2, num: 2
+ ` + ); + + component.nums = [1, 2, 3]; + + assert.htmlEqual( + target.innerHTML, + ` +0
+bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1
+bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2
+bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3
+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-each-function/main.svelte b/test/runtime/samples/const-tag-each-function/main.svelte new file mode 100644 index 000000000000..2e027c662080 --- /dev/null +++ b/test/runtime/samples/const-tag-each-function/main.svelte @@ -0,0 +1,26 @@ + + +{foo}
+{#each nums as num, index} + {@const bar = nums.map((num) => { + function func(foos, num) { + return [...foos.map((foo) => foo), num]; + } + return func(foos[index].nums, num); + })} +bar: {bar}, num: {num}
+{/each} diff --git a/test/runtime/samples/const-tag-shadow-2/_config.js b/test/runtime/samples/const-tag-shadow-2/_config.js new file mode 100644 index 000000000000..9ad4aed48cdd --- /dev/null +++ b/test/runtime/samples/const-tag-shadow-2/_config.js @@ -0,0 +1,37 @@ +export default { + html: ` +1
+3,6,9
+2
+3,6,9
+3
+3,6,9
+ `, + test({ component, target, assert }) { + component.baz = 5; + assert.htmlEqual( + target.innerHTML, + ` +1
+5,10,15
+2
+5,10,15
+3
+5,10,15
+ ` + ); + + component.array = [3, 4, 5]; + assert.htmlEqual( + target.innerHTML, + ` +3
+15,20,25
+4
+15,20,25
+5
+15,20,25
+ ` + ); + } +}; diff --git a/test/runtime/samples/const-tag-shadow-2/main.svelte b/test/runtime/samples/const-tag-shadow-2/main.svelte new file mode 100644 index 000000000000..c3bcb2f6051b --- /dev/null +++ b/test/runtime/samples/const-tag-shadow-2/main.svelte @@ -0,0 +1,15 @@ + + +{#each array as item} +{foo(item)}
+ {@const bar = array.map((item) => { + const bar = baz; + const foo = (item) => item * bar; + return foo(item); + })} +{bar}
+{/each}