mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-14 15:12:23 +00:00
[PHP 7.4] Add id tag support + remove default array on collection
This commit is contained in:
parent
1d11fa00b5
commit
35ef3a0217
|
@ -36,6 +36,16 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
|
|||
*/
|
||||
protected $orderedVisibleItems;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $hasOpeningBracket = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $hasClosingBracket = false;
|
||||
|
||||
/**
|
||||
* @param mixed[] $item
|
||||
*/
|
||||
|
@ -145,5 +155,8 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
|
|||
|
||||
$this->hasNewlineAfterOpening = (bool) Strings::match($originalContent, '#^(\(\s+|\n)#m');
|
||||
$this->hasNewlineBeforeClosing = (bool) Strings::match($originalContent, '#(\s+\)|\n(\s+)?)$#m');
|
||||
|
||||
$this->hasOpeningBracket = (bool) Strings::match($originalContent, '#^\(#');
|
||||
$this->hasClosingBracket = (bool) Strings::match($originalContent, '#\)$#');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,24 @@ use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
|
|||
|
||||
final class IdTagValueNode extends AbstractDoctrineTagValueNode
|
||||
{
|
||||
public function __construct(?string $annotationContent = null)
|
||||
{
|
||||
$this->resolveOriginalContentSpacingAndOrder($annotationContent);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '';
|
||||
$content = '';
|
||||
|
||||
if ($this->hasOpeningBracket) {
|
||||
$content .= '(';
|
||||
}
|
||||
|
||||
if ($this->hasClosingBracket) {
|
||||
$content .= ')';
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function getShortName(): string
|
||||
|
|
|
@ -20,6 +20,8 @@ final class IdPhpDocNodeFactory extends AbstractPhpDocNodeFactory
|
|||
|
||||
public function createFromNodeAndTokens(Node $node, TokenIterator $tokenIterator): ?PhpDocTagValueNode
|
||||
{
|
||||
return new IdTagValueNode();
|
||||
$annotationContent = $this->resolveContentFromTokenIterator($tokenIterator);
|
||||
|
||||
return new IdTagValueNode($annotationContent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ final class IntersectionTypeMapper implements TypeMapperInterface
|
|||
{
|
||||
$intersectionTypesNodes = [];
|
||||
|
||||
foreach ($type->getTypes() as $unionedType) {
|
||||
$intersectionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType);
|
||||
foreach ($type->getTypes() as $intersectionedType) {
|
||||
$intersectionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($intersectionedType);
|
||||
}
|
||||
|
||||
$intersectionTypesNodes = array_unique($intersectionTypesNodes);
|
||||
|
|
|
@ -121,6 +121,7 @@ PHP
|
|||
}
|
||||
|
||||
$this->removeVarPhpTagValueNodeIfNotComment($node, $varType);
|
||||
$this->removeDefaultValueForDoctrineCollection($node, $varType);
|
||||
|
||||
$node->type = $propertyTypeNode;
|
||||
|
||||
|
@ -181,4 +182,14 @@ PHP
|
|||
{
|
||||
return $varTagValueNode->type instanceof ArrayTypeNode;
|
||||
}
|
||||
|
||||
private function removeDefaultValueForDoctrineCollection(Property $property, Type $varType): void
|
||||
{
|
||||
if (! $this->doctrineTypeAnalyzer->isDoctrineCollectionWithIterableUnionType($varType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$onlyProperty = $property->props[0];
|
||||
$onlyProperty->default = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Pehapkari\Training\Entity\TrainingTerm;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class DoctrineCollectionWithDefaultArray
|
||||
{
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="Pehapkari\Training\Entity\TrainingTerm", mappedBy="training")
|
||||
* @var TrainingTerm[]|Collection
|
||||
*/
|
||||
private $trainingTerms = [];
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Pehapkari\Training\Entity\TrainingTerm;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class DoctrineCollectionWithDefaultArray
|
||||
{
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="Pehapkari\Training\Entity\TrainingTerm", mappedBy="training")
|
||||
* @var TrainingTerm[]|Collection
|
||||
*/
|
||||
private \Doctrine\Common\Collections\Collection $trainingTerms;
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class DoctrineId
|
||||
{
|
||||
/**
|
||||
* @ORM\Id()
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class DoctrineId
|
||||
{
|
||||
/**
|
||||
* @ORM\Id()
|
||||
*/
|
||||
private int $id;
|
||||
}
|
||||
|
||||
?>
|
|
@ -10,6 +10,7 @@ use PHPStan\Type\NullType;
|
|||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\VoidType;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||
use Rector\PHPStanStaticTypeMapper\DoctrineTypeAnalyzer;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\PropertyTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer\DefaultValuePropertyTypeInferer;
|
||||
|
||||
|
@ -30,17 +31,24 @@ final class PropertyTypeInferer extends AbstractPriorityAwareTypeInferer
|
|||
*/
|
||||
private $typeFactory;
|
||||
|
||||
/**
|
||||
* @var DoctrineTypeAnalyzer
|
||||
*/
|
||||
private $doctrineTypeAnalyzer;
|
||||
|
||||
/**
|
||||
* @param PropertyTypeInfererInterface[] $propertyTypeInferers
|
||||
*/
|
||||
public function __construct(
|
||||
array $propertyTypeInferers,
|
||||
DefaultValuePropertyTypeInferer $defaultValuePropertyTypeInferer,
|
||||
TypeFactory $typeFactory
|
||||
TypeFactory $typeFactory,
|
||||
DoctrineTypeAnalyzer $doctrineTypeAnalyzer
|
||||
) {
|
||||
$this->propertyTypeInferers = $this->sortTypeInferersByPriority($propertyTypeInferers);
|
||||
$this->defaultValuePropertyTypeInferer = $defaultValuePropertyTypeInferer;
|
||||
$this->typeFactory = $typeFactory;
|
||||
$this->doctrineTypeAnalyzer = $doctrineTypeAnalyzer;
|
||||
}
|
||||
|
||||
public function inferProperty(Property $property): Type
|
||||
|
@ -53,7 +61,7 @@ final class PropertyTypeInferer extends AbstractPriorityAwareTypeInferer
|
|||
|
||||
// default value type must be added to each resolved type
|
||||
$defaultValueType = $this->defaultValuePropertyTypeInferer->inferProperty($property);
|
||||
if (! $defaultValueType instanceof MixedType) {
|
||||
if ($this->shouldUnionWithDefaultValue($defaultValueType, $type)) {
|
||||
return $this->unionWithDefaultValueType($type, $defaultValueType);
|
||||
}
|
||||
|
||||
|
@ -73,4 +81,13 @@ final class PropertyTypeInferer extends AbstractPriorityAwareTypeInferer
|
|||
$types = [$type, $defaultValueType];
|
||||
return $this->typeFactory->createMixedPassedOrUnionType($types);
|
||||
}
|
||||
|
||||
private function shouldUnionWithDefaultValue(Type $defaultValueType, Type $type): bool
|
||||
{
|
||||
if ($defaultValueType instanceof MixedType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! $this->doctrineTypeAnalyzer->isDoctrineCollectionWithIterableUnionType($type);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user