@@ -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 ) {
@@ -908,39 +914,35 @@ function validate_no_const_assignment(node, argument, scope, is_binding) {
908
914
function validate_assignment ( node , argument , state ) {
909
915
validate_no_const_assignment ( node , argument , state . scope , false ) ;
910
916
911
- let left = /** @type {import('estree').Expression | import('estree').Super } */ ( argument ) ;
912
-
913
- if ( left . type === 'Identifier' ) {
914
- const binding = state . scope . get ( left . name ) ;
917
+ if ( state . analysis . runes && argument . type === 'Identifier' ) {
918
+ const binding = state . scope . get ( argument . name ) ;
915
919
if ( binding ?. kind === 'derived' ) {
916
920
error ( node , 'invalid-derived-assignment' ) ;
917
921
}
922
+
923
+ if ( binding ?. kind === 'each' ) {
924
+ error ( node , 'invalid-each-assignment' ) ;
925
+ }
918
926
}
919
927
928
+ let object = /** @type {import('estree').Expression | import('estree').Super } */ ( argument ) ;
929
+
920
930
/** @type {import('estree').Expression | import('estree').PrivateIdentifier | null } */
921
931
let property = null ;
922
932
923
- while ( left . type === 'MemberExpression' ) {
924
- property = left . property ;
925
- left = left . object ;
933
+ while ( object . type === 'MemberExpression' ) {
934
+ property = object . property ;
935
+ object = object . object ;
926
936
}
927
937
928
- if ( left . type === 'ThisExpression' && property ?. type === 'PrivateIdentifier' ) {
938
+ if ( object . type === 'ThisExpression' && property ?. type === 'PrivateIdentifier' ) {
929
939
if ( state . private_derived_state . includes ( property . name ) ) {
930
940
error ( node , 'invalid-derived-assignment' ) ;
931
941
}
932
942
}
933
943
}
934
944
935
945
export const validation_runes = merge ( validation , a11y_validators , {
936
- AssignmentExpression ( node , { state, path } ) {
937
- const parent = path . at ( - 1 ) ;
938
- if ( parent && parent . type === 'ConstTag' ) return ;
939
- validate_assignment ( node , node . left , state ) ;
940
- } ,
941
- UpdateExpression ( node , { state } ) {
942
- validate_assignment ( node , node . argument , state ) ;
943
- } ,
944
946
LabeledStatement ( node , { path } ) {
945
947
if ( node . label . name !== '$' || path . at ( - 1 ) ?. type !== 'Program' ) return ;
946
948
error ( node , 'invalid-legacy-reactive-statement' ) ;
0 commit comments