@@ -47,32 +47,39 @@ public function checkExtendsTags(Node $node, array $extendsTags): array
4747 continue ;
4848 }
4949
50- $ class = $ type ->getObjectClassNames ()[0 ];
51- $ referencedClassReflection = $ type ->getObjectClassReflections ()[0 ] ?? null ;
50+ $ referencedClassReflections = array_map (fn ($ reflection ) => [$ reflection , $ reflection ->getName ()], $ type ->getObjectClassReflections ());
51+ $ referencedClassReflectionsMap = array_column ($ referencedClassReflections , 0 , 1 );
52+ foreach ($ type ->getObjectClassNames () as $ class ) {
53+ $ referencedClassReflection = $ referencedClassReflectionsMap [$ class ]?? null ;
54+ if ($ referencedClassReflection === null ) {
55+ $ errors [] = RuleErrorBuilder::message (sprintf ('PHPDoc tag @phpstan-require-extends contains unknown class %s. ' , $ class ))
56+ ->discoveringSymbolsTip ()
57+ ->identifier ('class.notFound ' )
58+ ->build ();
59+ continue ;
60+ }
5261
53- if ($ referencedClassReflection === null ) {
54- $ errors [] = RuleErrorBuilder::message (sprintf ('PHPDoc tag @phpstan-require-extends contains unknown class %s. ' , $ class ))
55- ->discoveringSymbolsTip ()
56- ->identifier ('class.notFound ' )
57- ->build ();
58- continue ;
59- }
60-
61- if (!$ referencedClassReflection ->isClass ()) {
62- $ errors [] = RuleErrorBuilder::message (sprintf ('PHPDoc tag @phpstan-require-extends cannot contain non-class type %s. ' , $ class ))
63- ->identifier (sprintf ('requireExtends.%s ' , strtolower ($ referencedClassReflection ->getClassTypeDescription ())))
64- ->build ();
65- } elseif ($ referencedClassReflection ->isFinal ()) {
66- $ errors [] = RuleErrorBuilder::message (sprintf ('PHPDoc tag @phpstan-require-extends cannot contain final class %s. ' , $ class ))
67- ->identifier ('requireExtends.finalClass ' )
68- ->build ();
69- } else {
70- $ errors = array_merge (
71- $ errors ,
72- $ this ->classCheck ->checkClassNames ([
73- new ClassNameNodePair ($ class , $ node ),
74- ], $ this ->checkClassCaseSensitivity ),
75- );
62+ if ($ referencedClassReflection ->isInterface ()) {
63+ $ errors [] = RuleErrorBuilder::message (sprintf ('PHPDoc tag @phpstan-require-extends cannot contain an interface %s, expected a class. ' , $ class ))
64+ ->tip ('If you meant an interface, use @phpstan-require-implements instead. ' )
65+ ->identifier ('requireExtends.interface ' )
66+ ->build ();
67+ } elseif (!$ referencedClassReflection ->isClass ()) {
68+ $ errors [] = RuleErrorBuilder::message (sprintf ('PHPDoc tag @phpstan-require-extends cannot contain non-class type %s. ' , $ class ))
69+ ->identifier (sprintf ('requireExtends.%s ' , strtolower ($ referencedClassReflection ->getClassTypeDescription ())))
70+ ->build ();
71+ } elseif ($ referencedClassReflection ->isFinal ()) {
72+ $ errors [] = RuleErrorBuilder::message (sprintf ('PHPDoc tag @phpstan-require-extends cannot contain final class %s. ' , $ class ))
73+ ->identifier ('requireExtends.finalClass ' )
74+ ->build ();
75+ } else {
76+ $ errors = array_merge (
77+ $ errors ,
78+ $ this ->classCheck ->checkClassNames ([
79+ new ClassNameNodePair ($ class , $ node ),
80+ ], $ this ->checkClassCaseSensitivity ),
81+ );
82+ }
7683 }
7784 }
7885
0 commit comments