Updated Rector to commit 53c6c5fcaf92b3ff40b6f45e476ff981b9028e95

53c6c5fcaf Remove Kind from doc mapper, as used just once (#4234)
This commit is contained in:
Tomas Votruba 2023-06-16 03:34:15 +00:00
parent 708954a81f
commit d793888f8a
70 changed files with 467 additions and 460 deletions

View File

@ -34,7 +34,6 @@ use Rector\Comments\NodeDocBlock\DocBlockUpdater;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\TypeDeclaration\PhpDocParser\ParamPhpDocNodeFactory;
final class PhpDocTypeChanger
@ -116,7 +115,7 @@ final class PhpDocTypeChanger
return;
}
// override existing type
$newPHPStanPhpDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType, TypeKind::PROPERTY);
$newPHPStanPhpDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType);
$currentVarTagValueNode = $phpDocInfo->getVarTagValueNode();
if ($currentVarTagValueNode instanceof VarTagValueNode) {
// only change type
@ -143,7 +142,7 @@ final class PhpDocTypeChanger
return \false;
}
// override existing type
$newPHPStanPhpDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType, TypeKind::RETURN);
$newPHPStanPhpDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType);
$currentReturnTagValueNode = $phpDocInfo->getReturnTagValue();
if ($currentReturnTagValueNode instanceof ReturnTagValueNode) {
// only change type
@ -166,7 +165,7 @@ final class PhpDocTypeChanger
if (!$this->newPhpDocFromPHPStanTypeGuard->isLegal($newType)) {
return;
}
$phpDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType, TypeKind::PARAM);
$phpDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType);
$paramTagValueNode = $phpDocInfo->getParamTagValueByName($paramName);
// override existing type
if ($paramTagValueNode instanceof ParamTagValueNode) {

View File

@ -23,7 +23,6 @@ use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\ValueObject\OldToNewType;
use Rector\PhpDocParser\PhpDocParser\PhpDocNodeVisitor\AbstractPhpDocNodeVisitor;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
@ -105,7 +104,7 @@ final class ClassRenamePhpDocNodeVisitor extends AbstractPhpDocNodeVisitor
if (!$objectType->equals($oldToNewType->getOldType())) {
continue;
}
$newTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($oldToNewType->getNewType(), TypeKind::ANY);
$newTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($oldToNewType->getNewType());
$parentType = $node->getAttribute(PhpDocAttributeKey::PARENT);
if ($parentType instanceof TypeNode) {
// mirror attributes

View File

@ -21,9 +21,8 @@ interface TypeMapperInterface
public function getNodeClass() : string;
/**
* @param TType $type
* @param TypeKind::* $typeKind
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode;
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode;
/**
* @param TType $type
* @param TypeKind::* $typeKind

View File

@ -28,16 +28,13 @@ final class PHPStanStaticTypeMapper
{
$this->typeMappers = $typeMappers;
}
/**
* @param TypeKind::* $typeKind
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
foreach ($this->typeMappers as $typeMapper) {
if (!\is_a($type, $typeMapper->getNodeClass(), \true)) {
continue;
}
return $typeMapper->mapToPHPStanPhpDocTypeNode($type, $typeKind);
return $typeMapper->mapToPHPStanPhpDocTypeNode($type);
}
if ($type->isString()->yes()) {
return new IdentifierTypeNode('string');

View File

@ -36,7 +36,7 @@ final class AccessoryLiteralStringTypeMapper implements TypeMapperInterface
/**
* @param AccessoryLiteralStringType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('string');
}

View File

@ -36,7 +36,7 @@ final class AccessoryNonEmptyStringTypeMapper implements TypeMapperInterface
/**
* @param AccessoryNonEmptyStringType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('string');
}

View File

@ -36,7 +36,7 @@ final class AccessoryNonFalsyStringTypeMapper implements TypeMapperInterface
/**
* @param AccessoryNonFalsyStringType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('string');
}

View File

@ -36,7 +36,7 @@ final class AccessoryNumericStringTypeMapper implements TypeMapperInterface
/**
* @param AccessoryNumericStringType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('string');
}

View File

@ -12,7 +12,6 @@ use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\MixedType;
use PHPStan\Type\NeverType;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
final class ArrayShapeTypeMapper
{
@ -52,7 +51,7 @@ final class ArrayShapeTypeMapper
}
$keyDocTypeNode = new IdentifierTypeNode($keyValue);
$valueType = $constantArrayType->getValueTypes()[$index];
$valueDocTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($valueType, TypeKind::RETURN);
$valueDocTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($valueType);
$arrayShapeItemNodes[] = new ArrayShapeItemNode($keyDocTypeNode, $constantArrayType->isOptionalKey($index), $valueDocTypeNode);
}
return new ArrayShapeNode($arrayShapeItemNodes);

View File

@ -22,7 +22,6 @@ use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
use Rector\BetterPhpDocParser\ValueObject\Type\SpacingAwareArrayTypeNode;
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
use Rector\PHPStanStaticTypeMapper\TypeAnalyzer\UnionTypeCommonTypeNarrower;
use Rector\TypeDeclaration\NodeTypeAnalyzer\DetailedTypeAnalyzer;
@ -84,32 +83,31 @@ final class ArrayTypeMapper implements TypeMapperInterface
return ArrayType::class;
}
/**
* @param TypeKind::* $typeKind
* @param ArrayType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$itemType = $type->getItemType();
if ($itemType instanceof UnionType && !$type instanceof ConstantArrayType) {
return $this->createArrayTypeNodeFromUnionType($itemType, $typeKind);
return $this->createArrayTypeNodeFromUnionType($itemType);
}
if ($type instanceof ConstantArrayType && $typeKind === TypeKind::RETURN) {
if ($type instanceof ConstantArrayType) {
$arrayShapeNode = $this->arrayShapeTypeMapper->mapConstantArrayType($type);
if ($arrayShapeNode instanceof TypeNode) {
return $arrayShapeNode;
}
}
if ($itemType instanceof ArrayType && $this->isGenericArrayCandidate($itemType)) {
return $this->createGenericArrayType($type, $typeKind, \true);
return $this->createGenericArrayType($type, \true);
}
if ($this->isGenericArrayCandidate($type)) {
return $this->createGenericArrayType($type, $typeKind, \true);
return $this->createGenericArrayType($type, \true);
}
$narrowedTypeNode = $this->narrowConstantArrayTypeOfUnionType($type, $itemType, $typeKind);
$narrowedTypeNode = $this->narrowConstantArrayTypeOfUnionType($type, $itemType);
if ($narrowedTypeNode instanceof TypeNode) {
return $narrowedTypeNode;
}
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($itemType, $typeKind);
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($itemType);
return new SpacingAwareArrayTypeNode($itemTypeNode);
}
/**
@ -119,14 +117,11 @@ final class ArrayTypeMapper implements TypeMapperInterface
{
return new Identifier('array');
}
/**
* @param TypeKind::* $typeKind
*/
private function createArrayTypeNodeFromUnionType(UnionType $unionType, string $typeKind) : SpacingAwareArrayTypeNode
private function createArrayTypeNodeFromUnionType(UnionType $unionType) : SpacingAwareArrayTypeNode
{
$unionedArrayType = [];
foreach ($unionType->getTypes() as $unionedType) {
$typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType, $typeKind);
$typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType);
$unionedArrayType[(string) $typeNode] = $typeNode;
}
if (\count($unionedArrayType) > 1) {
@ -166,22 +161,19 @@ final class ArrayTypeMapper implements TypeMapperInterface
}
return \false;
}
/**
* @param TypeKind::* $typeKind
*/
private function createGenericArrayType(ArrayType $arrayType, string $typeKind, bool $withKey = \false) : GenericTypeNode
private function createGenericArrayType(ArrayType $arrayType, bool $withKey = \false) : GenericTypeNode
{
$itemType = $arrayType->getItemType();
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($itemType, $typeKind);
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($itemType);
$identifierTypeNode = new IdentifierTypeNode('array');
// is class-string[] list only
if ($this->isClassStringArrayType($arrayType)) {
$withKey = \false;
}
if ($withKey) {
$keyTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($arrayType->getKeyType(), $typeKind);
$keyTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($arrayType->getKeyType());
if ($itemTypeNode instanceof BracketsAwareUnionTypeNode && $this->isPairClassTooDetailed($itemType)) {
$genericTypes = [$keyTypeNode, $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode(new ClassStringType(), $typeKind)];
$genericTypes = [$keyTypeNode, $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode(new ClassStringType())];
} else {
$genericTypes = [$keyTypeNode, $itemTypeNode];
}
@ -213,35 +205,31 @@ final class ArrayTypeMapper implements TypeMapperInterface
}
return !$arrayType->getItemType() instanceof ArrayType;
}
/**
* @param TypeKind::* $typeKind
*/
private function narrowConstantArrayTypeOfUnionType(ArrayType $arrayType, Type $itemType, string $typeKind) : ?TypeNode
private function narrowConstantArrayTypeOfUnionType(ArrayType $arrayType, Type $itemType) : ?TypeNode
{
if ($arrayType instanceof ConstantArrayType && $itemType instanceof UnionType) {
$narrowedItemType = $this->unionTypeCommonTypeNarrower->narrowToSharedObjectType($itemType);
if ($narrowedItemType instanceof ObjectType) {
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($narrowedItemType, $typeKind);
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($narrowedItemType);
return new SpacingAwareArrayTypeNode($itemTypeNode);
}
$narrowedItemType = $this->unionTypeCommonTypeNarrower->narrowToGenericClassStringType($itemType);
if ($narrowedItemType instanceof GenericClassStringType) {
return $this->createTypeNodeFromGenericClassStringType($narrowedItemType, $typeKind);
return $this->createTypeNodeFromGenericClassStringType($narrowedItemType);
}
}
return null;
}
/**
* @param TypeKind::* $typeKind
* @return \PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode|\PHPStan\PhpDocParser\Ast\Type\GenericTypeNode
*/
private function createTypeNodeFromGenericClassStringType(GenericClassStringType $genericClassStringType, string $typeKind)
private function createTypeNodeFromGenericClassStringType(GenericClassStringType $genericClassStringType)
{
$genericType = $genericClassStringType->getGenericType();
if ($genericType instanceof ObjectType && !$this->reflectionProvider->hasClass($genericType->getClassName())) {
return new IdentifierTypeNode($genericType->getClassName());
}
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($genericClassStringType, $typeKind);
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($genericClassStringType);
return new GenericTypeNode(new IdentifierTypeNode('array'), [$itemTypeNode]);
}
private function isClassStringArrayType(ArrayType $arrayType) : bool

View File

@ -37,7 +37,7 @@ final class BooleanTypeMapper implements TypeMapperInterface
/**
* @param BooleanType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
if ($type instanceof ConstantBooleanType) {
return new IdentifierTypeNode($type->getValue() ? 'true' : 'false');

View File

@ -39,12 +39,11 @@ final class CallableTypeMapper implements TypeMapperInterface
return CallableType::class;
}
/**
* @param TypeKind::* $typeKind
* @param CallableType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$returnTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type->getReturnType(), $typeKind);
$returnTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type->getReturnType());
return new SpacingAwareCallableTypeNode(new IdentifierTypeNode('callable'), [], $returnTypeNode);
}
/**

View File

@ -43,10 +43,10 @@ final class ClassStringTypeMapper implements TypeMapperInterface
/**
* @param ClassStringType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
if ($type instanceof GenericClassStringType) {
return $this->genericClassStringTypeMapper->mapToPHPStanPhpDocTypeNode($type, $typeKind);
return $this->genericClassStringTypeMapper->mapToPHPStanPhpDocTypeNode($type);
}
return new IdentifierTypeNode('class-string');
}

View File

@ -36,11 +36,11 @@ final class ClosureTypeMapper implements TypeMapperInterface
/**
* @param ClosureType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$identifierTypeNode = new IdentifierTypeNode($type->getClassName());
$returnDocTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type->getReturnType(), $typeKind);
$callableTypeParameterNodes = $this->createCallableTypeParameterNodes($type, $typeKind);
$returnDocTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type->getReturnType());
$callableTypeParameterNodes = $this->createCallableTypeParameterNodes($type);
// callable parameters must be of specific type
Assert::allIsInstanceOf($callableTypeParameterNodes, CallableTypeParameterNode::class);
return new SpacingAwareCallableTypeNode($identifierTypeNode, $callableTypeParameterNodes, $returnDocTypeNode);
@ -64,15 +64,14 @@ final class ClosureTypeMapper implements TypeMapperInterface
$this->phpStanStaticTypeMapper = $phpStanStaticTypeMapper;
}
/**
* @param TypeKind::* $typeKind
* @return CallableTypeParameterNode[]
*/
private function createCallableTypeParameterNodes(ClosureType $closureType, string $typeKind) : array
private function createCallableTypeParameterNodes(ClosureType $closureType) : array
{
$callableTypeParameterNodes = [];
foreach ($closureType->getParameters() as $parameterReflection) {
/** @var ParameterReflection $parameterReflection */
$typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($parameterReflection->getType(), $typeKind);
$typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($parameterReflection->getType());
$callableTypeParameterNodes[] = new CallableTypeParameterNode($typeNode, $parameterReflection->passedByReference()->yes(), $parameterReflection->isVariadic(), $parameterReflection->getName() !== '' && $parameterReflection->getName() !== '0' ? '$' . $parameterReflection->getName() : '', $parameterReflection->isOptional());
}
return $callableTypeParameterNodes;

View File

@ -37,12 +37,11 @@ final class ConditionalTypeForParameterMapper implements TypeMapperInterface
}
/**
* @param ConditionalTypeForParameter $type
* @param TypeKind::* $typeKind
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$type = TypeCombinator::union($type->getIf(), $type->getElse());
return $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type, $typeKind);
return $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type);
}
/**
* @param ConditionalTypeForParameter $type

View File

@ -36,7 +36,7 @@ final class FloatTypeMapper implements TypeMapperInterface
/**
* @param FloatType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('float');
}

View File

@ -52,11 +52,11 @@ final class GenericClassStringTypeMapper implements TypeMapperInterface
/**
* @param GenericClassStringType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$attributeAwareIdentifierTypeNode = new IdentifierTypeNode('class-string');
$genericType = $this->resolveGenericObjectType($type);
$genericTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($genericType, $typeKind);
$genericTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($genericType);
return new GenericTypeNode($attributeAwareIdentifierTypeNode, [$genericTypeNode]);
}
/**

View File

@ -33,7 +33,7 @@ final class HasMethodTypeMapper implements TypeMapperInterface
/**
* @param HasMethodType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('object');
}

View File

@ -26,7 +26,7 @@ final class HasOffsetTypeMapper implements TypeMapperInterface
/**
* @param HasOffsetType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new ArrayTypeNode(new IdentifierTypeNode('mixed'));
}

View File

@ -26,7 +26,7 @@ final class HasOffsetValueTypeTypeMapper implements TypeMapperInterface
/**
* @param HasOffsetValueType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new ArrayTypeNode(new IdentifierTypeNode('mixed'));
}

View File

@ -33,7 +33,7 @@ final class HasPropertyTypeMapper implements TypeMapperInterface
/**
* @param HasPropertyType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('object');
}

View File

@ -36,7 +36,7 @@ final class IntegerTypeMapper implements TypeMapperInterface
/**
* @param IntegerType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('int');
}

View File

@ -59,11 +59,11 @@ final class IntersectionTypeMapper implements TypeMapperInterface
/**
* @param IntersectionType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$intersectionTypesNodes = [];
foreach ($type->getTypes() as $intersectionedType) {
$intersectionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($intersectionedType, $typeKind);
$intersectionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($intersectionedType);
}
$intersectionTypesNodes = \array_unique($intersectionTypesNodes);
if (\count($intersectionTypesNodes) === 1) {

View File

@ -41,9 +41,9 @@ final class IterableTypeMapper implements TypeMapperInterface
/**
* @param IterableType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type->getItemType(), $typeKind);
$itemTypeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($type->getItemType());
if ($itemTypeNode instanceof UnionTypeNode) {
return $this->convertUnionArrayTypeNodesToArrayTypeOfUnionTypeNodes($itemTypeNode);
}

View File

@ -36,7 +36,7 @@ final class MixedTypeMapper implements TypeMapperInterface
/**
* @param MixedType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('mixed');
}

View File

@ -9,7 +9,6 @@ use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Type\NeverType;
use PHPStan\Type\Type;
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
/**
* @implements TypeMapperInterface<NeverType>
*/
@ -23,15 +22,11 @@ final class NeverTypeMapper implements TypeMapperInterface
return NeverType::class;
}
/**
* @param TypeKind::* $typeKind
* @param NeverType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
if ($typeKind === TypeKind::RETURN) {
return new IdentifierTypeNode('never');
}
return new IdentifierTypeNode('mixed');
return new IdentifierTypeNode('never');
}
/**
* @param NeverType $type

View File

@ -26,7 +26,7 @@ final class NonEmptyArrayTypeMapper implements TypeMapperInterface
/**
* @param NonEmptyArrayType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new SpacingAwareArrayTypeNode(new IdentifierTypeNode('mixed'));
}

View File

@ -26,7 +26,7 @@ final class NullTypeMapper implements TypeMapperInterface
/**
* @param NullType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('null');
}

View File

@ -15,7 +15,6 @@ use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedGenericObjectType;
@ -43,7 +42,7 @@ final class ObjectTypeMapper implements TypeMapperInterface
/**
* @param ObjectType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
if ($type instanceof ShortenedObjectType) {
return new IdentifierTypeNode($type->getClassName());
@ -52,7 +51,7 @@ final class ObjectTypeMapper implements TypeMapperInterface
return new IdentifierTypeNode($type->getClassName());
}
if ($type instanceof GenericObjectType) {
return $this->mapGenericObjectType($type, $typeKind);
return $this->mapGenericObjectType($type);
}
if ($type instanceof NonExistingObjectType) {
// possibly generic type
@ -97,10 +96,7 @@ final class ObjectTypeMapper implements TypeMapperInterface
{
$this->phpStanStaticTypeMapper = $phpStanStaticTypeMapper;
}
/**
* @param TypeKind::* $typeKind
*/
private function mapGenericObjectType(GenericObjectType $genericObjectType, string $typeKind) : TypeNode
private function mapGenericObjectType(GenericObjectType $genericObjectType) : TypeNode
{
$name = $this->resolveGenericObjectTypeName($genericObjectType);
$identifierTypeNode = new IdentifierTypeNode($name);
@ -110,7 +106,7 @@ final class ObjectTypeMapper implements TypeMapperInterface
if ($name === 'Iterator' && $genericType instanceof MixedType && $key === 0) {
continue;
}
$typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($genericType, $typeKind);
$typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($genericType);
$genericTypeNodes[] = $typeNode;
}
if ($genericTypeNodes === []) {

View File

@ -42,7 +42,7 @@ final class ObjectWithoutClassTypeMapper implements TypeMapperInterface
/**
* @param ObjectWithoutClassType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
if ($type instanceof ParentObjectWithoutClassType) {
return new IdentifierTypeNode('parent');

View File

@ -25,10 +25,9 @@ final class OversizedArrayTypeMapper implements TypeMapperInterface
return OversizedArrayType::class;
}
/**
* @param TypeKind::* $typeKind
* @param OversizedArrayType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new ArrayTypeNode(new IdentifierTypeNode('mixed'));
}

View File

@ -26,7 +26,7 @@ final class ParentStaticTypeMapper implements TypeMapperInterface
/**
* @param ParentStaticType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode(ObjectReference::PARENT);
}

View File

@ -24,7 +24,7 @@ final class ResourceTypeMapper implements TypeMapperInterface
/**
* @param ResourceType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('resource');
}

View File

@ -25,7 +25,7 @@ final class SelfObjectTypeMapper implements TypeMapperInterface
/**
* @param SelfObjectType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('self');
}

View File

@ -41,7 +41,7 @@ final class StaticTypeMapper implements TypeMapperInterface
/**
* @param StaticType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new ThisTypeNode();
}

View File

@ -29,7 +29,7 @@ final class StrictMixedTypeMapper implements TypeMapperInterface
/**
* @param StrictMixedType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode(self::MIXED);
}

View File

@ -36,7 +36,7 @@ final class StringTypeMapper implements TypeMapperInterface
/**
* @param StringType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('string');
}

View File

@ -25,7 +25,7 @@ final class ThisTypeMapper implements TypeMapperInterface
/**
* @param ThisType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new ThisTypeNode();
}

View File

@ -36,7 +36,7 @@ final class TypeWithClassNameTypeMapper implements TypeMapperInterface
/**
* @param TypeWithClassName $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode('string-class');
}

View File

@ -112,7 +112,7 @@ final class UnionTypeMapper implements TypeMapperInterface
/**
* @param UnionType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
$unionTypesNodes = [];
$skipIterable = $this->shouldSkipIterable($type);
@ -120,7 +120,7 @@ final class UnionTypeMapper implements TypeMapperInterface
if ($unionedType instanceof IterableType && $skipIterable) {
continue;
}
$unionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType, $typeKind);
$unionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType);
}
$unionTypesNodes = \array_unique($unionTypesNodes);
return new BracketsAwareUnionTypeNode($unionTypesNodes);

View File

@ -41,7 +41,7 @@ final class VoidTypeMapper implements TypeMapperInterface
/**
* @param VoidType $type
*/
public function mapToPHPStanPhpDocTypeNode(Type $type, string $typeKind) : TypeNode
public function mapToPHPStanPhpDocTypeNode(Type $type) : TypeNode
{
return new IdentifierTypeNode(self::VOID);
}

View File

@ -70,12 +70,9 @@ final class StaticTypeMapper
$this->phpParserNodeMapper = $phpParserNodeMapper;
$this->nodeNameResolver = $nodeNameResolver;
}
/**
* @param TypeKind::* $typeKind
*/
public function mapPHPStanTypeToPHPStanPhpDocTypeNode(Type $phpStanType, string $typeKind) : TypeNode
public function mapPHPStanTypeToPHPStanPhpDocTypeNode(Type $phpStanType) : TypeNode
{
return $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($phpStanType, $typeKind);
return $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($phpStanType);
}
/**
* @param TypeKind::* $typeKind

View File

@ -5,6 +5,7 @@ namespace Rector\CodingStyle\Rector\ClassConst;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassConst;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
@ -16,11 +17,12 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\Privatization\TypeManipulator\TypeNormalizer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @deprecated The doc block types are not reliable, and typed constants are comming to PHP 8.3, use those instead.
*
* @see \Rector\Tests\CodingStyle\Rector\ClassConst\VarConstantCommentRector\VarConstantCommentRectorTest
*/
final class VarConstantCommentRector extends AbstractRector
@ -93,6 +95,10 @@ CODE_SAMPLE
if ($this->typeComparator->isSubtype($constType, $phpDocInfo->getVarType())) {
return null;
}
// already filled
if ($phpDocInfo->getVarTagValueNode() instanceof VarTagValueNode) {
return null;
}
$this->phpDocTypeChanger->changeVarType($node, $phpDocInfo, $constType);
if (!$phpDocInfo->hasChanged()) {
return null;
@ -101,7 +107,7 @@ CODE_SAMPLE
}
private function hasTwoAndMoreGenericClassStringTypes(ConstantArrayType $constantArrayType) : bool
{
$typeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($constantArrayType, TypeKind::RETURN);
$typeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($constantArrayType);
if (!$typeNode instanceof ArrayTypeNode) {
return \false;
}

View File

@ -5,6 +5,12 @@ namespace Rector\Privatization\TypeManipulator;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantFloatType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeTraverser;
final class TypeNormalizer
@ -19,6 +25,15 @@ final class TypeNormalizer
if ($type instanceof ConstantBooleanType) {
return new BooleanType();
}
if ($type instanceof ConstantStringType) {
return new StringType();
}
if ($type instanceof ConstantFloatType) {
return new FloatType();
}
if ($type instanceof ConstantIntegerType) {
return new IntegerType();
}
return $traverseCallback($type, $traverseCallback);
});
}

View File

@ -19,7 +19,6 @@ use Rector\BetterPhpDocParser\ValueObject\Type\SpacingAwareArrayTypeNode;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\Util\StringUtils;
use Rector\PhpDocParser\TypeAnalyzer\ClassMethodReturnTypeResolver;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -109,7 +108,7 @@ CODE_SAMPLE
return null;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$returnExprTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($returnExprType, TypeKind::RETURN);
$returnExprTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($returnExprType);
if ($returnExprTypeNode instanceof GenericTypeNode) {
return null;
}

View File

@ -14,7 +14,6 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\TypeDeclaration\Guard\PhpDocNestedAnnotationGuard;
use Rector\TypeDeclaration\Helper\PhpDocNullableTypeHelper;
use Rector\TypeDeclaration\NodeAnalyzer\ParamAnalyzer;
@ -124,7 +123,7 @@ CODE_SAMPLE
if ($phpDocInfo->hasInvalidTag('@param')) {
return \false;
}
$typeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType, TypeKind::PARAM);
$typeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType);
$paramTagValueNode = $phpDocInfo->getParamTagValueByName($paramName);
// override existing type
if ($paramTagValueNode instanceof ParamTagValueNode) {

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '2694671fccfefc21daf1bd17353cd7d42b4af023';
public const PACKAGE_VERSION = '53c6c5fcaf92b3ff40b6f45e476ff981b9028e95';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-06-14 22:27:39';
public const RELEASE_DATE = '2023-06-16 03:30:30';
/**
* @var int
*/

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit28ff5c4fe249d08f92863955ee115fdc::getLoader();
return ComposerAutoloaderIniteb0064a8b8a25d42770f16ffddb22ddd::getLoader();

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit28ff5c4fe249d08f92863955ee115fdc
class ComposerAutoloaderIniteb0064a8b8a25d42770f16ffddb22ddd
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInit28ff5c4fe249d08f92863955ee115fdc
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit28ff5c4fe249d08f92863955ee115fdc', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderIniteb0064a8b8a25d42770f16ffddb22ddd', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit28ff5c4fe249d08f92863955ee115fdc', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderIniteb0064a8b8a25d42770f16ffddb22ddd', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit28ff5c4fe249d08f92863955ee115fdc::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticIniteb0064a8b8a25d42770f16ffddb22ddd::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit28ff5c4fe249d08f92863955ee115fdc::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticIniteb0064a8b8a25d42770f16ffddb22ddd::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit28ff5c4fe249d08f92863955ee115fdc
class ComposerStaticIniteb0064a8b8a25d42770f16ffddb22ddd
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -3092,9 +3092,9 @@ class ComposerStaticInit28ff5c4fe249d08f92863955ee115fdc
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit28ff5c4fe249d08f92863955ee115fdc::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit28ff5c4fe249d08f92863955ee115fdc::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit28ff5c4fe249d08f92863955ee115fdc::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticIniteb0064a8b8a25d42770f16ffddb22ddd::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticIniteb0064a8b8a25d42770f16ffddb22ddd::$prefixDirsPsr4;
$loader->classMap = ComposerStaticIniteb0064a8b8a25d42770f16ffddb22ddd::$classMap;
}, null, ClassLoader::class);
}

View File

@ -1921,12 +1921,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-doctrine.git",
"reference": "cec9ccd2105529534f66b422d19da3d095008764"
"reference": "f0c1a5f636005a1c5ce8fbf0c57146c96e90f341"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/cec9ccd2105529534f66b422d19da3d095008764",
"reference": "cec9ccd2105529534f66b422d19da3d095008764",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/f0c1a5f636005a1c5ce8fbf0c57146c96e90f341",
"reference": "f0c1a5f636005a1c5ce8fbf0c57146c96e90f341",
"shasum": ""
},
"require": {
@ -1951,7 +1951,7 @@
"tomasvotruba\/type-coverage": "^0.2",
"tomasvotruba\/unused-public": "^0.1"
},
"time": "2023-06-14T04:37:58+00:00",
"time": "2023-06-15T12:43:01+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {
@ -1986,12 +1986,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-downgrade-php.git",
"reference": "ba00f59eafc80698ce25e00678b9cd47cb8b7594"
"reference": "aeea59d14fc29606b196446d2126b0f4d9a707e6"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/ba00f59eafc80698ce25e00678b9cd47cb8b7594",
"reference": "ba00f59eafc80698ce25e00678b9cd47cb8b7594",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/aeea59d14fc29606b196446d2126b0f4d9a707e6",
"reference": "aeea59d14fc29606b196446d2126b0f4d9a707e6",
"shasum": ""
},
"require": {
@ -2015,7 +2015,7 @@
"tomasvotruba\/type-coverage": "^0.2",
"tomasvotruba\/unused-public": "^0.1"
},
"time": "2023-06-14T04:37:44+00:00",
"time": "2023-06-15T13:02:01+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {
@ -2053,12 +2053,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-phpunit.git",
"reference": "2d6ed1024c0d623a2fa3df80c2bca7fceb111b3d"
"reference": "a27c88d6463e2c82fe38c9f6ae4b0af083904a2c"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/2d6ed1024c0d623a2fa3df80c2bca7fceb111b3d",
"reference": "2d6ed1024c0d623a2fa3df80c2bca7fceb111b3d",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/a27c88d6463e2c82fe38c9f6ae4b0af083904a2c",
"reference": "a27c88d6463e2c82fe38c9f6ae4b0af083904a2c",
"shasum": ""
},
"require": {
@ -2087,7 +2087,7 @@
"tomasvotruba\/type-coverage": "^0.1",
"tomasvotruba\/unused-public": "^0.1"
},
"time": "2023-06-13T16:17:56+00:00",
"time": "2023-06-14T16:00:01+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {
@ -2125,12 +2125,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-symfony.git",
"reference": "53b70ec19c1187abb987766652dcfe1704f1a794"
"reference": "f1020f60ac6461092ebd9470ad21a13698899ecb"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/53b70ec19c1187abb987766652dcfe1704f1a794",
"reference": "53b70ec19c1187abb987766652dcfe1704f1a794",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/f1020f60ac6461092ebd9470ad21a13698899ecb",
"reference": "f1020f60ac6461092ebd9470ad21a13698899ecb",
"shasum": ""
},
"require": {
@ -2160,7 +2160,7 @@
"tomasvotruba\/type-coverage": "^0.2",
"tomasvotruba\/unused-public": "^0.1"
},
"time": "2023-06-14T04:37:57+00:00",
"time": "2023-06-15T13:15:20+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
*/
final class GeneratedConfig
{
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main cec9ccd'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main ba00f59'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 2d6ed10'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 53b70ec'));
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main f0c1a5f'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main aeea59d'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main a27c88d'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main f1020f6'));
private function __construct()
{
}

View File

@ -35,12 +35,8 @@ final class ConstructorAssignPropertyAnalyzer
$this->nodeNameResolver = $nodeNameResolver;
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
}
public function resolveConstructorAssign(Property $property) : ?Node
public function resolveConstructorAssign(Class_ $class, Property $property) : ?Node
{
$class = $this->betterNodeFinder->findParentType($property, Class_::class);
if (!$class instanceof Class_) {
return null;
}
$constructClassMethod = $class->getMethod(MethodName::CONSTRUCT);
if (!$constructClassMethod instanceof ClassMethod) {
return null;

View File

@ -8,13 +8,10 @@ use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
use PHPStan\Reflection\Php\PhpPropertyReflection;
use PHPStan\Type\ObjectType;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -35,19 +32,13 @@ final class SetterClassMethodAnalyzer
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(NodeTypeResolver $nodeTypeResolver, NodeNameResolver $nodeNameResolver, ReflectionResolver $reflectionResolver, BetterNodeFinder $betterNodeFinder)
public function __construct(NodeTypeResolver $nodeTypeResolver, NodeNameResolver $nodeNameResolver, ReflectionResolver $reflectionResolver)
{
$this->nodeTypeResolver = $nodeTypeResolver;
$this->nodeNameResolver = $nodeNameResolver;
$this->reflectionResolver = $reflectionResolver;
$this->betterNodeFinder = $betterNodeFinder;
}
public function matchNullalbeClassMethodProperty(ClassMethod $classMethod) : ?Property
public function matchNullalbeClassMethodPropertyName(ClassMethod $classMethod) : ?string
{
$propertyFetch = $this->matchNullalbeClassMethodPropertyFetch($classMethod);
if (!$propertyFetch instanceof PropertyFetch) {
@ -57,12 +48,8 @@ final class SetterClassMethodAnalyzer
if (!$phpPropertyReflection instanceof PhpPropertyReflection) {
return null;
}
$classLike = $this->betterNodeFinder->findParentType($classMethod, ClassLike::class);
if (!$classLike instanceof ClassLike) {
return null;
}
$propertyName = (string) $this->nodeNameResolver->getName($propertyFetch->name);
return $classLike->getProperty($propertyName);
$reflectionProperty = $phpPropertyReflection->getNativeReflection();
return $reflectionProperty->getName();
}
/**
* Matches:

View File

@ -4,9 +4,7 @@ declare (strict_types=1);
namespace Rector\Doctrine\PhpDocParser;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
final class DoctrineDocBlockResolver
{
/**
@ -14,25 +12,11 @@ final class DoctrineDocBlockResolver
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(PhpDocInfoFactory $phpDocInfoFactory, BetterNodeFinder $betterNodeFinder)
public function __construct(PhpDocInfoFactory $phpDocInfoFactory)
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->betterNodeFinder = $betterNodeFinder;
}
public function isInDoctrineEntityClass(ClassMethod $classMethod) : bool
{
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (!$class instanceof Class_) {
return \false;
}
return $this->isDoctrineEntityClass($class);
}
private function isDoctrineEntityClass(Class_ $class) : bool
public function isDoctrineEntityClass(Class_ $class) : bool
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($class);
return $phpDocInfo->hasByAnnotationClasses(['Doctrine\\ORM\\Mapping\\Entity', 'Doctrine\\ORM\\Mapping\\Embeddable']);

View File

@ -6,7 +6,7 @@ namespace Rector\Doctrine\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\ComplexType;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprFalseNode;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
@ -88,50 +88,62 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [ClassMethod::class];
return [Class_::class];
}
/**
* @param ClassMethod $node
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
// is setter in doctrine?
if (!$this->doctrineDocBlockResolver->isInDoctrineEntityClass($node)) {
if (!$this->doctrineDocBlockResolver->isDoctrineEntityClass($node)) {
return null;
}
$property = $this->setterClassMethodAnalyzer->matchNullalbeClassMethodProperty($node);
if (!$property instanceof Property) {
return null;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$doctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass('Doctrine\\ORM\\Mapping\\ManyToOne');
if (!$doctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
return null;
}
$param = $node->params[0];
$paramType = $param->type;
if (!$this->isJoinColumnNullable($phpDocInfo)) {
// remove nullable if has one
if (!$paramType instanceof NullableType) {
return null;
$hasChanged = \false;
foreach ($node->getMethods() as $classMethod) {
$propertyName = $this->setterClassMethodAnalyzer->matchNullalbeClassMethodPropertyName($classMethod);
if ($propertyName === null) {
continue;
}
$param->type = $paramType->type;
$property = $node->getProperty($propertyName);
if (!$property instanceof Property) {
continue;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$doctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass('Doctrine\\ORM\\Mapping\\ManyToOne');
if (!$doctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
continue;
}
$param = $classMethod->params[0];
$paramType = $param->type;
if (!$this->isJoinColumnNullable($phpDocInfo)) {
// remove nullable if has one
if (!$paramType instanceof NullableType) {
continue;
}
$param->type = $paramType->type;
$hasChanged = \true;
continue;
}
// already nullable, lets skip it
if ($paramType instanceof NullableType) {
continue;
}
// we skip complex type as multiple or nullable already
if ($paramType instanceof ComplexType) {
continue;
}
// no type at all, there is nothing we can do
if (!$paramType instanceof Node) {
continue;
}
$param->type = new NullableType($paramType);
$hasChanged = \true;
}
if ($hasChanged) {
return $node;
}
// already nullable, lets skip it
if ($paramType instanceof NullableType) {
return null;
}
// we skip complex type as multiple or nullable already
if ($paramType instanceof ComplexType) {
return null;
}
// no type at all, there is nothing we can do
if (!$paramType instanceof Node) {
return null;
}
$param->type = new NullableType($paramType);
return $node;
return null;
}
private function isJoinColumnNullable(PhpDocInfo $phpDocInfo) : bool
{

View File

@ -5,9 +5,11 @@ namespace Rector\Doctrine\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprTrueNode;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDoc\StringNode;
@ -108,10 +110,10 @@ CODE_SAMPLE
foreach ($node->getProperties() as $property) {
$this->refactorProperty($property, $node);
}
if (!$this->hasChanged) {
return null;
if ($this->hasChanged) {
return $node;
}
return $node;
return null;
}
private function refactorProperty(Property $property, Class_ $class) : void
{
@ -131,9 +133,14 @@ CODE_SAMPLE
if ($typeValue !== 'datetime') {
return;
}
$node = $this->constructorAssignPropertyAnalyzer->resolveConstructorAssign($property);
$constructorAssign = $this->constructorAssignPropertyAnalyzer->resolveConstructorAssign($class, $property);
// skip nullable
$nullableArrayItemNode = $doctrineAnnotationTagValueNode->getValue('nullable');
if ($nullableArrayItemNode instanceof ArrayItemNode && $nullableArrayItemNode->value instanceof ConstExprTrueNode) {
return;
}
// 0. already has default
if ($node instanceof Node) {
if ($constructorAssign instanceof Assign) {
return;
}
// 1. remove default options from database level

View File

@ -5,7 +5,7 @@ namespace Rector\Doctrine\Rector\Property;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
@ -128,10 +128,10 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [Property::class, ClassMethod::class];
return [Property::class, Class_::class];
}
/**
* @param Property|ClassMethod $node
* @param Property|Class_ $node
*/
public function refactor(Node $node) : ?Node
{
@ -152,32 +152,39 @@ CODE_SAMPLE
}
return $this->refactorAttribute($targetEntityExpr, $phpDocInfo, $property);
}
private function refactorClassMethod(ClassMethod $classMethod) : ?ClassMethod
private function refactorClassMethod(Class_ $class) : ?Class_
{
if (!$this->doctrineDocBlockResolver->isInDoctrineEntityClass($classMethod)) {
if (!$this->doctrineDocBlockResolver->isDoctrineEntityClass($class)) {
return null;
}
if (!$classMethod->isPublic()) {
return null;
$hasChanged = \false;
foreach ($class->getMethods() as $classMethod) {
if (!$classMethod->isPublic()) {
continue;
}
$collectionObjectType = $this->resolveCollectionSetterAssignType($class, $classMethod);
if (!$collectionObjectType instanceof Type) {
continue;
}
if (\count($classMethod->params) !== 1) {
continue;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$param = $classMethod->params[0];
if ($param->type instanceof Node) {
continue;
}
/** @var string $parameterName */
$parameterName = $this->getName($param);
$this->phpDocTypeChanger->changeParamType($classMethod, $phpDocInfo, $collectionObjectType, $param, $parameterName);
$hasChanged = \true;
}
$collectionObjectType = $this->resolveCollectionSetterAssignType($classMethod);
if (!$collectionObjectType instanceof Type) {
return null;
if ($hasChanged) {
return $class;
}
if (\count($classMethod->params) !== 1) {
return null;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$param = $classMethod->params[0];
if ($param->type instanceof Node) {
return null;
}
/** @var string $parameterName */
$parameterName = $this->getName($param);
$this->phpDocTypeChanger->changeParamType($classMethod, $phpDocInfo, $collectionObjectType, $param, $parameterName);
return $classMethod;
return null;
}
private function resolveCollectionSetterAssignType(ClassMethod $classMethod) : ?Type
private function resolveCollectionSetterAssignType(Class_ $class, ClassMethod $classMethod) : ?Type
{
$propertyFetches = $this->assignManipulator->resolveAssignsToLocalPropertyFetches($classMethod);
if (\count($propertyFetches) !== 1) {
@ -187,12 +194,8 @@ CODE_SAMPLE
if (!$phpPropertyReflection instanceof PhpPropertyReflection) {
return null;
}
$classLike = $this->betterNodeFinder->findParentType($classMethod, ClassLike::class);
if (!$classLike instanceof ClassLike) {
return null;
}
$propertyName = (string) $this->nodeNameResolver->getName($propertyFetches[0]);
$property = $classLike->getProperty($propertyName);
$property = $class->getProperty($propertyName);
if (!$property instanceof Property) {
return null;
}

View File

@ -6,7 +6,6 @@ namespace Rector\DowngradePhp72\PhpDoc;
use PhpParser\Node\Expr;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\NullType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
@ -80,6 +79,6 @@ final class NativeParamToPhpDocDecorator
return $paramType;
}
// add default null type
return new UnionType([$paramType, new NullType()]);
return TypeCombinator::addNull($paramType);
}
}

View File

@ -4,6 +4,7 @@ declare (strict_types=1);
namespace Rector\DowngradePhp80\Rector\Instanceof_;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\Instanceof_;
use Rector\Core\Rector\AbstractRector;
use Rector\DowngradePhp81\NodeManipulator\ObjectToResourceReturn;
@ -84,10 +85,10 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [Instanceof_::class];
return [BinaryOp::class, Instanceof_::class];
}
/**
* @param Instanceof_ $node
* @param BinaryOp|Instanceof_ $node
*/
public function refactor(Node $node) : ?Node
{

View File

@ -4,7 +4,7 @@ declare (strict_types=1);
namespace Rector\DowngradePhp81\NodeManipulator;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\FuncCall;
@ -15,40 +15,59 @@ use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser;
final class ObjectToResourceReturn
{
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @readonly
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\NodeFactory
*/
private $nodeFactory;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @readonly
* @var \Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
/**
* @readonly
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
*/
private $nodeComparator;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\NodeFactory
* @var string
*/
private $nodeFactory;
public function __construct(BetterNodeFinder $betterNodeFinder, NodeNameResolver $nodeNameResolver, NodeComparator $nodeComparator, NodeFactory $nodeFactory)
private const IS_INSTANCEOF_IN_BINARYOP = 'is_instanceof_in_binaryop';
public function __construct(NodeNameResolver $nodeNameResolver, NodeFactory $nodeFactory, BetterNodeFinder $betterNodeFinder, SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeComparator $nodeComparator)
{
$this->betterNodeFinder = $betterNodeFinder;
$this->nodeNameResolver = $nodeNameResolver;
$this->nodeComparator = $nodeComparator;
$this->nodeFactory = $nodeFactory;
$this->betterNodeFinder = $betterNodeFinder;
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->nodeComparator = $nodeComparator;
}
/**
* @param string[] $collectionObjectToResource
* @param \PhpParser\Node\Expr\BinaryOp|\PhpParser\Node\Expr\Instanceof_ $instanceof
*/
public function refactor(Instanceof_ $instanceof, array $collectionObjectToResource) : ?BooleanOr
public function refactor($instanceof, array $collectionObjectToResource) : ?BooleanOr
{
if ($instanceof instanceof BinaryOp) {
$this->setIsInstanceofInBinaryOpAttribute($instanceof);
return null;
}
if ($instanceof->getAttribute(self::IS_INSTANCEOF_IN_BINARYOP) === \true) {
return null;
}
if (!$instanceof->class instanceof FullyQualified) {
return null;
}
@ -57,34 +76,40 @@ final class ObjectToResourceReturn
if ($singleCollectionObjectToResource !== $className) {
continue;
}
$binaryOp = $this->betterNodeFinder->findParentType($instanceof, BinaryOp::class);
if ($this->hasIsResourceCheck($instanceof->expr, $binaryOp)) {
continue;
}
return new BooleanOr($this->nodeFactory->createFuncCall('is_resource', [$instanceof->expr]), $instanceof);
}
return null;
}
private function hasIsResourceCheck(Expr $expr, ?BinaryOp $binaryOp) : bool
private function setIsInstanceofInBinaryOpAttribute(BinaryOp $binaryOp) : void
{
if ($binaryOp instanceof BinaryOp) {
return (bool) $this->betterNodeFinder->findFirst($binaryOp, function (Node $subNode) use($expr) : bool {
if (!$subNode instanceof FuncCall) {
return \false;
}
if (!$subNode->name instanceof Name) {
return \false;
}
if (!$this->nodeNameResolver->isName($subNode->name, 'is_resource')) {
return \false;
}
$args = $subNode->getArgs();
if (!isset($args[0])) {
return \false;
}
return $this->nodeComparator->areNodesEqual($args[0], $expr);
});
$node = $this->betterNodeFinder->findFirst($binaryOp, function (Node $subNode) : bool {
if (!$subNode instanceof FuncCall) {
return \false;
}
if (!$subNode->name instanceof Name) {
return \false;
}
if (!$this->nodeNameResolver->isName($subNode->name, 'is_resource')) {
return \false;
}
if ($subNode->isFirstClassCallable()) {
return \false;
}
$args = $subNode->getArgs();
return isset($args[0]);
});
if (!$node instanceof FuncCall) {
return;
}
return \false;
/** @var Arg $currentArg */
$currentArg = $node->getArgs()[0];
$currentArgValue = $currentArg->value;
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($binaryOp, function (Node $subNode) use($currentArgValue) : ?Instanceof_ {
if ($subNode instanceof Instanceof_ && $this->nodeComparator->areNodesEqual($currentArgValue, $subNode->expr)) {
$subNode->setAttribute(self::IS_INSTANCEOF_IN_BINARYOP, \true);
return $subNode;
}
return null;
});
}
}

View File

@ -5,6 +5,7 @@ namespace Rector\DowngradePhp81\Rector\Instanceof_;
use finfo;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\Instanceof_;
use Rector\Core\Rector\AbstractRector;
use Rector\DowngradePhp81\NodeManipulator\ObjectToResourceReturn;
@ -75,10 +76,10 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [Instanceof_::class];
return [BinaryOp::class, Instanceof_::class];
}
/**
* @param Instanceof_ $node
* @param BinaryOp|Instanceof_ $node
*/
public function refactor(Node $node) : ?Node
{

View File

@ -9,12 +9,10 @@ use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Interface_;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ThisType;
use PHPStan\Type\Type;
@ -23,7 +21,6 @@ use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeNameResolver\NodeNameResolver;
@ -58,11 +55,6 @@ final class PhpDocFromTypeDeclarationDecorator
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
*/
private $phpDocTypeChanger;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @readonly
* @var \Rector\PhpAttribute\NodeFactory\PhpAttributeGroupFactory
@ -87,13 +79,12 @@ final class PhpDocFromTypeDeclarationDecorator
* @var ClassMethodWillChangeReturnType[]
*/
private $classMethodWillChangeReturnTypes = [];
public function __construct(StaticTypeMapper $staticTypeMapper, PhpDocInfoFactory $phpDocInfoFactory, NodeNameResolver $nodeNameResolver, PhpDocTypeChanger $phpDocTypeChanger, BetterNodeFinder $betterNodeFinder, PhpAttributeGroupFactory $phpAttributeGroupFactory, ReflectionResolver $reflectionResolver, PhpAttributeAnalyzer $phpAttributeAnalyzer, PhpVersionProvider $phpVersionProvider)
public function __construct(StaticTypeMapper $staticTypeMapper, PhpDocInfoFactory $phpDocInfoFactory, NodeNameResolver $nodeNameResolver, PhpDocTypeChanger $phpDocTypeChanger, PhpAttributeGroupFactory $phpAttributeGroupFactory, ReflectionResolver $reflectionResolver, PhpAttributeAnalyzer $phpAttributeAnalyzer, PhpVersionProvider $phpVersionProvider)
{
$this->staticTypeMapper = $staticTypeMapper;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->nodeNameResolver = $nodeNameResolver;
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->betterNodeFinder = $betterNodeFinder;
$this->phpAttributeGroupFactory = $phpAttributeGroupFactory;
$this->reflectionResolver = $reflectionResolver;
$this->phpAttributeAnalyzer = $phpAttributeAnalyzer;
@ -125,11 +116,11 @@ final class PhpDocFromTypeDeclarationDecorator
if (!$functionLike instanceof ClassMethod) {
return;
}
$classLike = $this->betterNodeFinder->findParentByTypes($functionLike, [Class_::class, Interface_::class]);
if (!$classLike instanceof ClassLike) {
$classReflection = $this->reflectionResolver->resolveClassReflection($functionLike);
if (!$classReflection instanceof ClassReflection || !$classReflection->isInterface() && !$classReflection->isClass()) {
return;
}
if (!$this->isRequireReturnTypeWillChange($classLike, $functionLike)) {
if (!$this->isRequireReturnTypeWillChange($classReflection, $functionLike)) {
return;
}
$functionLike->attrGroups[] = $this->phpAttributeGroupFactory->createFromClass('ReturnTypeWillChange');
@ -187,17 +178,12 @@ final class PhpDocFromTypeDeclarationDecorator
$this->decorateReturn($functionLike);
return \true;
}
private function isRequireReturnTypeWillChange(ClassLike $classLike, ClassMethod $classMethod) : bool
private function isRequireReturnTypeWillChange(ClassReflection $classReflection, ClassMethod $classMethod) : bool
{
$className = $this->nodeNameResolver->getName($classLike);
if (!\is_string($className)) {
return \false;
}
$methodName = $classMethod->name->toString();
$classReflection = $this->reflectionResolver->resolveClassAndAnonymousClass($classLike);
if ($classReflection->isAnonymous()) {
return \false;
}
$methodName = $classMethod->name->toString();
// support for will return change type in case of removed return doc type
// @see https://php.watch/versions/8.1/ReturnTypeWillChange
foreach ($this->classMethodWillChangeReturnTypes as $classMethodWillChangeReturnType) {

View File

@ -232,7 +232,7 @@ CODE_SAMPLE
/** @var string $paramName */
$paramName = $this->getName($paramAndArg->getVariable());
/** @var TypeNode $staticTypeNode */
$staticTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($staticType, TypeKind::PARAM);
$staticTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($staticType);
$paramTagValueNode = $this->createParamTagNode($paramName, $staticTypeNode);
$phpDocInfo->addTagValueNode($paramTagValueNode);
}

View File

@ -46,48 +46,51 @@ final class AddRouteAnnotationRector extends AbstractRector
}
public function getNodeTypes() : array
{
return [ClassMethod::class];
return [Class_::class];
}
/**
* @param ClassMethod $node
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
// only public methods can be controller routes
if (!$node->isPublic()) {
return null;
}
if ($node->isStatic()) {
return null;
}
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (!$class instanceof Class_) {
return null;
}
if ($this->symfonyRoutesProvider->provide() === []) {
return null;
}
$controllerReference = $this->resolveControllerReference($class, $node);
if (!$controllerReference) {
return null;
$hasChanged = \false;
foreach ($node->getMethods() as $classMethod) {
// only public methods can be controller routes
if (!$classMethod->isPublic()) {
continue;
}
if ($classMethod->isStatic()) {
continue;
}
$controllerReference = $this->resolveControllerReference($node, $classMethod);
if (!$controllerReference) {
continue;
}
// is there a route for this annotation?
$symfonyRouteMetadatas = $this->matchSymfonyRouteMetadataByControllerReference($controllerReference);
if ($symfonyRouteMetadatas === []) {
continue;
}
// skip if already has an annotation
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$doctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass(SymfonyAnnotation::ROUTE);
if ($doctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
continue;
}
foreach ($symfonyRouteMetadatas as $symfonyRouteMetadata) {
$items = $this->createRouteItems($symfonyRouteMetadata);
$symfonyRouteTagValueNode = $this->symfonyRouteTagValueNodeFactory->createFromItems($items);
$phpDocInfo->addTagValueNode($symfonyRouteTagValueNode);
}
$hasChanged = \true;
}
// is there a route for this annotation?
$symfonyRouteMetadatas = $this->matchSymfonyRouteMetadataByControllerReference($controllerReference);
if ($symfonyRouteMetadatas === []) {
return null;
if ($hasChanged) {
return $node;
}
// skip if already has an annotation
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$doctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass(SymfonyAnnotation::ROUTE);
if ($doctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
return null;
}
foreach ($symfonyRouteMetadatas as $symfonyRouteMetadata) {
$items = $this->createRouteItems($symfonyRouteMetadata);
$symfonyRouteTagValueNode = $this->symfonyRouteTagValueNodeFactory->createFromItems($items);
$phpDocInfo->addTagValueNode($symfonyRouteTagValueNode);
}
return $node;
return null;
}
public function getRuleDefinition() : RuleDefinition
{

View File

@ -81,37 +81,39 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [ClassMethod::class];
return [Class_::class];
}
/**
* @param ClassMethod $node
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isClassAndMethodMatch($node)) {
return null;
$hasChanged = \false;
foreach ($node->getMethods() as $classMethod) {
if (!$this->isClassAndMethodMatch($node, $classMethod)) {
continue;
}
$this->traverseNodesWithCallable((array) $classMethod->stmts, function (Node $node) use(&$hasChanged) : ?Node {
if (!$node instanceof Return_) {
return null;
}
if (!$node->expr instanceof Expr) {
return null;
}
if (!$node->expr instanceof String_) {
return null;
}
$this->replaceStringWIthFormTypeClassConstIfFound($node->expr->value, $node, $hasChanged);
return $node;
});
}
$this->traverseNodesWithCallable((array) $node->stmts, function (Node $node) : ?Node {
if (!$node instanceof Return_) {
return null;
}
if (!$node->expr instanceof Expr) {
return null;
}
if (!$node->expr instanceof String_) {
return null;
}
$this->replaceStringWIthFormTypeClassConstIfFound($node->expr->value, $node);
if ($hasChanged) {
return $node;
});
}
return null;
}
private function isClassAndMethodMatch(ClassMethod $classMethod) : bool
private function isClassAndMethodMatch(Class_ $class, ClassMethod $classMethod) : bool
{
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (!$class instanceof Class_) {
return \false;
}
if ($this->isName($classMethod->name, 'getParent')) {
return $this->isObjectType($class, new ObjectType('Symfony\\Component\\Form\\AbstractType'));
}
@ -120,12 +122,13 @@ CODE_SAMPLE
}
return \false;
}
private function replaceStringWIthFormTypeClassConstIfFound(string $stringValue, Return_ $return) : void
private function replaceStringWIthFormTypeClassConstIfFound(string $stringValue, Return_ $return, bool &$hasChanged) : void
{
$formClass = $this->formTypeStringToTypeProvider->matchClassForNameWithPrefix($stringValue);
if ($formClass === null) {
return;
}
$return->expr = $this->nodeFactory->createClassConstReference($formClass);
$hasChanged = \true;
}
}

View File

@ -5,7 +5,6 @@ namespace Rector\Symfony\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDoc\StringNode;
@ -77,45 +76,48 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [ClassMethod::class];
return [ClassLike::class];
}
/**
* @param ClassMethod $node
* @param ClassLike $node
*/
public function refactor(Node $node) : ?Node
{
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
if (!$classLike instanceof ClassLike) {
return null;
$hasChanged = \false;
foreach ($node->getMethods() as $classMethod) {
if (!$classMethod->isPublic()) {
continue;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$sensioDoctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass(SensioAttribute::METHOD);
if (!$sensioDoctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
continue;
}
$symfonyDoctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass(SymfonyAnnotation::ROUTE);
if (!$symfonyDoctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
continue;
}
$sensioMethods = $this->resolveMethods($sensioDoctrineAnnotationTagValueNode);
if ($sensioMethods === null) {
continue;
}
if (\is_string($sensioMethods) || $sensioMethods instanceof StringNode) {
$sensioMethods = new CurlyListNode([new ArrayItemNode($sensioMethods)]);
}
$symfonyMethodsArrayItemNode = $symfonyDoctrineAnnotationTagValueNode->getValue('methods');
// value is already filled, do not enter anything
if ($symfonyMethodsArrayItemNode instanceof ArrayItemNode) {
continue;
}
$symfonyDoctrineAnnotationTagValueNode->values[] = new ArrayItemNode($sensioMethods, 'methods');
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $sensioDoctrineAnnotationTagValueNode);
$this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo);
$hasChanged = \true;
}
if (!$node->isPublic()) {
return null;
if ($hasChanged) {
return $node;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$sensioDoctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass(SensioAttribute::METHOD);
if (!$sensioDoctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
return null;
}
$symfonyDoctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass(SymfonyAnnotation::ROUTE);
if (!$symfonyDoctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
return null;
}
$sensioMethods = $this->resolveMethods($sensioDoctrineAnnotationTagValueNode);
if ($sensioMethods === null) {
return null;
}
if (\is_string($sensioMethods) || $sensioMethods instanceof StringNode) {
$sensioMethods = new CurlyListNode([new ArrayItemNode($sensioMethods)]);
}
$symfonyMethodsArrayItemNode = $symfonyDoctrineAnnotationTagValueNode->getValue('methods');
// value is already filled, do not enter anything
if ($symfonyMethodsArrayItemNode instanceof ArrayItemNode) {
return null;
}
$symfonyDoctrineAnnotationTagValueNode->values[] = new ArrayItemNode($sensioMethods, 'methods');
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $sensioDoctrineAnnotationTagValueNode);
$this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo);
return $node;
return null;
}
/**
* @return string|string[]|null|CurlyListNode|StringNode

View File

@ -34,41 +34,44 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
return [Class_::class];
}
/**
* @param MethodCall $node
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
if ($this->shouldSkip($node)) {
return null;
$hasChanged = \false;
$this->traverseNodesWithCallable($node->getMethods(), function (Node $subNode) use($node, &$hasChanged) {
if (!$subNode instanceof MethodCall) {
return null;
}
if (!$this->isName($subNode->name, 'createMessage')) {
return null;
}
// If there is no property with a SwiftMailer type we should skip this class
$swiftMailerProperty = $this->getSwiftMailerProperty($node);
if (!$swiftMailerProperty instanceof Property) {
return null;
}
$var = $subNode->var;
if (!$var instanceof PropertyFetch) {
return null;
}
$propertyName = $this->getName($swiftMailerProperty);
if (!$this->isName($var, $propertyName)) {
return null;
}
$hasChanged = \true;
return new New_(new FullyQualified('Symfony\\Component\\Mime\\Email'));
});
if ($hasChanged) {
return $node;
}
return new New_(new FullyQualified('Symfony\\Component\\Mime\\Email'));
return null;
}
private function shouldSkip(MethodCall $methodCall) : bool
private function getSwiftMailerProperty(Class_ $class) : ?Property
{
if (!$this->isName($methodCall->name, 'createMessage')) {
return \true;
}
// If there is no property with a SwiftMailer type we should skip this class
$swiftMailerProperty = $this->getSwiftMailerProperty($methodCall);
if (!$swiftMailerProperty instanceof Property) {
return \true;
}
$var = $methodCall->var;
if (!$var instanceof PropertyFetch) {
return \true;
}
$propertyName = $this->getName($swiftMailerProperty);
return !$this->isName($var, $propertyName);
}
private function getSwiftMailerProperty(MethodCall $methodCall) : ?Property
{
$class = $this->betterNodeFinder->findParentType($methodCall, Class_::class);
if (!$class instanceof Class_) {
return null;
}
$properties = $class->getProperties();
foreach ($properties as $property) {
$propertyType = $this->nodeTypeResolver->getType($property);

View File

@ -85,44 +85,54 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [Return_::class];
return [ClassMethod::class];
}
/**
* @param Return_ $node
* @param ClassMethod $node
*/
public function refactor(Node $node) : ?Node
{
if (!$node->expr instanceof Expr) {
if ($node->stmts === null) {
return null;
}
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
if (!$classReflection instanceof ClassReflection) {
if ($this->shouldSkip($node)) {
return null;
}
$hasChanged = \false;
foreach ($node->stmts as $stmt) {
if (!$stmt instanceof Return_ || !$stmt->expr instanceof Expr) {
continue;
}
$this->traverseNodesWithCallable($stmt->expr, function (Node $node) use(&$hasChanged) : ?Node {
if (!$node instanceof ArrayItem) {
return null;
}
if (!$node->value instanceof New_) {
return null;
}
$newObjectType = $this->nodeTypeResolver->getType($node->value);
$this->processArrayItem($node, $newObjectType, $hasChanged);
return $node;
});
break;
}
if ($hasChanged) {
return $node;
}
return null;
}
private function shouldSkip(ClassMethod $classMethod) : bool
{
$classReflection = $this->reflectionResolver->resolveClassReflection($classMethod);
if (!$classReflection instanceof ClassReflection) {
return \true;
}
if (!$classReflection->isSubclassOf('Twig_Extension')) {
return null;
return \true;
}
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
if (!$classMethod instanceof ClassMethod) {
return null;
}
if (!$this->nodeNameResolver->isNames($classMethod, ['getFunctions', 'getFilters'])) {
return null;
}
$this->traverseNodesWithCallable($node->expr, function (Node $node) : ?Node {
if (!$node instanceof ArrayItem) {
return null;
}
if (!$node->value instanceof New_) {
return null;
}
$newObjectType = $this->nodeTypeResolver->getType($node->value);
$this->processArrayItem($node, $newObjectType);
return $node;
});
return $node;
return !$this->nodeNameResolver->isNames($classMethod, ['getFunctions', 'getFilters']);
}
private function processArrayItem(ArrayItem $arrayItem, Type $newNodeType) : void
private function processArrayItem(ArrayItem $arrayItem, Type $newNodeType, bool &$hasChanged) : void
{
foreach (self::OLD_TO_NEW_CLASSES as $oldClass => $newClass) {
$oldClassObjectType = new ObjectType($oldClass);
@ -141,6 +151,7 @@ CODE_SAMPLE
$arrayItem->value->class = new FullyQualified($newClass);
$oldArguments = $arrayItem->value->getArgs();
$this->decorateArrayItem($arrayItem, $oldArguments, $filterName);
$hasChanged = \true;
break;
}
}