mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-02 09:20:52 +00:00
decopule ArrayTypeMapper and TypeWithClassNameTypeMapper
This commit is contained in:
parent
71cdc8fe40
commit
ccc63bbb75
|
@ -10,17 +10,11 @@ use PhpParser\Node\Name;
|
|||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\UnionType as PhpParserUnionType;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\StaticType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareUnionTypeNode;
|
||||
use Rector\Exception\NotImplementedException;
|
||||
use Rector\PHPStan\Type\SelfObjectType;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
|
||||
final class PHPStanStaticTypeMapper
|
||||
|
@ -40,16 +34,6 @@ final class PHPStanStaticTypeMapper
|
|||
|
||||
public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode
|
||||
{
|
||||
// @todo move to ArrayTypeMapper
|
||||
if ($type instanceof ArrayType) {
|
||||
$itemTypeNode = $this->mapToPHPStanPhpDocTypeNode($type->getItemType());
|
||||
if ($itemTypeNode instanceof UnionTypeNode) {
|
||||
return $this->convertUnionArrayTypeNodesToArrayTypeOfUnionTypeNodes($itemTypeNode);
|
||||
}
|
||||
|
||||
return new ArrayTypeNode($itemTypeNode);
|
||||
}
|
||||
|
||||
foreach ($this->typeMappers as $typeMapper) {
|
||||
if (! is_a($type, $typeMapper->getNodeClass(), true)) {
|
||||
continue;
|
||||
|
@ -75,20 +59,12 @@ final class PHPStanStaticTypeMapper
|
|||
return $typeMapper->mapToPhpParserNode($phpStanType, $kind);
|
||||
}
|
||||
|
||||
if ($phpStanType instanceof ArrayType) {
|
||||
return new Identifier('array');
|
||||
}
|
||||
|
||||
if ($phpStanType instanceof StaticType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($phpStanType instanceof TypeWithClassName) {
|
||||
$lowerCasedClassName = strtolower($phpStanType->getClassName());
|
||||
if ($lowerCasedClassName === 'callable') {
|
||||
return new Identifier('callable');
|
||||
}
|
||||
|
||||
if ($lowerCasedClassName === 'self') {
|
||||
return new Identifier('self');
|
||||
}
|
||||
|
@ -118,52 +94,6 @@ final class PHPStanStaticTypeMapper
|
|||
return $typeMapper->mapToDocString($phpStanType, $parentType);
|
||||
}
|
||||
|
||||
if ($phpStanType instanceof ArrayType) {
|
||||
if ($phpStanType->getItemType() instanceof UnionType) {
|
||||
$unionedTypesAsString = [];
|
||||
foreach ($phpStanType->getItemType()->getTypes() as $unionedArrayItemType) {
|
||||
$unionedTypesAsString[] = $this->mapToDocString($unionedArrayItemType, $phpStanType) . '[]';
|
||||
}
|
||||
|
||||
$unionedTypesAsString = array_values($unionedTypesAsString);
|
||||
$unionedTypesAsString = array_unique($unionedTypesAsString);
|
||||
|
||||
return implode('|', $unionedTypesAsString);
|
||||
}
|
||||
|
||||
$docString = $this->mapToDocString($phpStanType->getItemType(), $parentType);
|
||||
|
||||
// @todo improve this
|
||||
$docStringTypes = explode('|', $docString);
|
||||
$docStringTypes = array_filter($docStringTypes);
|
||||
|
||||
foreach ($docStringTypes as $key => $docStringType) {
|
||||
$docStringTypes[$key] = $docStringType . '[]';
|
||||
}
|
||||
|
||||
return implode('|', $docStringTypes);
|
||||
}
|
||||
|
||||
throw new NotImplementedException(__METHOD__ . ' for ' . get_class($phpStanType));
|
||||
}
|
||||
|
||||
private function convertUnionArrayTypeNodesToArrayTypeOfUnionTypeNodes(
|
||||
UnionTypeNode $unionTypeNode
|
||||
): AttributeAwareUnionTypeNode {
|
||||
$unionedArrayType = [];
|
||||
foreach ($unionTypeNode->types as $unionedType) {
|
||||
if ($unionedType instanceof UnionTypeNode) {
|
||||
foreach ($unionedType->types as $key => $subUnionedType) {
|
||||
$unionedType->types[$key] = new ArrayTypeNode($subUnionedType);
|
||||
}
|
||||
|
||||
$unionedArrayType[] = $unionedType;
|
||||
continue;
|
||||
}
|
||||
|
||||
$unionedArrayType[] = new ArrayTypeNode($unionedType);
|
||||
}
|
||||
|
||||
return new AttributeAwareUnionTypeNode($unionedArrayType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanStaticTypeMapper\TypeMapper;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareUnionTypeNode;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
|
||||
|
||||
final class ArrayTypeMapper implements TypeMapperInterface
|
||||
{
|
||||
/**
|
||||
* @var PHPStanStaticTypeMapper
|
||||
*/
|
||||
private $phpStanStaticTypeMapper;
|
||||
|
||||
public function getNodeClass(): string
|
||||
{
|
||||
return ArrayType::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ArrayType $type
|
||||
*/
|
||||
public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode
|
||||
{
|
||||
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type->getItemType());
|
||||
|
||||
if ($itemTypeNode instanceof UnionTypeNode) {
|
||||
return $this->convertUnionArrayTypeNodesToArrayTypeOfUnionTypeNodes($itemTypeNode);
|
||||
}
|
||||
|
||||
return new ArrayTypeNode($itemTypeNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ArrayType $type
|
||||
*/
|
||||
public function mapToPhpParserNode(Type $type, ?string $kind = null): ?Node
|
||||
{
|
||||
return new Identifier('array');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ArrayType $type
|
||||
*/
|
||||
public function mapToDocString(Type $type, ?Type $parentType = null): string
|
||||
{
|
||||
$itemType = $type->getItemType();
|
||||
|
||||
if ($itemType instanceof UnionType) {
|
||||
return $this->mapArrayUnionTypeToDocString($type, $itemType);
|
||||
}
|
||||
|
||||
$docString = $this->phpStanStaticTypeMapper->mapToDocString($type->getItemType(), $parentType);
|
||||
|
||||
// @todo improve this
|
||||
$docStringTypes = explode('|', $docString);
|
||||
$docStringTypes = array_filter($docStringTypes);
|
||||
|
||||
foreach ($docStringTypes as $key => $docStringType) {
|
||||
$docStringTypes[$key] = $docStringType . '[]';
|
||||
}
|
||||
|
||||
return implode('|', $docStringTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireArrayTypeMapper(PHPStanStaticTypeMapper $phpStanStaticTypeMapper): void
|
||||
{
|
||||
$this->phpStanStaticTypeMapper = $phpStanStaticTypeMapper;
|
||||
}
|
||||
|
||||
private function mapArrayUnionTypeToDocString(ArrayType $arrayType, UnionType $unionType): string
|
||||
{
|
||||
$unionedTypesAsString = [];
|
||||
|
||||
foreach ($unionType->getTypes() as $unionedArrayItemType) {
|
||||
$unionedTypesAsString[] = $this->phpStanStaticTypeMapper->mapToDocString(
|
||||
$unionedArrayItemType,
|
||||
$arrayType
|
||||
) . '[]';
|
||||
}
|
||||
|
||||
$unionedTypesAsString = array_values($unionedTypesAsString);
|
||||
$unionedTypesAsString = array_unique($unionedTypesAsString);
|
||||
|
||||
return implode('|', $unionedTypesAsString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo improve
|
||||
*/
|
||||
private function convertUnionArrayTypeNodesToArrayTypeOfUnionTypeNodes(
|
||||
UnionTypeNode $unionTypeNode
|
||||
): AttributeAwareUnionTypeNode {
|
||||
$unionedArrayType = [];
|
||||
foreach ($unionTypeNode->types as $unionedType) {
|
||||
if ($unionedType instanceof UnionTypeNode) {
|
||||
foreach ($unionedType->types as $key => $subUnionedType) {
|
||||
$unionedType->types[$key] = new ArrayTypeNode($subUnionedType);
|
||||
}
|
||||
|
||||
$unionedArrayType[] = $unionedType;
|
||||
continue;
|
||||
}
|
||||
|
||||
$unionedArrayType[] = new ArrayTypeNode($unionedType);
|
||||
}
|
||||
|
||||
return new AttributeAwareUnionTypeNode($unionedArrayType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanStaticTypeMapper\TypeMapper;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\StringType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\VerbosityLevel;
|
||||
use Rector\Php\PhpVersionProvider;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
use Rector\ValueObject\PhpVersionFeature;
|
||||
|
||||
final class TypeWithClassNameTypeMapper implements TypeMapperInterface
|
||||
{
|
||||
/**
|
||||
* @var PhpVersionProvider
|
||||
*/
|
||||
private $phpVersionProvider;
|
||||
|
||||
public function __construct(PhpVersionProvider $phpVersionProvider)
|
||||
{
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
}
|
||||
|
||||
public function getNodeClass(): string
|
||||
{
|
||||
return StringType::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StringType $type
|
||||
*/
|
||||
public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode
|
||||
{
|
||||
return new IdentifierTypeNode('string');
|
||||
}
|
||||
|
||||
public function mapToPhpParserNode(Type $type, ?string $kind = null): ?Node
|
||||
{
|
||||
if (! $this->phpVersionProvider->isAtLeast(PhpVersionFeature::SCALAR_TYPES)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Identifier('string');
|
||||
}
|
||||
|
||||
public function mapToDocString(Type $type, ?Type $parentType = null): string
|
||||
{
|
||||
return $type->describe(VerbosityLevel::typeOnly());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user