Skip to content

Commit

Permalink
[CodeQuality] Deprecate NarrowUnionTypeDocRector as focused on docblo…
Browse files Browse the repository at this point in the history
…cks, and moving to type declarations (#3848)
  • Loading branch information
TomasVotruba committed May 14, 2023
1 parent 4ac2cf8 commit 6568360
Show file tree
Hide file tree
Showing 16 changed files with 15 additions and 313 deletions.
2 changes: 0 additions & 2 deletions config/set/code-quality.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector;
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;
use Rector\CodeQuality\Rector\ClassMethod\NarrowUnionTypeDocRector;
use Rector\CodeQuality\Rector\ClassMethod\OptionalParametersAfterRequiredRector;
use Rector\CodeQuality\Rector\ClassMethod\ReturnTypeFromStrictScalarReturnExprRector;
use Rector\CodeQuality\Rector\Concat\JoinStringConcatRector;
Expand Down Expand Up @@ -179,7 +178,6 @@
SwitchNegatedTernaryRector::class,
SingularSwitchToIfRector::class,
SimplifyIfNullableReturnRector::class,
NarrowUnionTypeDocRector::class,
FuncGetArgsToVariadicParamRector::class,
CallUserFuncToMethodCallRector::class,
CallUserFuncWithArrowFunctionToInlineRector::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
namespace Rector\PHPStanStaticTypeMapper\TypeAnalyzer;

use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\IterableType;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
use Rector\PHPStanStaticTypeMapper\ValueObject\UnionTypeAnalysis;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Traversable;

final class UnionTypeAnalyzer
Expand Down Expand Up @@ -69,65 +66,6 @@ public function matchExclusiveTypesWithClassNames(UnionType $unionType): array
return $typesWithClassNames;
}

public function hasObjectWithoutClassType(UnionType $unionType): bool
{
$types = $unionType->getTypes();
foreach ($types as $type) {
if ($type instanceof ObjectWithoutClassType) {
return true;
}
}

return false;
}

public function hasObjectWithoutClassTypeWithOnlyFullyQualifiedObjectType(UnionType $unionType): bool
{
$types = $unionType->getTypes();
foreach ($types as $type) {
if ($type instanceof ObjectWithoutClassType) {
continue;
}

if (! $type instanceof FullyQualifiedObjectType) {
return false;
}
}

return true;
}

public function isScalar(UnionType $unionType): bool
{
$types = $unionType->getTypes();

if (count($types) !== 4) {
return false;
}

foreach ($types as $type) {
if ($type->isString()->yes() && ! $type instanceof ConstantStringType) {
continue;
}

if ($type->isFloat()->yes()) {
continue;
}

if ($type->isInteger()->yes()) {
continue;
}

if ($type->isBoolean()->yes()) {
continue;
}

return false;
}

return true;
}

public function isNullable(UnionType $unionType, bool $checkTwoTypes = false): bool
{
$types = $unionType->getTypes();
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -797,3 +797,4 @@ parameters:

# deprecated
- '#Register "Rector\\Php80\\Rector\\FunctionLike\\UnionTypesRector" service to "php80\.php" config set#'
- '#Fetching class constant class of deprecated class Rector\\CodeQuality\\Rector\\ClassMethod\\NarrowUnionTypeDocRector#'

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

81 changes: 7 additions & 74 deletions rules/CodeQuality/Rector/ClassMethod/NarrowUnionTypeDocRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,15 @@

use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\Rector\AbstractRector;
use Rector\PHPStanStaticTypeMapper\TypeAnalyzer\UnionTypeAnalyzer;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @see \Rector\Tests\CodeQuality\Rector\ClassMethod\NarrowUnionTypeDocRector\NarrowUnionTypeDocRectorTest
* @deprecated This split is deprecated as dangerous to rely on docblock strings. Instead, use strict type declaration rules.
*/
final class NarrowUnionTypeDocRector extends AbstractRector
{
public function __construct(
private readonly UnionTypeAnalyzer $unionTypeAnalyzer
) {
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Changes docblock by narrowing type', [
Expand Down Expand Up @@ -67,70 +57,13 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): ?Node
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$params = $node->getParams();

$hasChanged = false;

foreach ($params as $key => $param) {
/** @var string $paramName */
$paramName = $this->getName($param->var);
$paramType = $phpDocInfo->getParamType($paramName);

if (! $paramType instanceof UnionType) {
continue;
}

if ($this->unionTypeAnalyzer->isScalar($paramType)) {
$this->changeDocObjectScalar($key, $phpDocInfo);
$hasChanged = true;
continue;
}

if ($this->unionTypeAnalyzer->hasObjectWithoutClassType($paramType)) {
$this->changeDocObjectWithoutClassType($paramType, $key, $phpDocInfo);
$hasChanged = true;
}
}

if ($hasChanged) {
return $node;
}
$errorMessage = sprintf(
'Rule "%s" is deprecated, as we moved from docblocks for type declarations. Use strict type rules instead',
self::class
);
trigger_error($errorMessage, E_USER_WARNING);
sleep(3);

return null;
}

private function changeDocObjectWithoutClassType(
UnionType $unionType,
int $key,
PhpDocInfo $phpDocInfo
): void {
if (! $this->unionTypeAnalyzer->hasObjectWithoutClassTypeWithOnlyFullyQualifiedObjectType($unionType)) {
return;
}

$types = $unionType->getTypes();
$resultType = '';
foreach ($types as $type) {
if ($type instanceof FullyQualifiedObjectType) {
$resultType .= $type->getClassName() . '|';
}
}

$resultType = rtrim($resultType, '|');
$paramTagValueNodes = $phpDocInfo->getParamTagValueNodes();

if (isset($paramTagValueNodes[$key])) {
$paramTagValueNodes[$key]->type = new IdentifierTypeNode($resultType);
}
}

private function changeDocObjectScalar(int $key, PhpDocInfo $phpDocInfo): void
{
$paramTagValueNodes = $phpDocInfo->getParamTagValueNodes();

if (isset($paramTagValueNodes[$key])) {
$paramTagValueNodes[$key]->type = new IdentifierTypeNode('scalar');
}
}
}
2 changes: 1 addition & 1 deletion rules/Php80/Rector/FunctionLike/UnionTypesRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @deprecated This split is deprecated as dangerous to rely on doblock strings. Instead, use strict type declaration rules.
* @deprecated This split is deprecated as dangerous to rely on docblock strings. Instead, use strict type declaration rules.
*/
final class UnionTypesRector extends AbstractRector implements MinPhpVersionInterface
{
Expand Down

0 comments on commit 6568360

Please sign in to comment.