fix: apply ownership mutation ignores to bindings (#18718)

Fixes #18715.

Copy ignore comment info to the generated assignment so it's recognized later

---------

Co-authored-by: svelte-triage-bot <team@svelte.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
pull/18721/head
svelte-triage-bot[bot] 1 month ago committed by GitHub
parent 68e7c9b521
commit c7d8233a5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: apply ownership mutation ignores to binding assignments

@ -1,7 +1,7 @@
/** @import { CallExpression, Expression, Pattern } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { ComponentContext } from '../types' */
import { dev, is_ignored } from '../../../../state.js';
import { dev, ignore_map, is_ignored } from '../../../../state.js';
import { is_text_attribute } from '../../../../utils/ast.js';
import * as b from '#compiler/builders';
import { binding_properties } from '../../../bindings.js';
@ -40,9 +40,15 @@ export function BindDirective(node, context) {
validate_binding(context.state, node, expression);
}
const assignment = /** @type {Expression} */ (
context.visit(b.assignment('=', /** @type {Pattern} */ (node.expression), b.id('$$value')))
const raw_assignment = b.assignment(
'=',
/** @type {Pattern} */ (node.expression),
b.id('$$value')
);
// The assignment is generated, so inherit any ignores attached to the binding
ignore_map.set(raw_assignment, ignore_map.get(node) ?? []);
const assignment = /** @type {Expression} */ (context.visit(raw_assignment));
if (dev) {
// in dev, create named functions, so that `$inspect(...)` delivers
@ -58,16 +64,7 @@ export function BindDirective(node, context) {
get = b.thunk(expression);
/** @type {Expression | undefined} */
set = b.unthunk(
b.arrow(
[b.id('$$value')],
/** @type {Expression} */ (
context.visit(
b.assignment('=', /** @type {Pattern} */ (node.expression), b.id('$$value'))
)
)
)
);
set = b.unthunk(b.arrow([b.id('$$value')], assignment));
if (get === set) {
set = undefined;

@ -0,0 +1,6 @@
<script>
let { item } = $props();
</script>
<!-- svelte-ignore ownership_invalid_mutation -->
<input bind:value={item.heading} />

@ -0,0 +1,22 @@
import { flushSync } from 'svelte';
import { ok, test } from '../../test';
export default test({
mode: ['client'],
compileOptions: {
dev: true
},
test({ assert, target, warnings }) {
const input = target.querySelector('input');
const output = target.querySelector('p');
ok(input);
ok(output);
input.value = 'renamed';
input.dispatchEvent(new Event('input', { bubbles: true }));
flushSync();
assert.equal(output.textContent, 'renamed');
assert.deepEqual(warnings, []);
}
});

@ -0,0 +1,8 @@
<script>
import Item from './Item.svelte';
let item = $state({ heading: 'initial' });
</script>
<Item {item} />
<p>{item.heading}</p>
Loading…
Cancel
Save