Skip to content

Commit d7a6d36

Browse files
committed
Method, Parameter: added support for PHP 7.1 nullable types
1 parent fd404a8 commit d7a6d36

File tree

4 files changed

+97
-2
lines changed

4 files changed

+97
-2
lines changed

src/PhpGenerator/Method.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class Method
5858
/** @var string|NULL */
5959
private $returnType;
6060

61+
/** @var bool */
62+
private $returnNullable;
63+
6164

6265
/**
6366
* @return static
@@ -88,6 +91,7 @@ public static function from($from)
8891
$method->comment = $from->getDocComment() ? preg_replace('#^\s*\* ?#m', '', trim($from->getDocComment(), "/* \r\n\t")) : NULL;
8992
if (PHP_VERSION_ID >= 70000 && $from->hasReturnType()) {
9093
$method->returnType = (string) $from->getReturnType();
94+
$method->returnNullable = $from->getReturnType()->allowsNull();
9195
}
9296
return $method;
9397
}
@@ -111,7 +115,7 @@ public function __toString()
111115
foreach ($this->parameters as $param) {
112116
$variadic = $this->variadic && $param === end($this->parameters);
113117
$hint = $param->getTypeHint();
114-
$parameters[] = ($hint ? ($this->namespace ? $this->namespace->unresolveName($hint) : $hint) . ' ' : '')
118+
$parameters[] = ($hint ? ($param->isNullable() ? '?' : '') . ($this->namespace ? $this->namespace->unresolveName($hint) : $hint) . ' ' : '')
115119
. ($param->isReference() ? '&' : '')
116120
. ($variadic ? '...' : '')
117121
. '$' . $param->getName()
@@ -132,7 +136,8 @@ public function __toString()
132136
. ' ' . $this->name
133137
. '(' . implode(', ', $parameters) . ')'
134138
. ($this->uses ? ' use (' . implode(', ', $uses) . ')' : '')
135-
. ($this->returnType ? ': ' . ($this->namespace ? $this->namespace->unresolveName($this->returnType) : $this->returnType) : '')
139+
. ($this->returnType ? ': ' . ($this->returnNullable ? '?' : '')
140+
. ($this->namespace ? $this->namespace->unresolveName($this->returnType) : $this->returnType) : '')
136141
. ($this->abstract || $this->body === FALSE ? ';'
137142
: ($this->name ? "\n" : ' ') . "{\n" . Nette\Utils\Strings::indent(ltrim(rtrim($this->body) . "\n"), 1) . '}');
138143
}
@@ -355,6 +360,26 @@ public function getReturnReference()
355360
}
356361

357362

363+
/**
364+
* @param bool
365+
* @return static
366+
*/
367+
public function setReturnNullable($val)
368+
{
369+
$this->returnNullable = (bool) $val;
370+
return $this;
371+
}
372+
373+
374+
/**
375+
* @return bool
376+
*/
377+
public function getReturnNullable()
378+
{
379+
return $this->returnNullable;
380+
}
381+
382+
358383
/**
359384
* @param bool
360385
* @return static

src/PhpGenerator/Parameter.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class Parameter
2626
/** @var string|NULL */
2727
private $typeHint;
2828

29+
/** @var bool */
30+
private $nullable = FALSE;
31+
2932
/** @var bool */
3033
private $hasDefaultValue = FALSE;
3134

@@ -42,6 +45,7 @@ public static function from(\ReflectionParameter $from)
4245
$param->reference = $from->isPassedByReference();
4346
if (PHP_VERSION_ID >= 70000) {
4447
$param->typeHint = $from->hasType() ? (string) $from->getType() : NULL;
48+
$param->nullable = $from->hasType() && $from->getType()->allowsNull();
4549
} elseif ($from->isArray() || $from->isCallable()) {
4650
$param->typeHint = $from->isArray() ? 'array' : 'callable';
4751
} else {
@@ -57,6 +61,7 @@ public static function from(\ReflectionParameter $from)
5761
}
5862
$param->hasDefaultValue = $from->isDefaultValueAvailable();
5963
$param->defaultValue = $from->isDefaultValueAvailable() ? $from->getDefaultValue() : NULL;
64+
$param->nullable = $param->nullable && (!$param->hasDefaultValue || $param->defaultValue !== NULL);
6065
return $param;
6166
}
6267

@@ -148,6 +153,26 @@ public function isOptional()
148153
}
149154

150155

156+
/**
157+
* @param bool
158+
* @return static
159+
*/
160+
public function setNullable($state = TRUE)
161+
{
162+
$this->nullable = (bool) $state;
163+
return $this;
164+
}
165+
166+
167+
/**
168+
* @return bool
169+
*/
170+
public function isNullable()
171+
{
172+
return $this->nullable;
173+
}
174+
175+
151176
/**
152177
* @return static
153178
*/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class ClassA
2+
{
3+
4+
function func1(A $a, ?B $b, C $c = NULL, D $d = NULL, E $e, ?int $i = 1, ?array $arr = [])
5+
{
6+
}
7+
8+
9+
function func2(): ?stdClass
10+
{
11+
}
12+
13+
14+
function func3(): void
15+
{
16+
}
17+
18+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\PhpGenerator generator.
5+
* @phpversion 7.1
6+
*/
7+
8+
use Nette\PhpGenerator\ClassType;
9+
use Tester\Assert;
10+
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
/** */
15+
class ClassA
16+
{
17+
function func1(A $a, ?B $b, ?C $c = NULL, D $d = NULL, E $e, ?int $i = 1, ?array $arr = []) {}
18+
19+
function func2(): ?stdClass {}
20+
21+
function func3(): void {}
22+
}
23+
24+
25+
$res[] = ClassType::from(ClassA::class);
26+
27+
Assert::matchFile(__DIR__ . '/ClassType.from.php71.expect', implode("\n", $res));

0 commit comments

Comments
 (0)