/** * Maps reflection type * * @param php.ReflectionMethod|php.ReflectionParameter $reflect * @param string $name * @return php.Closure */ private function mapReflectionType($reflect, $name) { if ('self' === $name) { return function () use($reflect) { return new XPClass($reflect->getDeclaringClass()); }; } else { if ('parent' === $name) { return function () use($reflect) { if ($parent = $reflect->getDeclaringClass()->getParentClass()) { return new XPClass($parent); } throw new IllegalStateException('Cannot resolve parent type of class without parent'); }; } else { return function () use($name) { return Type::forName($name); }; } } }
/** * Maps method annotations * * @param php.ReflectionMethod $reflect * @return [:var] */ protected function methodAnnotations($reflect) { $annotations = []; foreach ($reflect->getAttributes() as $name => $value) { $annotations[$name] = empty($value) ? null : new Value($value[0]); } return empty($annotations) ? parent::methodAnnotations($reflect) : $annotations; }
/** * Invokes the method * * @param php.ReflectionMethod $reflect * @param var $instance * @param var[] $args * @return var */ private function invokeMethod($reflect, $instance, $args) { $reflect->setAccessible(true); try { return $reflect->invokeArgs($instance, $args); } catch (Throwable $e) { throw new TargetInvocationException('Invoking ' . $reflect->name . '() raised ' . nameof($e), $e); } catch (\ReflectionException $e) { throw new IllegalArgumentException('Verifying ' . $reflect->name . '(): ' . $e->getMessage()); } catch (\Exception $e) { throw new TargetInvocationException('Invoking ' . $reflect->name . '() raised ' . get_class($e), new Error($e->getMessage())); } catch (\Throwable $e) { throw new TargetInvocationException('Invoking ' . $reflect->name . '() raised ' . get_class($e), new Error($e->getMessage())); } }