keep non-simple array types for typed properties

This commit is contained in:
TomasVotruba 2019-12-30 18:03:48 +01:00
parent 8e4e386c91
commit 38a6bbdcfc
4 changed files with 112 additions and 0 deletions

View File

@ -554,6 +554,13 @@ final class StaticTypeMapper
throw new NotImplementedException(sprintf('%s for "%s"', __METHOD__, $type));
}
public function mapPHPStanPhpDocTypeNodeToPhpDocString(TypeNode $typeNode, Node $node): string
{
$phpStanType = $this->mapPHPStanPhpDocTypeNodeToPHPStanType($typeNode, $node);
return $this->mapPHPStanTypeToDocString($phpStanType);
}
public function mapPHPStanPhpDocTypeNodeToPHPStanType(TypeNode $typeNode, Node $node): Type
{
if ($typeNode instanceof IdentifierTypeNode) {

View File

@ -7,6 +7,9 @@ namespace Rector\Php74\Rector\Property;
use PhpParser\Node;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\Type\MixedType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
@ -126,7 +129,44 @@ PHP
return;
}
// keep string[] etc.
if ($this->isNonBasicArrayType($property, $varTagValueNode)) {
return;
}
$propertyPhpDocInfo->removeByType(VarTagValueNode::class);
$this->docBlockManipulator->updateNodeWithPhpDocInfo($property, $propertyPhpDocInfo);
}
private function isNonBasicArrayType(Property $property, VarTagValueNode $varTagValueNode): bool
{
if (! $this->isArrayGenericTypeNode($varTagValueNode) && ! $this->isArrayTypeNode($varTagValueNode)) {
return false;
}
$varTypeDocString = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPhpDocString(
$varTagValueNode->type,
$property
);
return $varTypeDocString !== 'array';
}
private function isArrayGenericTypeNode(VarTagValueNode $varTagValueNode): bool
{
if (! $varTagValueNode->type instanceof GenericTypeNode) {
return false;
}
if (! $varTagValueNode->type->type instanceof IdentifierTypeNode) {
return false;
}
return $varTagValueNode->type->type->name === 'array';
}
private function isArrayTypeNode(VarTagValueNode $varTagValueNode): bool
{
return $varTagValueNode->type instanceof ArrayTypeNode;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
use Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Source\SomeParent;
final class ComplexArray
{
/**
* @var array<int, string>
*/
private $foo;
/**
* @var int[]
*/
private $foos;
}
?>
-----
<?php
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
use Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Source\SomeParent;
final class ComplexArray
{
/**
* @var array<int, string>
*/
private array $foo;
/**
* @var int[]
*/
private array $foos;
}
?>

View File

@ -0,0 +1,24 @@
<?php
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
final class SimpleArray
{
/**
* @var array
*/
private $foo;
}
?>
-----
<?php
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
final class SimpleArray
{
private array $foo;
}
?>