From a8a79d0b986fd08f699980f28c049d18ad04a4b8 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 19 Sep 2021 12:54:47 +0200 Subject: [PATCH] [Arguments] Use native types over weak string to define types (#903) * [Arguments] Use native types over weak string to define types * [ci-review] Rector Rectify Co-authored-by: GitHub Action --- .../docs/rector_rules_overview.md | 14 ++++++++++- .../config/configured_rule.php | 24 +++++++++++++++---- .../NodeAnalyzer/ChangedArgumentsDetector.php | 15 ++++++++---- .../ClassMethod/ArgumentAdderRector.php | 15 +++++++----- rules/Arguments/ValueObject/ArgumentAdder.php | 5 ++-- 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/build/target-repository/docs/rector_rules_overview.md b/build/target-repository/docs/rector_rules_overview.md index 9253f2eeaf3..fd636e497da 100644 --- a/build/target-repository/docs/rector_rules_overview.md +++ b/build/target-repository/docs/rector_rules_overview.md @@ -109,6 +109,7 @@ This Rector adds new default arguments in calls of defined methods and class typ - class: [`Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector`](../rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php) ```php +use PHPStan\Type\ObjectType; use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector; use Rector\Arguments\ValueObject\ArgumentAdder; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; @@ -120,7 +121,18 @@ return static function (ContainerConfigurator $containerConfigurator): void { $services->set(ArgumentAdderRector::class) ->call('configure', [[ ArgumentAdderRector::ADDED_ARGUMENTS => ValueObjectInliner::inline([ - new ArgumentAdder('SomeExampleClass', 'someMethod', 0, 'someArgument', true, 'SomeType', null), + new ArgumentAdder('SomeExampleClass', 'someMethod', 0, 'someArgument', true, new ObjectType( + 'SomeType', + null, + null, + [], + null, + null, + [], + [], + [], + [ + ]), null), ]), ]]); }; diff --git a/rules-tests/Arguments/Rector/ClassMethod/ArgumentAdderRector/config/configured_rule.php b/rules-tests/Arguments/Rector/ClassMethod/ArgumentAdderRector/config/configured_rule.php index 6dc0395efd4..cf0e4bdafa3 100644 --- a/rules-tests/Arguments/Rector/ClassMethod/ArgumentAdderRector/config/configured_rule.php +++ b/rules-tests/Arguments/Rector/ClassMethod/ArgumentAdderRector/config/configured_rule.php @@ -2,6 +2,10 @@ declare(strict_types=1); +use PHPStan\Type\ArrayType; +use PHPStan\Type\IntegerType; +use PHPStan\Type\MixedType; +use PHPStan\Type\ObjectType; use Rector\Arguments\NodeAnalyzer\ArgumentAddingScope; use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector; use Rector\Arguments\ValueObject\ArgumentAdder; @@ -13,6 +17,9 @@ return static function (ContainerConfigurator $containerConfigurator): void { $services = $containerConfigurator->services(); + + $arrayType = new ArrayType(new MixedType(), new MixedType()); + $services->set(ArgumentAdderRector::class) ->call('configure', [[ ArgumentAdderRector::ADDED_ARGUMENTS => ValueObjectInliner::inline([ @@ -23,10 +30,17 @@ 0, 'request', null, - 'Illuminate\Http\Illuminate\Http' + new ObjectType('Illuminate\Http\Illuminate\Http') ), new ArgumentAdder(SomeContainerBuilder::class, 'compile', 0, 'isCompiled', false), - new ArgumentAdder(SomeContainerBuilder::class, 'addCompilerPass', 2, 'priority', 0, 'int'), + new ArgumentAdder( + SomeContainerBuilder::class, + 'addCompilerPass', + 2, + 'priority', + 0, + new IntegerType() + ), // scoped new ArgumentAdder( SomeParentClient::class, @@ -34,7 +48,7 @@ 2, 'serverParameters', [], - 'array', + $arrayType, ArgumentAddingScope::SCOPE_PARENT_CALL ), new ArgumentAdder( @@ -43,10 +57,10 @@ 2, 'serverParameters', [], - 'array', + $arrayType, ArgumentAddingScope::SCOPE_CLASS_METHOD ), - new ArgumentAdder(SomeClass::class, 'withoutTypeOrDefaultValue', 0, 'arguments', [], 'array'), + new ArgumentAdder(SomeClass::class, 'withoutTypeOrDefaultValue', 0, 'arguments', [], $arrayType), ]), ]]); }; diff --git a/rules/Arguments/NodeAnalyzer/ChangedArgumentsDetector.php b/rules/Arguments/NodeAnalyzer/ChangedArgumentsDetector.php index 5bb6e5238f1..0a0711fc880 100644 --- a/rules/Arguments/NodeAnalyzer/ChangedArgumentsDetector.php +++ b/rules/Arguments/NodeAnalyzer/ChangedArgumentsDetector.php @@ -5,14 +5,17 @@ namespace Rector\Arguments\NodeAnalyzer; use PhpParser\Node\Param; +use PHPStan\Type\Type; use Rector\Core\PhpParser\Node\Value\ValueResolver; -use Rector\NodeNameResolver\NodeNameResolver; +use Rector\NodeTypeResolver\TypeComparator\TypeComparator; +use Rector\StaticTypeMapper\StaticTypeMapper; final class ChangedArgumentsDetector { public function __construct( private ValueResolver $valueResolver, - private NodeNameResolver $nodeNameResolver + private StaticTypeMapper $staticTypeMapper, + private TypeComparator $typeComparator ) { } @@ -28,16 +31,18 @@ public function isDefaultValueChanged(Param $param, $value): bool return ! $this->valueResolver->isValue($param->default, $value); } - public function isTypeChanged(Param $param, ?string $type): bool + public function isTypeChanged(Param $param, ?Type $newType): bool { if ($param->type === null) { return false; } - if ($type === null) { + if ($newType === null) { return true; } - return ! $this->nodeNameResolver->isName($param->type, $type); + $currentParamType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($param->type); + + return ! $this->typeComparator->areTypesEqual($currentParamType, $newType); } } diff --git a/rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php b/rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php index 591d737eed4..09bfcceb481 100644 --- a/rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php +++ b/rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php @@ -10,13 +10,12 @@ use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\Variable; -use PhpParser\Node\Identifier; use PhpParser\Node\Name; -use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Param; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PHPStan\Type\ObjectType; +use PHPStan\Type\Type; use Rector\Arguments\NodeAnalyzer\ArgumentAddingScope; use Rector\Arguments\NodeAnalyzer\ChangedArgumentsDetector; use Rector\Arguments\ValueObject\ArgumentAdder; @@ -24,6 +23,7 @@ use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\Rector\AbstractRector; use Rector\NodeTypeResolver\Node\AttributeKey; +use Rector\PHPStanStaticTypeMapper\ValueObject\TypeKind; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Webmozart\Assert\Assert; @@ -53,9 +53,11 @@ public function __construct( public function getRuleDefinition(): RuleDefinition { + $objectType = new ObjectType('SomeType'); + $exampleConfiguration = [ self::ADDED_ARGUMENTS => [ - new ArgumentAdder('SomeExampleClass', 'someMethod', 0, 'someArgument', true, 'SomeType'), + new ArgumentAdder('SomeExampleClass', 'someMethod', 0, 'someArgument', true, $objectType), ], ]; @@ -234,7 +236,7 @@ private function addClassMethodParam( ClassMethod $classMethod, ArgumentAdder $argumentAdder, mixed $defaultValue, - ?string $type, + ?Type $type, int $position ): void { $argumentName = $argumentAdder->getArgumentName(); @@ -243,8 +245,9 @@ private function addClassMethodParam( } $param = new Param(new Variable($argumentName), BuilderHelpers::normalizeValue($defaultValue)); - if ($type) { - $param->type = ctype_upper($type[0]) ? new FullyQualified($type) : new Identifier($type); + if ($type !== null) { + $typeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($type, TypeKind::PARAM()); + $param->type = $typeNode; } $classMethod->params[$position] = $param; diff --git a/rules/Arguments/ValueObject/ArgumentAdder.php b/rules/Arguments/ValueObject/ArgumentAdder.php index 6de73c40ab3..1bdb6a8215d 100644 --- a/rules/Arguments/ValueObject/ArgumentAdder.php +++ b/rules/Arguments/ValueObject/ArgumentAdder.php @@ -5,6 +5,7 @@ namespace Rector\Arguments\ValueObject; use PHPStan\Type\ObjectType; +use PHPStan\Type\Type; final class ArgumentAdder { @@ -17,7 +18,7 @@ public function __construct( private int $position, private ?string $argumentName = null, private $argumentDefaultValue = null, - private ?string $argumentType = null, + private Type | null $argumentType = null, private ?string $scope = null ) { } @@ -50,7 +51,7 @@ public function getArgumentDefaultValue() return $this->argumentDefaultValue; } - public function getArgumentType(): ?string + public function getArgumentType(): ?Type { return $this->argumentType; }