mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-20 06:38:46 +01:00
Add multiple annotation support on class (#4064)
* add test case for #3230 * position * add support for multi doc annotations * [rector] add support for multi doc annotations * [cs] add support for multi doc annotations Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
parent
4a2ba04b05
commit
f8b485305f
@ -78,14 +78,16 @@ final class NodeAnnotationReader
|
||||
{
|
||||
$classReflection = $this->createClassReflectionFromNode($class);
|
||||
|
||||
$annotation = $this->reader->getClassAnnotation($classReflection, $annotationClassName);
|
||||
if ($annotation === null) {
|
||||
try {
|
||||
// covers cases like https://github.com/rectorphp/rector/issues/3046
|
||||
|
||||
/** @var object[] $classAnnotations */
|
||||
$classAnnotations = $this->reader->getClassAnnotations($classReflection);
|
||||
return $this->matchNextAnnotation($classAnnotations, $annotationClassName, $class);
|
||||
} catch (AnnotationException $annotationException) {
|
||||
// unable to load
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->constantReferenceIdentifierRestorer->restoreObject($annotation);
|
||||
|
||||
return $annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,28 +105,11 @@ final class NodeAnnotationReader
|
||||
|
||||
/** @var object[] $propertyAnnotations */
|
||||
$propertyAnnotations = $this->reader->getPropertyAnnotations($propertyReflection);
|
||||
|
||||
foreach ($propertyAnnotations as $propertyAnnotation) {
|
||||
if (! is_a($propertyAnnotation, $annotationClassName, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$objectHash = md5(spl_object_hash($propertyReflection) . serialize($propertyAnnotation));
|
||||
if (in_array($objectHash, $this->alreadyProvidedAnnotations, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->alreadyProvidedAnnotations[] = $objectHash;
|
||||
$this->constantReferenceIdentifierRestorer->restoreObject($propertyAnnotation);
|
||||
|
||||
return $propertyAnnotation;
|
||||
}
|
||||
return $this->matchNextAnnotation($propertyAnnotations, $annotationClassName, $property);
|
||||
} catch (AnnotationException $annotationException) {
|
||||
// unable to laod
|
||||
// unable to load
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,9 +158,35 @@ final class NodeAnnotationReader
|
||||
/** @var string $className */
|
||||
$className = $this->nodeNameResolver->getName($class);
|
||||
|
||||
// covers cases like https://github.com/rectorphp/rector/issues/3230#issuecomment-683317288
|
||||
|
||||
return new ReflectionClass($className);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object[] $annotations
|
||||
*/
|
||||
private function matchNextAnnotation(array $annotations, string $annotationClassName, Node $node): ?object
|
||||
{
|
||||
foreach ($annotations as $annotatoin) {
|
||||
if (! is_a($annotatoin, $annotationClassName, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$objectHash = md5(spl_object_hash($node) . serialize($annotatoin));
|
||||
if (in_array($objectHash, $this->alreadyProvidedAnnotations, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->alreadyProvidedAnnotations[] = $objectHash;
|
||||
$this->constantReferenceIdentifierRestorer->restoreObject($annotatoin);
|
||||
|
||||
return $annotatoin;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function createPropertyReflectionFromPropertyNode(Property $property): ?ReflectionProperty
|
||||
{
|
||||
/** @var string $propertyName */
|
||||
|
@ -144,8 +144,8 @@ final class PhpDocInfoPrinter
|
||||
// node output
|
||||
$nodeCount = count($attributeAwarePhpDocNode->children);
|
||||
|
||||
foreach ($attributeAwarePhpDocNode->children as $i => $phpDocChildNode) {
|
||||
$output .= $this->printNode($phpDocChildNode, null, $i + 1, $nodeCount);
|
||||
foreach ($attributeAwarePhpDocNode->children as $key => $phpDocChildNode) {
|
||||
$output .= $this->printNode($phpDocChildNode, null, $key + 1, $nodeCount);
|
||||
}
|
||||
|
||||
$output = $this->printEnd($output);
|
||||
@ -171,7 +171,7 @@ final class PhpDocInfoPrinter
|
||||
private function printNode(
|
||||
AttributeAwareNodeInterface $attributeAwareNode,
|
||||
?StartEndValueObject $startEndValueObject = null,
|
||||
int $i = 0,
|
||||
int $key = 0,
|
||||
int $nodeCount = 0
|
||||
): string {
|
||||
$output = '';
|
||||
@ -181,7 +181,7 @@ final class PhpDocInfoPrinter
|
||||
$attributeAwareNode = $this->multilineSpaceFormatPreserver->fixMultilineDescriptions($attributeAwareNode);
|
||||
|
||||
if ($startEndValueObject !== null) {
|
||||
$isLastToken = ($nodeCount === $i);
|
||||
$isLastToken = ($nodeCount === $key);
|
||||
|
||||
$output = $this->addTokensFromTo(
|
||||
$output,
|
||||
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* @Route("/", name="homepage")
|
||||
* @Route("/another-path", name="another-path")
|
||||
*/
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/hey", name="hey")
|
||||
* @Route("/hey-me", name="hey_me")
|
||||
*/
|
||||
class DoubleRoute extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @Route("/property", name="property")
|
||||
* @Route("/property-me", name="property_me")
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @Route("/change", name="facility_change")
|
||||
* @Route("/change-me", name="facility_change_me")
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user