EVOLUTION-NINJA
Edit File: ClassMethodReturnVendorLockResolver.php
<?php declare (strict_types=1); namespace Rector\VendorLocker\NodeVendorLocker; use PhpParser\Node\Stmt\ClassMethod; use PHPStan\Analyser\Scope; use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\FunctionVariantWithPhpDocs; use PHPStan\Type\MixedType; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; final class ClassMethodReturnVendorLockResolver { /** * @readonly * @var \Rector\NodeNameResolver\NodeNameResolver */ private $nodeNameResolver; public function __construct(\Rector\NodeNameResolver\NodeNameResolver $nodeNameResolver) { $this->nodeNameResolver = $nodeNameResolver; } public function isVendorLocked(\PhpParser\Node\Stmt\ClassMethod $classMethod) : bool { $scope = $classMethod->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE); if (!$scope instanceof \PHPStan\Analyser\Scope) { return \false; } $classReflection = $scope->getClassReflection(); if (!$classReflection instanceof \PHPStan\Reflection\ClassReflection) { return \false; } $methodName = $this->nodeNameResolver->getName($classMethod); return $this->isVendorLockedByAncestors($classReflection, $methodName); } private function isVendorLockedByAncestors(\PHPStan\Reflection\ClassReflection $classReflection, string $methodName) : bool { foreach ($classReflection->getAncestors() as $ancestorClassReflections) { if ($ancestorClassReflections === $classReflection) { continue; } $nativeClassReflection = $ancestorClassReflections->getNativeReflection(); // this should avoid detecting @method as real method if (!$nativeClassReflection->hasMethod($methodName)) { continue; } $parentClassMethodReflection = $ancestorClassReflections->getNativeMethod($methodName); $parametersAcceptor = $parentClassMethodReflection->getVariants()[0]; if (!$parametersAcceptor instanceof \PHPStan\Reflection\FunctionVariantWithPhpDocs) { continue; } // here we count only on strict types, not on docs return !$parametersAcceptor->getNativeReturnType() instanceof \PHPStan\Type\MixedType; } return \false; } }