Skip to content

Commit c295032

Browse files
phpstan-botclaude
andcommitted
Replace resolveCallUserFuncCalleeReflection with CallableParametersAcceptor::getCalleeReflection()
Add getCalleeReflection() to CallableParametersAcceptor interface, returning the underlying FunctionReflection or MethodReflection when available. This replaces the manual callable resolution logic in FuncCallHandler with the existing callable type abstraction. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 98edaa0 commit c295032

9 files changed

Lines changed: 60 additions & 38 deletions

src/Analyser/ExprHandler/FuncCallHandler.php

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
use PHPStan\Reflection\Callables\SimpleImpurePoint;
3636
use PHPStan\Reflection\Callables\SimpleThrowPoint;
3737
use PHPStan\Reflection\FunctionReflection;
38-
use PHPStan\Reflection\MethodReflection;
3938
use PHPStan\Reflection\ParametersAcceptor;
4039
use PHPStan\Reflection\ParametersAcceptorSelector;
4140
use PHPStan\Reflection\ReflectionProvider;
@@ -241,8 +240,17 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
241240
continue;
242241
}
243242

244-
$innerCalleeReflection ??= $this->resolveCallUserFuncCalleeReflection($innerFuncCall, $scope);
245-
$byRefType = $nodeScopeResolver->resolveByRefParameterType($innerFuncCall, $innerCalleeReflection, $innerParameter, $scope);
243+
if ($innerCalleeReflection === null && $innerFuncCall->name instanceof Expr) {
244+
$calledOnType = $scope->getType($innerFuncCall->name);
245+
$callableAcceptors = $calledOnType->getCallableParametersAcceptors($scope);
246+
$innerCalleeReflection = count($callableAcceptors) === 1
247+
? $callableAcceptors[0]->getCalleeReflection()
248+
: false;
249+
}
250+
if ($innerCalleeReflection === null) {
251+
$innerCalleeReflection = false;
252+
}
253+
$byRefType = $nodeScopeResolver->resolveByRefParameterType($innerFuncCall, $innerCalleeReflection !== false ? $innerCalleeReflection : null, $innerParameter, $scope);
246254
$scope = $nodeScopeResolver->processVirtualAssign(
247255
$scope,
248256
$storage,
@@ -868,41 +876,6 @@ public function resolveType(MutatingScope $scope, Expr $expr): Type
868876
return VoidToNullTypeTransformer::transform($parametersAcceptor->getReturnType(), $expr);
869877
}
870878

871-
private function resolveCallUserFuncCalleeReflection(FuncCall $innerFuncCall, MutatingScope $scope): FunctionReflection|MethodReflection|null
872-
{
873-
if ($innerFuncCall->name instanceof Name) {
874-
if ($this->reflectionProvider->hasFunction($innerFuncCall->name, $scope)) {
875-
return $this->reflectionProvider->getFunction($innerFuncCall->name, $scope);
876-
}
877-
return null;
878-
}
879-
880-
$callbackType = $scope->getType($innerFuncCall->name);
881-
882-
$constantStrings = $callbackType->getConstantStrings();
883-
if (count($constantStrings) === 1 && $constantStrings[0]->getValue() !== '') {
884-
$funcName = new Name($constantStrings[0]->getValue());
885-
if ($this->reflectionProvider->hasFunction($funcName, $scope)) {
886-
return $this->reflectionProvider->getFunction($funcName, $scope);
887-
}
888-
889-
return null;
890-
}
891-
892-
$constantArrays = $callbackType->getConstantArrays();
893-
if (count($constantArrays) === 1) {
894-
$typeAndMethods = $constantArrays[0]->findTypeAndMethodNames();
895-
if (count($typeAndMethods) === 1 && !$typeAndMethods[0]->isUnknown() && $typeAndMethods[0]->getCertainty()->yes()) {
896-
$methodType = $typeAndMethods[0]->getType();
897-
if ($methodType->hasMethod($typeAndMethods[0]->getMethod())->yes()) {
898-
return $methodType->getMethod($typeAndMethods[0]->getMethod(), $scope);
899-
}
900-
}
901-
}
902-
903-
return null;
904-
}
905-
906879
private function getDynamicFunctionReturnType(MutatingScope $scope, FuncCall $normalizedNode, FunctionReflection $functionReflection): ?Type
907880
{
908881
foreach ($this->dynamicReturnTypeExtensionRegistryProvider->getRegistry()->getDynamicFunctionReturnTypeExtensions($functionReflection) as $dynamicFunctionReturnTypeExtension) {

src/Reflection/Callables/CallableParametersAcceptor.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use PHPStan\Node\InvalidateExprNode;
66
use PHPStan\Reflection\Assertions;
7+
use PHPStan\Reflection\FunctionReflection;
8+
use PHPStan\Reflection\MethodReflection;
79
use PHPStan\Reflection\ParametersAcceptor;
810
use PHPStan\TrinaryLogic;
911

@@ -60,4 +62,6 @@ public function mustUseReturnValue(): TrinaryLogic;
6062

6163
public function getAsserts(): Assertions;
6264

65+
public function getCalleeReflection(): FunctionReflection|MethodReflection|null;
66+
6367
}

src/Reflection/Callables/FunctionCallableVariant.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,9 @@ public function getAsserts(): Assertions
179179
return $this->function->getAsserts();
180180
}
181181

182+
public function getCalleeReflection(): FunctionReflection|ExtendedMethodReflection
183+
{
184+
return $this->function;
185+
}
186+
182187
}

src/Reflection/ExtendedCallableFunctionVariant.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use PHPStan\Reflection\Callables\CallableParametersAcceptor;
77
use PHPStan\Reflection\Callables\SimpleImpurePoint;
88
use PHPStan\Reflection\Callables\SimpleThrowPoint;
9+
use PHPStan\Reflection\FunctionReflection;
10+
use PHPStan\Reflection\MethodReflection;
911
use PHPStan\TrinaryLogic;
1012
use PHPStan\Type\Generic\TemplateTypeMap;
1113
use PHPStan\Type\Generic\TemplateTypeVarianceMap;
@@ -92,4 +94,9 @@ public function getAsserts(): Assertions
9294
return $this->assertions ?? Assertions::createEmpty();
9395
}
9496

97+
public function getCalleeReflection(): FunctionReflection|MethodReflection|null
98+
{
99+
return null;
100+
}
101+
95102
}

src/Reflection/InaccessibleMethod.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,9 @@ public function getAsserts(): Assertions
9898
return Assertions::createEmpty();
9999
}
100100

101+
public function getCalleeReflection(): ExtendedMethodReflection
102+
{
103+
return $this->methodReflection;
104+
}
105+
101106
}

src/Reflection/ResolvedFunctionVariantWithCallable.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use PHPStan\Reflection\Callables\CallableParametersAcceptor;
77
use PHPStan\Reflection\Callables\SimpleImpurePoint;
88
use PHPStan\Reflection\Callables\SimpleThrowPoint;
9+
use PHPStan\Reflection\FunctionReflection;
10+
use PHPStan\Reflection\MethodReflection;
911
use PHPStan\TrinaryLogic;
1012
use PHPStan\Type\Generic\TemplateTypeMap;
1113
use PHPStan\Type\Generic\TemplateTypeVarianceMap;
@@ -124,4 +126,9 @@ public function getAsserts(): Assertions
124126
return $this->assertions ?? Assertions::createEmpty();
125127
}
126128

129+
public function getCalleeReflection(): FunctionReflection|MethodReflection|null
130+
{
131+
return null;
132+
}
133+
127134
}

src/Reflection/TrivialParametersAcceptor.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use PHPStan\Reflection\Callables\CallableParametersAcceptor;
66
use PHPStan\Reflection\Callables\SimpleImpurePoint;
7+
use PHPStan\Reflection\FunctionReflection;
8+
use PHPStan\Reflection\MethodReflection;
79
use PHPStan\TrinaryLogic;
810
use PHPStan\Type\Generic\TemplateTypeMap;
911
use PHPStan\Type\Generic\TemplateTypeVarianceMap;
@@ -108,4 +110,9 @@ public function getAsserts(): Assertions
108110
return Assertions::createEmpty();
109111
}
110112

113+
public function getCalleeReflection(): FunctionReflection|MethodReflection|null
114+
{
115+
return null;
116+
}
117+
111118
}

src/Type/CallableType.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use PHPStan\Reflection\Callables\SimpleImpurePoint;
1818
use PHPStan\Reflection\Callables\SimpleThrowPoint;
1919
use PHPStan\Reflection\ClassMemberAccessAnswerer;
20+
use PHPStan\Reflection\FunctionReflection;
21+
use PHPStan\Reflection\MethodReflection;
2022
use PHPStan\Reflection\ExtendedParameterReflection;
2123
use PHPStan\Reflection\Native\NativeParameterReflection;
2224
use PHPStan\Reflection\ParameterReflection;
@@ -404,6 +406,11 @@ public function getAsserts(): Assertions
404406
return Assertions::createEmpty();
405407
}
406408

409+
public function getCalleeReflection(): FunctionReflection|MethodReflection|null
410+
{
411+
return null;
412+
}
413+
407414
public function toNumber(): Type
408415
{
409416
return new ErrorType();

src/Type/ClosureType.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use PHPStan\Reflection\Callables\SimpleImpurePoint;
1919
use PHPStan\Reflection\Callables\SimpleThrowPoint;
2020
use PHPStan\Reflection\ClassConstantReflection;
21+
use PHPStan\Reflection\FunctionReflection;
22+
use PHPStan\Reflection\MethodReflection;
2123
use PHPStan\Reflection\ClassMemberAccessAnswerer;
2224
use PHPStan\Reflection\ClassReflection;
2325
use PHPStan\Reflection\ExtendedMethodReflection;
@@ -138,6 +140,11 @@ public function getAsserts(): Assertions
138140
return $this->assertions;
139141
}
140142

143+
public function getCalleeReflection(): FunctionReflection|MethodReflection|null
144+
{
145+
return null;
146+
}
147+
141148
/**
142149
* @return array<non-empty-string, TemplateTag>
143150
*/

0 commit comments

Comments
 (0)