Skip to content

Commit 5bfceb9

Browse files
committed
use existing validate_assignment logic
1 parent 39d7c3e commit 5bfceb9

File tree

2 files changed

+19
-35
lines changed

2 files changed

+19
-35
lines changed

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -189,30 +189,12 @@ function get_delegated_event(event_name, handler, context) {
189189
return non_hoistable;
190190
}
191191

192-
const is_runes = context.state.analysis.runes;
193-
194-
// Validate that we don't have any each bindings that are mutated.
195-
if (is_runes && binding !== null && binding.kind === 'each') {
196-
for (const { path } of binding.references) {
197-
const last = path.at(-1);
198-
199-
// If the last reference node is an update or assigment expression to the binding
200-
// then we know the binding was mutated directly rather than part of another node path.
201-
if (
202-
last != null &&
203-
(last.type === 'AssignmentExpression' || last.type === 'UpdateExpression')
204-
) {
205-
error(last, 'invalid-each-mutation');
206-
}
207-
}
208-
}
209-
210192
if (
211193
binding !== null &&
212194
// Bail-out if the the binding is a rest param
213195
(binding.declaration_kind === 'rest_param' ||
214196
// Bail-out if we reference anything from the EachBlock (for now) that mutates in non-runes mode,
215-
(((!is_runes && binding.kind === 'each') ||
197+
(((!context.state.analysis.runes && binding.kind === 'each') ||
216198
// or any normal not reactive bindings that are mutated.
217199
binding.kind === 'normal' ||
218200
// or any reactive imports (those are rewritten) (can only happen in legacy mode)

packages/svelte/src/compiler/phases/2-analyze/validation.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ function is_tag_valid_with_parent(tag, parent_tag) {
334334
* @type {import('zimmerframe').Visitors<import('#compiler').SvelteNode, import('./types.js').AnalysisState>}
335335
*/
336336
const validation = {
337+
AssignmentExpression(node, context) {
338+
validate_assignment(node, node.left, context.state);
339+
},
337340
BindDirective(node, context) {
338341
validate_no_const_assignment(node, node.expression, context.state.scope, true);
339342

@@ -655,6 +658,9 @@ const validation = {
655658
error(child, 'invalid-title-content');
656659
}
657660
},
661+
UpdateExpression(node, context) {
662+
validate_assignment(node, node.argument, context.state);
663+
},
658664
ExpressionTag(node, context) {
659665
if (!node.parent) return;
660666
if (context.state.parent_element) {
@@ -904,39 +910,35 @@ function validate_no_const_assignment(node, argument, scope, is_binding) {
904910
function validate_assignment(node, argument, state) {
905911
validate_no_const_assignment(node, argument, state.scope, false);
906912

907-
let left = /** @type {import('estree').Expression | import('estree').Super} */ (argument);
908-
909-
if (left.type === 'Identifier') {
910-
const binding = state.scope.get(left.name);
913+
if (state.analysis.runes && argument.type === 'Identifier') {
914+
const binding = state.scope.get(argument.name);
911915
if (binding?.kind === 'derived') {
912916
error(node, 'invalid-derived-assignment');
913917
}
918+
919+
if (binding?.kind === 'each') {
920+
error(node, 'invalid-each-mutation');
921+
}
914922
}
915923

924+
let object = /** @type {import('estree').Expression | import('estree').Super} */ (argument);
925+
916926
/** @type {import('estree').Expression | import('estree').PrivateIdentifier | null} */
917927
let property = null;
918928

919-
while (left.type === 'MemberExpression') {
920-
property = left.property;
921-
left = left.object;
929+
while (object.type === 'MemberExpression') {
930+
property = object.property;
931+
object = object.object;
922932
}
923933

924-
if (left.type === 'ThisExpression' && property?.type === 'PrivateIdentifier') {
934+
if (object.type === 'ThisExpression' && property?.type === 'PrivateIdentifier') {
925935
if (state.private_derived_state.includes(property.name)) {
926936
error(node, 'invalid-derived-assignment');
927937
}
928938
}
929939
}
930940

931941
export const validation_runes = merge(validation, a11y_validators, {
932-
AssignmentExpression(node, { state, path }) {
933-
const parent = path.at(-1);
934-
if (parent && parent.type === 'ConstTag') return;
935-
validate_assignment(node, node.left, state);
936-
},
937-
UpdateExpression(node, { state }) {
938-
validate_assignment(node, node.argument, state);
939-
},
940942
LabeledStatement(node, { path }) {
941943
if (node.label.name !== '$' || path.at(-1)?.type !== 'Program') return;
942944
error(node, 'invalid-legacy-reactive-statement');

0 commit comments

Comments
 (0)