|
7 | 7 | use Nette\PhpGenerator\ClassType;
|
8 | 8 | use Nette\PhpGenerator\Factory;
|
9 | 9 | use Nette\PhpGenerator\Method;
|
10 |
| -use Nette\PhpGenerator\Parameter; |
11 | 10 | use Nette\PhpGenerator\PhpNamespace;
|
| 11 | +use Nette\PhpGenerator\PromotedParameter; |
12 | 12 | use Nette\PhpGenerator\Property;
|
13 |
| -use Nette\Utils\Type; |
14 | 13 | use Okapi\Aop\Core\Cache\CachePaths;
|
15 | 14 | use Okapi\Aop\Core\Container\AdviceContainer;
|
16 | 15 | use Okapi\Aop\Core\Container\AdviceType\MethodAdviceContainer;
|
17 | 16 | use Okapi\Aop\Core\JoinPoint\JoinPoint;
|
18 | 17 | use Okapi\Aop\Core\JoinPoint\JoinPointInjector;
|
19 | 18 | use Okapi\CodeTransformer\Core\DI;
|
20 | 19 | use Okapi\CodeTransformer\Transformer\Code;
|
| 20 | +use Roave\BetterReflection\Reflection\Adapter\ReflectionMethod; |
21 | 21 | use Roave\BetterReflection\Reflection\ReflectionMethod as BetterReflectionMethod;
|
22 | 22 |
|
23 | 23 | /**
|
@@ -206,24 +206,31 @@ private function buildMethods(): array
|
206 | 206 | * @param BetterReflectionMethod $refMethod
|
207 | 207 | *
|
208 | 208 | * @return Method
|
| 209 | + * |
| 210 | + * @noinspection PhpDocMissingThrowsInspection |
209 | 211 | */
|
210 | 212 | private function buildMethod(BetterReflectionMethod $refMethod): Method
|
211 | 213 | {
|
212 |
| - $method = (new Factory)->fromMethodReflection($refMethod); |
| 214 | + /** @noinspection PhpUnhandledExceptionInspection */ |
| 215 | + $method = (new Factory)->fromMethodReflection( |
| 216 | + new ReflectionMethod($refMethod), |
| 217 | + ); |
| 218 | + |
213 | 219 | $methodName = $refMethod->getName();
|
214 | 220 |
|
215 |
| - // Replace parameter and return types with the proxied class |
216 |
| - $declaringClass = $refMethod->getDeclaringClass(); |
217 |
| - $fullClassName = '\\' . $declaringClass->getNamespaceName() |
218 |
| - . '\\' . $declaringClass->getShortName(); |
219 |
| - $proxiedClassName = $fullClassName . $this->cachePaths::PROXIED_SUFFIX; |
220 |
| - foreach ($method->getParameters() as $parameter) { |
221 |
| - $this->replaceParameterType($parameter, $proxiedClassName); |
222 |
| - } |
223 |
| - if ($method->getReturnType() === 'self') { |
224 |
| - $method->setReturnType( |
225 |
| - $proxiedClassName, |
226 |
| - ); |
| 221 | + // ReadOnly Hack: https://github.com/nette/php-generator/issues/158 |
| 222 | + foreach ($refMethod->getParameters() as $refParameter) { |
| 223 | + if ($refParameter->isPromoted() |
| 224 | + && ($declaringClass = $refParameter->getDeclaringClass()) |
| 225 | + && ($refParameterName = $refParameter->getName()) |
| 226 | + && $declaringClass->hasProperty($refParameterName) |
| 227 | + && ($property = $declaringClass->getProperty($refParameterName)) |
| 228 | + && $property->isReadOnly() |
| 229 | + ) { |
| 230 | + /** @var PromotedParameter $parameter */ |
| 231 | + $parameter = $method->getParameter($refParameterName); |
| 232 | + $parameter->setReadOnly(); |
| 233 | + } |
227 | 234 | }
|
228 | 235 |
|
229 | 236 | // Add "return" if the method has a return type
|
@@ -260,67 +267,6 @@ private function buildMethod(BetterReflectionMethod $refMethod): Method
|
260 | 267 | return $method;
|
261 | 268 | }
|
262 | 269 |
|
263 |
| - /** |
264 |
| - * Replace the parameter type with the proxied class. |
265 |
| - * |
266 |
| - * @param Parameter|Type $parameterOrType |
267 |
| - * @param string $proxiedClassName |
268 |
| - * |
269 |
| - * @return void |
270 |
| - */ |
271 |
| - private function replaceParameterType( |
272 |
| - Parameter|Type $parameterOrType, |
273 |
| - string $proxiedClassName |
274 |
| - ): void { |
275 |
| - $objectType = $parameterOrType instanceof Parameter |
276 |
| - ? $parameterOrType->getType(true) |
277 |
| - : $parameterOrType; |
278 |
| - if (!$objectType) { |
279 |
| - return; |
280 |
| - } |
281 |
| - |
282 |
| - $typeString = $this->getTypeString($objectType, $proxiedClassName); |
283 |
| - $parameterOrType->setType($typeString); |
284 |
| - } |
285 |
| - |
286 |
| - /** |
287 |
| - * Get the parameter array as a string. |
288 |
| - * |
289 |
| - * @param Type $type |
290 |
| - * @param string $proxiedClassName |
291 |
| - * |
292 |
| - * @return string |
293 |
| - */ |
294 |
| - private function getTypeString(Type $type, string $proxiedClassName): string |
295 |
| - { |
296 |
| - // If the type is a union or intersection, we need to replace each type |
297 |
| - if ($type->isUnion() || $type->isIntersection()) { |
298 |
| - $typeNames = array_map(function ($type) use ($proxiedClassName) { |
299 |
| - return $this->getTypeString($type, $proxiedClassName); |
300 |
| - }, $type->getTypes()); |
301 |
| - $glue = $type->isUnion() ? '|' : '&'; |
302 |
| - return implode($glue, $typeNames); |
303 |
| - } elseif ($type->getSingleName() === 'self') { |
304 |
| - // If the type is "self", we need to replace it with the proxied |
305 |
| - // class |
306 |
| - return $proxiedClassName; |
307 |
| - } elseif ($type->isClass()) { |
308 |
| - // If the type is a class, we need to check if the class |
309 |
| - // is a proxy |
310 |
| - $typeFullClassName = '\\' . $type->getSingleName(); |
311 |
| - $typeProxiedClassName = |
312 |
| - $typeFullClassName . $this->cachePaths::PROXIED_SUFFIX; |
313 |
| - |
314 |
| - if (class_exists($typeFullClassName) |
315 |
| - && class_exists($typeProxiedClassName) |
316 |
| - ) { |
317 |
| - return $typeProxiedClassName; |
318 |
| - } |
319 |
| - } |
320 |
| - |
321 |
| - return $type->getSingleName(); |
322 |
| - } |
323 |
| - |
324 | 270 | /**
|
325 | 271 | * Create an associative array with the parameter name as key and the
|
326 | 272 | * parameter as value.
|
|
0 commit comments