mirror of
https://github.com/rectorphp/rector.git
synced 2024-07-02 23:53:30 +00:00
[TypeDeclaration] Do not add void on possibly overriden protected class method (#1921)
This commit is contained in:
parent
07df2bc028
commit
36e81c09e1
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector\Fixture;
|
||||
|
||||
final class FinalProtectedMethod
|
||||
{
|
||||
protected function getValues()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector\Fixture;
|
||||
|
||||
final class FinalProtectedMethod
|
||||
{
|
||||
protected function getValues(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector\Fixture;
|
||||
|
||||
class SkipNonFinalProtectedMethod
|
||||
{
|
||||
protected function getValues()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -9,12 +9,15 @@ use PhpParser\Node\Expr\Closure;
|
|||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\NeverType;
|
||||
use PHPStan\Type\VoidType;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||
use Rector\Core\Contract\Rector\AllowEmptyConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\TypeDeclaration\TypeInferer\SilentVoidResolver;
|
||||
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnVendorLockResolver;
|
||||
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
|
||||
|
@ -92,7 +95,7 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassMethod && ($node->isMagic() || $node->isAbstract())) {
|
||||
if ($this->shouldSkipClassMethod($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -140,4 +143,40 @@ CODE_SAMPLE
|
|||
|
||||
$this->phpDocTypeChanger->changeReturnType($phpDocInfo, new VoidType());
|
||||
}
|
||||
|
||||
private function shouldSkipClassMethod(ClassMethod|Function_|Closure $functionLike): bool
|
||||
{
|
||||
if (! $functionLike instanceof ClassMethod) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($functionLike->isMagic()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($functionLike->isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($functionLike->isProtected()) {
|
||||
return ! $this->isInsideFinalClass($functionLike);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isInsideFinalClass(ClassMethod $classMethod): bool
|
||||
{
|
||||
$scope = $classMethod->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $classReflection->isFinal();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user