Updated Rector to commit d2f7c2ee24

d2f7c2ee24 [PHP 8.0] Extend DoctrineAnnotationClassToAttributeRector rule to cover short target annotations (#1260)
This commit is contained in:
Tomas Votruba 2021-11-17 17:46:14 +00:00
parent 5f23715e04
commit dc03241b5b
12 changed files with 105 additions and 63 deletions

View File

@ -251,6 +251,20 @@ final class PhpDocInfo
{
return $this->getByAnnotationClasses($annotationsClasses) !== null;
}
/**
* @param string[] $desiredClasses
*/
public function findOneByAnnotationClasses(array $desiredClasses) : ?\Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode
{
foreach ($desiredClasses as $desiredClass) {
$doctrineAnnotationTagValueNode = $this->findOneByAnnotationClass($desiredClass);
if (!$doctrineAnnotationTagValueNode instanceof \Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode) {
continue;
}
return $doctrineAnnotationTagValueNode;
}
return null;
}
/**
* @param class-string $desiredClass
*/

View File

@ -20,6 +20,11 @@ use Rector\Core\Configuration\CurrentNodeProvider;
use Rector\Core\Exception\ShouldNotHappenException;
final class DoctrineAnnotationDecorator
{
/**
* Special short annotations, that are resolved as FQN by Doctrine annotation parser
* @var string[]
*/
private const ALLOWED_SHORT_ANNOTATIONS = ['Target'];
/**
* @var \Rector\Core\Configuration\CurrentNodeProvider
*/
@ -129,7 +134,7 @@ final class DoctrineAnnotationDecorator
// known doc tag to annotation class
$fullyQualifiedAnnotationClass = $this->classAnnotationMatcher->resolveTagFullyQualifiedName($phpDocChildNode->name, $currentPhpNode);
// not an annotations class
if (\strpos($fullyQualifiedAnnotationClass, '\\') === \false) {
if (\strpos($fullyQualifiedAnnotationClass, '\\') === \false && !\in_array($fullyQualifiedAnnotationClass, self::ALLOWED_SHORT_ANNOTATIONS, \true)) {
continue;
}
$genericTagValueNode = $phpDocChildNode->value;

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\DowngradePhp55\Rector\Foreach_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\List_;
use PhpParser\Node\Expr\Variable;
@ -15,7 +14,6 @@ use Rector\Naming\Naming\VariableNaming;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix20211117\Webmozart\Assert\Assert;
/**
* @changelog https://wiki.php.net/rfc/foreachlist
*
@ -62,9 +60,9 @@ CODE_SAMPLE
return null;
}
$variable = $this->createVariable($node);
$exprAssign = new \PhpParser\Node\Stmt\Expression(new \PhpParser\Node\Expr\Assign($node->valueVar, $variable));
$expression = new \PhpParser\Node\Stmt\Expression(new \PhpParser\Node\Expr\Assign($node->valueVar, $variable));
$node->valueVar = $variable;
$node->stmts = \array_merge([$exprAssign], $node->stmts);
$node->stmts = \array_merge([$expression], $node->stmts);
return $node;
}
private function createVariable(\PhpParser\Node\Stmt\Foreach_ $foreach) : \PhpParser\Node\Expr\Variable

View File

@ -0,0 +1,46 @@
<?php
declare (strict_types=1);
namespace Rector\Php80\NodeAnalyzer;
use PhpParser\Node\Expr\ClassConstFetch;
use Rector\Core\PhpParser\Node\NodeFactory;
final class AnnotationTargetResolver
{
/**
* @see https://github.com/doctrine/annotations/blob/e6e7b7d5b45a2f2abc5460cc6396480b2b1d321f/lib/Doctrine/Common/Annotations/Annotation/Target.php#L24-L29
* @var array<string, string>
*/
private const TARGET_TO_CONSTANT_MAP = [
'METHOD' => 'TARGET_METHOD',
'PROPERTY' => 'TARGET_PROPERTY',
'CLASS' => 'TARGET_CLASS',
'FUNCTION' => 'TARGET_FUNCTION',
'ALL' => 'TARGET_ALL',
// special case
'ANNOTATION' => 'TARGET_CLASS',
];
/**
* @var \Rector\Core\PhpParser\Node\NodeFactory
*/
private $nodeFactory;
public function __construct(\Rector\Core\PhpParser\Node\NodeFactory $nodeFactory)
{
$this->nodeFactory = $nodeFactory;
}
/**
* @param array<int|string, mixed> $targetValues
* @return ClassConstFetch[]
*/
public function resolveFlagClassConstFetches(array $targetValues) : array
{
$classConstFetches = [];
foreach (self::TARGET_TO_CONSTANT_MAP as $target => $constant) {
if (!\in_array($target, $targetValues, \true)) {
continue;
}
$classConstFetches[] = $this->nodeFactory->createClassConstFetch('Attribute', $constant);
}
return $classConstFetches;
}
}

View File

@ -9,17 +9,17 @@ use PhpParser\Node\Expr\ClassConstFetch;
final class AttributeFlagFactory
{
/**
* @param ClassConstFetch[] $flags
* @param ClassConstFetch[] $classConstFetches
* @return ClassConstFetch|BitwiseOr|null
*/
public function createFlagCollection(array $flags) : ?\PhpParser\Node\Expr
public function createFlagCollection(array $classConstFetches) : ?\PhpParser\Node\Expr
{
if ($flags === []) {
if ($classConstFetches === []) {
return null;
}
$flagCollection = \array_shift($flags);
foreach ($flags as $flag) {
$flagCollection = new \PhpParser\Node\Expr\BinaryOp\BitwiseOr($flagCollection, $flag);
$flagCollection = \array_shift($classConstFetches);
foreach ($classConstFetches as $classConstFetch) {
$flagCollection = new \PhpParser\Node\Expr\BinaryOp\BitwiseOr($flagCollection, $classConstFetch);
}
return $flagCollection;
}

View File

@ -6,7 +6,6 @@ namespace Rector\Php80\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\AttributeGroup;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Type\MixedType;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
@ -16,6 +15,7 @@ use Rector\BetterPhpDocParser\ValueObject\PhpDoc\DoctrineAnnotation\CurlyListNod
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Php80\NodeAnalyzer\AnnotationTargetResolver;
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
use Rector\Php80\NodeFactory\AttributeFlagFactory;
use Rector\PhpAttribute\Printer\PhpAttributeGroupFactory;
@ -39,19 +39,6 @@ final class DoctrineAnnotationClassToAttributeRector extends \Rector\Core\Rector
* @var string
*/
public const REMOVE_ANNOTATIONS = 'remove_annotations';
/**
* @see https://github.com/doctrine/annotations/blob/e6e7b7d5b45a2f2abc5460cc6396480b2b1d321f/lib/Doctrine/Common/Annotations/Annotation/Target.php#L24-L29
* @var array<string, string>
*/
private const TARGET_TO_CONSTANT_MAP = [
'METHOD' => 'TARGET_METHOD',
'PROPERTY' => 'TARGET_PROPERTY',
'CLASS' => 'TARGET_CLASS',
'FUNCTION' => 'TARGET_FUNCTION',
'ALL' => 'TARGET_ALL',
// special case
'ANNOTATION' => 'TARGET_CLASS',
];
/**
* @var string
*/
@ -80,13 +67,18 @@ final class DoctrineAnnotationClassToAttributeRector extends \Rector\Core\Rector
* @var \Rector\PostRector\Collector\PropertyToAddCollector
*/
private $propertyToAddCollector;
public function __construct(\Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover $phpDocTagRemover, \Rector\Php80\NodeFactory\AttributeFlagFactory $attributeFlagFactory, \Rector\PhpAttribute\Printer\PhpAttributeGroupFactory $phpAttributeGroupFactory, \Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer $phpAttributeAnalyzer, \Rector\PostRector\Collector\PropertyToAddCollector $propertyToAddCollector)
/**
* @var \Rector\Php80\NodeAnalyzer\AnnotationTargetResolver
*/
private $annotationTargetResolver;
public function __construct(\Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover $phpDocTagRemover, \Rector\Php80\NodeFactory\AttributeFlagFactory $attributeFlagFactory, \Rector\PhpAttribute\Printer\PhpAttributeGroupFactory $phpAttributeGroupFactory, \Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer $phpAttributeAnalyzer, \Rector\PostRector\Collector\PropertyToAddCollector $propertyToAddCollector, \Rector\Php80\NodeAnalyzer\AnnotationTargetResolver $annotationTargetResolver)
{
$this->phpDocTagRemover = $phpDocTagRemover;
$this->attributeFlagFactory = $attributeFlagFactory;
$this->phpAttributeGroupFactory = $phpAttributeGroupFactory;
$this->phpAttributeAnalyzer = $phpAttributeAnalyzer;
$this->propertyToAddCollector = $propertyToAddCollector;
$this->annotationTargetResolver = $annotationTargetResolver;
}
public function provideMinPhpVersion() : int
{
@ -172,24 +164,9 @@ CODE_SAMPLE
\RectorPrefix20211117\Webmozart\Assert\Assert::boolean($shouldRemoveAnnotations);
$this->shouldRemoveAnnotations = $shouldRemoveAnnotations;
}
/**
* @param array<int|string, mixed> $targetValues
* @return ClassConstFetch[]
*/
private function resolveFlags(array $targetValues) : array
{
$flags = [];
foreach (self::TARGET_TO_CONSTANT_MAP as $target => $constant) {
if (!\in_array($target, $targetValues, \true)) {
continue;
}
$flags[] = $this->nodeFactory->createClassConstFetch(self::ATTRIBUTE, $constant);
}
return $flags;
}
private function decorateTarget(\Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo $phpDocInfo, \PhpParser\Node\AttributeGroup $attributeGroup) : void
{
$targetDoctrineAnnotationTagValueNode = $phpDocInfo->findOneByAnnotationClass('Doctrine\\Common\\Annotations\\Annotation\\Target');
$targetDoctrineAnnotationTagValueNode = $phpDocInfo->findOneByAnnotationClasses(['Doctrine\\Common\\Annotations\\Annotation\\Target', 'Target']);
if (!$targetDoctrineAnnotationTagValueNode instanceof \Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode) {
return;
}
@ -204,8 +181,8 @@ CODE_SAMPLE
} else {
return;
}
$flags = $this->resolveFlags($targetValues);
$flagCollection = $this->attributeFlagFactory->createFlagCollection($flags);
$flagClassConstFetches = $this->annotationTargetResolver->resolveFlagClassConstFetches($targetValues);
$flagCollection = $this->attributeFlagFactory->createFlagCollection($flagClassConstFetches);
if ($flagCollection === null) {
return;
}

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = '660adeb2bf831d6bda96098d1f75b2078f81e7ed';
public const PACKAGE_VERSION = 'd2f7c2ee24d41ed6570598ae66d49a81aafc3e9d';
/**
* @var string
*/
public const RELEASE_DATE = '2021-11-17 13:41:36';
public const RELEASE_DATE = '2021-11-17 17:30:06';
public static function resolvePackageVersion() : string
{
$process = new \RectorPrefix20211117\Symfony\Component\Process\Process(['git', 'log', '--pretty="%H"', '-n1', 'HEAD'], __DIR__);

2
vendor/autoload.php vendored
View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066::getLoader();
return ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5::getLoader();

View File

@ -2442,6 +2442,7 @@ return array(
'Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\StrncmpMatchAndRefactor' => $baseDir . '/rules/Php80/MatchAndRefactor/StrStartsWithMatchAndRefactor/StrncmpMatchAndRefactor.php',
'Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\StrposMatchAndRefactor' => $baseDir . '/rules/Php80/MatchAndRefactor/StrStartsWithMatchAndRefactor/StrposMatchAndRefactor.php',
'Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\SubstrMatchAndRefactor' => $baseDir . '/rules/Php80/MatchAndRefactor/StrStartsWithMatchAndRefactor/SubstrMatchAndRefactor.php',
'Rector\\Php80\\NodeAnalyzer\\AnnotationTargetResolver' => $baseDir . '/rules/Php80/NodeAnalyzer/AnnotationTargetResolver.php',
'Rector\\Php80\\NodeAnalyzer\\MatchSwitchAnalyzer' => $baseDir . '/rules/Php80/NodeAnalyzer/MatchSwitchAnalyzer.php',
'Rector\\Php80\\NodeAnalyzer\\PhpAttributeAnalyzer' => $baseDir . '/rules/Php80/NodeAnalyzer/PhpAttributeAnalyzer.php',
'Rector\\Php80\\NodeAnalyzer\\PromotedPropertyCandidateResolver' => $baseDir . '/rules/Php80/NodeAnalyzer/PromotedPropertyCandidateResolver.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066
class ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5
{
private static $loader;
@ -22,15 +22,15 @@ class ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInite188f0420dcb75cdb5dc38f0090863f5::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
@ -42,19 +42,19 @@ class ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066::$files;
$includeFiles = Composer\Autoload\ComposerStaticInite188f0420dcb75cdb5dc38f0090863f5::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirebfd43c5d05b4b7c8a3c3ff39772a8066($fileIdentifier, $file);
composerRequiree188f0420dcb75cdb5dc38f0090863f5($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequirebfd43c5d05b4b7c8a3c3ff39772a8066($fileIdentifier, $file)
function composerRequiree188f0420dcb75cdb5dc38f0090863f5($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066
class ComposerStaticInite188f0420dcb75cdb5dc38f0090863f5
{
public static $files = array (
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
@ -2772,6 +2772,7 @@ class ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066
'Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\StrncmpMatchAndRefactor' => __DIR__ . '/../..' . '/rules/Php80/MatchAndRefactor/StrStartsWithMatchAndRefactor/StrncmpMatchAndRefactor.php',
'Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\StrposMatchAndRefactor' => __DIR__ . '/../..' . '/rules/Php80/MatchAndRefactor/StrStartsWithMatchAndRefactor/StrposMatchAndRefactor.php',
'Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\SubstrMatchAndRefactor' => __DIR__ . '/../..' . '/rules/Php80/MatchAndRefactor/StrStartsWithMatchAndRefactor/SubstrMatchAndRefactor.php',
'Rector\\Php80\\NodeAnalyzer\\AnnotationTargetResolver' => __DIR__ . '/../..' . '/rules/Php80/NodeAnalyzer/AnnotationTargetResolver.php',
'Rector\\Php80\\NodeAnalyzer\\MatchSwitchAnalyzer' => __DIR__ . '/../..' . '/rules/Php80/NodeAnalyzer/MatchSwitchAnalyzer.php',
'Rector\\Php80\\NodeAnalyzer\\PhpAttributeAnalyzer' => __DIR__ . '/../..' . '/rules/Php80/NodeAnalyzer/PhpAttributeAnalyzer.php',
'Rector\\Php80\\NodeAnalyzer\\PromotedPropertyCandidateResolver' => __DIR__ . '/../..' . '/rules/Php80/NodeAnalyzer/PromotedPropertyCandidateResolver.php',
@ -3552,9 +3553,9 @@ class ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitbfd43c5d05b4b7c8a3c3ff39772a8066::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInite188f0420dcb75cdb5dc38f0090863f5::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInite188f0420dcb75cdb5dc38f0090863f5::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInite188f0420dcb75cdb5dc38f0090863f5::$classMap;
}, null, ClassLoader::class);
}

View File

@ -12,8 +12,8 @@ if (!class_exists('GenerateChangelogCommand', false) && !interface_exists('Gener
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20211117\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066', false) && !interface_exists('ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066', false) && !trait_exists('ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066', false)) {
spl_autoload_call('RectorPrefix20211117\ComposerAutoloaderInitbfd43c5d05b4b7c8a3c3ff39772a8066');
if (!class_exists('ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5', false) && !interface_exists('ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5', false) && !trait_exists('ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5', false)) {
spl_autoload_call('RectorPrefix20211117\ComposerAutoloaderInite188f0420dcb75cdb5dc38f0090863f5');
}
if (!class_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !interface_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !trait_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false)) {
spl_autoload_call('RectorPrefix20211117\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -81,9 +81,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20211117\print_node(...func_get_args());
}
}
if (!function_exists('composerRequirebfd43c5d05b4b7c8a3c3ff39772a8066')) {
function composerRequirebfd43c5d05b4b7c8a3c3ff39772a8066() {
return \RectorPrefix20211117\composerRequirebfd43c5d05b4b7c8a3c3ff39772a8066(...func_get_args());
if (!function_exists('composerRequiree188f0420dcb75cdb5dc38f0090863f5')) {
function composerRequiree188f0420dcb75cdb5dc38f0090863f5() {
return \RectorPrefix20211117\composerRequiree188f0420dcb75cdb5dc38f0090863f5(...func_get_args());
}
}
if (!function_exists('parseArgs')) {