diff --git a/packages/ReadWrite/Guard/VariableToConstantGuard.php b/packages/ReadWrite/Guard/VariableToConstantGuard.php index 46cb09ea653..e2a47ac3083 100644 --- a/packages/ReadWrite/Guard/VariableToConstantGuard.php +++ b/packages/ReadWrite/Guard/VariableToConstantGuard.php @@ -7,14 +7,14 @@ use PhpParser\Node\Arg; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; +use PHPStan\Analyser\Scope; use PHPStan\Reflection\FunctionReflection; -use PHPStan\Reflection\Native\NativeFunctionReflection; +use PHPStan\Reflection\ParameterReflection; +use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Reflection\ReflectionProvider; use Rector\Core\Exception\ShouldNotHappenException; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; -use ReflectionFunction; -use Symplify\PackageBuilder\Reflection\PrivatesAccessor; final class VariableToConstantGuard { @@ -26,7 +26,6 @@ final class VariableToConstantGuard public function __construct( private NodeNameResolver $nodeNameResolver, private ReflectionProvider $reflectionProvider, - private PrivatesAccessor $privatesAccessor ) { } @@ -52,7 +51,11 @@ public function isReadArg(Arg $arg): bool $functionReflection = $this->reflectionProvider->getFunction($functionName, $argScope); - $referenceParametersPositions = $this->resolveFunctionReferencePositions($functionReflection); + $referenceParametersPositions = $this->resolveFunctionReferencePositions( + $functionReflection, + [$arg], + $argScope + ); if ($referenceParametersPositions === []) { // no reference always only write return true; @@ -63,37 +66,31 @@ public function isReadArg(Arg $arg): bool } /** + * @param Arg[] $args * @return int[] */ - private function resolveFunctionReferencePositions(FunctionReflection $functionReflection): array - { + private function resolveFunctionReferencePositions( + FunctionReflection $functionReflection, + array $args, + Scope $scope + ): array { if (isset($this->referencePositionsByFunctionName[$functionReflection->getName()])) { return $this->referencePositionsByFunctionName[$functionReflection->getName()]; } - // this is needed, as native function reflection does not have access to referenced parameters - if ($functionReflection instanceof NativeFunctionReflection) { - $functionName = $functionReflection->getName(); - if (! function_exists($functionName)) { - return []; - } - - $nativeFunctionReflection = new ReflectionFunction($functionName); - } else { - $nativeFunctionReflection = $this->privatesAccessor->getPrivateProperty($functionReflection, 'reflection'); - } - $referencePositions = []; - foreach ($nativeFunctionReflection->getParameters() as $position => $reflectionParameter) { - if (! $reflectionParameter->isPassedByReference()) { + $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs( + $scope, + $args, + $functionReflection->getVariants() + ); + foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) { + /** @var ParameterReflection $parameterReflection */ + if (! $parameterReflection->passedByReference()->yes()) { continue; } - if (! is_int($position)) { - throw new ShouldNotHappenException(); - } - $referencePositions[] = $position; }