Skip to content

Commit 8b2a561

Browse files
committed
added Factory
1 parent 3f04d8a commit 8b2a561

File tree

6 files changed

+164
-87
lines changed

6 files changed

+164
-87
lines changed

src/PhpGenerator/ClassType.php

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,9 @@ class ClassType
7070
*/
7171
public static function from($from)
7272
{
73-
$from = $from instanceof \ReflectionClass ? $from : new \ReflectionClass($from);
74-
if (PHP_VERSION_ID >= 70000 && $from->isAnonymous()) {
75-
$class = new static;
76-
} else {
77-
$class = new static($from->getShortName(), new PhpNamespace($from->getNamespaceName()));
78-
}
79-
$class->type = $from->isInterface() ? 'interface' : ($from->isTrait() ? 'trait' : 'class');
80-
$class->final = $from->isFinal() && $class->type === 'class';
81-
$class->abstract = $from->isAbstract() && $class->type === 'class';
82-
$class->implements = $from->getInterfaceNames();
83-
$class->comment = Helpers::unformatDocComment($from->getDocComment());
84-
if ($from->getParentClass()) {
85-
$class->extends = $from->getParentClass()->getName();
86-
$class->implements = array_diff($class->implements, $from->getParentClass()->getInterfaceNames());
87-
}
88-
foreach ($from->getProperties() as $prop) {
89-
if ($prop->isDefault() && $prop->getDeclaringClass()->getName() === $from->getName()) {
90-
$class->properties[$prop->getName()] = Property::from($prop);
91-
}
92-
}
93-
foreach ($from->getMethods() as $method) {
94-
if ($method->getDeclaringClass()->getName() === $from->getName()) {
95-
$class->methods[$method->getName()] = Method::from($method)->setNamespace($class->namespace);
96-
}
97-
}
98-
return $class;
73+
return (new Factory)->fromClassReflection(
74+
$from instanceof \ReflectionClass ? $from : new \ReflectionClass($from)
75+
);
9976
}
10077

10178

src/PhpGenerator/Factory.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Nette Framework (https://nette.org)
5+
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6+
*/
7+
8+
namespace Nette\PhpGenerator;
9+
10+
use Nette;
11+
12+
13+
/**
14+
* Creates a representation based on reflection.
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+
}

src/PhpGenerator/Method.php

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,34 +56,9 @@ class Method extends Member
5656
*/
5757
public static function from($from)
5858
{
59-
if (is_string($from) && strpos($from, '::')) {
60-
$from = new \ReflectionMethod($from);
61-
} elseif (is_array($from)) {
62-
$from = new \ReflectionMethod($from[0], $from[1]);
63-
} elseif (!$from instanceof \ReflectionFunctionAbstract) {
64-
$from = new \ReflectionFunction($from);
65-
}
66-
67-
$method = new static($from->isClosure() ? NULL : $from->getName());
68-
foreach ($from->getParameters() as $param) {
69-
$method->parameters[$param->getName()] = Parameter::from($param);
70-
}
71-
if ($from instanceof \ReflectionMethod) {
72-
$isInterface = $from->getDeclaringClass()->isInterface();
73-
$method->static = $from->isStatic();
74-
$method->setVisibility($from->isPrivate() ? 'private' : ($from->isProtected() ? 'protected' : ($isInterface ? NULL : 'public')));
75-
$method->final = $from->isFinal();
76-
$method->abstract = $from->isAbstract() && !$isInterface;
77-
$method->body = $from->isAbstract() ? FALSE : '';
78-
}
79-
$method->returnReference = $from->returnsReference();
80-
$method->variadic = $from->isVariadic();
81-
$method->setComment(Helpers::unformatDocComment($from->getDocComment()));
82-
if (PHP_VERSION_ID >= 70000 && $from->hasReturnType()) {
83-
$method->returnType = (string) $from->getReturnType();
84-
$method->returnNullable = $from->getReturnType()->allowsNull();
85-
}
86-
return $method;
59+
return (new Factory)->fromFunctionReflection(
60+
$from instanceof \ReflectionFunctionAbstract ? $from : Nette\Utils\Callback::toReflection($from)
61+
);
8762
}
8863

8964

src/PhpGenerator/Parameter.php

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,7 @@ class Parameter
4141
*/
4242
public static function from(\ReflectionParameter $from)
4343
{
44-
$param = new static($from->getName());
45-
$param->reference = $from->isPassedByReference();
46-
if (PHP_VERSION_ID >= 70000) {
47-
$param->typeHint = $from->hasType() ? (string) $from->getType() : NULL;
48-
$param->nullable = $from->hasType() && $from->getType()->allowsNull();
49-
} elseif ($from->isArray() || $from->isCallable()) {
50-
$param->typeHint = $from->isArray() ? 'array' : 'callable';
51-
} else {
52-
try {
53-
$param->typeHint = $from->getClass() ? $from->getClass()->getName() : NULL;
54-
} catch (\ReflectionException $e) {
55-
if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) {
56-
$param->typeHint = $m[1];
57-
} else {
58-
throw $e;
59-
}
60-
}
61-
}
62-
if ($from->isDefaultValueAvailable()) {
63-
$param->hasDefaultValue = TRUE;
64-
$param->defaultValue = $from->isDefaultValueConstant()
65-
? new PhpLiteral($from->getDefaultValueConstantName())
66-
: $from->getDefaultValue();
67-
$param->nullable = $param->nullable && $param->defaultValue !== NULL;
68-
}
69-
return $param;
44+
return (new Factory)->fromParameterReflection($from);
7045
}
7146

7247

src/PhpGenerator/Property.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,7 @@ class Property extends Member
2727
*/
2828
public static function from(\ReflectionProperty $from)
2929
{
30-
$prop = new static($from->getName());
31-
$defaults = $from->getDeclaringClass()->getDefaultProperties();
32-
$prop->value = isset($defaults[$prop->getName()]) ? $defaults[$prop->getName()] : NULL;
33-
$prop->setStatic($from->isStatic());
34-
$prop->setVisibility($from->isPrivate() ? 'private' : ($from->isProtected() ? 'protected' : 'public'));
35-
$prop->setComment(Helpers::unformatDocComment($from->getDocComment()));
36-
return $prop;
30+
return (new Factory)->fromPropertyReflection($from);
3731
}
3832

3933

tests/PhpGenerator/Factory.phpt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\PhpGenerator\Factory
5+
*/
6+
7+
use Nette\PhpGenerator\Factory;
8+
use Tester\Assert;
9+
10+
11+
require __DIR__ . '/../bootstrap.php';
12+
13+
14+
$factory = new Factory;
15+
16+
$res = $factory->fromClassReflection(new ReflectionClass(stdClass::class));
17+
Assert::type(Nette\PhpGenerator\ClassType::class, $res);
18+
Assert::same('stdClass', $res->getName());
19+
20+
21+
$res = $factory->fromFunctionReflection(new \ReflectionMethod(ReflectionClass::class, 'getName'));
22+
Assert::type(Nette\PhpGenerator\Method::class, $res);
23+
Assert::same('getName', $res->getName());
24+
25+
26+
$res = $factory->fromFunctionReflection(new \ReflectionFunction('trim'));
27+
Assert::type(Nette\PhpGenerator\Method::class, $res);
28+
Assert::same('trim', $res->getName());
29+
30+
31+
$res = $factory->fromFunctionReflection(new \ReflectionFunction(function () {}));
32+
Assert::type(Nette\PhpGenerator\Method::class, $res);
33+
Assert::same('', $res->getName());

0 commit comments

Comments
 (0)