chore: add warning for derived self referencin

pull/12746/head
Dominic Gannaway 2 years ago
parent 98ae05b569
commit bf248594b7

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: add warning for derived self referencing

@ -2,6 +2,10 @@
> Use `$derived.by(() => {...})` instead of `$derived((() => {...})())`
## derived_referenced_self
> A derived value should not reference itself.
## export_let_unused
> Component has unused export property '%name%'. If it is for external reference only, please consider using `export const %name%`

@ -65,7 +65,16 @@ export function Identifier(node, context) {
let binding = context.state.scope.get(node.name);
if (!context.state.analysis.runes) {
if (context.state.analysis.runes) {
// Check for recursive references of a derived from within a derived and issue a warning.
if (
binding?.kind === 'derived' &&
node !== binding.node &&
context.path.find((n) => n.type === 'VariableDeclarator' && n.init === binding.initial)
) {
w.derived_referenced_self(node);
}
} else {
if (node.name === '$$props') {
context.state.analysis.uses_props = true;
}

@ -103,6 +103,7 @@ export const codes = [
"reactive_declaration_invalid_placement",
"reactive_declaration_module_script",
"state_referenced_locally",
"derived_referenced_self",
"store_rune_conflict",
"css_unused_selector",
"attribute_avoid_is",
@ -644,6 +645,14 @@ export function state_referenced_locally(node) {
w(node, "state_referenced_locally", "State referenced in its own scope will never update. Did you mean to reference it inside a closure?");
}
/**
* A derived value should not reference itself.
* @param {null | NodeLike} node
*/
export function derived_referenced_self(node) {
w(node, "derived_referenced_self", "A derived value should not reference itself.");
}
/**
* It looks like you're using the `$%name%` rune, but there is a local binding called `%name%`. Referencing a local variable with a `$` prefix will create a store subscription. Please rename `%name%` to avoid the ambiguity
* @param {null | NodeLike} node

@ -0,0 +1,26 @@
<script>
let count = $state(0);
let disabled = $state(false);
let even = $derived.by(() => {
if (disabled) return even;
return count % 2 === 0;
})
function increment() {
count += 1;
}
</script>
<p>Is {even ? 'even' : 'odd'}</p>
<button onclick={increment}>
clicks: {count}
</button>
<label>
<input type="checkbox" bind:checked={disabled} />
Disable
</label>

@ -0,0 +1,14 @@
[
{
"code": "derived_referenced_self",
"message": "A derived value should not reference itself.",
"start": {
"column": 23,
"line": 6
},
"end": {
"column": 27,
"line": 6
}
}
]
Loading…
Cancel
Save