Skip to content

Commit

Permalink
[TypeDeclaration] Allow __invoke() method for return type changed on …
Browse files Browse the repository at this point in the history
…ClassMethodReturnTypeOverrideGuard (#4667)

Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
samsonasik and actions-user authored Aug 6, 2023
1 parent 4e3be87 commit 0977854
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\MixedType;
use Rector\Core\FileSystem\FilePathHelper;
use Rector\Core\NodeAnalyzer\MagicClassMethodAnalyzer;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Reflection\ReflectionResolver;
Expand Down Expand Up @@ -42,14 +43,15 @@ public function __construct(
private readonly ReflectionResolver $reflectionResolver,
private readonly ReturnTypeInferer $returnTypeInferer,
private readonly ParentClassMethodTypeOverrideGuard $parentClassMethodTypeOverrideGuard,
private readonly FilePathHelper $filePathHelper
private readonly FilePathHelper $filePathHelper,
private readonly MagicClassMethodAnalyzer $magicClassMethodAnalyzer
) {
}

public function shouldSkipClassMethod(ClassMethod $classMethod, Scope $scope): bool
{
// 1. skip magic methods
if ($classMethod->isMagic()) {
if ($this->magicClassMethodAnalyzer->isUnsafeOverridden($classMethod)) {
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture;

use Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Source\SomeExternalCaller;

final class InvokeMethod
{
public function __invoke(SomeExternalCaller $someExternalCaller)
{
return $someExternalCaller->getName();
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture;

use Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Source\SomeExternalCaller;

final class InvokeMethod
{
public function __invoke(SomeExternalCaller $someExternalCaller): string
{
return $someExternalCaller->getName();
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,6 @@ public function provideMinPhpVersion(): int
private function shouldSkip(ClassMethod | Function_ | Closure $node, Scope $scope): bool
{
$hasReturn = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($node, Return_::class);
if ($node instanceof ClassMethod && $node->isMagic()) {
return true;
}

if ($hasReturn) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,8 @@ private function shouldSkip(ClassMethod | Function_ | Closure $node, Scope $scop
return true;
}

if ($node instanceof ClassMethod) {
if ($this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope)) {
return true;
}

if ($node->isMagic()) {
return true;
}
if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope)) {
return true;
}

return $this->isUnionPossibleReturnsVoid($node);
Expand Down
25 changes: 25 additions & 0 deletions src/NodeAnalyzer/MagicClassMethodAnalyzer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Rector\Core\NodeAnalyzer;

use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeNameResolver\NodeNameResolver;

final class MagicClassMethodAnalyzer
{
public function __construct(private readonly NodeNameResolver $nodeNameResolver)
{
}

public function isUnsafeOverridden(ClassMethod $classMethod): bool
{
if ($this->nodeNameResolver->isName($classMethod, MethodName::INVOKE)) {
return false;
}

return $classMethod->isMagic();
}
}

0 comments on commit 0977854

Please sign in to comment.