-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathHandlerFinder.php
More file actions
118 lines (93 loc) · 3.48 KB
/
HandlerFinder.php
File metadata and controls
118 lines (93 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
declare(strict_types=1);
namespace Patchlevel\EventSourcing\CommandBus;
use Patchlevel\EventSourcing\Attribute\Handle;
use ReflectionClass;
use ReflectionMethod;
use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\Type\UnionType;
use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
final class HandlerFinder
{
private static TypeResolver $typeResolver;
/**
* @param class-string $classString
*
* @return iterable<int, HandlerReference>
*/
public static function findInClass(string $classString): iterable
{
$reflectionClass = new ReflectionClass($classString);
foreach ($reflectionClass->getMethods() as $reflectionMethod) {
$handleAttributes = $reflectionMethod->getAttributes(Handle::class);
if ($handleAttributes === []) {
continue;
}
foreach ($handleAttributes as $attribute) {
$handle = $attribute->newInstance();
if ($handle->commandClass !== null) {
yield new HandlerReference(
$handle->commandClass,
$reflectionMethod->getName(),
$reflectionMethod->isStatic(),
);
continue;
}
foreach (self::guessHandledClasses($reflectionMethod) as $class) {
yield new HandlerReference(
$class,
$reflectionMethod->getName(),
$reflectionMethod->isStatic(),
);
}
}
}
}
/** @return list<class-string> */
private static function guessHandledClasses(ReflectionMethod $reflectionMethod): array
{
$parameters = $reflectionMethod->getParameters();
if ($parameters === []) {
throw InvalidHandleMethod::noParameters(
$reflectionMethod->getDeclaringClass()->getName(),
$reflectionMethod->getName(),
);
}
$reflectionType = $parameters[0]->getType();
if ($reflectionType === null) {
throw InvalidHandleMethod::incompatibleType(
$reflectionMethod->getDeclaringClass()->getName(),
$reflectionMethod->getName(),
);
}
$type = self::typeResolver()->resolve($reflectionType);
if ($type instanceof ObjectType) {
/** @var class-string $className */
$className = $type->getClassName();
return [$className];
}
if ($type instanceof UnionType) {
$types = [];
foreach ($type->getTypes() as $unionType) {
if (!$unionType instanceof ObjectType) {
throw InvalidHandleMethod::incompatibleType(
$reflectionMethod->getDeclaringClass()->getName(),
$reflectionMethod->getName(),
);
}
/** @var class-string $className */
$className = $unionType->getClassName();
$types[] = $className;
}
return $types;
}
throw InvalidHandleMethod::incompatibleType(
$reflectionMethod->getDeclaringClass()->getName(),
$reflectionMethod->getName(),
);
}
private static function typeResolver(): TypeResolver
{
return self::$typeResolver ??= TypeResolver::create();
}
}