@@ -113,17 +113,24 @@ private function registerMethodCall(
113113 $ methodNames = $ this ->getMethodName ($ methodCall , $ scope );
114114
115115 if ($ methodCall instanceof New_) {
116- if ($ methodCall ->class instanceof Expr || $ methodCall -> class instanceof Name ) {
116+ if ($ methodCall ->class instanceof Expr) {
117117 $ callerType = $ scope ->getType ($ methodCall );
118+ $ possibleDescendantCall = null ;
119+
120+ } elseif ($ methodCall ->class instanceof Name) {
121+ $ callerType = $ scope ->resolveTypeByName ($ methodCall ->class );
122+ $ possibleDescendantCall = $ methodCall ->class ->toString () === 'static ' ;
123+
118124 } else {
119125 return ;
120126 }
121127 } else {
122128 $ callerType = $ scope ->getType ($ methodCall ->var );
129+ $ possibleDescendantCall = null ;
123130 }
124131
125132 foreach ($ methodNames as $ methodName ) {
126- foreach ($ this ->getDeclaringTypesWithMethod ($ methodName , $ callerType , TrinaryLogic::createNo ()) as $ methodRef ) {
133+ foreach ($ this ->getDeclaringTypesWithMethod ($ methodName , $ callerType , TrinaryLogic::createNo (), $ possibleDescendantCall ) as $ methodRef ) {
127134 $ this ->registerUsage (
128135 new ClassMethodUsage (
129136 $ this ->usageOriginDetector ->detectOrigin ($ scope ),
@@ -145,12 +152,15 @@ private function registerStaticCall(
145152
146153 if ($ staticCall ->class instanceof Expr) {
147154 $ callerType = $ scope ->getType ($ staticCall ->class );
155+ $ possibleDescendantCall = null ;
156+
148157 } else {
149- $ callerType = $ scope ->resolveTypeByName ($ staticCall ->class ); // broken in PHPStan, the type here is marked as NOT final
158+ $ callerType = $ scope ->resolveTypeByName ($ staticCall ->class );
159+ $ possibleDescendantCall = $ staticCall ->class ->toString () === 'static ' ;
150160 }
151161
152162 foreach ($ methodNames as $ methodName ) {
153- foreach ($ this ->getDeclaringTypesWithMethod ($ methodName , $ callerType , TrinaryLogic::createYes ()) as $ methodRef ) {
163+ foreach ($ this ->getDeclaringTypesWithMethod ($ methodName , $ callerType , TrinaryLogic::createYes (), $ possibleDescendantCall ) as $ methodRef ) {
154164 $ this ->registerUsage (
155165 new ClassMethodUsage (
156166 $ this ->usageOriginDetector ->detectOrigin ($ scope ),
@@ -249,7 +259,8 @@ private function getMethodName(CallLike $call, Scope $scope): array
249259 private function getDeclaringTypesWithMethod (
250260 string $ methodName ,
251261 Type $ type ,
252- TrinaryLogic $ isStaticCall
262+ TrinaryLogic $ isStaticCall ,
263+ ?bool $ isPossibleDescendant = null
253264 ): array
254265 {
255266 $ typeNoNull = TypeCombinator::removeNull ($ type ); // remove null to support nullsafe calls
@@ -259,7 +270,8 @@ private function getDeclaringTypesWithMethod(
259270 $ result = [];
260271
261272 foreach ($ classReflections as $ classReflection ) {
262- $ result [] = new ClassMethodRef ($ classReflection ->getName (), $ methodName , !$ classReflection ->isFinal ());
273+ $ possibleDescendant = $ isPossibleDescendant ?? !$ classReflection ->isFinal ();
274+ $ result [] = new ClassMethodRef ($ classReflection ->getName (), $ methodName , $ possibleDescendant );
263275 }
264276
265277 if ($ this ->trackMixedAccess ) {
0 commit comments