Skip to content

Commit

Permalink
[TypeDeclaration] Skip ReturnTypeFromStrictTypedCallRector on possibl…
Browse files Browse the repository at this point in the history
…e no return (#441)

* [TypeDeclaration] Skip ReturnTypeFromStrictTypedCallRector on possible no return

* Fixed 🎉

* [ci-review] Rector Rectify

Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
samsonasik and actions-user authored Jul 16, 2021
1 parent 40fbe10 commit b001e38
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 16 deletions.
2 changes: 0 additions & 2 deletions packages/ReadWrite/NodeAnalyzer/ReadWritePropertyAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use PhpParser\Node\Stmt\Unset_;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeManipulator\AssignManipulator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNestingScope\ParentFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\ReadWrite\Guard\VariableToConstantGuard;
Expand All @@ -28,7 +27,6 @@ public function __construct(
private VariableToConstantGuard $variableToConstantGuard,
private AssignManipulator $assignManipulator,
private ReadExprAnalyzer $readExprAnalyzer,
private BetterNodeFinder $betterNodeFinder,
private ParentFinder $parentFinder
) {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

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

final class SkipPossibleNoReturn
{
public function getData()
{
if (mt_rand(0, 100)) {
return $this->getNumber();
}
}

private function getNumber(): int
{
return 100;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\UnionType;
use PHPStan\Type\VoidType;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\PHPStanStaticTypeMapper\ValueObject\TypeKind;
use Rector\TypeDeclaration\NodeAnalyzer\TypeNodeUnwrapper;
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

Expand All @@ -37,7 +39,8 @@ final class ReturnTypeFromStrictTypedCallRector extends AbstractRector
{
public function __construct(
private TypeNodeUnwrapper $typeNodeUnwrapper,
private ReflectionResolver $reflectionResolver
private ReflectionResolver $reflectionResolver,
private ReturnTypeInferer $returnTypeInferer
) {
}

Expand Down Expand Up @@ -95,6 +98,10 @@ public function refactor(Node $node): ?Node
return null;
}

if ($this->isUnionPossibleReturnsVoid($node)) {
return null;
}

/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->find((array) $node->stmts, function (Node $n) use ($node) {
$currentFunctionLike = $this->betterNodeFinder->findParentType($n, FunctionLike::class);
Expand Down Expand Up @@ -136,6 +143,20 @@ public function refactor(Node $node): ?Node
return null;
}

private function isUnionPossibleReturnsVoid(ClassMethod | Function_ | Closure $node): bool
{
$inferReturnType = $this->returnTypeInferer->inferFunctionLike($node);
if ($inferReturnType instanceof UnionType) {
foreach ($inferReturnType->getTypes() as $type) {
if ($type instanceof VoidType) {
return true;
}
}
}

return false;
}

private function processSingleUnionType(
ClassMethod | Function_ | Closure $node,
UnionType $unionType,
Expand Down
5 changes: 3 additions & 2 deletions src/NodeFactory/ClassWithPublicPropertiesFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

namespace Rector\Core\NodeFactory;

use PhpParser\Node;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Namespace_;
use Symplify\Astral\ValueObject\NodeBuilder\ClassBuilder;
use Symplify\Astral\ValueObject\NodeBuilder\NamespaceBuilder;
use Symplify\Astral\ValueObject\NodeBuilder\PropertyBuilder;
Expand All @@ -27,7 +28,7 @@ public function createNode(
array $properties,
?string $parent = null,
array $traits = []
): Node {
): Namespace_ | Class_ {
$namespaceParts = explode('\\', ltrim($fullyQualifiedName, '\\'));
$className = array_pop($namespaceParts);
$namespace = implode('\\', $namespaceParts);
Expand Down
15 changes: 4 additions & 11 deletions src/PhpParser/Node/BetterNodeFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public function __construct(
/**
* @template T of Node
* @param class-string<T> $type
* @return T|null
*/
public function findParentType(Node $node, string $type): ?Node
{
Expand Down Expand Up @@ -101,7 +100,6 @@ public function findInstanceOf(Node | array $nodes, string $type): array
* @template T of Node
* @param class-string<T> $type
* @param Node|Node[] $nodes
* @return T|null
*/
public function findFirstInstanceOf(Node | array $nodes, string $type): ?Node
{
Expand Down Expand Up @@ -182,7 +180,6 @@ public function hasInstancesOf(Node | array $nodes, array $types): bool
* @template T of Node
* @param class-string<T> $type
* @param Node|Node[] $nodes
* @return T|null
*/
public function findLastInstanceOf(Node | array $nodes, string $type): ?Node
{
Expand Down Expand Up @@ -317,7 +314,6 @@ public function findFirstPrevious(Node $node, callable $filter): ?Node
/**
* @template T of Node
* @param array<class-string<T>> $types
* @return T|null
*/
public function findFirstPreviousOfTypes(Node $mainNode, array $types): ?Node
{
Expand Down Expand Up @@ -373,12 +369,11 @@ public function findSameNamedExprs(Expr | Variable | Property | PropertyFetch |
}

$variables = $this->findInstancesOf($scopeNode, [Variable::class]);
$foundVariables = array_filter(

return array_filter(
$variables,
fn (Variable $variable) => $this->nodeNameResolver->isName($variable, $exprName)
);

return $foundVariables;
}

if ($expr instanceof Property) {
Expand All @@ -395,20 +390,18 @@ public function findSameNamedExprs(Expr | Variable | Property | PropertyFetch |
}

$propertyFetches = $this->findInstancesOf($scopeNode, [PropertyFetch::class, StaticPropertyFetch::class]);
$foundProperties = array_filter(

return array_filter(
$propertyFetches,
fn (PropertyFetch | StaticPropertyFetch $propertyFetch) =>
$this->nodeNameResolver->isName($propertyFetch->name, $exprName)
);

return $foundProperties;
}

/**
* @template T of Node
* @param Node|Node[] $nodes
* @param class-string<T> $type
* @return T|null
*/
private function findInstanceOfName(Node | array $nodes, string $type, string $name): ?Node
{
Expand Down

0 comments on commit b001e38

Please sign in to comment.