@@ -131,7 +131,7 @@ private function registerFetch(ClassConstFetch $node, Scope $scope): void
131131 {
132132 if ($ node ->class instanceof Expr) {
133133 $ ownerType = $ scope ->getType ($ node ->class );
134- $ possibleDescendantFetch = true ;
134+ $ possibleDescendantFetch = null ;
135135 } else {
136136 $ ownerType = $ scope ->resolveTypeByName ($ node ->class );
137137 $ possibleDescendantFetch = $ node ->class ->toString () === 'static ' ;
@@ -146,11 +146,11 @@ private function registerFetch(ClassConstFetch $node, Scope $scope): void
146146 continue ; // reserved for class name fetching
147147 }
148148
149- foreach ($ this ->getDeclaringTypesWithConstant ($ ownerType , $ constantName ) as $ className ) {
149+ foreach ($ this ->getDeclaringTypesWithConstant ($ ownerType , $ constantName, $ possibleDescendantFetch ) as $ constantRef ) {
150150 $ this ->registerUsage (
151151 new ClassConstantUsage (
152152 UsageOrigin::createRegular ($ node , $ scope ),
153- new ClassConstantRef ( $ className , $ constantName , $ possibleDescendantFetch ) ,
153+ $ constantRef ,
154154 ),
155155 $ node ,
156156 $ scope ,
@@ -160,29 +160,26 @@ private function registerFetch(ClassConstFetch $node, Scope $scope): void
160160 }
161161
162162 /**
163- * @return list<class-string<object>|null >
163+ * @return list<ClassConstantRef >
164164 */
165165 private function getDeclaringTypesWithConstant (
166166 Type $ type ,
167- string $ constantName
167+ string $ constantName ,
168+ ?bool $ isPossibleDescendant
168169 ): array
169170 {
170- $ typeNormalized = TypeUtils::toBenevolentUnion ($ type ); // extract possible calls even from Class|int
171+ $ typeNormalized = TypeUtils::toBenevolentUnion ($ type ); // extract possible fetches even from Class|int
171172 $ classReflections = $ typeNormalized ->getObjectTypeOrClassStringObjectType ()->getObjectClassReflections ();
172173
173174 $ result = [];
174175
175176 foreach ($ classReflections as $ classReflection ) {
176- if ($ classReflection ->hasConstant ($ constantName )) {
177- $ result [] = $ classReflection ->getConstant ($ constantName )->getDeclaringClass ()->getName ();
178-
179- } else { // unknown constant fetch (might be present on children)
180- $ result [] = $ classReflection ->getName ();
181- }
177+ $ possibleDescendant = $ isPossibleDescendant ?? !$ classReflection ->isFinal ();
178+ $ result [] = new ClassConstantRef ($ classReflection ->getName (), $ constantName , $ possibleDescendant );
182179 }
183180
184181 if ($ result === []) {
185- $ result [] = null ; // call over unknown type
182+ $ result [] = new ClassConstantRef ( null , $ constantName , true ) ; // call over unknown type
186183 }
187184
188185 return $ result ;
0 commit comments