mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-21 07:52:01 +02:00
Updated Rector to commit 22915933d05f2a3e38355cd150ec67401a0fe3b9
22915933d0
[automated] Apply Coding Standard (#6627)
This commit is contained in:
parent
0aa5d110fd
commit
b40bc10c7c
8
vendor/composer/installed.json
vendored
8
vendor/composer/installed.json
vendored
@ -1691,12 +1691,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/rectorphp\/rector-doctrine.git",
|
||||
"reference": "1523ce5841f90a9b76c454410d7f6495640f5248"
|
||||
"reference": "f740789641b7a6f7e58397a88725a73ca1402d61"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/1523ce5841f90a9b76c454410d7f6495640f5248",
|
||||
"reference": "1523ce5841f90a9b76c454410d7f6495640f5248",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/f740789641b7a6f7e58397a88725a73ca1402d61",
|
||||
"reference": "f740789641b7a6f7e58397a88725a73ca1402d61",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1719,7 +1719,7 @@
|
||||
"tomasvotruba\/class-leak": "^2.0",
|
||||
"tracy\/tracy": "^2.10"
|
||||
},
|
||||
"time": "2024-12-21T00:29:21+00:00",
|
||||
"time": "2024-12-24T01:21:32+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/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 1523ce5'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 183795c'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main bd24ae1'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 29a1abf'));
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main f740789'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 183795c'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main bd24ae1'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 29a1abf'));
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ CODE_SAMPLE
|
||||
}
|
||||
// update docblock with known collection type
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
|
||||
$newVarType = $this->collectionTypeFactory->createType($collectionObjectType, $this->collectionTypeResolver->hasIndexBy($property));
|
||||
$newVarType = $this->collectionTypeFactory->createType($collectionObjectType, $this->collectionTypeResolver->hasIndexBy($property), $property);
|
||||
$this->phpDocTypeChanger->changeReturnType($classMethod, $phpDocInfo, $newVarType);
|
||||
$hasChanged = \true;
|
||||
}
|
||||
|
@ -197,14 +197,14 @@ CODE_SAMPLE
|
||||
if (!$collectionObjectType instanceof FullyQualifiedObjectType) {
|
||||
return null;
|
||||
}
|
||||
$newVarType = $this->collectionTypeFactory->createType($collectionObjectType, $this->collectionTypeResolver->hasIndexBy($property));
|
||||
$newVarType = $this->collectionTypeFactory->createType($collectionObjectType, $this->collectionTypeResolver->hasIndexBy($property), $property);
|
||||
$this->phpDocTypeChanger->changeVarType($property, $phpDocInfo, $newVarType);
|
||||
} else {
|
||||
$collectionObjectType = $this->collectionTypeResolver->resolveFromToManyProperty($property);
|
||||
if (!$collectionObjectType instanceof FullyQualifiedObjectType) {
|
||||
return null;
|
||||
}
|
||||
$newVarType = $this->collectionTypeFactory->createType($collectionObjectType, $this->collectionTypeResolver->hasIndexBy($property));
|
||||
$newVarType = $this->collectionTypeFactory->createType($collectionObjectType, $this->collectionTypeResolver->hasIndexBy($property), $property);
|
||||
$this->phpDocTypeChanger->changeVarType($property, $phpDocInfo, $newVarType);
|
||||
}
|
||||
return $property;
|
||||
@ -226,7 +226,7 @@ CODE_SAMPLE
|
||||
return null;
|
||||
}
|
||||
$fullyQualifiedObjectType = new FullyQualifiedObjectType($targetEntityClassName);
|
||||
$genericObjectType = $this->collectionTypeFactory->createType($fullyQualifiedObjectType, $this->collectionTypeResolver->hasIndexBy($property));
|
||||
$genericObjectType = $this->collectionTypeFactory->createType($fullyQualifiedObjectType, $this->collectionTypeResolver->hasIndexBy($property), $property);
|
||||
$this->phpDocTypeChanger->changeVarType($property, $phpDocInfo, $genericObjectType);
|
||||
return $property;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ final class SetterCollectionResolver
|
||||
if (\count($nonCollectionTypes) === 1) {
|
||||
$soleType = $nonCollectionTypes[0];
|
||||
if ($soleType instanceof ArrayType && $soleType->getItemType() instanceof ObjectType) {
|
||||
return $this->collectionTypeFactory->createType($soleType->getItemType(), $this->collectionTypeResolver->hasIndexBy($property));
|
||||
return $this->collectionTypeFactory->createType($soleType->getItemType(), $this->collectionTypeResolver->hasIndexBy($property), $property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,6 @@ final class ToManyRelationPropertyTypeResolver
|
||||
}
|
||||
$entityFullyQualifiedClass = $this->shortClassExpander->resolveFqnTargetEntity($targetEntity, $property);
|
||||
$fullyQualifiedObjectType = new FullyQualifiedObjectType($entityFullyQualifiedClass);
|
||||
return $this->collectionTypeFactory->createType($fullyQualifiedObjectType, $this->collectionTypeResolver->hasIndexBy($property));
|
||||
return $this->collectionTypeFactory->createType($fullyQualifiedObjectType, $this->collectionTypeResolver->hasIndexBy($property), $property);
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,159 @@
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\TypeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
use PHPStan\Type\IntegerType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\StringType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
|
||||
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
|
||||
use Rector\BetterPhpDocParser\PhpDoc\StringNode;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\PhpParser\AstResolver;
|
||||
use Rector\PhpParser\Node\Value\ValueResolver;
|
||||
final class CollectionTypeFactory
|
||||
{
|
||||
public function createType(ObjectType $objectType, bool $withIndexBy) : GenericObjectType
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private PhpDocInfoFactory $phpDocInfoFactory;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private AstResolver $astResolver;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private ValueResolver $valueResolver;
|
||||
public function __construct(PhpDocInfoFactory $phpDocInfoFactory, AstResolver $astResolver, ValueResolver $valueResolver)
|
||||
{
|
||||
$genericTypes = $withIndexBy ? [$objectType] : [new IntegerType(), $objectType];
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
$this->astResolver = $astResolver;
|
||||
$this->valueResolver = $valueResolver;
|
||||
}
|
||||
/**
|
||||
* @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $property
|
||||
*/
|
||||
public function createType(ObjectType $objectType, bool $withIndexBy, $property) : GenericObjectType
|
||||
{
|
||||
$keyType = new IntegerType();
|
||||
if ($withIndexBy) {
|
||||
$keyType = $this->resolveKeyType($property, $objectType->getClassName());
|
||||
}
|
||||
$genericTypes = [$keyType, $objectType];
|
||||
return new GenericObjectType('Doctrine\\Common\\Collections\\Collection', $genericTypes);
|
||||
}
|
||||
/**
|
||||
* @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $property
|
||||
* @return \PHPStan\Type\IntegerType|\PHPStan\Type\StringType
|
||||
*/
|
||||
private function resolveKeyType($property, string $className)
|
||||
{
|
||||
$class = $this->astResolver->resolveClassFromName($className);
|
||||
if (!$class instanceof Class_) {
|
||||
return new IntegerType();
|
||||
}
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($property);
|
||||
// key need to be initialized here
|
||||
// so it can be checked in target class annotation or attribute
|
||||
$key = null;
|
||||
if ($phpDocInfo instanceof PhpDocInfo) {
|
||||
// only on OneToMany and ManyToMany
|
||||
// https://www.doctrine-project.org/projects/doctrine-orm/en/3.3/tutorials/working-with-indexed-associations.html#mapping-indexed-associations
|
||||
$annotations = $phpDocInfo->findByAnnotationClass('Doctrine\\ORM\\Mapping\\OneToMany') !== [] ? $phpDocInfo->findByAnnotationClass('Doctrine\\ORM\\Mapping\\OneToMany') : $phpDocInfo->findByAnnotationClass('Doctrine\\ORM\\Mapping\\ManyToMany');
|
||||
if (\count($annotations) === 1 && $annotations[0] instanceof DoctrineAnnotationTagValueNode) {
|
||||
foreach ($annotations[0]->getValues() as $arrayItemNode) {
|
||||
if ($arrayItemNode instanceof ArrayItemNode && $arrayItemNode->key instanceof StringNode && $arrayItemNode->key->value === 'indexBy' && $arrayItemNode->value instanceof StringNode) {
|
||||
$key = $arrayItemNode->value->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($key !== null) {
|
||||
$type = $this->resolveKeyFromAnnotation($class, $key);
|
||||
if ($type instanceof Type) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$attrGroups = $property->attrGroups;
|
||||
foreach ($attrGroups as $attrGroup) {
|
||||
foreach ($attrGroup->attrs as $attr) {
|
||||
if (\in_array($attr->name->toString(), ['Doctrine\\ORM\\Mapping\\OneToMany', 'Doctrine\\ORM\\Mapping\\ManyToMany'], \true)) {
|
||||
foreach ($attr->args as $arg) {
|
||||
if ($arg->name instanceof Identifier && $arg->name->name === 'indexBy' && $arg->value instanceof String_) {
|
||||
$key = $arg->value->value;
|
||||
$type = $this->resolveKeyFromAnnotation($class, $key);
|
||||
if ($type instanceof Type) {
|
||||
return $type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($key !== null) {
|
||||
return $this->resolveKeyFromAttribute($class, $key);
|
||||
}
|
||||
return new IntegerType();
|
||||
}
|
||||
/**
|
||||
* @return null|\PHPStan\Type\IntegerType|\PHPStan\Type\StringType
|
||||
*/
|
||||
private function resolveKeyFromAnnotation(Class_ $class, string $key)
|
||||
{
|
||||
// get property from class
|
||||
$targetProperty = $class->getProperty($key);
|
||||
if (!$targetProperty instanceof Property) {
|
||||
return new IntegerType();
|
||||
}
|
||||
$phpDocInfoTargetClass = $this->phpDocInfoFactory->createFromNode($targetProperty);
|
||||
if ($phpDocInfoTargetClass instanceof PhpDocInfo) {
|
||||
$columns = $phpDocInfoTargetClass->findByAnnotationClass('Doctrine\\ORM\\Mapping\\Column');
|
||||
if (\count($columns) === 1 && $columns[0] instanceof DoctrineAnnotationTagValueNode) {
|
||||
$type = null;
|
||||
foreach ($columns[0]->getValues() as $arrayItemNode) {
|
||||
if ($arrayItemNode instanceof ArrayItemNode && $arrayItemNode->key === 'type' && $arrayItemNode->value instanceof StringNode) {
|
||||
$type = $arrayItemNode->value->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $type === null ? new IntegerType() : ($type === 'string' ? new StringType() : new IntegerType());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @return \PHPStan\Type\IntegerType|\PHPStan\Type\StringType
|
||||
*/
|
||||
private function resolveKeyFromAttribute(Class_ $class, string $key)
|
||||
{
|
||||
// get property from class
|
||||
$targetProperty = $class->getProperty($key);
|
||||
if (!$targetProperty instanceof Property) {
|
||||
return new IntegerType();
|
||||
}
|
||||
$attrGroups = $targetProperty->attrGroups;
|
||||
foreach ($attrGroups as $attrGroup) {
|
||||
foreach ($attrGroup->attrs as $attr) {
|
||||
if ($attr->name->toString() === 'Doctrine\\ORM\\Mapping\\Column') {
|
||||
foreach ($attr->args as $arg) {
|
||||
if ($arg->name instanceof Identifier && $arg->name->name === 'type') {
|
||||
$type = $this->valueResolver->getValue($arg->value);
|
||||
return $type === 'string' ? new StringType() : new IntegerType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new IntegerType();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user