Skip to content

Commit

Permalink
[Fix] Make UnionTypesRector and ReturnAnnotationIncorrectNullableRect…
Browse files Browse the repository at this point in the history
…or skip chaotic methods (#2067)

* [Fix] Make UnionTypesRector and ReturnAnnotationIncorrectNullableRector skip chaotic methods

* [Fix] Fix UnionTypesRector

Co-authored-by: Jiří Bok <jiri.bok@protonmail.com>
  • Loading branch information
dorrogeray and dorrogeray committed Apr 13, 2022
1 parent dd96863 commit 0ba8579
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 2 deletions.
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ parameters:
message: '#Class cognitive complexity is \d+, keep it under \d+#'
paths:
- packages/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php
- rules/Php80/Rector/FunctionLike/UnionTypesRector.php

-
message: '#Property with protected modifier is not allowed\. Use interface contract method instead#'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Fixture;

use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;

final class SkipAnnotationsOnChaoticMethods extends NodeVisitorAbstract
{
/**
* @return Node|null
*/
public function enterNode(Node $node): ?Node
{
return $node;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Fixture;

class SkipRemovingMixedReturnType
{
/**
* @return mixed[]
*/
private function x(): array
{
return [];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Fixture;

class SkipRemovingNullableMixedReturnType
{
/**
* @return mixed[]|null
*/
private function x(bool $returnNull): ?array
{
return $returnNull ? null : [];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

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

use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;

final class SkipAnnotationsOnChaoticMethods extends NodeVisitorAbstract
{
/**
* @return Node
*/
public function enterNode(Node $node): ?Node
{
return $node;
}
}

6 changes: 6 additions & 0 deletions rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer;
use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;

final class DeadReturnTagValueNodeAnalyzer
Expand All @@ -22,6 +23,7 @@ public function __construct(
private readonly TypeComparator $typeComparator,
private readonly BetterNodeFinder $betterNodeFinder,
private readonly GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer,
private readonly MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer,
) {
}

Expand Down Expand Up @@ -57,6 +59,10 @@ public function isDead(ReturnTagValueNode $returnTagValueNode, FunctionLike $fun
return false;
}

if ($this->mixedArrayTypeNodeAnalyzer->hasMixedArrayType($returnTagValueNode->type)) {
return false;
}

if ($this->hasTruePseudoType($returnTagValueNode->type)) {
return false;
}
Expand Down
32 changes: 32 additions & 0 deletions rules/DeadCode/TypeNodeAnalyzer/MixedArrayTypeNodeAnalyzer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Rector\DeadCode\TypeNodeAnalyzer;

use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
use Rector\BetterPhpDocParser\ValueObject\Type\SpacingAwareArrayTypeNode;

final class MixedArrayTypeNodeAnalyzer
{
public function hasMixedArrayType(UnionTypeNode $unionTypeNode): bool
{
$types = $unionTypeNode->types;

foreach ($types as $type) {
if ($type instanceof SpacingAwareArrayTypeNode) {
$typeNode = $type->type;
if (! $typeNode instanceof IdentifierTypeNode) {
continue;
}

if ($typeNode->name === 'mixed') {
return true;
}
}
}

return false;
}
}
6 changes: 6 additions & 0 deletions rules/Php80/Rector/FunctionLike/UnionTypesRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\PHPStanStaticTypeMapper\TypeAnalyzer\UnionTypeAnalyzer;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodParamVendorLockResolver;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
Expand All @@ -43,6 +44,7 @@ public function __construct(
private readonly ReturnTagRemover $returnTagRemover,
private readonly ParamTagRemover $paramTagRemover,
private readonly ClassMethodParamVendorLockResolver $classMethodParamVendorLockResolver,
private readonly ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard,
private readonly UnionTypeAnalyzer $unionTypeAnalyzer,
private readonly TypeFactory $typeFactory
) {
Expand Down Expand Up @@ -95,6 +97,10 @@ public function refactor(Node $node): ?Node
{
$this->hasChanged = false;

if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}

$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);

$this->refactorParamTypes($node, $phpDocInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\TypeDeclaration\Guard\PhpDocNestedAnnotationGuard;
use Rector\TypeDeclaration\Helper\PhpDocNullableTypeHelper;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

Expand All @@ -25,6 +26,7 @@ final class ReturnAnnotationIncorrectNullableRector extends AbstractRector
public function __construct(
private readonly PhpDocTypeChanger $phpDocTypeChanger,
private readonly PhpDocNullableTypeHelper $phpDocNullableTypeHelper,
private readonly ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard,
private readonly PhpDocNestedAnnotationGuard $phpDocNestedAnnotationGuard
) {
}
Expand Down Expand Up @@ -75,12 +77,16 @@ public function getNodeTypes(): array
}

/**
* @param ClassMethod $node
* @param ClassMethod|Function_ $node
*/
public function refactor(Node $node): ?Node
{
$returnType = $node->getReturnType();

if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}

if ($returnType === null) {
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/PhpParser/Node/Value/ValueResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ private function getConstExprEvaluator(): ConstExprEvaluator
}

/**
* @return mixed[]
* @return mixed[]|null
*/
private function extractConstantArrayTypeValue(ConstantArrayType $constantArrayType): ?array
{
Expand Down

0 comments on commit 0ba8579

Please sign in to comment.