Skip to content

Commit 7efbe7b

Browse files
authored
Merge pull request #3158 from sveltejs/gh-3038
Fix assignments inside inline function expressions
2 parents 71e0d27 + 04339ef commit 7efbe7b

File tree

3 files changed

+72
-37
lines changed

3 files changed

+72
-37
lines changed

src/compiler/compile/nodes/shared/Expression.ts

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ export default class Expression {
270270
});
271271
} else {
272272
dependencies.add(name);
273-
component.add_reference(name);
273+
component.add_reference(name); // TODO is this redundant/misplaced?
274274
}
275275
} else if (!is_synthetic && is_contextual(component, template_scope, name)) {
276276
code.prependRight(node.start, key === 'key' && parent.shorthand
@@ -288,41 +288,7 @@ export default class Expression {
288288
this.skip();
289289
}
290290

291-
if (function_expression) {
292-
if (node.type === 'AssignmentExpression') {
293-
const names = node.left.type === 'MemberExpression'
294-
? [get_object(node.left).name]
295-
: extract_names(node.left);
296-
297-
if (node.operator === '=' && nodes_match(node.left, node.right)) {
298-
const dirty = names.filter(name => {
299-
return !scope.declarations.has(name);
300-
});
301-
302-
if (dirty.length) component.has_reactive_assignments = true;
303-
304-
code.overwrite(node.start, node.end, dirty.map(n => component.invalidate(n)).join('; '));
305-
} else {
306-
names.forEach(name => {
307-
if (scope.declarations.has(name)) return;
308-
309-
const variable = component.var_lookup.get(name);
310-
if (variable && variable.hoistable) return;
311-
312-
pending_assignments.add(name);
313-
});
314-
}
315-
} else if (node.type === 'UpdateExpression') {
316-
const { name } = get_object(node.argument);
317-
318-
if (scope.declarations.has(name)) return;
319-
320-
const variable = component.var_lookup.get(name);
321-
if (variable && variable.hoistable) return;
322-
323-
pending_assignments.add(name);
324-
}
325-
} else {
291+
if (!function_expression) {
326292
if (node.type === 'AssignmentExpression') {
327293
// TODO should this be a warning/error? `<p>{foo = 1}</p>`
328294
}
@@ -451,6 +417,40 @@ export default class Expression {
451417
contextual_dependencies = null;
452418
}
453419

420+
if (node.type === 'AssignmentExpression') {
421+
const names = node.left.type === 'MemberExpression'
422+
? [get_object(node.left).name]
423+
: extract_names(node.left);
424+
425+
if (node.operator === '=' && nodes_match(node.left, node.right)) {
426+
const dirty = names.filter(name => {
427+
return !scope.declarations.has(name);
428+
});
429+
430+
if (dirty.length) component.has_reactive_assignments = true;
431+
432+
code.overwrite(node.start, node.end, dirty.map(n => component.invalidate(n)).join('; '));
433+
} else {
434+
names.forEach(name => {
435+
if (scope.declarations.has(name)) return;
436+
437+
const variable = component.var_lookup.get(name);
438+
if (variable && variable.hoistable) return;
439+
440+
pending_assignments.add(name);
441+
});
442+
}
443+
} else if (node.type === 'UpdateExpression') {
444+
const { name } = get_object(node.argument);
445+
446+
if (scope.declarations.has(name)) return;
447+
448+
const variable = component.var_lookup.get(name);
449+
if (variable && variable.hoistable) return;
450+
451+
pending_assignments.add(name);
452+
}
453+
454454
if (/Statement/.test(node.type)) {
455455
if (pending_assignments.size > 0) {
456456
const has_semi = code.original[node.end - 1] === ';';
@@ -463,7 +463,7 @@ export default class Expression {
463463
if (/^(Break|Continue|Return)Statement/.test(node.type)) {
464464
if (node.argument) {
465465
code.overwrite(node.start, node.argument.start, `var $$result = `);
466-
code.appendLeft(node.argument.end, `${insert}; return $$result`);
466+
code.appendLeft(node.end, `${insert}; return $$result`);
467467
} else {
468468
code.prependRight(node.start, `${insert}; `);
469469
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export default {
2+
html: `
3+
<button>click me</button>
4+
<p>1</p>
5+
<p>2</p>
6+
<p>3</p>
7+
`,
8+
9+
async test({ assert, component, target, window }) {
10+
const button = target.querySelector('button');
11+
const click = new window.MouseEvent('click');
12+
13+
await button.dispatchEvent(click);
14+
15+
assert.htmlEqual(target.innerHTML, `
16+
<button>click me</button>
17+
<p>2</p>
18+
<p>4</p>
19+
<p>6</p>
20+
`);
21+
}
22+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
let list = [1, 2, 3];
3+
</script>
4+
5+
<button on:click={event => {
6+
list = list.map(item => {
7+
return item * 2;
8+
});
9+
}}>click me</button>
10+
11+
{#each list as number}
12+
<p>{number}</p>
13+
{/each}

0 commit comments

Comments
 (0)