@@ -504,6 +504,11 @@ private function compareStatementsInNamespace(array $oldStmts, array $newStmts,
504504
505505 // todo has a constant been removed?
506506
507+ // Compare class-level attributes
508+ if ($ this ->hasAttributeChanges ($ old , $ new )) {
509+ return $ this ->stmtDiff ($ old , $ new , $ updateTo );
510+ }
511+
507512 $ old ->stmts = $ newStmtsToSet ;
508513
509514 return [$ old ];
@@ -691,6 +696,72 @@ private function stmtDiff(Node $old, Node $new, string $updateTo): array
691696 return [$ old , $ new ];
692697 }
693698
699+ /**
700+ * Check if class-level attributes have changed between old and new class declarations.
701+ * @param Node\Stmt\ClassLike $old
702+ * @param Node\Stmt\ClassLike $new
703+ * @return bool
704+ */
705+ private function hasAttributeChanges (Node \Stmt \ClassLike $ old , Node \Stmt \ClassLike $ new ): bool
706+ {
707+ $ oldAttribGroups = $ old ->attrGroups ;
708+ $ oldAttribs = [];
709+ foreach ($ oldAttribGroups as $ group ) {
710+ foreach ($ group ->attrs as $ attrib ) {
711+ if ($ attrib ->name ->toLowerString () !== 'since ' && $ attrib ->name ->toLowerString () !== 'until ' ) {
712+ $ oldAttribs [] = $ attrib ;
713+ }
714+ }
715+ }
716+
717+ $ newAttribGroups = $ new ->attrGroups ;
718+ $ newAttribs = [];
719+ foreach ($ newAttribGroups as $ group ) {
720+ foreach ($ group ->attrs as $ attrib ) {
721+ if ($ attrib ->name ->toLowerString () !== 'since ' && $ attrib ->name ->toLowerString () !== 'until ' ) {
722+ $ newAttribs [] = $ attrib ;
723+ }
724+ }
725+ }
726+
727+ if (count ($ oldAttribs ) !== count ($ newAttribs )) {
728+ return true ;
729+ }
730+
731+ foreach ($ oldAttribs as $ idx => $ oldAttrib ) {
732+ $ newAttrib = $ newAttribs [$ idx ];
733+ if ($ oldAttrib ->name ->name !== $ newAttrib ->name ->name ) {
734+ return true ;
735+ }
736+
737+ $ oldArgs = $ oldAttrib ->args ;
738+ $ newArgs = $ newAttrib ->args ;
739+ if (count ($ oldArgs ) !== count ($ newArgs )) {
740+ return true ;
741+ }
742+
743+ foreach ($ oldArgs as $ argIdx => $ oldArg ) {
744+ $ newArg = $ newArgs [$ argIdx ];
745+ if ($ oldArg ->name !== null && $ newArg ->name !== null ) {
746+ if ($ oldArg ->name ->name !== $ newArg ->name ->name ) {
747+ return true ;
748+ }
749+ } elseif ($ oldArg ->name !== null || $ newArg ->name !== null ) {
750+ return true ;
751+ }
752+
753+ // Compare attribute argument values
754+ $ oldArgValue = $ this ->printer ->prettyPrintExpr ($ oldArg ->value );
755+ $ newArgValue = $ this ->printer ->prettyPrintExpr ($ newArg ->value );
756+ if ($ oldArgValue !== $ newArgValue ) {
757+ return true ;
758+ }
759+ }
760+ }
761+
762+ return false ;
763+ }
764+
694765 /**
695766 * @return Node\Stmt\ClassConst[]
696767 */
0 commit comments