|
35 | 35 | use function assert; |
36 | 36 | use function get_class; |
37 | 37 | use function in_array; |
| 38 | +use function is_a; |
38 | 39 | use function reset; |
39 | 40 | use function strpos; |
40 | 41 | use function strrpos; |
41 | 42 | use function substr; |
| 43 | +use const PHP_MAJOR_VERSION; |
42 | 44 |
|
43 | 45 | class AnnotationReader |
44 | 46 | { |
@@ -217,6 +219,21 @@ public function getParameterAnnotationsPerParameter(array $refParameters): array |
217 | 219 | } |
218 | 220 | } |
219 | 221 |
|
| 222 | + // Now, let's add PHP 8 parameter attributes |
| 223 | + if (PHP_MAJOR_VERSION >= 8) { |
| 224 | + foreach ($refParameters as $refParameter) { |
| 225 | + $attributes = $refParameter->getAttributes(); |
| 226 | + $parameterAnnotationsPerParameter[$refParameter->getName()] = array_merge($parameterAnnotationsPerParameter[$refParameter->getName()] ?? [], array_map( |
| 227 | + static function ($attribute) { |
| 228 | + return $attribute->newInstance(); |
| 229 | + }, |
| 230 | + array_filter($attributes, static function ($annotation): bool { |
| 231 | + return is_a($annotation->getName(), ParameterAnnotationInterface::class, true); |
| 232 | + }) |
| 233 | + )); |
| 234 | + } |
| 235 | + } |
| 236 | + |
220 | 237 | return array_map(static function (array $parameterAnnotations) { |
221 | 238 | return new ParameterAnnotations($parameterAnnotations); |
222 | 239 | }, $parameterAnnotationsPerParameter); |
@@ -246,6 +263,16 @@ private function getClassAnnotation(ReflectionClass $refClass, string $annotatio |
246 | 263 | { |
247 | 264 | $type = null; |
248 | 265 | try { |
| 266 | + // If attribute & annotation, let's prefer the PHP 8 attribute |
| 267 | + if (PHP_MAJOR_VERSION >= 8) { |
| 268 | + $attribute = $refClass->getAttributes($annotationClass)[0] ?? null; |
| 269 | + if ($attribute) { |
| 270 | + /** @var T $instance */ |
| 271 | + $instance = $attribute->newInstance(); |
| 272 | + return $instance; |
| 273 | + } |
| 274 | + } |
| 275 | + |
249 | 276 | $type = $this->reader->getClassAnnotation($refClass, $annotationClass); |
250 | 277 | assert($type === null || $type instanceof $annotationClass); |
251 | 278 | } catch (AnnotationException $e) { |
@@ -282,6 +309,14 @@ private function getMethodAnnotation(ReflectionMethod $refMethod, string $annota |
282 | 309 | } |
283 | 310 |
|
284 | 311 | try { |
| 312 | + // If attribute & annotation, let's prefer the PHP 8 attribute |
| 313 | + if (PHP_MAJOR_VERSION >= 8) { |
| 314 | + $attribute = $refMethod->getAttributes($annotationClass)[0] ?? null; |
| 315 | + if ($attribute) { |
| 316 | + return $this->methodAnnotationCache[$cacheKey] = $attribute->newInstance(); |
| 317 | + } |
| 318 | + } |
| 319 | + |
285 | 320 | return $this->methodAnnotationCache[$cacheKey] = $this->reader->getMethodAnnotation($refMethod, $annotationClass); |
286 | 321 | } catch (AnnotationException $e) { |
287 | 322 | switch ($this->mode) { |
@@ -336,6 +371,17 @@ public function getClassAnnotations(ReflectionClass $refClass, string $annotatio |
336 | 371 | $toAddAnnotations[] = array_filter($allAnnotations, static function ($annotation) use ($annotationClass): bool { |
337 | 372 | return $annotation instanceof $annotationClass; |
338 | 373 | }); |
| 374 | + if (PHP_MAJOR_VERSION >= 8) { |
| 375 | + $attributes = $refClass->getAttributes(); |
| 376 | + $toAddAnnotations[] = array_map( |
| 377 | + static function ($attribute) { |
| 378 | + return $attribute->newInstance(); |
| 379 | + }, |
| 380 | + array_filter($attributes, static function ($annotation) use ($annotationClass): bool { |
| 381 | + return is_a($annotation->getName(), $annotationClass, true); |
| 382 | + }) |
| 383 | + ); |
| 384 | + } |
339 | 385 | } catch (AnnotationException $e) { |
340 | 386 | if ($this->mode === self::STRICT_MODE) { |
341 | 387 | throw $e; |
@@ -384,6 +430,17 @@ public function getMethodAnnotations(ReflectionMethod $refMethod, string $annota |
384 | 430 | $toAddAnnotations = array_filter($allAnnotations, static function ($annotation) use ($annotationClass): bool { |
385 | 431 | return $annotation instanceof $annotationClass; |
386 | 432 | }); |
| 433 | + if (PHP_MAJOR_VERSION >= 8) { |
| 434 | + $attributes = $refMethod->getAttributes(); |
| 435 | + $toAddAnnotations = array_merge($toAddAnnotations, array_map( |
| 436 | + static function ($attribute) { |
| 437 | + return $attribute->newInstance(); |
| 438 | + }, |
| 439 | + array_filter($attributes, static function ($annotation) use ($annotationClass): bool { |
| 440 | + return is_a($annotation->getName(), $annotationClass, true); |
| 441 | + }) |
| 442 | + )); |
| 443 | + } |
387 | 444 | } catch (AnnotationException $e) { |
388 | 445 | if ($this->mode === self::STRICT_MODE) { |
389 | 446 | throw $e; |
|
0 commit comments