yiistack /
annotated
| 1 | <?php |
||||
| 2 | |||||
| 3 | declare(strict_types=1); |
||||
| 4 | |||||
| 5 | namespace Yiistack\Annotated; |
||||
| 6 | |||||
| 7 | use Doctrine\Common\Annotations\AnnotationReader; |
||||
| 8 | use Generator; |
||||
| 9 | use ReflectionClass; |
||||
| 10 | use Spiral\Tokenizer\ClassesInterface; |
||||
| 11 | |||||
| 12 | final class AnnotationLoader |
||||
| 13 | { |
||||
| 14 | private ClassesInterface $classLocator; |
||||
| 15 | private AnnotationReader $reader; |
||||
| 16 | private array $targets = []; |
||||
| 17 | |||||
| 18 | 5 | public function __construct(ClassesInterface $classLocator, AnnotationReader $reader = null) |
|||
| 19 | { |
||||
| 20 | 5 | $this->classLocator = $classLocator; |
|||
| 21 | 5 | $this->reader = $reader ?? new AnnotationReader(); |
|||
| 22 | } |
||||
| 23 | |||||
| 24 | 3 | public function withTargets(array $targets): self |
|||
| 25 | { |
||||
| 26 | 3 | $new = clone $this; |
|||
| 27 | 3 | $new->targets = $targets; |
|||
| 28 | |||||
| 29 | 3 | return $new; |
|||
| 30 | } |
||||
| 31 | |||||
| 32 | /** |
||||
| 33 | * Find all classes with given annotation. |
||||
| 34 | * |
||||
| 35 | * @param string $annotation |
||||
| 36 | * |
||||
| 37 | * @psalm-suppress ArgumentTypeCoercion |
||||
| 38 | * @psalm-return Generator<AnnotatedClass> |
||||
| 39 | * |
||||
| 40 | * @return AnnotatedClass[]|Generator |
||||
| 41 | */ |
||||
| 42 | 1 | public function findClasses(string $annotation, ?ReflectionClass $class = null): Generator |
|||
| 43 | { |
||||
| 44 | 1 | if ($class !== null) { |
|||
| 45 | $annotations = $this->reader->getClassAnnotations($class); |
||||
| 46 | foreach ($annotations as $classAnnotation) { |
||||
| 47 | if ($classAnnotation instanceof $annotation) { |
||||
| 48 | yield new AnnotatedClass($class, $classAnnotation); |
||||
| 49 | } |
||||
| 50 | } |
||||
| 51 | } |
||||
| 52 | 1 | foreach ($this->getTargets() as $target) { |
|||
| 53 | 1 | $annotations = $this->reader->getClassAnnotations($target); |
|||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 54 | 1 | foreach ($annotations as $classAnnotation) { |
|||
| 55 | 1 | if ($classAnnotation instanceof $annotation) { |
|||
| 56 | 1 | yield new AnnotatedClass($target, $classAnnotation); |
|||
|
0 ignored issues
–
show
$target of type ReflectionClass[] is incompatible with the type ReflectionClass expected by parameter $class of Yiistack\Annotated\AnnotatedClass::__construct().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 57 | } |
||||
| 58 | } |
||||
| 59 | } |
||||
| 60 | } |
||||
| 61 | |||||
| 62 | /** |
||||
| 63 | * Find all methods with given annotation. |
||||
| 64 | * |
||||
| 65 | * @param string $annotation |
||||
| 66 | * @param ReflectionClass|null $class |
||||
| 67 | * |
||||
| 68 | * @psalm-suppress ArgumentTypeCoercion |
||||
| 69 | * @psalm-return Generator<AnnotatedMethod> |
||||
| 70 | * |
||||
| 71 | * @return AnnotatedMethod[]|Generator |
||||
| 72 | */ |
||||
| 73 | 2 | public function findMethods(string $annotation, ?ReflectionClass $class = null): Generator |
|||
| 74 | { |
||||
| 75 | 2 | if ($class !== null) { |
|||
| 76 | 1 | foreach ($class->getMethods() as $method) { |
|||
| 77 | 1 | $annotations = $this->reader->getMethodAnnotations($method); |
|||
| 78 | 1 | foreach ($annotations as $methodAnnotation) { |
|||
| 79 | 1 | if ($methodAnnotation instanceof $annotation) { |
|||
| 80 | 1 | yield new AnnotatedMethod($method, $methodAnnotation); |
|||
| 81 | } |
||||
| 82 | } |
||||
| 83 | } |
||||
| 84 | 1 | return; |
|||
| 85 | } |
||||
| 86 | 1 | foreach ($this->getTargets() as $target) { |
|||
| 87 | 1 | foreach ($target->getMethods() as $method) { |
|||
| 88 | 1 | $annotations = $this->reader->getMethodAnnotations($method); |
|||
| 89 | 1 | foreach ($annotations as $methodAnnotation) { |
|||
| 90 | 1 | if ($methodAnnotation instanceof $annotation) { |
|||
| 91 | 1 | yield new AnnotatedMethod($method, $methodAnnotation); |
|||
| 92 | } |
||||
| 93 | } |
||||
| 94 | } |
||||
| 95 | } |
||||
| 96 | } |
||||
| 97 | |||||
| 98 | /** |
||||
| 99 | * Find all properties with given annotation. |
||||
| 100 | * |
||||
| 101 | * @param string $annotation |
||||
| 102 | * @param ReflectionClass|null $class |
||||
| 103 | * |
||||
| 104 | * @psalm-suppress ArgumentTypeCoercion |
||||
| 105 | * @psalm-return Generator<AnnotatedProperty> |
||||
| 106 | * |
||||
| 107 | * @return AnnotatedProperty[]|Generator |
||||
| 108 | */ |
||||
| 109 | 2 | public function findProperties(string $annotation, ?ReflectionClass $class = null): Generator |
|||
| 110 | { |
||||
| 111 | 2 | if ($class !== null) { |
|||
| 112 | 1 | foreach ($class->getProperties() as $property) { |
|||
| 113 | 1 | $annotations = $this->reader->getPropertyAnnotations($property); |
|||
| 114 | 1 | foreach ($annotations as $propertyAnnotation) { |
|||
| 115 | 1 | if ($propertyAnnotation instanceof $annotation) { |
|||
| 116 | 1 | yield new AnnotatedProperty($property, $propertyAnnotation); |
|||
| 117 | } |
||||
| 118 | } |
||||
| 119 | } |
||||
| 120 | 1 | return; |
|||
| 121 | } |
||||
| 122 | 1 | foreach ($this->getTargets() as $target) { |
|||
| 123 | 1 | foreach ($target->getProperties() as $property) { |
|||
| 124 | 1 | $annotations = $this->reader->getPropertyAnnotations($property); |
|||
| 125 | 1 | foreach ($annotations as $propertyAnnotation) { |
|||
| 126 | 1 | if ($propertyAnnotation instanceof $annotation) { |
|||
| 127 | 1 | yield new AnnotatedProperty($property, $propertyAnnotation); |
|||
| 128 | } |
||||
| 129 | } |
||||
| 130 | } |
||||
| 131 | } |
||||
| 132 | } |
||||
| 133 | |||||
| 134 | 3 | private function getTargets(): Generator |
|||
| 135 | { |
||||
| 136 | 3 | if ($this->targets === []) { |
|||
| 137 | yield from $this->classLocator->getClasses(); |
||||
| 138 | return; |
||||
| 139 | } |
||||
| 140 | |||||
| 141 | 3 | foreach ($this->targets as $target) { |
|||
| 142 | 3 | yield from $this->classLocator->getClasses($target); |
|||
| 143 | } |
||||
| 144 | } |
||||
| 145 | } |
||||
| 146 |