@@ -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 */
336336const 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 ) {
@@ -908,39 +914,35 @@ function validate_no_const_assignment(node, argument, scope, is_binding) {
908914function validate_assignment ( node , argument , state ) {
909915 validate_no_const_assignment ( node , argument , state . scope , false ) ;
910916
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 ) ;
915919 if ( binding ?. kind === 'derived' ) {
916920 error ( node , 'invalid-derived-assignment' ) ;
917921 }
922+
923+ if ( binding ?. kind === 'each' ) {
924+ error ( node , 'invalid-each-assignment' ) ;
925+ }
918926 }
919927
928+ let object = /** @type {import('estree').Expression | import('estree').Super } */ ( argument ) ;
929+
920930 /** @type {import('estree').Expression | import('estree').PrivateIdentifier | null } */
921931 let property = null ;
922932
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 ;
926936 }
927937
928- if ( left . type === 'ThisExpression' && property ?. type === 'PrivateIdentifier' ) {
938+ if ( object . type === 'ThisExpression' && property ?. type === 'PrivateIdentifier' ) {
929939 if ( state . private_derived_state . includes ( property . name ) ) {
930940 error ( node , 'invalid-derived-assignment' ) ;
931941 }
932942 }
933943}
934944
935945export 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- } ,
944946 LabeledStatement ( node , { path } ) {
945947 if ( node . label . name !== '$' || path . at ( - 1 ) ?. type !== 'Program' ) return ;
946948 error ( node , 'invalid-legacy-reactive-statement' ) ;
0 commit comments