@@ -334,6 +334,9 @@ function is_tag_valid_with_parent(tag, parent_tag) {
334
334
* @type {import('zimmerframe').Visitors<import('#compiler').SvelteNode, import('./types.js').AnalysisState> }
335
335
*/
336
336
const validation = {
337
+ AssignmentExpression ( node , context ) {
338
+ validate_assignment ( node , node . left , context . state ) ;
339
+ } ,
337
340
BindDirective ( node , context ) {
338
341
validate_no_const_assignment ( node , node . expression , context . state . scope , true ) ;
339
342
@@ -655,6 +658,9 @@ const validation = {
655
658
error ( child , 'invalid-title-content' ) ;
656
659
}
657
660
} ,
661
+ UpdateExpression ( node , context ) {
662
+ validate_assignment ( node , node . argument , context . state ) ;
663
+ } ,
658
664
ExpressionTag ( node , context ) {
659
665
if ( ! node . parent ) return ;
660
666
if ( context . state . parent_element ) {
@@ -904,39 +910,35 @@ function validate_no_const_assignment(node, argument, scope, is_binding) {
904
910
function validate_assignment ( node , argument , state ) {
905
911
validate_no_const_assignment ( node , argument , state . scope , false ) ;
906
912
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 ) ;
911
915
if ( binding ?. kind === 'derived' ) {
912
916
error ( node , 'invalid-derived-assignment' ) ;
913
917
}
918
+
919
+ if ( binding ?. kind === 'each' ) {
920
+ error ( node , 'invalid-each-mutation' ) ;
921
+ }
914
922
}
915
923
924
+ let object = /** @type {import('estree').Expression | import('estree').Super } */ ( argument ) ;
925
+
916
926
/** @type {import('estree').Expression | import('estree').PrivateIdentifier | null } */
917
927
let property = null ;
918
928
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 ;
922
932
}
923
933
924
- if ( left . type === 'ThisExpression' && property ?. type === 'PrivateIdentifier' ) {
934
+ if ( object . type === 'ThisExpression' && property ?. type === 'PrivateIdentifier' ) {
925
935
if ( state . private_derived_state . includes ( property . name ) ) {
926
936
error ( node , 'invalid-derived-assignment' ) ;
927
937
}
928
938
}
929
939
}
930
940
931
941
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
- } ,
940
942
LabeledStatement ( node , { path } ) {
941
943
if ( node . label . name !== '$' || path . at ( - 1 ) ?. type !== 'Program' ) return ;
942
944
error ( node , 'invalid-legacy-reactive-statement' ) ;
0 commit comments