From dee5bed82917cfaf7b283773505ebfdb1423acda Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Fri, 24 Nov 2023 23:02:53 +0000 Subject: [PATCH] fix: improve each block index handling (#9644) * fix: improve each block index handling * format --- .changeset/thirty-wombats-relax.md | 5 +++++ .../3-transform/client/visitors/template.js | 16 ++++++++++++---- packages/svelte/src/compiler/phases/scope.js | 10 ++++------ .../samples/keyed-each-index-same-2/_config.js | 5 +++++ .../samples/keyed-each-index-same-2/main.svelte | 3 +++ 5 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 .changeset/thirty-wombats-relax.md create mode 100644 packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/_config.js create mode 100644 packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/main.svelte diff --git a/.changeset/thirty-wombats-relax.md b/.changeset/thirty-wombats-relax.md new file mode 100644 index 0000000000..0ed0f40a75 --- /dev/null +++ b/.changeset/thirty-wombats-relax.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: improve each block index handling diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index c265b89d6d..5f002bbebf 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -2491,7 +2491,7 @@ export const template_visitors = { next(); }, BindDirective(node, context) { - const { state, path } = context; + const { state, path, visit } = context; /** @type {import('estree').Expression[]} */ const properties = []; @@ -2621,10 +2621,18 @@ export const template_visitors = { break; } - case 'this': - call_expr = b.call(`$.bind_this`, state.node, setter, node.expression); + case 'this': { + const expression = node.expression; + call_expr = b.call( + `$.bind_this`, + state.node, + setter, + expression.type === 'Identifier' + ? expression + : /** @type {import('estree').Expression} */ (visit(expression)) + ); break; - + } case 'textContent': case 'innerHTML': case 'innerText': diff --git a/packages/svelte/src/compiler/phases/scope.js b/packages/svelte/src/compiler/phases/scope.js index 6c73002d5b..c839a78276 100644 --- a/packages/svelte/src/compiler/phases/scope.js +++ b/packages/svelte/src/compiler/phases/scope.js @@ -495,12 +495,10 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) { } if (node.index) { - scope.declare( - b.id(node.index), - // TODO see logic in EachBlock in dom.ts - node.key ? 'derived' : 'normal', - 'const' - ); + const is_keyed = + node.key && + (node.key.type !== 'Identifier' || !node.index || node.key.name !== node.index); + scope.declare(b.id(node.index), is_keyed ? 'derived' : 'normal', 'const'); } if (node.key) visit(node.key, { scope }); diff --git a/packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/_config.js b/packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/_config.js new file mode 100644 index 0000000000..8627d28b23 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + html: '
0
1
' +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/main.svelte b/packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/main.svelte new file mode 100644 index 0000000000..c21812be4a --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/keyed-each-index-same-2/main.svelte @@ -0,0 +1,3 @@ +{#each ["a", "b"] as result, i (i)} +
{i}
+{/each}