Skip to content

Commit 5e52825

Browse files
fix: take private and public into account for constant_assignment of derived state (#15276)
Fixes #15273
1 parent 1848138 commit 5e52825

File tree

6 files changed

+35
-7
lines changed

6 files changed

+35
-7
lines changed

.changeset/five-apes-develop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: take private and public into account for `constant_assignment` of derived state

packages/svelte/src/compiler/phases/2-analyze/types.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface AnalysisState {
1919
component_slots: Set<string>;
2020
/** Information about the current expression/directive/block value */
2121
expression: ExpressionMetadata | null;
22-
derived_state: string[];
22+
derived_state: { name: string; private: boolean }[];
2323
function_depth: number;
2424

2525
// legacy stuff

packages/svelte/src/compiler/phases/2-analyze/visitors/ClassBody.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { get_rune } from '../../scope.js';
77
* @param {Context} context
88
*/
99
export function ClassBody(node, context) {
10-
/** @type {string[]} */
10+
/** @type {{name: string, private: boolean}[]} */
1111
const derived_state = [];
1212

1313
for (const definition of node.body) {
@@ -18,7 +18,10 @@ export function ClassBody(node, context) {
1818
) {
1919
const rune = get_rune(definition.value, context.state.scope);
2020
if (rune === '$derived' || rune === '$derived.by') {
21-
derived_state.push(definition.key.name);
21+
derived_state.push({
22+
name: definition.key.name,
23+
private: definition.key.type === 'PrivateIdentifier'
24+
});
2225
}
2326
}
2427
}

packages/svelte/src/compiler/phases/2-analyze/visitors/shared/utils.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { AssignmentExpression, Expression, Literal, Node, Pattern, PrivateIdentifier, Super, UpdateExpression, VariableDeclarator } from 'estree' */
1+
/** @import { AssignmentExpression, Expression, Identifier, Literal, Node, Pattern, PrivateIdentifier, Super, UpdateExpression, VariableDeclarator } from 'estree' */
22
/** @import { AST, Binding } from '#compiler' */
33
/** @import { AnalysisState, Context } from '../../types' */
44
/** @import { Scope } from '../../../scope' */
@@ -38,16 +38,22 @@ export function validate_assignment(node, argument, state) {
3838
e.snippet_parameter_assignment(node);
3939
}
4040
}
41-
4241
if (
4342
argument.type === 'MemberExpression' &&
4443
argument.object.type === 'ThisExpression' &&
4544
(((argument.property.type === 'PrivateIdentifier' || argument.property.type === 'Identifier') &&
46-
state.derived_state.includes(argument.property.name)) ||
45+
state.derived_state.some(
46+
(derived) =>
47+
derived.name === /** @type {PrivateIdentifier | Identifier} */ (argument.property).name &&
48+
derived.private === (argument.property.type === 'PrivateIdentifier')
49+
)) ||
4750
(argument.property.type === 'Literal' &&
4851
argument.property.value &&
4952
typeof argument.property.value === 'string' &&
50-
state.derived_state.includes(argument.property.value)))
53+
state.derived_state.some(
54+
(derived) =>
55+
derived.name === /** @type {Literal} */ (argument.property).value && !derived.private
56+
)))
5157
) {
5258
e.constant_assignment(node, 'derived state');
5359
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
class Test {
3+
#deps = () => [];
4+
5+
deps = $derived.by(() => {
6+
return [];
7+
});
8+
9+
constructor(f = () => []) {
10+
this.#deps = f;
11+
}
12+
}
13+
</script>

0 commit comments

Comments
 (0)