Skip to content

Commit f5ead28

Browse files
committed
Method split to GlobalFunction & Closure (BC break)
BC break: Method cannot render closure
1 parent e58789d commit f5ead28

File tree

8 files changed

+214
-84
lines changed

8 files changed

+214
-84
lines changed

src/PhpGenerator/Closure.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
* Closure.
15+
*
16+
* @property string $body
17+
*/
18+
class Closure
19+
{
20+
use Nette\SmartObject;
21+
use Traits\FunctionLike;
22+
23+
/** @var Parameter[] */
24+
private $uses = [];
25+
26+
27+
/**
28+
* @return static
29+
*/
30+
public static function from(\Closure $closure)
31+
{
32+
return (new Factory)->fromFunctionReflection(new \ReflectionFunction($closure));
33+
}
34+
35+
36+
/**
37+
* @return string PHP code
38+
*/
39+
public function __toString()
40+
{
41+
$uses = [];
42+
foreach ($this->uses as $param) {
43+
$uses[] = ($param->isReference() ? '&' : '') . '$' . $param->getName();
44+
}
45+
return 'function '
46+
. ($this->returnReference ? '&' : '')
47+
. $this->parametersToString()
48+
. ($this->uses ? ' use (' . implode(', ', $uses) . ')' : '')
49+
. $this->returnTypeToString()
50+
. " {\n" . Nette\Utils\Strings::indent(ltrim(rtrim($this->body) . "\n"), 1) . '}';
51+
}
52+
53+
54+
/**
55+
* @param Parameter[]
56+
* @return static
57+
*/
58+
public function setUses(array $uses)
59+
{
60+
$this->uses = $uses;
61+
return $this;
62+
}
63+
64+
65+
/**
66+
* @return array
67+
*/
68+
public function getUses()
69+
{
70+
return $this->uses;
71+
}
72+
73+
74+
/**
75+
* @return Parameter
76+
*/
77+
public function addUse($name)
78+
{
79+
return $this->uses[] = new Parameter($name);
80+
}
81+
82+
}

src/PhpGenerator/Factory.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ public function fromClassReflection(\ReflectionClass $from)
5858
*/
5959
public function fromFunctionReflection(\ReflectionFunctionAbstract $from)
6060
{
61-
$method = new Method($from->isClosure() ? NULL : $from->getName());
61+
$method = $from instanceof \ReflectionMethod
62+
? new Method($from->getName())
63+
: ($from->isClosure() ? new Closure : new GlobalFunction($from->getName()));
6264
$method->setParameters(array_map([$this, 'fromParameterReflection'], $from->getParameters()));
6365
if ($from instanceof \ReflectionMethod) {
6466
$isInterface = $from->getDeclaringClass()->isInterface();
@@ -70,7 +72,9 @@ public function fromFunctionReflection(\ReflectionFunctionAbstract $from)
7072
}
7173
$method->setReturnReference($from->returnsReference());
7274
$method->setVariadic($from->isVariadic());
73-
$method->setComment(Helpers::unformatDocComment($from->getDocComment()));
75+
if (!$from->isClosure()) {
76+
$method->setComment(Helpers::unformatDocComment($from->getDocComment()));
77+
}
7478
if (PHP_VERSION_ID >= 70000 && $from->hasReturnType()) {
7579
$method->setReturnType((string) $from->getReturnType());
7680
$method->setReturnNullable($from->getReturnType()->allowsNull());

src/PhpGenerator/GlobalFunction.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
* Global function.
15+
*
16+
* @property string $body
17+
*/
18+
class GlobalFunction
19+
{
20+
use Nette\SmartObject;
21+
use Traits\FunctionLike;
22+
use Traits\NameAware;
23+
use Traits\CommentAware;
24+
25+
/**
26+
* @param string
27+
* @return static
28+
*/
29+
public static function from($function)
30+
{
31+
return (new Factory)->fromFunctionReflection(new \ReflectionFunction($function));
32+
}
33+
34+
35+
/**
36+
* @return string PHP code
37+
*/
38+
public function __toString()
39+
{
40+
return Helpers::formatDocComment($this->comment . "\n")
41+
. 'function '
42+
. ($this->returnReference ? '&' : '')
43+
. $this->name
44+
. $this->parametersToString()
45+
. $this->returnTypeToString()
46+
. "\n{\n" . Nette\Utils\Strings::indent(ltrim(rtrim($this->body) . "\n"), 1) . '}';
47+
}
48+
49+
}

src/PhpGenerator/Method.php

Lines changed: 16 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
/**
14-
* Method or function description.
14+
* Class method.
1515
*
1616
* @property string|FALSE $body
1717
*/
@@ -23,12 +23,6 @@ class Method
2323
use Traits\VisibilityAware;
2424
use Traits\CommentAware;
2525

26-
/** @var Parameter[] */
27-
private $uses = [];
28-
29-
/** @var string|FALSE */
30-
private $body = '';
31-
3226
/** @var bool */
3327
private $static = FALSE;
3428

@@ -51,15 +45,23 @@ public static function from($method)
5145
}
5246

5347

48+
/**
49+
* @param string
50+
*/
51+
public function __construct($name = NULL)
52+
{
53+
if ($name === NULL) {
54+
throw new Nette\DeprecatedException('For closures use Nette\PhpGenerator\GlobalFunction instead of Nette\PhpGenerator\Method.');
55+
}
56+
$this->setName($name);
57+
}
58+
59+
5460
/**
5561
* @return string PHP code
5662
*/
5763
public function __toString()
5864
{
59-
$uses = [];
60-
foreach ($this->uses as $param) {
61-
$uses[] = ($param->isReference() ? '&' : '') . '$' . $param->getName();
62-
}
6365
return Helpers::formatDocComment($this->comment . "\n")
6466
. ($this->abstract ? 'abstract ' : '')
6567
. ($this->final ? 'final ' : '')
@@ -69,38 +71,10 @@ public function __toString()
6971
. ($this->returnReference ? '&' : '')
7072
. $this->name
7173
. $this->parametersToString()
72-
. ($this->uses ? ' use (' . implode(', ', $uses) . ')' : '')
7374
. $this->returnTypeToString()
74-
. ($this->abstract || $this->body === FALSE ? ';'
75-
: ($this->name ? "\n" : ' ') . "{\n" . Nette\Utils\Strings::indent(ltrim(rtrim($this->body) . "\n"), 1) . '}');
76-
}
77-
78-
79-
/**
80-
* @return static
81-
*/
82-
public function setUses(array $val)
83-
{
84-
$this->uses = $val;
85-
return $this;
86-
}
87-
88-
89-
/**
90-
* @return array
91-
*/
92-
public function getUses()
93-
{
94-
return $this->uses;
95-
}
96-
97-
98-
/**
99-
* @return Parameter
100-
*/
101-
public function addUse($name)
102-
{
103-
return $this->uses[] = new Parameter($name);
75+
. ($this->abstract || $this->body === FALSE
76+
? ';'
77+
: "\n{\n" . Nette\Utils\Strings::indent(ltrim(rtrim($this->body) . "\n"), 1) . '}');
10478
}
10579

10680

@@ -124,17 +98,6 @@ public function getBody()
12498
}
12599

126100

127-
/**
128-
* @param string
129-
* @return static
130-
*/
131-
public function addBody($code, array $args = NULL)
132-
{
133-
$this->body .= ($args === NULL ? $code : Helpers::formatArgs($code, $args)) . "\n";
134-
return $this;
135-
}
136-
137-
138101
/**
139102
* @param bool
140103
* @return static

src/PhpGenerator/Traits/FunctionLike.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
trait FunctionLike
2020
{
21+
/** @var string */
22+
private $body = '';
23+
2124
/** @var array of name => Parameter */
2225
private $parameters = [];
2326

@@ -37,6 +40,37 @@ trait FunctionLike
3740
private $namespace;
3841

3942

43+
/**
44+
* @param string
45+
* @return static
46+
*/
47+
public function setBody($code, array $args = NULL)
48+
{
49+
$this->body = $args === NULL ? $code : Helpers::formatArgs($code, $args);
50+
return $this;
51+
}
52+
53+
54+
/**
55+
* @return string
56+
*/
57+
public function getBody()
58+
{
59+
return $this->body;
60+
}
61+
62+
63+
/**
64+
* @param string
65+
* @return static
66+
*/
67+
public function addBody($code, array $args = NULL)
68+
{
69+
$this->body .= ($args === NULL ? $code : Helpers::formatArgs($code, $args)) . "\n";
70+
return $this;
71+
}
72+
73+
4074
/**
4175
* @param Parameter[]
4276
* @return static
Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
<?php
22

3-
/**
4-
* Test: Nette\PhpGenerator & function.
5-
*/
6-
7-
use Nette\PhpGenerator\Method;
3+
use Nette\PhpGenerator\Closure;
84
use Tester\Assert;
95

106

117
require __DIR__ . '/../bootstrap.php';
128

139

14-
$function = new Method;
10+
$function = new Closure;
1511
$function
1612
->setReturnReference(TRUE)
1713
->setBody('return $a + $b;');
@@ -28,26 +24,8 @@ Assert::match(
2824
}', (string) $function);
2925

3026

31-
/** closure */
3227
$closure = function (stdClass $a, $b = NULL) {};
33-
$function = Method::from($closure);
34-
Assert::match(
35-
'/**
36-
* closure
37-
*/
38-
function (stdClass $a, $b = NULL) {
39-
}', (string) $function);
40-
41-
42-
/** global */
43-
function func(stdClass $a, $b = NULL) {
44-
};
45-
46-
$function = Method::from('func');
28+
$function = Closure::from($closure);
4729
Assert::match(
48-
'/**
49-
* global
50-
*/
51-
function func(stdClass $a, $b = NULL)
52-
{
30+
'function (stdClass $a, $b = NULL) {
5331
}', (string) $function);

tests/PhpGenerator/Factory.phpt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ Assert::same('getName', $res->getName());
2424

2525

2626
$res = $factory->fromFunctionReflection(new \ReflectionFunction('trim'));
27-
Assert::type(Nette\PhpGenerator\Method::class, $res);
27+
Assert::type(Nette\PhpGenerator\GlobalFunction::class, $res);
2828
Assert::same('trim', $res->getName());
2929

3030

3131
$res = $factory->fromFunctionReflection(new \ReflectionFunction(function () {}));
32-
Assert::type(Nette\PhpGenerator\Method::class, $res);
33-
Assert::same('', $res->getName());
32+
Assert::type(Nette\PhpGenerator\Closure::class, $res);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
use Nette\PhpGenerator\GlobalFunction;
4+
use Tester\Assert;
5+
6+
7+
require __DIR__ . '/../bootstrap.php';
8+
9+
10+
/** global */
11+
function func(stdClass $a, $b = NULL) {
12+
};
13+
14+
$function = GlobalFunction::from('func');
15+
Assert::match(
16+
'/**
17+
* global
18+
*/
19+
function func(stdClass $a, $b = NULL)
20+
{
21+
}', (string) $function);

0 commit comments

Comments
 (0)