Skip to content

Commit 5d6415c

Browse files
Remove bootstrap file and autoload AttributeHelper
1 parent 58ef429 commit 5d6415c

31 files changed

+155
-277
lines changed

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
"PhpStaticAnalysis\\Attributes\\": "src/"
99
}
1010
},
11+
"autoload-dev": {
12+
"files": ["tests/AttributeHelper.php"]
13+
},
1114
"authors": [
1215
{
1316
"name": "Carlos Granados",

tests/AssertIfFalseTest.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,26 +115,17 @@ private function getAsserts(string $functionName): array
115115
public static function getAssertsFromReflection(
116116
ReflectionMethod | ReflectionFunction $reflection
117117
): array {
118-
$attributes = $reflection->getAttributes();
118+
$instances = AttributeHelper::getFunctionInstances($reflection, AssertIfFalse::class);
119119
$asserts = [];
120-
foreach ($attributes as $attribute) {
121-
if ($attribute->getName() === AssertIfFalse::class) {
122-
$instance = $attribute->newInstance();
123-
assert($instance instanceof AssertIfFalse);
124-
$asserts = array_merge($asserts, $instance->params);
125-
}
120+
121+
foreach ($instances['function'] as $instance) {
122+
$asserts = array_merge($asserts, $instance->params);
126123
}
127124

128-
$parameters = $reflection->getParameters();
129-
foreach ($parameters as $parameter) {
130-
$attributes = $parameter->getAttributes();
131-
foreach ($attributes as $attribute) {
132-
if ($attribute->getName() === AssertIfFalse::class) {
133-
$instance = $attribute->newInstance();
134-
assert($instance instanceof AssertIfFalse);
135-
$argument = $instance->params[array_key_first($instance->params)];
136-
$asserts[$parameter->name] = $argument;
137-
}
125+
foreach ($instances['parameters'] as $name => $attrs) {
126+
foreach ($attrs as $instance) {
127+
$argument = $instance->params[array_key_first($instance->params)];
128+
$asserts[$name] = $argument;
138129
}
139130
}
140131

tests/AssertIfTrueTest.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,26 +115,17 @@ private function getAsserts(string $functionName): array
115115
public static function getAssertsFromReflection(
116116
ReflectionMethod | ReflectionFunction $reflection
117117
): array {
118-
$attributes = $reflection->getAttributes();
118+
$instances = AttributeHelper::getFunctionInstances($reflection, AssertIfTrue::class);
119119
$asserts = [];
120-
foreach ($attributes as $attribute) {
121-
if ($attribute->getName() === AssertIfTrue::class) {
122-
$instance = $attribute->newInstance();
123-
assert($instance instanceof AssertIfTrue);
124-
$asserts = array_merge($asserts, $instance->params);
125-
}
120+
121+
foreach ($instances['function'] as $instance) {
122+
$asserts = array_merge($asserts, $instance->params);
126123
}
127124

128-
$parameters = $reflection->getParameters();
129-
foreach ($parameters as $parameter) {
130-
$attributes = $parameter->getAttributes();
131-
foreach ($attributes as $attribute) {
132-
if ($attribute->getName() === AssertIfTrue::class) {
133-
$instance = $attribute->newInstance();
134-
assert($instance instanceof AssertIfTrue);
135-
$argument = $instance->params[array_key_first($instance->params)];
136-
$asserts[$parameter->name] = $argument;
137-
}
125+
foreach ($instances['parameters'] as $name => $attrs) {
126+
foreach ($attrs as $instance) {
127+
$argument = $instance->params[array_key_first($instance->params)];
128+
$asserts[$name] = $argument;
138129
}
139130
}
140131

tests/AssertTest.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,26 +104,17 @@ private function getAsserts(string $functionName): array
104104
public static function getAssertsFromReflection(
105105
ReflectionMethod | ReflectionFunction $reflection
106106
): array {
107-
$attributes = $reflection->getAttributes();
107+
$instances = AttributeHelper::getFunctionInstances($reflection, Assert::class);
108108
$asserts = [];
109-
foreach ($attributes as $attribute) {
110-
if ($attribute->getName() === Assert::class) {
111-
$instance = $attribute->newInstance();
112-
assert($instance instanceof Assert);
113-
$asserts = array_merge($asserts, $instance->params);
114-
}
109+
110+
foreach ($instances['function'] as $instance) {
111+
$asserts = array_merge($asserts, $instance->params);
115112
}
116113

117-
$parameters = $reflection->getParameters();
118-
foreach ($parameters as $parameter) {
119-
$attributes = $parameter->getAttributes();
120-
foreach ($attributes as $attribute) {
121-
if ($attribute->getName() === Assert::class) {
122-
$instance = $attribute->newInstance();
123-
assert($instance instanceof Assert);
124-
$argument = $instance->params[array_key_first($instance->params)];
125-
$asserts[$parameter->name] = $argument;
126-
}
114+
foreach ($instances['parameters'] as $name => $attrs) {
115+
foreach ($attrs as $instance) {
116+
$argument = $instance->params[array_key_first($instance->params)];
117+
$asserts[$name] = $argument;
127118
}
128119
}
129120

tests/AttributeHelper.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
6+
final class AttributeHelper
7+
{
8+
/**
9+
* Return instances of an attribute on a reflector.
10+
*
11+
* @template T of object
12+
* @param \ReflectionClass|\ReflectionFunction|\ReflectionMethod|\ReflectionParameter|\ReflectionProperty|\ReflectionClassConstant $reflector
13+
* @param class-string<T> $attributeClass
14+
* @return list<T>
15+
*/
16+
public static function getInstances(\Reflector $reflector, string $attributeClass): array
17+
{
18+
return array_map(
19+
static fn (\ReflectionAttribute $attribute) => $attribute->newInstance(),
20+
$reflector->getAttributes($attributeClass)
21+
);
22+
}
23+
24+
/**
25+
* Retrieve attribute instances from a function or method and its parameters.
26+
*
27+
* @template T of object
28+
* @param \ReflectionFunction|\ReflectionMethod $reflector
29+
* @param class-string<T> $attributeClass
30+
* @return array{function: list<T>, parameters: array<string, list<T>>}
31+
*/
32+
public static function getFunctionInstances(\ReflectionFunctionAbstract $reflector, string $attributeClass): array
33+
{
34+
$function = self::getInstances($reflector, $attributeClass);
35+
$parameters = [];
36+
foreach ($reflector->getParameters() as $parameter) {
37+
$parameters[$parameter->name] = self::getInstances($parameter, $attributeClass);
38+
}
39+
return ['function' => $function, 'parameters' => $parameters];
40+
}
41+
}

tests/DefineTypeTest.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,10 @@ public function testClassTypes(): void
2727
public static function getPropertiesFromReflection(
2828
ReflectionClass $reflection
2929
): array {
30-
$attributes = $reflection->getAttributes();
30+
$instances = AttributeHelper::getInstances($reflection, DefineType::class);
3131
$properties = [];
32-
foreach ($attributes as $attribute) {
33-
if ($attribute->getName() === DefineType::class) {
34-
$instance = $attribute->newInstance();
35-
assert($instance instanceof DefineType);
36-
$properties = array_merge($properties, $instance->types);
37-
}
32+
foreach ($instances as $instance) {
33+
$properties = array_merge($properties, $instance->types);
3834
}
3935

4036
return $properties;

tests/DeprecatedTest.php

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,7 @@ private function getDeprecated(string $methodName): bool
7878
public static function getDeprecatedFromReflection(
7979
ReflectionMethod | ReflectionFunction | ReflectionClass | ReflectionProperty $reflection
8080
): bool {
81-
$attributes = $reflection->getAttributes();
82-
$deprecated = false;
83-
foreach ($attributes as $attribute) {
84-
if ($attribute->getName() === Deprecated::class) {
85-
$attribute->newInstance();
86-
$deprecated = true;
87-
}
88-
}
89-
90-
return $deprecated;
81+
return AttributeHelper::getInstances($reflection, Deprecated::class) !== [];
9182
}
9283
}
9384

tests/ImmutableTest.php

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,7 @@ public function testInterfaceImmutable(): void
2929
public static function getImmutableFromReflection(
3030
ReflectionClass $reflection
3131
): bool {
32-
$attributes = $reflection->getAttributes();
33-
$immutable = false;
34-
foreach ($attributes as $attribute) {
35-
if ($attribute->getName() === Immutable::class) {
36-
$attribute->newInstance();
37-
$immutable = true;
38-
}
39-
}
40-
41-
return $immutable;
32+
return AttributeHelper::getInstances($reflection, Immutable::class) !== [];
4233
}
4334
}
4435

tests/ImportTypeTest.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,10 @@ public function testClassTypes(): void
2828
public static function getPropertiesFromReflection(
2929
ReflectionClass $reflection
3030
): array {
31-
$attributes = $reflection->getAttributes();
31+
$instances = AttributeHelper::getInstances($reflection, ImportType::class);
3232
$properties = [];
33-
foreach ($attributes as $attribute) {
34-
if ($attribute->getName() === ImportType::class) {
35-
$instance = $attribute->newInstance();
36-
assert($instance instanceof ImportType);
37-
$properties = array_merge($properties, $instance->from);
38-
}
33+
foreach ($instances as $instance) {
34+
$properties = array_merge($properties, $instance->from);
3935
}
4036

4137
return $properties;

tests/ImpureTest.php

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,7 @@ private function getImpure(string $methodName): bool
3232
public static function getImpureFromReflection(
3333
ReflectionMethod | ReflectionFunction $reflection
3434
): bool {
35-
$attributes = $reflection->getAttributes();
36-
$impure = false;
37-
foreach ($attributes as $attribute) {
38-
if ($attribute->getName() === Impure::class) {
39-
$attribute->newInstance();
40-
$impure = true;
41-
}
42-
}
43-
44-
return $impure;
35+
return AttributeHelper::getInstances($reflection, Impure::class) !== [];
4536
}
4637
}
4738

tests/IsReadOnlyTest.php

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,6 @@ private function multipleReadOnly(): bool
6464
private function getReadOnly(string $propertyName): bool
6565
{
6666
$reflection = new ReflectionProperty($this, $propertyName);
67-
$attributes = $reflection->getAttributes();
68-
$isReadOnly = false;
69-
foreach ($attributes as $attribute) {
70-
if ($attribute->getName() === IsReadOnly::class) {
71-
$attribute->newInstance();
72-
$isReadOnly = true;
73-
}
74-
}
75-
76-
return $isReadOnly;
67+
return AttributeHelper::getInstances($reflection, IsReadOnly::class) !== [];
7768
}
7869
}

tests/MethodTest.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,10 @@ public function testClassMethods(): void
2525
public static function getMethodsFromReflection(
2626
ReflectionClass $reflection
2727
): array {
28-
$attributes = $reflection->getAttributes();
28+
$instances = AttributeHelper::getInstances($reflection, Method::class);
2929
$methods = [];
30-
foreach ($attributes as $attribute) {
31-
if ($attribute->getName() === Method::class) {
32-
$instance = $attribute->newInstance();
33-
assert($instance instanceof Method);
34-
$methods = array_merge($methods, $instance->methods);
35-
}
30+
foreach ($instances as $instance) {
31+
$methods = array_merge($methods, $instance->methods);
3632
}
3733

3834
return $methods;

tests/MixinTest.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,10 @@ public function testClassMixins(): void
3333
public static function getMixinsFromReflection(
3434
ReflectionClass $reflection
3535
): array {
36-
$attributes = $reflection->getAttributes();
36+
$instances = AttributeHelper::getInstances($reflection, Mixin::class);
3737
$mixins = [];
38-
foreach ($attributes as $attribute) {
39-
if ($attribute->getName() === Mixin::class) {
40-
$instance = $attribute->newInstance();
41-
assert($instance instanceof Mixin);
42-
$mixins = array_merge($mixins, $instance->classes);
43-
}
38+
foreach ($instances as $instance) {
39+
$mixins = array_merge($mixins, $instance->classes);
4440
}
4541

4642
return $mixins;

tests/ParamOutTest.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -111,26 +111,17 @@ private function getParamOuts(string $functionName): array
111111
public static function getParamOutsFromReflection(
112112
ReflectionMethod | ReflectionFunction $reflection
113113
): array {
114-
$attributes = $reflection->getAttributes();
114+
$instances = AttributeHelper::getFunctionInstances($reflection, ParamOut::class);
115115
$paramOuts = [];
116-
foreach ($attributes as $attribute) {
117-
if ($attribute->getName() === ParamOut::class) {
118-
$instance = $attribute->newInstance();
119-
assert($instance instanceof ParamOut);
120-
$paramOuts = array_merge($paramOuts, $instance->params);
121-
}
116+
117+
foreach ($instances['function'] as $instance) {
118+
$paramOuts = array_merge($paramOuts, $instance->params);
122119
}
123120

124-
$parameters = $reflection->getParameters();
125-
foreach ($parameters as $parameter) {
126-
$attributes = $parameter->getAttributes();
127-
foreach ($attributes as $attribute) {
128-
if ($attribute->getName() === ParamOut::class) {
129-
$instance = $attribute->newInstance();
130-
assert($instance instanceof ParamOut);
131-
$argument = $instance->params[array_key_first($instance->params)];
132-
$paramOuts[$parameter->name] = $argument;
133-
}
121+
foreach ($instances['parameters'] as $name => $attrs) {
122+
foreach ($attrs as $instance) {
123+
$argument = $instance->params[array_key_first($instance->params)];
124+
$paramOuts[$name] = $argument;
134125
}
135126
}
136127

tests/ParamTest.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,26 +115,17 @@ private function getParams(string $functionName): array
115115
public static function getParamsFromReflection(
116116
ReflectionMethod | ReflectionFunction $reflection
117117
): array {
118-
$attributes = $reflection->getAttributes();
118+
$instances = AttributeHelper::getFunctionInstances($reflection, Param::class);
119119
$params = [];
120-
foreach ($attributes as $attribute) {
121-
if ($attribute->getName() === Param::class) {
122-
$instance = $attribute->newInstance();
123-
assert($instance instanceof Param);
124-
$params = array_merge($params, $instance->params);
125-
}
120+
121+
foreach ($instances['function'] as $instance) {
122+
$params = array_merge($params, $instance->params);
126123
}
127124

128-
$parameters = $reflection->getParameters();
129-
foreach ($parameters as $parameter) {
130-
$attributes = $parameter->getAttributes();
131-
foreach ($attributes as $attribute) {
132-
if ($attribute->getName() === Param::class) {
133-
$instance = $attribute->newInstance();
134-
assert($instance instanceof Param);
135-
$argument = $instance->params[array_key_first($instance->params)];
136-
$params[$parameter->name] = $argument;
137-
}
125+
foreach ($instances['parameters'] as $name => $attrs) {
126+
foreach ($attrs as $instance) {
127+
$argument = $instance->params[array_key_first($instance->params)];
128+
$params[$name] = $argument;
138129
}
139130
}
140131

tests/PropertyReadTest.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,10 @@ public function testClassProperties(): void
2727
public static function getPropertiesFromReflection(
2828
ReflectionClass $reflection
2929
): array {
30-
$attributes = $reflection->getAttributes();
30+
$instances = AttributeHelper::getInstances($reflection, PropertyRead::class);
3131
$properties = [];
32-
foreach ($attributes as $attribute) {
33-
if ($attribute->getName() === PropertyRead::class) {
34-
$instance = $attribute->newInstance();
35-
assert($instance instanceof PropertyRead);
36-
$properties = array_merge($properties, $instance->properties);
37-
}
32+
foreach ($instances as $instance) {
33+
$properties = array_merge($properties, $instance->properties);
3834
}
3935

4036
return $properties;

0 commit comments

Comments
 (0)