88use Ock \Helpers \Util \MessageUtil ;
99use Ock \Reflection \FactoryReflectionInterface ;
1010use Ock \Reflection \NameHavingReflectionInterface ;
11- use Ock \ReflectorAwareAttributes \ReflectorAwareAttributeInterface ;
11+ use function Ock \ReflectorAwareAttributes \get_attributes ;
1212
1313/**
1414 * Helper methods to read attributes from reflectors.
@@ -31,15 +31,7 @@ public static function getAll(
3131 \ReflectionClass |\ReflectionFunctionAbstract |\ReflectionParameter |\ReflectionClassConstant |\ReflectionProperty |FactoryReflectionInterface $ reflector ,
3232 string $ name ,
3333 ): array {
34- $ instances = [];
35- /** @var \ReflectionAttribute<T> $attribute */
36- foreach ($ reflector ->getAttributes ($ name , \ReflectionAttribute::IS_INSTANCEOF ) as $ attribute ) {
37- $ instances [] = $ instance = $ attribute ->newInstance ();
38- if ($ instance instanceof ReflectorAwareAttributeInterface) {
39- $ instance ->setReflector ($ reflector );
40- }
41- }
42- return $ instances ;
34+ return get_attributes ($ reflector , $ name );
4335 }
4436
4537 /**
@@ -58,7 +50,14 @@ public static function hasSingle(
5850 \ReflectionClass |\ReflectionFunctionAbstract |\ReflectionParameter |\ReflectionClassConstant |\ReflectionProperty |FactoryReflectionInterface $ reflector ,
5951 string $ name ,
6052 ): bool {
61- return self ::getSingleAttribute ($ reflector , $ name ) !== null ;
53+ $ attributes = $ reflector ->getAttributes ($ name , \ReflectionAttribute::IS_INSTANCEOF );
54+ if (!$ attributes ) {
55+ return false ;
56+ }
57+ if (count ($ attributes ) > 1 ) {
58+ self ::failForRepeatedAttribute ($ name , $ reflector );
59+ }
60+ return true ;
6261 }
6362
6463 /**
@@ -80,17 +79,14 @@ public static function requireSingle(
8079 \ReflectionClass |\ReflectionFunctionAbstract |\ReflectionParameter |\ReflectionClassConstant |\ReflectionProperty |FactoryReflectionInterface $ reflector ,
8180 string $ name ,
8281 ): object {
83- $ instance = self ::getSingle ($ reflector , $ name );
84- if ($ instance === NULL ) {
85- throw new MalformedDeclarationException (sprintf (
86- 'Required attribute %s missing on %s. ' ,
87- $ name ,
88- $ reflector instanceof NameHavingReflectionInterface
89- ? $ reflector ->getDebugName ()
90- : MessageUtil::formatReflector ($ reflector ),
91- ));
82+ $ instances = get_attributes ($ reflector , $ name );
83+ if ($ instances === []) {
84+ self ::failForAttributeMissing ($ name , $ reflector );
85+ }
86+ if (count ($ instances ) > 1 ) {
87+ self ::failForRepeatedAttribute ($ name , $ reflector );
9288 }
93- return $ instance ;
89+ return reset ( $ instances ) ;
9490 }
9591
9692 /**
@@ -115,52 +111,60 @@ public static function getSingle(
115111 \ReflectionClass |\ReflectionFunctionAbstract |\ReflectionParameter |\ReflectionClassConstant |\ReflectionProperty |FactoryReflectionInterface $ reflector ,
116112 string $ name ,
117113 ): ?object {
118- $ attribute = self :: getSingleAttribute ($ reflector , $ name );
119- if ($ attribute === NULL ) {
120- return NULL ;
114+ $ instances = get_attributes ($ reflector , $ name );
115+ if ($ instances === [] ) {
116+ return null ;
121117 }
122- $ instance = $ attribute ->newInstance ();
123- if ($ instance instanceof ReflectorAwareAttributeInterface) {
124- $ instance ->setReflector ($ reflector );
118+ if (count ($ instances ) > 1 ) {
119+ self ::failForRepeatedAttribute ($ name , $ reflector );
125120 }
126- return $ instance ;
121+ return reset ( $ instances ) ;
127122 }
128123
129124 /**
130- * Gets and instantiates the first attribute of a given type, if exists .
125+ * Throws an exception stating that an attribute is missing .
131126 *
132- * @template T of object
127+ * @param class-string $name
128+ * Expected attribute class or interface.
129+ * @param \ReflectionClass|\ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionClassConstant|\ReflectionProperty|\Ock\Reflection\FactoryReflectionInterface $reflector
130+ * Reflector on which the attribute was expected.
133131 *
134- * @param \ReflectionClass<object>|\ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionClassConstant|\ReflectionProperty|\Ock\Reflection\FactoryReflectionInterface<object> $reflector
135- * Element that has the attribute.
136- * @param class-string<T> $name
137- * Expected attribute type/name.
132+ * @return never
133+ */
134+ private static function failForAttributeMissing (
135+ string $ name ,
136+ \ReflectionClass |\ReflectionFunctionAbstract |\ReflectionParameter |\ReflectionClassConstant |\ReflectionProperty |FactoryReflectionInterface $ reflector ,
137+ ): never {
138+ throw new MalformedDeclarationException (sprintf (
139+ 'Required attribute %s missing on %s. ' ,
140+ $ name ,
141+ $ reflector instanceof NameHavingReflectionInterface
142+ ? $ reflector ->getDebugName ()
143+ : MessageUtil::formatReflector ($ reflector ),
144+ ));
145+ }
146+
147+ /**
148+ * Throws an exception stating that too many attributes were found.
138149 *
139- * @return \ReflectionAttribute<T>|null
140- * Instance from the attribute, or NULL if no matching attribute found.
150+ * @param class-string $name
151+ * Filtering attribute class or interface.
152+ * @param \ReflectionClass|\ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionClassConstant|\ReflectionProperty|\Ock\Reflection\FactoryReflectionInterface $reflector
153+ * Reflector on which the attributes were found.
141154 *
142- * @throws \Ock\ClassDiscovery\Exception\MalformedDeclarationException
143- * More than one attribute of the given type.
155+ * @return never
144156 */
145- private static function getSingleAttribute (
146- \ReflectionClass |\ReflectionFunctionAbstract |\ReflectionParameter |\ReflectionClassConstant |\ReflectionProperty |FactoryReflectionInterface $ reflector ,
157+ private static function failForRepeatedAttribute (
147158 string $ name ,
148- ): ?\ReflectionAttribute {
149- /** @var \ReflectionAttribute<T>[] $attributes */
150- $ attributes = $ reflector ->getAttributes ($ name , \ReflectionAttribute::IS_INSTANCEOF );
151- if (!$ attributes ) {
152- return null ;
153- }
154- if (\array_keys ($ attributes ) !== [0 ]) {
155- throw new MalformedDeclarationException (\sprintf (
156- 'More than one %s attribute found on %s. ' ,
157- $ name ,
158- $ reflector instanceof NameHavingReflectionInterface
159- ? $ reflector ->getDebugName ()
160- : MessageUtil::formatReflector ($ reflector ),
161- ));
162- }
163- return $ attributes [0 ];
159+ \ReflectionClass |\ReflectionFunctionAbstract |\ReflectionParameter |\ReflectionClassConstant |\ReflectionProperty |FactoryReflectionInterface $ reflector ,
160+ ): never {
161+ throw new MalformedDeclarationException (\sprintf (
162+ 'More than one %s attribute found on %s. ' ,
163+ $ name ,
164+ $ reflector instanceof NameHavingReflectionInterface
165+ ? $ reflector ->getDebugName ()
166+ : MessageUtil::formatReflector ($ reflector ),
167+ ));
164168 }
165169
166170}
0 commit comments