mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-21 01:41:00 +01:00
Merge pull request #1953 from rectorphp/static-mapper
StaticTypeMapper refactoring
This commit is contained in:
commit
a223c79830
@ -13,7 +13,7 @@ use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\StaticTypeToStringResolver;
|
||||
use Rector\NodeTypeResolver\StaticTypeMapper;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
@ -32,20 +32,18 @@ final class CompleteDynamicPropertiesRector extends AbstractRector
|
||||
private const LARAVEL_COLLECTION_CLASS = 'Illuminate\Support\Collection';
|
||||
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeToStringResolver;
|
||||
private $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
public function __construct(
|
||||
StaticTypeToStringResolver $staticTypeToStringResolver,
|
||||
DocBlockManipulator $docBlockManipulator
|
||||
) {
|
||||
$this->staticTypeToStringResolver = $staticTypeToStringResolver;
|
||||
public function __construct(StaticTypeMapper $staticTypeMapper, DocBlockManipulator $docBlockManipulator)
|
||||
{
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
}
|
||||
|
||||
@ -233,7 +231,7 @@ CODE_SAMPLE
|
||||
if ($parentNode instanceof Assign) {
|
||||
$assignedValueStaticType = $this->getStaticType($parentNode->expr);
|
||||
if ($assignedValueStaticType) {
|
||||
return $this->staticTypeToStringResolver->resolveAnyType($assignedValueStaticType);
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToStrings($assignedValueStaticType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace Rector\CodingStyle\Rector\ClassConst;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\StaticTypeToStringResolver;
|
||||
use Rector\NodeTypeResolver\StaticTypeMapper;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
@ -21,16 +21,14 @@ final class VarConstantCommentRector extends AbstractRector
|
||||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeToStringResolver;
|
||||
private $staticTypeMapper;
|
||||
|
||||
public function __construct(
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
StaticTypeToStringResolver $staticTypeToStringResolver
|
||||
) {
|
||||
public function __construct(DocBlockManipulator $docBlockManipulator, StaticTypeMapper $staticTypeMapper)
|
||||
{
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->staticTypeToStringResolver = $staticTypeToStringResolver;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
@ -79,7 +77,7 @@ CODE_SAMPLE
|
||||
return null;
|
||||
}
|
||||
|
||||
$staticTypesInStrings = $this->staticTypeToStringResolver->resolveAnyType($constStaticType);
|
||||
$staticTypesInStrings = $this->staticTypeMapper->mapPHPStanTypeToStrings($constStaticType);
|
||||
|
||||
// nothing we can do
|
||||
if ($staticTypesInStrings === []) {
|
||||
|
@ -259,7 +259,7 @@ final class AssertManipulator
|
||||
|
||||
private function processContainsCall(StaticCall $staticCall): void
|
||||
{
|
||||
if ($this->nodeTypeResolver->isStringyType($staticCall->args[1]->value)) {
|
||||
if ($this->nodeTypeResolver->isStringOrUnionStringType($staticCall->args[1]->value)) {
|
||||
$name = $this->nameResolver->isName(
|
||||
$staticCall,
|
||||
'contains'
|
||||
|
@ -9,7 +9,6 @@ use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\Node\NodeToStringTypeResolver;
|
||||
use Rector\NodeTypeResolver\Php\VarTypeInfo;
|
||||
use Rector\Php\TypeAnalyzer;
|
||||
use Rector\PhpParser\Node\BetterNodeFinder;
|
||||
@ -17,11 +16,6 @@ use Rector\PhpParser\Node\Resolver\NameResolver;
|
||||
|
||||
final class ComplexNodeTypeResolver
|
||||
{
|
||||
/**
|
||||
* @var NodeToStringTypeResolver
|
||||
*/
|
||||
private $nodeToStringTypeResolver;
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
@ -42,14 +36,19 @@ final class ComplexNodeTypeResolver
|
||||
*/
|
||||
private $typeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeMapper;
|
||||
|
||||
public function __construct(
|
||||
NodeToStringTypeResolver $nodeToStringTypeResolver,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
NameResolver $nameResolver,
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
TypeAnalyzer $typeAnalyzer
|
||||
) {
|
||||
$this->nodeToStringTypeResolver = $nodeToStringTypeResolver;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
@ -65,7 +64,7 @@ final class ComplexNodeTypeResolver
|
||||
|
||||
$propertyDefault = $property->props[0]->default;
|
||||
if ($propertyDefault !== null) {
|
||||
$types[] = $this->nodeToStringTypeResolver->resolver($propertyDefault);
|
||||
$types[] = $this->staticTypeMapper->mapPhpParserNodeToString($propertyDefault);
|
||||
}
|
||||
|
||||
$classNode = $property->getAttribute(AttributeKey::CLASS_NODE);
|
||||
|
@ -1,60 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Node;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Scalar\DNumber;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PHPStan\Type\IntegerType;
|
||||
use PHPStan\Type\StringType;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\PhpParser\Node\Manipulator\ConstFetchManipulator;
|
||||
|
||||
final class NodeToStringTypeResolver
|
||||
{
|
||||
/**
|
||||
* @var ConstFetchManipulator
|
||||
*/
|
||||
private $constFetchManipulator;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
public function __construct(ConstFetchManipulator $constFetchManipulator, NodeTypeResolver $nodeTypeResolver)
|
||||
{
|
||||
$this->constFetchManipulator = $constFetchManipulator;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
public function resolver(Node $node): string
|
||||
{
|
||||
if ($node instanceof LNumber) {
|
||||
return 'int';
|
||||
}
|
||||
|
||||
if ($node instanceof Array_) {
|
||||
return 'mixed[]';
|
||||
}
|
||||
|
||||
if ($node instanceof DNumber) {
|
||||
return 'float';
|
||||
}
|
||||
|
||||
if ($this->nodeTypeResolver->isStaticType($node, IntegerType::class)) {
|
||||
return 'int';
|
||||
}
|
||||
|
||||
if ($this->nodeTypeResolver->isStaticType($node, StringType::class)) {
|
||||
return 'string';
|
||||
}
|
||||
|
||||
if ($this->constFetchManipulator->isBool($node)) {
|
||||
return 'bool';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
@ -44,7 +44,6 @@ use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Contract\NodeTypeResolverAwareInterface;
|
||||
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\StaticTypeToStringResolver as TypeToStringResolver;
|
||||
use Rector\NodeTypeResolver\Reflection\ClassReflectionTypesResolver;
|
||||
use Rector\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\PhpParser\NodeTraverser\CallableNodeTraverser;
|
||||
@ -78,14 +77,9 @@ final class NodeTypeResolver
|
||||
private $betterStandardPrinter;
|
||||
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeToStringResolver;
|
||||
|
||||
/**
|
||||
* @var TypeToStringResolver
|
||||
*/
|
||||
private $typeToStringResolver;
|
||||
private $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var CallableNodeTraverser
|
||||
@ -96,19 +90,17 @@ final class NodeTypeResolver
|
||||
* @param PerNodeTypeResolverInterface[] $perNodeTypeResolvers
|
||||
*/
|
||||
public function __construct(
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
BetterStandardPrinter $betterStandardPrinter,
|
||||
NameResolver $nameResolver,
|
||||
StaticTypeToStringResolver $staticTypeToStringResolver,
|
||||
TypeToStringResolver $typeToStringResolver,
|
||||
Broker $broker,
|
||||
ClassReflectionTypesResolver $classReflectionTypesResolver,
|
||||
CallableNodeTraverser $callableNodeTraverser,
|
||||
array $perNodeTypeResolvers
|
||||
) {
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->betterStandardPrinter = $betterStandardPrinter;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->staticTypeToStringResolver = $staticTypeToStringResolver;
|
||||
$this->typeToStringResolver = $typeToStringResolver;
|
||||
$this->broker = $broker;
|
||||
$this->classReflectionTypesResolver = $classReflectionTypesResolver;
|
||||
|
||||
@ -191,7 +183,7 @@ final class NodeTypeResolver
|
||||
return $types;
|
||||
}
|
||||
|
||||
public function isStringyType(Node $node): bool
|
||||
public function isStringOrUnionStringType(Node $node): bool
|
||||
{
|
||||
$nodeType = $this->getStaticType($node);
|
||||
if ($nodeType instanceof StringType) {
|
||||
@ -307,7 +299,7 @@ final class NodeTypeResolver
|
||||
if ($this->isArrayType($node)) {
|
||||
$arrayType = $this->getStaticType($node);
|
||||
if ($arrayType instanceof ArrayType) {
|
||||
$itemTypes = $this->staticTypeToStringResolver->resolveObjectType($arrayType->getItemType());
|
||||
$itemTypes = $this->staticTypeMapper->mapPHPStanTypeToStrings($arrayType->getItemType());
|
||||
|
||||
foreach ($itemTypes as $key => $itemType) {
|
||||
$itemTypes[$key] = $itemType . '[]';
|
||||
@ -321,13 +313,16 @@ final class NodeTypeResolver
|
||||
return ['array'];
|
||||
}
|
||||
|
||||
if ($this->isStringyType($node)) {
|
||||
if ($this->isStringOrUnionStringType($node)) {
|
||||
return ['string'];
|
||||
}
|
||||
|
||||
$nodeStaticType = $this->getStaticType($node);
|
||||
if ($nodeStaticType === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->staticTypeToStringResolver->resolveObjectType($nodeStaticType);
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToStrings($nodeStaticType);
|
||||
}
|
||||
|
||||
public function isNullableObjectType(Node $node): bool
|
||||
@ -412,6 +407,7 @@ final class NodeTypeResolver
|
||||
{
|
||||
// nodes that cannot be resolver by PHPStan
|
||||
$nodeClass = get_class($node);
|
||||
|
||||
if (isset($this->perNodeTypeResolvers[$nodeClass])) {
|
||||
return $this->perNodeTypeResolvers[$nodeClass]->resolve($node);
|
||||
}
|
||||
@ -435,7 +431,7 @@ final class NodeTypeResolver
|
||||
|
||||
$type = $nodeScope->getType($node);
|
||||
|
||||
$typesInStrings = $this->typeToStringResolver->resolveAnyType($type);
|
||||
$typesInStrings = $this->staticTypeMapper->mapPHPStanTypeToStrings($type);
|
||||
|
||||
// hot fix for phpstan not resolving chain method calls
|
||||
if ($node instanceof MethodCall && ! $typesInStrings) {
|
||||
|
@ -1,92 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\PHPStan\Type;
|
||||
|
||||
use PHPStan\Type\Constant\ConstantArrayType;
|
||||
use PHPStan\Type\Constant\ConstantBooleanType;
|
||||
use PHPStan\Type\Constant\ConstantFloatType;
|
||||
use PHPStan\Type\Constant\ConstantIntegerType;
|
||||
use PHPStan\Type\Constant\ConstantStringType;
|
||||
use PHPStan\Type\ConstantType;
|
||||
use PHPStan\Type\IntersectionType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\Tests\StaticTypeToStringResolverTest
|
||||
*/
|
||||
final class StaticTypeToStringResolver
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function resolveAnyType(Type $type): array
|
||||
{
|
||||
$types = [];
|
||||
|
||||
if ($type instanceof ObjectType) {
|
||||
$types[] = $type->getClassName();
|
||||
}
|
||||
|
||||
if ($type instanceof UnionType || $type instanceof IntersectionType) {
|
||||
foreach ($type->getTypes() as $subType) {
|
||||
if ($subType instanceof ObjectType) {
|
||||
$types[] = $subType->getClassName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($type instanceof ConstantType) {
|
||||
return $this->resolveConstantType($type);
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function resolveConstantArrayType(ConstantArrayType $constantArrayType): array
|
||||
{
|
||||
$arrayTypes = [];
|
||||
|
||||
foreach ($constantArrayType->getValueTypes() as $valueType) {
|
||||
$arrayTypes = array_merge($arrayTypes, $this->resolveAnyType($valueType));
|
||||
}
|
||||
|
||||
$arrayTypes = array_unique($arrayTypes);
|
||||
|
||||
return array_map(function (string $arrayType): string {
|
||||
return $arrayType . '[]';
|
||||
}, $arrayTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function resolveConstantType(ConstantType $constantType): array
|
||||
{
|
||||
if ($constantType instanceof ConstantBooleanType) {
|
||||
return ['bool'];
|
||||
}
|
||||
|
||||
if ($constantType instanceof ConstantStringType) {
|
||||
return ['string'];
|
||||
}
|
||||
|
||||
if ($constantType instanceof ConstantIntegerType) {
|
||||
return ['int'];
|
||||
}
|
||||
|
||||
if ($constantType instanceof ConstantArrayType) {
|
||||
return $this->resolveConstantArrayType($constantType);
|
||||
}
|
||||
|
||||
if ($constantType instanceof ConstantFloatType) {
|
||||
return ['float'];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\NodeTypeResolver\PHPStan\Collector\TraitNodeScopeCollector;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\StaticTypeToStringResolver;
|
||||
use Rector\NodeTypeResolver\StaticTypeMapper;
|
||||
use Rector\PhpParser\Node\Resolver\NameResolver;
|
||||
|
||||
/**
|
||||
@ -29,9 +29,9 @@ final class VariableTypeResolver implements PerNodeTypeResolverInterface, NodeTy
|
||||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeToStringResolver;
|
||||
private $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
@ -50,12 +50,12 @@ final class VariableTypeResolver implements PerNodeTypeResolverInterface, NodeTy
|
||||
|
||||
public function __construct(
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
StaticTypeToStringResolver $staticTypeToStringResolver,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
NameResolver $nameResolver,
|
||||
TraitNodeScopeCollector $traitNodeScopeCollector
|
||||
) {
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->staticTypeToStringResolver = $staticTypeToStringResolver;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->traitNodeScopeCollector = $traitNodeScopeCollector;
|
||||
}
|
||||
@ -153,6 +153,6 @@ final class VariableTypeResolver implements PerNodeTypeResolverInterface, NodeTy
|
||||
return [$nodeScope->getClassReflection()->getName()];
|
||||
}
|
||||
|
||||
return $this->staticTypeToStringResolver->resolveAnyType($type);
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToStrings($type);
|
||||
}
|
||||
}
|
||||
|
@ -2,30 +2,46 @@
|
||||
|
||||
namespace Rector\NodeTypeResolver;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Scalar\DNumber;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\BooleanType;
|
||||
use PHPStan\Type\CallableType;
|
||||
use PHPStan\Type\ClosureType;
|
||||
use PHPStan\Type\Constant\ConstantArrayType;
|
||||
use PHPStan\Type\FloatType;
|
||||
use PHPStan\Type\IntegerType;
|
||||
use PHPStan\Type\IntersectionType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\NeverType;
|
||||
use PHPStan\Type\NullType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ObjectWithoutClassType;
|
||||
use PHPStan\Type\StringType;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\Type\AttributeAwareUnionTypeNode;
|
||||
use Rector\Exception\NotImplementedException;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Php\PhpVersionProvider;
|
||||
use Rector\PhpParser\Node\Manipulator\ConstFetchManipulator;
|
||||
|
||||
/**
|
||||
* Inspired by @see StaticTypeToStringResolver
|
||||
* Maps PhpParser <=> PHPStan <=> PHPStan doc <=> string type nodes to between all possible formats
|
||||
*/
|
||||
final class StaticTypeMapper
|
||||
{
|
||||
@ -39,9 +55,112 @@ final class StaticTypeMapper
|
||||
*/
|
||||
private $phpVersionProvider;
|
||||
|
||||
public function __construct(PhpVersionProvider $phpVersionProvider)
|
||||
{
|
||||
/**
|
||||
* @var ConstFetchManipulator
|
||||
*/
|
||||
private $constFetchManipulator;
|
||||
|
||||
public function __construct(
|
||||
PhpVersionProvider $phpVersionProvider,
|
||||
ConstFetchManipulator $constFetchManipulator
|
||||
) {
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
$this->constFetchManipulator = $constFetchManipulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function mapPHPStanTypeToStrings(Type $currentPHPStanType): array
|
||||
{
|
||||
if ($currentPHPStanType instanceof ObjectType) {
|
||||
return [$currentPHPStanType->getClassName()];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof IntegerType) {
|
||||
return ['int'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof ObjectWithoutClassType) {
|
||||
return ['object'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof ClosureType) {
|
||||
return ['callable'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof CallableType) {
|
||||
return ['callable'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof FloatType) {
|
||||
return ['float'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof BooleanType) {
|
||||
return ['bool'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof StringType) {
|
||||
return ['string'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof NullType) {
|
||||
return ['null'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof MixedType) {
|
||||
return ['mixed'];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof ConstantArrayType) {
|
||||
return $this->resolveConstantArrayType($currentPHPStanType);
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof ArrayType) {
|
||||
$types = $this->mapPHPStanTypeToStrings($currentPHPStanType->getItemType());
|
||||
|
||||
if ($types === []) {
|
||||
return ['array'];
|
||||
}
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
$types[$key] = $type . '[]';
|
||||
}
|
||||
|
||||
return array_unique($types);
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof UnionType) {
|
||||
$types = [];
|
||||
foreach ($currentPHPStanType->getTypes() as $singleStaticType) {
|
||||
$currentIterationTypes = $this->mapPHPStanTypeToStrings($singleStaticType);
|
||||
$types = array_merge($types, $currentIterationTypes);
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof IntersectionType) {
|
||||
$types = [];
|
||||
foreach ($currentPHPStanType->getTypes() as $singleStaticType) {
|
||||
$currentIterationTypes = $this->mapPHPStanTypeToStrings($singleStaticType);
|
||||
$types = array_merge($types, $currentIterationTypes);
|
||||
}
|
||||
|
||||
return $this->removeGenericArrayTypeIfThereIsSpecificArrayType($types);
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof NeverType) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($currentPHPStanType instanceof ThisType) {
|
||||
// @todo what is desired return value?
|
||||
return [$currentPHPStanType->getClassName()];
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public function mapPHPStanTypeToPHPStanPhpDocTypeNode(Type $currentPHPStanType): ?TypeNode
|
||||
@ -134,4 +253,84 @@ final class StaticTypeMapper
|
||||
|
||||
throw new NotImplementedException(__METHOD__ . ' for ' . get_class($currentPHPStanType));
|
||||
}
|
||||
|
||||
public function mapPhpParserNodeToString(Expr $expr): string
|
||||
{
|
||||
if ($expr instanceof LNumber) {
|
||||
return 'int';
|
||||
}
|
||||
|
||||
if ($expr instanceof Array_) {
|
||||
return 'mixed[]';
|
||||
}
|
||||
|
||||
if ($expr instanceof DNumber) {
|
||||
return 'float';
|
||||
}
|
||||
|
||||
/** @var Scope $scope */
|
||||
$scope = $expr->getAttribute(AttributeKey::SCOPE);
|
||||
$exprStaticType = $scope->getType($expr);
|
||||
|
||||
if ($exprStaticType instanceof IntegerType) {
|
||||
return 'int';
|
||||
}
|
||||
|
||||
if ($exprStaticType instanceof StringType) {
|
||||
return 'string';
|
||||
}
|
||||
|
||||
if ($this->constFetchManipulator->isBool($expr)) {
|
||||
return 'bool';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function resolveConstantArrayType(ConstantArrayType $constantArrayType): array
|
||||
{
|
||||
$arrayTypes = [];
|
||||
|
||||
foreach ($constantArrayType->getValueTypes() as $valueType) {
|
||||
$arrayTypes = array_merge($arrayTypes, $this->mapPHPStanTypeToStrings($valueType));
|
||||
}
|
||||
|
||||
$arrayTypes = array_unique($arrayTypes);
|
||||
|
||||
return array_map(function (string $arrayType): string {
|
||||
return $arrayType . '[]';
|
||||
}, $arrayTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes "array" if there is "SomeType[]" already
|
||||
*
|
||||
* @param string[] $types
|
||||
* @return string[]
|
||||
*/
|
||||
private function removeGenericArrayTypeIfThereIsSpecificArrayType(array $types): array
|
||||
{
|
||||
$hasSpecificArrayType = false;
|
||||
foreach ($types as $key => $type) {
|
||||
if (Strings::endsWith($type, '[]')) {
|
||||
$hasSpecificArrayType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasSpecificArrayType === false) {
|
||||
return $types;
|
||||
}
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
if ($type === 'array') {
|
||||
unset($types[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
}
|
||||
|
@ -1,147 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\BooleanType;
|
||||
use PHPStan\Type\CallableType;
|
||||
use PHPStan\Type\ClosureType;
|
||||
use PHPStan\Type\FloatType;
|
||||
use PHPStan\Type\IntegerType;
|
||||
use PHPStan\Type\IntersectionType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\NullType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ObjectWithoutClassType;
|
||||
use PHPStan\Type\StringType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Collector\CallableCollectorPopulator;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\Tests\StaticTypeToStringResolverTest
|
||||
*/
|
||||
final class StaticTypeToStringResolver
|
||||
{
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
private $resolversByArgumentType = [];
|
||||
|
||||
public function __construct(CallableCollectorPopulator $callableCollectorPopulator)
|
||||
{
|
||||
$resolvers = [
|
||||
IntegerType::class => ['int'],
|
||||
ObjectWithoutClassType::class => ['object'],
|
||||
ClosureType::class => ['callable'],
|
||||
CallableType::class => ['callable'],
|
||||
FloatType::class => ['float'],
|
||||
BooleanType::class => ['bool'],
|
||||
StringType::class => ['string'],
|
||||
NullType::class => ['null'],
|
||||
MixedType::class => ['mixed'],
|
||||
|
||||
// more complex callables
|
||||
function (ArrayType $arrayType): array {
|
||||
$types = $this->resolveObjectType($arrayType->getItemType());
|
||||
|
||||
if ($types === []) {
|
||||
return ['array'];
|
||||
}
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
$types[$key] = $type . '[]';
|
||||
}
|
||||
|
||||
return array_unique($types);
|
||||
},
|
||||
function (UnionType $unionType): array {
|
||||
$types = [];
|
||||
foreach ($unionType->getTypes() as $singleStaticType) {
|
||||
$types = array_merge($types, $this->resolveObjectType($singleStaticType));
|
||||
}
|
||||
|
||||
return $types;
|
||||
},
|
||||
|
||||
function (IntersectionType $intersectionType): array {
|
||||
$types = [];
|
||||
foreach ($intersectionType->getTypes() as $singleStaticType) {
|
||||
$types = array_merge($types, $this->resolveObjectType($singleStaticType));
|
||||
}
|
||||
|
||||
return $this->removeGenericArrayTypeIfThereIsSpecificArrayType($types);
|
||||
},
|
||||
function (ObjectType $objectType): array {
|
||||
return [$objectType->getClassName()];
|
||||
},
|
||||
];
|
||||
|
||||
$this->resolversByArgumentType = $callableCollectorPopulator->populate($resolvers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type[] $staticTypes
|
||||
* @return string[]
|
||||
*/
|
||||
public function resolveTypes(array $staticTypes): array
|
||||
{
|
||||
$typesAsStrings = [];
|
||||
foreach ($staticTypes as $staticType) {
|
||||
$currentTypesAsStrings = $this->resolveObjectType($staticType);
|
||||
$typesAsStrings = array_merge($typesAsStrings, $currentTypesAsStrings);
|
||||
}
|
||||
|
||||
return array_unique($typesAsStrings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function resolveObjectType(?Type $staticType): array
|
||||
{
|
||||
if ($staticType === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($this->resolversByArgumentType as $type => $resolverCallable) {
|
||||
if (is_a($staticType, $type, true)) {
|
||||
$types = $resolverCallable($staticType);
|
||||
|
||||
return array_unique($types);
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes "array" if there is "SomeType[]" already
|
||||
*
|
||||
* @param string[] $types
|
||||
* @return string[]
|
||||
*/
|
||||
private function removeGenericArrayTypeIfThereIsSpecificArrayType(array $types): array
|
||||
{
|
||||
$hasSpecificArrayType = false;
|
||||
foreach ($types as $key => $type) {
|
||||
if (Strings::endsWith($type, '[]')) {
|
||||
$hasSpecificArrayType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasSpecificArrayType === false) {
|
||||
return $types;
|
||||
}
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
if ($type === 'array') {
|
||||
unset($types[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
}
|
@ -7,33 +7,33 @@ use PHPStan\Type\Constant\ConstantArrayType;
|
||||
use PHPStan\Type\Constant\ConstantStringType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\HttpKernel\RectorKernel;
|
||||
use Rector\NodeTypeResolver\StaticTypeToStringResolver;
|
||||
use Rector\NodeTypeResolver\StaticTypeMapper;
|
||||
use Symplify\PackageBuilder\Tests\AbstractKernelTestCase;
|
||||
|
||||
final class StaticTypeToStringResolverTest extends AbstractKernelTestCase
|
||||
final class StaticTypeMapperTest extends AbstractKernelTestCase
|
||||
{
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeToStringResolver;
|
||||
private $staticTypeMapper;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->bootKernel(RectorKernel::class);
|
||||
|
||||
$this->staticTypeToStringResolver = self::$container->get(StaticTypeToStringResolver::class);
|
||||
$this->staticTypeMapper = self::$container->get(StaticTypeMapper::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideStaticTypesToStrings()
|
||||
* @dataProvider provideDataForTestMapPHPStanTypeToStrings()
|
||||
* @param string[] $expectedStrings
|
||||
*/
|
||||
public function test(Type $type, array $expectedStrings): void
|
||||
public function testMapPHPStanTypeToStrings(Type $type, array $expectedStrings): void
|
||||
{
|
||||
$this->assertSame($expectedStrings, $this->staticTypeToStringResolver->resolveObjectType($type));
|
||||
$this->assertSame($expectedStrings, $this->staticTypeMapper->mapPHPStanTypeToStrings($type));
|
||||
}
|
||||
|
||||
public function provideStaticTypesToStrings(): Iterator
|
||||
public function provideDataForTestMapPHPStanTypeToStrings(): Iterator
|
||||
{
|
||||
$constantArrayType = new ConstantArrayType([], [new ConstantStringType('a'), new ConstantStringType('b')]);
|
||||
|
@ -9,7 +9,7 @@ use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\NodeTypeResolver\StaticTypeToStringResolver;
|
||||
use Rector\NodeTypeResolver\StaticTypeMapper;
|
||||
use Rector\PHPUnit\ValueObject\DataProviderClassMethodRecipe;
|
||||
|
||||
final class DataProviderClassMethodFactory
|
||||
@ -20,9 +20,9 @@ final class DataProviderClassMethodFactory
|
||||
private $builderFactory;
|
||||
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeToStringResolver;
|
||||
private $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
@ -31,11 +31,11 @@ final class DataProviderClassMethodFactory
|
||||
|
||||
public function __construct(
|
||||
BuilderFactory $builderFactory,
|
||||
StaticTypeToStringResolver $staticTypeToStringResolver,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
DocBlockManipulator $docBlockManipulator
|
||||
) {
|
||||
$this->builderFactory = $builderFactory;
|
||||
$this->staticTypeToStringResolver = $staticTypeToStringResolver;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ final class DataProviderClassMethodFactory
|
||||
return;
|
||||
}
|
||||
|
||||
$typesAsStrings = $this->staticTypeToStringResolver->resolveTypes([$providedType]);
|
||||
$typesAsStrings = $this->staticTypeMapper->mapPHPStanTypeToStrings($providedType);
|
||||
$this->docBlockManipulator->addReturnTag($classMethod, implode('|', $typesAsStrings));
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\NodeTypeResolver\StaticTypeMapper;
|
||||
use Rector\NodeTypeResolver\StaticTypeToStringResolver;
|
||||
use Rector\PHPUnit\NodeFactory\DataProviderClassMethodFactory;
|
||||
use Rector\PHPUnit\ValueObject\DataProviderClassMethodRecipe;
|
||||
use Rector\PHPUnit\ValueObject\ParamAndArgValueObject;
|
||||
@ -46,11 +45,6 @@ final class ArrayArgumentInTestToDataProviderRector extends AbstractPHPUnitRecto
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
*/
|
||||
private $staticTypeToStringResolver;
|
||||
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
@ -71,13 +65,11 @@ final class ArrayArgumentInTestToDataProviderRector extends AbstractPHPUnitRecto
|
||||
*/
|
||||
public function __construct(
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
StaticTypeToStringResolver $staticTypeToStringResolver,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
DataProviderClassMethodFactory $dataProviderClassMethodFactory,
|
||||
array $configuration = []
|
||||
) {
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->staticTypeToStringResolver = $staticTypeToStringResolver;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->dataProviderClassMethodFactory = $dataProviderClassMethodFactory;
|
||||
$this->configuration = $configuration;
|
||||
@ -234,7 +226,7 @@ CODE_SAMPLE
|
||||
continue;
|
||||
}
|
||||
|
||||
$valueObjectHash = implode('_', $this->staticTypeToStringResolver->resolveObjectType($arrayItemStaticType));
|
||||
$valueObjectHash = implode('_', $this->staticTypeMapper->mapPHPStanTypeToStrings($arrayItemStaticType));
|
||||
|
||||
$itemStaticTypes[$valueObjectHash] = new ArrayType(new MixedType(), $arrayItemStaticType);
|
||||
}
|
||||
@ -351,7 +343,7 @@ CODE_SAMPLE
|
||||
{
|
||||
$uniqueStaticTypes = [];
|
||||
foreach ($itemsStaticTypes as $itemsStaticType) {
|
||||
$uniqueHash = implode('_', $this->staticTypeToStringResolver->resolveObjectType($itemsStaticType));
|
||||
$uniqueHash = implode('_', $this->staticTypeMapper->mapPHPStanTypeToStrings($itemsStaticType));
|
||||
$uniqueHash = md5($uniqueHash);
|
||||
|
||||
$uniqueStaticTypes[$uniqueHash] = $itemsStaticType;
|
||||
|
@ -63,11 +63,11 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isName($node, 'add')) {
|
||||
if (! $this->isName($node->name, 'add')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isType($node, $this->formBuilderType)) {
|
||||
if (! $this->isType($node->var, $this->formBuilderType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,11 @@ final class OptionNameRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
$this->doTestFiles([__DIR__ . '/Fixture/fixture.php.inc', __DIR__ . '/Fixture/fixture2.php.inc']);
|
||||
$this->doTestFiles([
|
||||
// temporary skipped due to chain call type regression in https://github.com/rectorphp/rector/pull/1953
|
||||
// __DIR__ . '/Fixture/fixture.php.inc',
|
||||
__DIR__ . '/Fixture/fixture2.php.inc',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace Rector\TypeDeclaration\TypeInferer;
|
||||
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\NodeTypeResolver\StaticTypeToStringResolver;
|
||||
use Rector\NodeTypeResolver\StaticTypeMapper;
|
||||
use Rector\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\PhpParser\NodeTraverser\CallableNodeTraverser;
|
||||
|
||||
@ -25,9 +25,9 @@ abstract class AbstractTypeInferer
|
||||
protected $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var StaticTypeToStringResolver
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
protected $staticTypeToStringResolver;
|
||||
protected $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @required
|
||||
@ -36,11 +36,11 @@ abstract class AbstractTypeInferer
|
||||
CallableNodeTraverser $callableNodeTraverser,
|
||||
NameResolver $nameResolver,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
StaticTypeToStringResolver $staticTypeToStringResolver
|
||||
StaticTypeMapper $staticTypeMapper
|
||||
): void {
|
||||
$this->callableNodeTraverser = $callableNodeTraverser;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->staticTypeToStringResolver = $staticTypeToStringResolver;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ final class PropertyNodeParamTypeInferer extends AbstractTypeInferer implements
|
||||
if ($propertyStaticTypes[0] instanceof ArrayType) {
|
||||
$itemType = $propertyStaticTypes[0]->getItemType();
|
||||
|
||||
$resolvedType = $this->staticTypeToStringResolver->resolveObjectType($itemType);
|
||||
$resolvedType = $this->staticTypeMapper->mapPHPStanTypeToStrings($itemType);
|
||||
if (isset($resolvedType[0])) {
|
||||
return [$resolvedType[0]];
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ final class AllAssignNodePropertyTypeInferer extends AbstractTypeInferer impleme
|
||||
|
||||
$assignedExprStaticType = new IntersectionType($assignedExprStaticTypes);
|
||||
|
||||
return $this->staticTypeToStringResolver->resolveObjectType($assignedExprStaticType);
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToStrings($assignedExprStaticType);
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
|
@ -81,7 +81,7 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
|
||||
return null;
|
||||
}
|
||||
|
||||
$typesAsStrings = $this->staticTypeToStringResolver->resolveObjectType($paramStaticType);
|
||||
$typesAsStrings = $this->staticTypeMapper->mapPHPStanTypeToStrings($paramStaticType);
|
||||
|
||||
foreach ($typesAsStrings as $i => $typesAsString) {
|
||||
$typesAsStrings[$i] = $this->removePreSlash($typesAsString);
|
||||
|
@ -23,7 +23,7 @@ final class DefaultValuePropertyTypeInferer extends AbstractTypeInferer implemen
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->staticTypeToStringResolver->resolveObjectType($nodeStaticType);
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToStrings($nodeStaticType);
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
|
@ -36,8 +36,11 @@ final class SingleMethodAssignedNodePropertyTypeInferer extends AbstractTypeInfe
|
||||
}
|
||||
|
||||
$nodeStaticType = $this->nodeTypeResolver->getStaticType($assignedNode);
|
||||
if ($nodeStaticType === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$stringTypes = $this->staticTypeToStringResolver->resolveObjectType($nodeStaticType);
|
||||
$stringTypes = $this->staticTypeMapper->mapPHPStanTypeToStrings($nodeStaticType);
|
||||
if ($stringTypes === []) {
|
||||
return [];
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ final class SetterNodeReturnTypeInferer extends AbstractTypeInferer implements R
|
||||
|
||||
$assignedExprStaticType = new IntersectionType($types);
|
||||
|
||||
return $this->staticTypeToStringResolver->resolveObjectType($assignedExprStaticType);
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToStrings($assignedExprStaticType);
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
|
@ -42,7 +42,7 @@ final class FullyQualifiedName
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][]|\Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddArrayReturnDocTypeRector\Source\ValidationResult[][]
|
||||
* @return \Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddArrayReturnDocTypeRector\Source\ValidationResult[][]|string[][]
|
||||
*/
|
||||
public function getValidationErrorMessagesAsStringDataProvider(): array
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ class A {
|
||||
|
||||
class B extends A {
|
||||
/** @return Foo */
|
||||
public function test($value): \Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture\NullableInheritance\Foo {
|
||||
public function test($value): ?\Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture\NullableInheritance\Foo {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\FunctionLike\ReturnTypeDeclarationRector;
|
||||
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
|
||||
final class InheritanceTest extends AbstractRectorTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$parameterProvider = self::$container->get(ParameterProvider::class);
|
||||
$parameterProvider->changeParameter('php_version_features', '7.0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to restore previous version
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$parameterProvider = self::$container->get(ParameterProvider::class);
|
||||
$parameterProvider->changeParameter('php_version_features', '10.0');
|
||||
}
|
||||
|
||||
public function test(): void
|
||||
{
|
||||
$this->doTestFiles([
|
||||
__DIR__ . '/Fixture/nikic/inheritance.php.inc',
|
||||
__DIR__ . '/Fixture/nikic/nullable_inheritance.php.inc',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return ReturnTypeDeclarationRector::class;
|
||||
}
|
||||
}
|
@ -62,16 +62,6 @@ final class ReturnTypeDeclarationRectorTest extends AbstractRectorTestCase
|
||||
$this->doTestFiles($files);
|
||||
}
|
||||
|
||||
public function testInheritance(): void
|
||||
{
|
||||
$files = [
|
||||
__DIR__ . '/Fixture/nikic/inheritance.php.inc',
|
||||
__DIR__ . '/Fixture/nikic/nullable_inheritance.php.inc',
|
||||
];
|
||||
|
||||
$this->doTestFiles($files);
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return ReturnTypeDeclarationRector::class;
|
||||
|
@ -6,6 +6,9 @@ use Closure;
|
||||
use Rector\Exception\DependencyInjection\CallableCollectorException;
|
||||
use ReflectionFunction;
|
||||
|
||||
/**
|
||||
* @deprecated Too much magic and hard to understand without personal explanation (= bad code), use clear "if (x) instead"
|
||||
*/
|
||||
final class CallableCollectorPopulator
|
||||
{
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@ trait NodeTypeResolverTrait
|
||||
|
||||
protected function isStringyType(Node $node): bool
|
||||
{
|
||||
return $this->nodeTypeResolver->isStringyType($node);
|
||||
return $this->nodeTypeResolver->isStringOrUnionStringType($node);
|
||||
}
|
||||
|
||||
protected function isNumberType(Node $node): bool
|
||||
|
Loading…
x
Reference in New Issue
Block a user