Skip to content

Commit

Permalink
PhpGenerator: Added support for variadics (PHP 5.6 feature) [Closes n…
Browse files Browse the repository at this point in the history
  • Loading branch information
Majkl578 authored and dg committed Feb 20, 2014
1 parent c44ffb6 commit 27d9814
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/PhpGenerator/Method.php
Expand Up @@ -32,6 +32,8 @@
* @method bool isAbstract()
* @method Method setReturnReference(bool)
* @method bool getReturnReference()
* @method Method setVariadic(bool)
* @method bool isVariadic()
* @method Method setDocuments(string[])
* @method string[] getDocuments()
* @method Method addDocument(string)
Expand Down Expand Up @@ -65,6 +67,9 @@ class Method extends Nette\Object
/** @var bool */
private $returnReference;

/** @var bool */
private $variadic;

/** @var array of string */
private $documents = array();

Expand All @@ -84,6 +89,7 @@ public static function from($from)
$method->abstract = $from->isAbstract() && !$from->getDeclaringClass()->isInterface();
$method->body = $from->isAbstract() ? FALSE : '';
$method->returnReference = $from->returnsReference();
$method->variadic = PHP_VERSION_ID >= 50600 && $from->isVariadic();
$method->documents = preg_replace('#^\s*\* ?#m', '', trim($from->getDocComment(), "/* \r\n"));
return $method;
}
Expand Down Expand Up @@ -129,10 +135,12 @@ public function __toString()
{
$parameters = array();
foreach ($this->parameters as $param) {
$variadic = $this->variadic && $param === end($this->parameters);
$parameters[] = ($param->typeHint ? $param->typeHint . ' ' : '')
. ($param->reference ? '&' : '')
. ($variadic ? '...' : '')
. '$' . $param->name
. ($param->optional ? ' = ' . Helpers::dump($param->defaultValue) : '');
. ($param->optional && !$variadic ? ' = ' . Helpers::dump($param->defaultValue) : '');
}
$uses = array();
foreach ($this->uses as $param) {
Expand Down
111 changes: 111 additions & 0 deletions tests/PhpGenerator/Method.variadics.phpt
@@ -0,0 +1,111 @@
<?php

/**
* Test: Nette\PhpGenerator & variadics.
*
* @author Michael Moravec
* @phpversion 5.6
*/

use Nette\PhpGenerator\Method,
Nette\PhpGenerator\Parameter,
Tester\Assert;


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


// test from

interface Variadics
{
function foo(...$foo);
function bar($foo, array &...$bar);
}

$method = Method::from(Variadics::class .'::foo');
Assert::true($method->isVariadic());

$method = Method::from(Variadics::class . '::bar');
Assert::true($method->isVariadic());
Assert::true($method->getParameters()['bar']->isReference());
Assert::same('array', $method->getParameters()['bar']->getTypeHint());



// test generating

// parameterless variadic method
$method = (new Method)
->setName('variadic')
->setVariadic(TRUE)
->setBody('return 42;');

Assert::match(
'function variadic()
{
return 42;
}
', (string) $method);


// variadic method with one parameter
$method = (new Method)
->setName('variadic')
->setVariadic(TRUE)
->setBody('return 42;');
$method->addParameter('foo');

Assert::match(
'function variadic(...$foo)
{
return 42;
}
', (string) $method);


// variadic method with multiple parameters
$method = (new Method)
->setName('variadic')
->setVariadic(TRUE)
->setBody('return 42;');
$method->addParameter('foo');
$method->addParameter('bar');
$method->addParameter('baz', []);

Assert::match(
'function variadic($foo, $bar, ...$baz)
{
return 42;
}
', (string) $method);


// method with typehinted variadic param
$method = (new Method)
->setName('variadic')
->setVariadic(TRUE)
->setBody('return 42;');
$method->addParameter('foo')->setTypeHint('array');

Assert::match(
'function variadic(array ...$foo)
{
return 42;
}
', (string) $method);


// method with typrhinted by-value variadic param
$method = (new Method)
->setName('variadic')
->setVariadic(TRUE)
->setBody('return 42;');
$method->addParameter('foo')->setTypeHint('array')->setReference(TRUE);

Assert::match(
'function variadic(array &...$foo)
{
return 42;
}
', (string) $method);

0 comments on commit 27d9814

Please sign in to comment.