fix: Move hasAnnotationOrAttribute to the reflector

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
Côme Chilliet 2026-03-11 11:13:30 +01:00
parent 27e51e5858
commit c30ad63d48
No known key found for this signature in database
GPG key ID: A3E2F658B28C760A
2 changed files with 42 additions and 6 deletions

View file

@ -9,23 +9,30 @@ declare(strict_types=1);
namespace OC\AppFramework\Utility;
use OCP\AppFramework\Utility\IControllerMethodReflector;
use Psr\Log\LoggerInterface;
/**
* Reads and parses annotations from doc comments
*/
class ControllerMethodReflector implements IControllerMethodReflector {
public $annotations = [];
private $types = [];
private $parameters = [];
public array $annotations = [];
private array $types = [];
private array $parameters = [];
private array $ranges = [];
private ?\ReflectionMethod $reflectionMethod = null;
public function __construct(
private readonly LoggerInterface $logger,
) {
}
/**
* @param object $object an object or classname
* @param string $method the method which we want to inspect
*/
public function reflect($object, string $method) {
$reflection = new \ReflectionMethod($object, $method);
$docs = $reflection->getDocComment();
$this->reflectionMethod = new \ReflectionMethod($object, $method);
$docs = $this->reflectionMethod->getDocComment();
if ($docs !== false) {
// extract everything prefixed by @ and first letter uppercase
@ -64,7 +71,7 @@ class ControllerMethodReflector implements IControllerMethodReflector {
}
}
foreach ($reflection->getParameters() as $param) {
foreach ($this->reflectionMethod->getParameters() as $param) {
// extract type information from PHP 7 scalar types and prefer them over phpdoc annotations
$type = $param->getType();
if ($type instanceof \ReflectionNamedType) {
@ -109,6 +116,24 @@ class ControllerMethodReflector implements IControllerMethodReflector {
return $this->parameters;
}
/**
* @template T
*
* @param class-string<T> $attributeClass
*/
public function hasAnnotationOrAttribute(?string $annotationName, string $attributeClass): bool {
if (!empty($this->reflectionMethod->getAttributes($attributeClass))) {
return true;
}
if ($annotationName && $this->hasAnnotation($annotationName)) {
$this->logger->debug($this->reflectionMethod->getDeclaringClass()->getName() . '::' . $this->reflectionMethod->getName() . ' uses the @' . $annotationName . ' annotation and should use the #[' . $attributeClass . '] attribute instead');
return true;
}
return false;
}
/**
* Check if a method contains an annotation
* @param string $name the name of the annotation

View file

@ -56,4 +56,15 @@ interface IControllerMethodReflector {
* @see https://help.nextcloud.com/t/how-should-we-use-php8-attributes/104278
*/
public function hasAnnotation(string $name): bool;
/**
* @template T
*
* Check if a method contains an annotation or an attribute.
* Log a debug line if the annotation is used.
*
* @param class-string<T> $attributeClass
* @since 34.0.0
*/
public function hasAnnotationOrAttribute(?string $annotationName, string $attributeClass): bool;
}