1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace EdmondsCommerce\DoctrineStaticMeta\CodeGeneration; |
||||
6 | |||||
7 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator; |
||||
8 | use ReflectionException; |
||||
9 | use RuntimeException; |
||||
10 | use ts\Reflection\ReflectionClass; |
||||
11 | |||||
12 | use function array_slice; |
||||
13 | use function str_replace; |
||||
14 | |||||
15 | class ReflectionHelper |
||||
16 | { |
||||
17 | |||||
18 | /** |
||||
19 | * @var NamespaceHelper |
||||
20 | */ |
||||
21 | protected $namespaceHelper; |
||||
22 | |||||
23 | 5 | public function __construct(NamespaceHelper $namespaceHelper) |
|||
24 | { |
||||
25 | 5 | $this->namespaceHelper = $namespaceHelper; |
|||
26 | 5 | } |
|||
27 | |||||
28 | /** |
||||
29 | * @param ReflectionClass $fieldTraitReflection |
||||
30 | * |
||||
31 | * @return string |
||||
32 | */ |
||||
33 | 1 | public function getFakerProviderFqnFromFieldTraitReflection(ReflectionClass $fieldTraitReflection): string |
|||
34 | { |
||||
35 | 1 | return str_replace( |
|||
36 | [ |
||||
37 | 1 | '\\Traits\\', |
|||
38 | 'FieldTrait', |
||||
39 | ], |
||||
40 | [ |
||||
41 | 1 | '\\FakerData\\', |
|||
42 | 'FakerData', |
||||
43 | ], |
||||
44 | 1 | $fieldTraitReflection->getName() |
|||
45 | ); |
||||
46 | } |
||||
47 | |||||
48 | /** |
||||
49 | * Work out the entity namespace root from a single entity reflection object. |
||||
50 | * |
||||
51 | * @param ReflectionClass $entityReflection |
||||
52 | * |
||||
53 | * @return string |
||||
54 | */ |
||||
55 | 1 | public function getEntityNamespaceRootFromEntityReflection( |
|||
56 | ReflectionClass $entityReflection |
||||
57 | ): string { |
||||
58 | 1 | return $this->namespaceHelper->tidy( |
|||
59 | 1 | $this->namespaceHelper->getNamespaceRootToDirectoryFromFqn( |
|||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
60 | 1 | $entityReflection->getName(), |
|||
61 | 1 | AbstractGenerator::ENTITIES_FOLDER_NAME |
|||
62 | ) |
||||
63 | ); |
||||
64 | } |
||||
65 | |||||
66 | /** |
||||
67 | * Find which trait is implementing a method in a class, |
||||
68 | * If it is not found in a trait, we return the class itself as it must be there |
||||
69 | * |
||||
70 | * @param ReflectionClass $reflectionClass |
||||
71 | * @param string $methodName |
||||
72 | * |
||||
73 | * @return ReflectionClass |
||||
74 | * @throws ReflectionException |
||||
75 | */ |
||||
76 | public function getTraitImplementingMethod(ReflectionClass $reflectionClass, string $methodName): ?ReflectionClass |
||||
77 | { |
||||
78 | $traitsWithMethod = []; |
||||
79 | foreach ($reflectionClass->getTraits() as $trait) { |
||||
80 | try { |
||||
81 | $trait->getMethod($methodName); |
||||
82 | $traitsWithMethod[] = $trait; |
||||
83 | } catch (ReflectionException $e) { |
||||
84 | continue; |
||||
85 | } |
||||
86 | } |
||||
87 | if (count($traitsWithMethod) > 1) { |
||||
88 | throw new RuntimeException( |
||||
89 | 'Found more than one trait implementing the method ' . $methodName . ' in ' . |
||||
90 | $reflectionClass->getShortName() |
||||
91 | ); |
||||
92 | } |
||||
93 | if ([] === $traitsWithMethod) { |
||||
94 | return null; |
||||
95 | } |
||||
96 | |||||
97 | return current($traitsWithMethod); |
||||
98 | } |
||||
99 | |||||
100 | /** |
||||
101 | * Find which trait is implementing a method in a class |
||||
102 | * |
||||
103 | * @param ReflectionClass $class |
||||
104 | * @param string $propertyName |
||||
105 | * |
||||
106 | * @return ReflectionClass |
||||
107 | * @throws ReflectionException |
||||
108 | */ |
||||
109 | 1 | public function getTraitProvidingProperty(ReflectionClass $class, string $propertyName): ReflectionClass |
|||
110 | { |
||||
111 | 1 | $traitsWithProperty = []; |
|||
112 | 1 | foreach ($class->getTraits() as $trait) { |
|||
113 | try { |
||||
114 | 1 | $trait->getProperty($propertyName); |
|||
115 | 1 | $traitsWithProperty[] = $trait; |
|||
116 | 1 | } catch (ReflectionException $e) { |
|||
117 | 1 | continue; |
|||
118 | } |
||||
119 | } |
||||
120 | 1 | if ([] === $traitsWithProperty) { |
|||
121 | if ($class->isTrait() && $class->hasProperty($propertyName)) { |
||||
122 | return $class; |
||||
123 | } |
||||
124 | throw new RuntimeException( |
||||
125 | 'Failed finding trait providing the property ' . $propertyName . ' in ' . |
||||
126 | $class->getShortName() |
||||
127 | ); |
||||
128 | } |
||||
129 | 1 | if (count($traitsWithProperty) > 1) { |
|||
130 | throw new RuntimeException( |
||||
131 | 'Found more than one trait providing the property ' . $propertyName . ' in ' . |
||||
132 | $class->getShortName() |
||||
133 | ); |
||||
134 | } |
||||
135 | |||||
136 | 1 | return current($traitsWithProperty); |
|||
137 | } |
||||
138 | |||||
139 | /** |
||||
140 | * Get the full method body using reflection |
||||
141 | * |
||||
142 | * @param string $methodName |
||||
143 | * @param ReflectionClass $reflectionClass |
||||
144 | * |
||||
145 | * @return string |
||||
146 | */ |
||||
147 | 1 | public function getMethodBody(string $methodName, ReflectionClass $reflectionClass): string |
|||
148 | { |
||||
149 | 1 | $method = $reflectionClass->getMethod($methodName); |
|||
150 | 1 | $startLine = $method->getStartLine() - 1; |
|||
151 | 1 | $length = $method->getEndLine() - $startLine; |
|||
152 | 1 | $lines = file($reflectionClass->getFileName()); |
|||
153 | 1 | $methodLines = array_slice($lines, $startLine, $length); |
|||
0 ignored issues
–
show
It seems like
$lines can also be of type false ; however, parameter $array of array_slice() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
154 | |||||
155 | 1 | return implode('', $methodLines); |
|||
156 | } |
||||
157 | |||||
158 | /** |
||||
159 | * @param ReflectionClass $reflectionClass |
||||
160 | * |
||||
161 | * @return array|string[] |
||||
162 | */ |
||||
163 | 1 | public function getUseStatements(ReflectionClass $reflectionClass): array |
|||
164 | { |
||||
165 | 1 | $content = \ts\file_get_contents($reflectionClass->getFileName()); |
|||
166 | 1 | preg_match_all('%^use.+?;%m', $content, $matches); |
|||
167 | |||||
168 | 1 | return $matches[0]; |
|||
169 | } |
||||
170 | } |
||||
171 |