1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\PhpGenerator;
9:
10: use Nette;
11:
12:
13: 14: 15:
16: class Factory
17: {
18: use Nette\SmartObject;
19:
20:
21: public function fromClassReflection(\ReflectionClass $from)
22: {
23: if (PHP_VERSION_ID >= 70000 && $from->isAnonymous()) {
24: $class = new ClassType;
25: } else {
26: $class = new ClassType($from->getShortName(), new PhpNamespace($from->getNamespaceName()));
27: }
28: $class->setType($from->isInterface() ? 'interface' : ($from->isTrait() ? 'trait' : 'class'));
29: $class->setFinal($from->isFinal() && $class->getType() === 'class');
30: $class->setAbstract($from->isAbstract() && $class->getType() === 'class');
31: $class->setImplements($from->getInterfaceNames());
32: $class->setComment(Helpers::unformatDocComment((string) $from->getDocComment()));
33: if ($from->getParentClass()) {
34: $class->setExtends($from->getParentClass()->getName());
35: $class->setImplements(array_diff($class->getImplements(), $from->getParentClass()->getInterfaceNames()));
36: }
37: $props = $methods = [];
38: foreach ($from->getProperties() as $prop) {
39: if ($prop->isDefault() && $prop->getDeclaringClass()->getName() === $from->getName()) {
40: $props[$prop->getName()] = $this->fromPropertyReflection($prop);
41: }
42: }
43: $class->setProperties($props);
44: foreach ($from->getMethods() as $method) {
45: if ($method->getDeclaringClass()->getName() === $from->getName()) {
46: $methods[$method->getName()] = $this->fromFunctionReflection($method)->setNamespace($class->getNamespace());
47: }
48: }
49: $class->setMethods($methods);
50: return $class;
51: }
52:
53:
54: public function fromFunctionReflection(\ReflectionFunctionAbstract $from)
55: {
56: $method = new Method($from->isClosure() ? NULL : $from->getName());
57: $params = [];
58: foreach ($from->getParameters() as $param) {
59: $params[$param->getName()] = $this->fromParameterReflection($param);
60: }
61: $method->setParameters($params);
62: if ($from instanceof \ReflectionMethod) {
63: $isInterface = $from->getDeclaringClass()->isInterface();
64: $method->setStatic($from->isStatic());
65: $method->setVisibility($from->isPrivate() ? 'private' : ($from->isProtected() ? 'protected' : ($isInterface ? NULL : 'public')));
66: $method->setFinal($from->isFinal());
67: $method->setAbstract($from->isAbstract() && !$isInterface);
68: $method->setBody($from->isAbstract() ? FALSE : '');
69: }
70: $method->setReturnReference($from->returnsReference());
71: $method->setVariadic($from->isVariadic());
72: $method->setComment(Helpers::unformatDocComment($from->getDocComment()));
73: if (PHP_VERSION_ID >= 70000 && $from->hasReturnType()) {
74: $method->setReturnType((string) $from->getReturnType());
75: $method->setReturnNullable($from->getReturnType()->allowsNull());
76: }
77: return $method;
78: }
79:
80:
81: public function fromParameterReflection(\ReflectionParameter $from)
82: {
83: $param = new Parameter($from->getName());
84: $param->setReference($from->isPassedByReference());
85: if (PHP_VERSION_ID >= 70000) {
86: $param->setTypeHint($from->hasType() ? (string) $from->getType() : NULL);
87: $param->setNullable($from->hasType() && $from->getType()->allowsNull());
88: } elseif ($from->isArray() || $from->isCallable()) {
89: $param->setTypeHint($from->isArray() ? 'array' : 'callable');
90: } else {
91: try {
92: $param->setTypeHint($from->getClass() ? $from->getClass()->getName() : NULL);
93: } catch (\ReflectionException $e) {
94: if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) {
95: $param->setTypeHint($m[1]);
96: } else {
97: throw $e;
98: }
99: }
100: }
101: if ($from->isDefaultValueAvailable()) {
102: $param->setOptional(TRUE);
103: $param->setDefaultValue($from->isDefaultValueConstant()
104: ? new PhpLiteral($from->getDefaultValueConstantName())
105: : $from->getDefaultValue());
106: $param->setNullable($param->isNullable() && $param->getDefaultValue() !== NULL);
107: }
108: return $param;
109: }
110:
111:
112: public function fromPropertyReflection(\ReflectionProperty $from)
113: {
114: $prop = new Property($from->getName());
115: $defaults = $from->getDeclaringClass()->getDefaultProperties();
116: $prop->setValue(isset($defaults[$prop->getName()]) ? $defaults[$prop->getName()] : NULL);
117: $prop->setStatic($from->isStatic());
118: $prop->setVisibility($from->isPrivate() ? 'private' : ($from->isProtected() ? 'protected' : 'public'));
119: $prop->setComment(Helpers::unformatDocComment($from->getDocComment()));
120: return $prop;
121: }
122:
123: }
124: