Skip to content

Commit 27d9814

Browse files
Majkl578dg
authored andcommitted
PhpGenerator: Added support for variadics (PHP 5.6 feature) [Closes nette/nette#1414]
1 parent c44ffb6 commit 27d9814

File tree

2 files changed

+120
-1
lines changed

2 files changed

+120
-1
lines changed

src/PhpGenerator/Method.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
* @method bool isAbstract()
3333
* @method Method setReturnReference(bool)
3434
* @method bool getReturnReference()
35+
* @method Method setVariadic(bool)
36+
* @method bool isVariadic()
3537
* @method Method setDocuments(string[])
3638
* @method string[] getDocuments()
3739
* @method Method addDocument(string)
@@ -65,6 +67,9 @@ class Method extends Nette\Object
6567
/** @var bool */
6668
private $returnReference;
6769

70+
/** @var bool */
71+
private $variadic;
72+
6873
/** @var array of string */
6974
private $documents = array();
7075

@@ -84,6 +89,7 @@ public static function from($from)
8489
$method->abstract = $from->isAbstract() && !$from->getDeclaringClass()->isInterface();
8590
$method->body = $from->isAbstract() ? FALSE : '';
8691
$method->returnReference = $from->returnsReference();
92+
$method->variadic = PHP_VERSION_ID >= 50600 && $from->isVariadic();
8793
$method->documents = preg_replace('#^\s*\* ?#m', '', trim($from->getDocComment(), "/* \r\n"));
8894
return $method;
8995
}
@@ -129,10 +135,12 @@ public function __toString()
129135
{
130136
$parameters = array();
131137
foreach ($this->parameters as $param) {
138+
$variadic = $this->variadic && $param === end($this->parameters);
132139
$parameters[] = ($param->typeHint ? $param->typeHint . ' ' : '')
133140
. ($param->reference ? '&' : '')
141+
. ($variadic ? '...' : '')
134142
. '$' . $param->name
135-
. ($param->optional ? ' = ' . Helpers::dump($param->defaultValue) : '');
143+
. ($param->optional && !$variadic ? ' = ' . Helpers::dump($param->defaultValue) : '');
136144
}
137145
$uses = array();
138146
foreach ($this->uses as $param) {
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\PhpGenerator & variadics.
5+
*
6+
* @author Michael Moravec
7+
* @phpversion 5.6
8+
*/
9+
10+
use Nette\PhpGenerator\Method,
11+
Nette\PhpGenerator\Parameter,
12+
Tester\Assert;
13+
14+
15+
require __DIR__ . '/../bootstrap.php';
16+
17+
18+
// test from
19+
20+
interface Variadics
21+
{
22+
function foo(...$foo);
23+
function bar($foo, array &...$bar);
24+
}
25+
26+
$method = Method::from(Variadics::class .'::foo');
27+
Assert::true($method->isVariadic());
28+
29+
$method = Method::from(Variadics::class . '::bar');
30+
Assert::true($method->isVariadic());
31+
Assert::true($method->getParameters()['bar']->isReference());
32+
Assert::same('array', $method->getParameters()['bar']->getTypeHint());
33+
34+
35+
36+
// test generating
37+
38+
// parameterless variadic method
39+
$method = (new Method)
40+
->setName('variadic')
41+
->setVariadic(TRUE)
42+
->setBody('return 42;');
43+
44+
Assert::match(
45+
'function variadic()
46+
{
47+
return 42;
48+
}
49+
', (string) $method);
50+
51+
52+
// variadic method with one parameter
53+
$method = (new Method)
54+
->setName('variadic')
55+
->setVariadic(TRUE)
56+
->setBody('return 42;');
57+
$method->addParameter('foo');
58+
59+
Assert::match(
60+
'function variadic(...$foo)
61+
{
62+
return 42;
63+
}
64+
', (string) $method);
65+
66+
67+
// variadic method with multiple parameters
68+
$method = (new Method)
69+
->setName('variadic')
70+
->setVariadic(TRUE)
71+
->setBody('return 42;');
72+
$method->addParameter('foo');
73+
$method->addParameter('bar');
74+
$method->addParameter('baz', []);
75+
76+
Assert::match(
77+
'function variadic($foo, $bar, ...$baz)
78+
{
79+
return 42;
80+
}
81+
', (string) $method);
82+
83+
84+
// method with typehinted variadic param
85+
$method = (new Method)
86+
->setName('variadic')
87+
->setVariadic(TRUE)
88+
->setBody('return 42;');
89+
$method->addParameter('foo')->setTypeHint('array');
90+
91+
Assert::match(
92+
'function variadic(array ...$foo)
93+
{
94+
return 42;
95+
}
96+
', (string) $method);
97+
98+
99+
// method with typrhinted by-value variadic param
100+
$method = (new Method)
101+
->setName('variadic')
102+
->setVariadic(TRUE)
103+
->setBody('return 42;');
104+
$method->addParameter('foo')->setTypeHint('array')->setReference(TRUE);
105+
106+
Assert::match(
107+
'function variadic(array &...$foo)
108+
{
109+
return 42;
110+
}
111+
', (string) $method);

0 commit comments

Comments
 (0)