@@ -224,6 +224,7 @@ public static function compare(string $a, string $b): bool
224224 */
225225 public static function getExtendedClasses ($ class ): array
226226 {
227+ static $ loadedExtendedRoots = [];
227228 $ result = [];
228229 foreach (Formatter::parseSignature ($ class ) as $ signature ) {
229230 if ($ signature ['type ' ] !== 'class ' ) {
@@ -236,6 +237,11 @@ public static function getExtendedClasses($class): array
236237 }
237238 $ classPath = Runtime::PHP_IMITATION_DIRECTORY . '\\' . implode ('\\' , $ path );
238239
240+ if (isset ($ loadedExtendedRoots [$ classPath ])) {
241+ $ extendedClasses = $ loadedExtendedRoots [$ classPath ];
242+ continue ;
243+ }
244+
239245 // Remove duplicated prefix
240246 $ classPath = preg_replace (
241247 '/^(?: ' . preg_quote (Runtime::PHP_IMITATION_DIRECTORY , '/ ' ) . ')+/ ' ,
@@ -250,6 +256,16 @@ public static function getExtendedClasses($class): array
250256 }
251257
252258 $ result [] = $ extendedClasses ;
259+
260+ $ loadedExtendedRoots = $ extendedClasses ;
261+ if (class_exists ($ classPath )) {
262+ $ reflectionClass = new \ReflectionClass ($ classPath );
263+ preg_match_all ('/\@parent\s+([^\r\n]+)/i ' , $ reflectionClass ->getDocComment (), $ parents );
264+ $ roots = array_merge ($ parents [1 ], [$ classPath ]);
265+ if (count ($ roots ) > $ extendedClasses ) {
266+ $ loadedExtendedRoots = $ roots ;
267+ }
268+ }
253269 }
254270
255271 array_walk_recursive ($ result , function (&$ className ) {
@@ -265,8 +281,7 @@ public static function getExtendedClasses($class): array
265281 $ newClassName [$ key ] = array_flip (Runtime::PHP_IMITATION_MAPS )[$ value ] ?? $ value ;
266282 }
267283
268- $ newClassName = implode ('. ' , $ newClassName );
269- $ className = $ newClassName ;
284+ $ className = $ newClassName = implode ('. ' , $ newClassName );
270285 });
271286
272287 return $ result ;
0 commit comments