From bfd2ae37448f2df371a2be691645c7dcf53e781b Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Fri, 22 Jan 2021 19:12:39 +0100 Subject: [PATCH] typed property --- phpstan.neon | 5 +++ ...pedPropertyFromStrictConstructorRector.php | 42 ++++++++++++++----- .../Fixture/some_class.php.inc | 8 ++-- ...ropertyFromStrictConstructorRectorTest.php | 5 ++- 4 files changed, 44 insertions(+), 16 deletions(-) rename rules/php80/src/Rector/{Class_ => Property}/TypedPropertyFromStrictConstructorRector.php (51%) rename rules/php80/tests/Rector/{Class_ => Property}/TypedPropertyFromStrictConstructorRector/Fixture/some_class.php.inc (53%) rename rules/php80/tests/Rector/{Class_ => Property}/TypedPropertyFromStrictConstructorRector/TypedPropertyFromStrictConstructorRectorTest.php (70%) diff --git a/phpstan.neon b/phpstan.neon index b2bdc2fd2b9e..6056ea5b5dc1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -549,3 +549,8 @@ parameters: # buggy phpstan clas-string - '#Method (.*?) should return class\-string but returns string#' - '#Method (.*?) should return array but returns array#' + + - + message: '#Unreachable statement \- code above always terminates#' + paths: + - rules/php80/src/Rector/Property/TypedPropertyFromStrictConstructorRector.php diff --git a/rules/php80/src/Rector/Class_/TypedPropertyFromStrictConstructorRector.php b/rules/php80/src/Rector/Property/TypedPropertyFromStrictConstructorRector.php similarity index 51% rename from rules/php80/src/Rector/Class_/TypedPropertyFromStrictConstructorRector.php rename to rules/php80/src/Rector/Property/TypedPropertyFromStrictConstructorRector.php index 7abbd2e42603..19d3012abe31 100644 --- a/rules/php80/src/Rector/Class_/TypedPropertyFromStrictConstructorRector.php +++ b/rules/php80/src/Rector/Property/TypedPropertyFromStrictConstructorRector.php @@ -2,20 +2,33 @@ declare(strict_types=1); -namespace Rector\Php80\Rector\Class_; +namespace Rector\Php80\Rector\Property; use PhpParser\Node; +use PhpParser\Node\Stmt\Property; +use PHPStan\Type\MixedType; use Rector\Core\Rector\AbstractRector; -use Rector\Core\ValueObject\MethodName; use Rector\Core\ValueObject\PhpVersionFeature; +use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper; +use Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer\ConstructorPropertyTypeInferer; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @see \Rector\Php80\Tests\Rector\Class_\TypedPropertyFromStrictConstructorRector\TypedPropertyFromStrictConstructorRectorTest + * @see \Rector\Php80\Tests\Rector\Property\TypedPropertyFromStrictConstructorRector\TypedPropertyFromStrictConstructorRectorTest */ final class TypedPropertyFromStrictConstructorRector extends AbstractRector { + /** + * @var ConstructorPropertyTypeInferer + */ + private $constructorPropertyTypeInferer; + + public function __construct(ConstructorPropertyTypeInferer $constructorPropertyTypeInferer) + { + $this->constructorPropertyTypeInferer = $constructorPropertyTypeInferer; + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Add typed properties based only on strict constructor types', [ @@ -54,11 +67,11 @@ public function __construct(string $name) */ public function getNodeTypes(): array { - return [\PhpParser\Node\Stmt\Class_::class]; + return [Property::class]; } /** - * @param \PhpParser\Node\Stmt\Class_ $node + * @param Property $node */ public function refactor(Node $node): ?Node { @@ -66,16 +79,25 @@ public function refactor(Node $node): ?Node return null; } - $constructClassMethod = $node->getMethod(MethodName::CONSTRUCT); - if ($constructClassMethod === null) { + if ($node->type !== null) { return null; } - // @todo resolve param to propery assign - foreach ($constructClassMethod->getParams() as $parameter) { + $varType = $this->constructorPropertyTypeInferer->inferProperty($node); + if ($varType instanceof MixedType) { + return null; + } + + $propertyTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode( + $varType, + PHPStanStaticTypeMapper::KIND_PROPERTY + ); + + if ($propertyTypeNode === null) { + return null; } - // change the node + $node->type = $propertyTypeNode; return $node; } diff --git a/rules/php80/tests/Rector/Class_/TypedPropertyFromStrictConstructorRector/Fixture/some_class.php.inc b/rules/php80/tests/Rector/Property/TypedPropertyFromStrictConstructorRector/Fixture/some_class.php.inc similarity index 53% rename from rules/php80/tests/Rector/Class_/TypedPropertyFromStrictConstructorRector/Fixture/some_class.php.inc rename to rules/php80/tests/Rector/Property/TypedPropertyFromStrictConstructorRector/Fixture/some_class.php.inc index 9af196655a49..b9edb0d63cc3 100644 --- a/rules/php80/tests/Rector/Class_/TypedPropertyFromStrictConstructorRector/Fixture/some_class.php.inc +++ b/rules/php80/tests/Rector/Property/TypedPropertyFromStrictConstructorRector/Fixture/some_class.php.inc @@ -1,8 +1,8 @@