mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-28 21:53:31 +00:00
Prevent UnionTypes rule from removing literal value scalar types (#1666)
This commit is contained in:
parent
fda8d1af45
commit
0947481ee6
|
@ -12,6 +12,7 @@ use PHPStan\Reflection\ClassReflection;
|
|||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\BooleanType;
|
||||
use PHPStan\Type\Constant\ConstantBooleanType;
|
||||
use PHPStan\Type\ConstantScalarType;
|
||||
use PHPStan\Type\Generic\GenericClassStringType;
|
||||
use PHPStan\Type\IntegerType;
|
||||
use PHPStan\Type\MixedType;
|
||||
|
@ -103,18 +104,11 @@ final class TypeComparator
|
|||
return false;
|
||||
}
|
||||
|
||||
// special case for non-final $this/self compare; in case of interface/abstract class, it can be another $this
|
||||
if ($phpStanDocType instanceof ThisType && $phpParserNodeType instanceof ThisType) {
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if ($scope instanceof Scope) {
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection instanceof ClassReflection) {
|
||||
return $classReflection->isFinal();
|
||||
}
|
||||
}
|
||||
if ($this->areTypesSameWithLiteralTypeInPhpDoc($areDifferentScalarTypes, $phpStanDocType, $phpParserNodeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return $this->isThisTypeInFinalClass($phpStanDocType, $phpParserNodeType, $node);
|
||||
}
|
||||
|
||||
public function isSubtype(Type $checkedType, Type $mainType): bool
|
||||
|
@ -264,4 +258,31 @@ final class TypeComparator
|
|||
&& $phpParserNodeType instanceof ThisType
|
||||
&& $phpStanDocTypeNode->getAttribute(PhpDocAttributeKey::PARENT) instanceof ParamTagValueNode;
|
||||
}
|
||||
|
||||
private function areTypesSameWithLiteralTypeInPhpDoc(
|
||||
bool $areDifferentScalarTypes,
|
||||
Type $phpStanDocType,
|
||||
Type $phpParserNodeType
|
||||
): bool
|
||||
{
|
||||
return $areDifferentScalarTypes
|
||||
&& $phpStanDocType instanceof ConstantScalarType
|
||||
&& $phpParserNodeType->isSuperTypeOf($phpStanDocType)->yes();
|
||||
}
|
||||
|
||||
private function isThisTypeInFinalClass(Type $phpStanDocType, Type $phpParserNodeType, Node $node) : bool
|
||||
{
|
||||
// special case for non-final $this/self compare; in case of interface/abstract class, it can be another $this
|
||||
if ($phpStanDocType instanceof ThisType && $phpParserNodeType instanceof ThisType) {
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if ($scope instanceof Scope) {
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection instanceof ClassReflection) {
|
||||
return $classReflection->isFinal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Fixture;
|
||||
|
||||
final class SkipLiteralValueStringUnionType
|
||||
{
|
||||
/**
|
||||
* @param 'a' $message
|
||||
*/
|
||||
private function getMessage(string $message): string
|
||||
{
|
||||
return $message;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user