Svelte 5: Incorrect Compiler Output With Private Fields
Describe the bug
class Box {
#value = $state();
swap(other) {
const value = this.#value;
this.#value = other.value;
other.#value = value;
}
}
The compiler converts other.#value = value; to $.get(other.#value) = value;.
Reproduction
https://svelte.dev/playground/untitled?version=5.1.3#H4sIAAAAAAAAE22OQWrDMBBFrzJMu3DAOHsnKTRddZUDVF0oYkoMiiQ0366L8d2L6jqk0NUw778_zMTBXoVbfg0u5iwO9BKvqfOS6dQj9eCaPzovyu3bxPhKRS6A67X6nFKjg3gUdrYq_3EXAyRAueW9utwlPJlg4LxVpWMcaSqrwcNgfS90oEeFhVSbnQlLop82VREXyZtVNnAxKGjt4NJps1zYrcYdowP99Ju_xsJuyn04lzGbsN_-_sw1Q0Zwi9zL_D5_A7TBU9ZAAQAA
Logs
No response
System Info
Not necessary
Severity
annoyance
Not sure if my input is helpful, but I see two potential ways to fix this issue.
Solution 1: Don't mess with how getters and setters are called.
Although, this might slightly decrease performance, it avoids weird bugs like this from coming up in the future. You would have to store the itself state in a separate private variable.
class Box {
#var0 = $.state();
get #value() {
return $.get(this.#var0);
}
set #value(value) {
$.set(this.#var0, value);
}
swap(other) {
const value = this.#value;
this.#value = other.value;
other.#value = value;
}
}
Solution 2: Handle private field access for external variables differently.
An admittedly hacky way to solve this is to first check if the field a signal first. You can also skip this step for private fields that aren't declared as $state.
class Box {
#value = $.state();
swap(other) {
const value = this.#value;
this.#value = other.value;
if ($.is_state(other.#value)) {
$.set(other.#value, value);
} else {
other.#value = value;
}
}
}
I really don't want to be annoying, but is there any progress on this issue? I worked around it for now by manually defining setters Java-style.
class Box {
#setValue(value) {
this.#value = value;
}
}
I really don't want to be annoying, but is there any progress on this issue? I worked around it for now by manually defining setters Java-style.
class Box { #setValue(value) { this.#value = value; } }
Don't worry, I actually forgot about this issue so good that you pinged hete... I'll look into it tomorrow if I can