mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-22 00:12:29 +02:00
Updated Rector to commit 53c6c5fcaf92b3ff40b6f45e476ff981b9028e95
53c6c5fcaf
Remove Kind from doc mapper, as used just once (#4234)
This commit is contained in:
parent
708954a81f
commit
d793888f8a
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
|
@ -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);
|
||||
}
|
||||
/**
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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]);
|
||||
}
|
||||
/**
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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'));
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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 === []) {
|
||||
|
@ -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');
|
||||
|
@ -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'));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
2
vendor/autoload.php
vendored
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit28ff5c4fe249d08f92863955ee115fdc::getLoader();
|
||||
return ComposerAutoloaderIniteb0064a8b8a25d42770f16ffddb22ddd::getLoader();
|
||||
|
10
vendor/composer/autoload_real.php
vendored
10
vendor/composer/autoload_real.php
vendored
@ -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;
|
||||
|
8
vendor/composer/autoload_static.php
vendored
8
vendor/composer/autoload_static.php
vendored
@ -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);
|
||||
}
|
||||
|
32
vendor/composer/installed.json
vendored
32
vendor/composer/installed.json
vendored
@ -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": {
|
||||
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
@ -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()
|
||||
{
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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']);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user