Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 920b970

Browse files
committed
added support for union types in arguments and persistent parameters
1 parent 6c7f23c commit 920b970

3 files changed

Lines changed: 91 additions & 4 deletions

File tree

src/Application/UI/ComponentReflection.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function getPersistentParams(string $class = null): array
5555
) {
5656
$params[$name] = [
5757
'def' => $default,
58-
'type' => Nette\Utils\Reflection::getPropertyType($rp) ?: gettype($default),
58+
'type' => self::getPropertyType($rp, $default),
5959
'since' => $isPresenter ? Nette\Utils\Reflection::getPropertyDeclaringClass($rp)->getName() : null,
6060
];
6161
}
@@ -190,7 +190,21 @@ public static function combineArgs(\ReflectionFunctionAbstract $method, array $a
190190
/**
191191
* Non data-loss type conversion.
192192
*/
193-
public static function convertType(&$val, string $type): bool
193+
public static function convertType(&$val, string $types): bool
194+
{
195+
foreach (explode('|', $types) as $type) {
196+
if (self::convertSingleType($val, $type)) {
197+
return true;
198+
}
199+
}
200+
return false;
201+
}
202+
203+
204+
/**
205+
* Non data-loss type conversion.
206+
*/
207+
private static function convertSingleType(&$val, string $type): bool
194208
{
195209
static $builtin = [
196210
'string' => 1, 'int' => 1, 'float' => 1, 'bool' => 1, 'array' => 1, 'object' => 1,
@@ -259,12 +273,22 @@ public static function parseAnnotation(\Reflector $ref, string $name): ?array
259273

260274
public static function getParameterType(\ReflectionParameter $param): string
261275
{
262-
return $param->hasType()
263-
? $param->getType()->getName()
276+
$type = $param->getType();
277+
return $type
278+
? ($type instanceof \ReflectionNamedType ? $type->getName() : (string) $type)
264279
: gettype($param->isDefaultValueAvailable() ? $param->getDefaultValue() : null);
265280
}
266281

267282

283+
public static function getPropertyType(\ReflectionProperty $prop, $default): string
284+
{
285+
$type = PHP_VERSION_ID < 70400 ? null : $prop->getType();
286+
return $type
287+
? ($type instanceof \ReflectionNamedType ? $type->getName() : (string) $type)
288+
: gettype($default);
289+
}
290+
291+
268292
/**
269293
* Has class specified annotation?
270294
*/
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/**
4+
* Test: ComponentReflection::combineArgs()
5+
* @phpVersion 8.0
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
use Nette\Application\UI\ComponentReflection as Reflection;
11+
use Tester\Assert;
12+
13+
require __DIR__ . '/../bootstrap.php';
14+
15+
16+
class MyPresenter
17+
{
18+
public function hintsUnion(int|array $intArray, string|array $strArray)
19+
{
20+
}
21+
}
22+
23+
24+
test('', function () {
25+
$method = new ReflectionMethod('MyPresenter', 'hintsUnion');
26+
27+
Assert::same([1, 'abc'], Reflection::combineArgs($method, ['intArray' => '1', 'strArray' => 'abc']));
28+
Assert::same([[1], [2]], Reflection::combineArgs($method, ['intArray' => [1], 'strArray' => [2]]));
29+
30+
Assert::exception(function () use ($method) {
31+
Reflection::combineArgs($method, []);
32+
}, Nette\InvalidArgumentException::class, 'Missing parameter $intArray required by MyPresenter::hintsUnion()');
33+
34+
Assert::exception(function () use ($method) {
35+
Reflection::combineArgs($method, ['intArray' => '']);
36+
}, Nette\InvalidArgumentException::class, 'Argument $intArray passed to MyPresenter::hintsUnion() must be array|int, string given.');
37+
38+
Assert::exception(function () use ($method) {
39+
Reflection::combineArgs($method, ['intArray' => null]);
40+
}, Nette\InvalidArgumentException::class, 'Missing parameter $intArray required by MyPresenter::hintsUnion()');
41+
42+
Assert::exception(function () use ($method) {
43+
Reflection::combineArgs($method, ['intArray' => new stdClass]);
44+
}, Nette\InvalidArgumentException::class, 'Argument $intArray passed to MyPresenter::hintsUnion() must be array|int, stdClass given.');
45+
});

tests/UI/ComponentReflection.convertType.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,21 @@ testIt('stdClass', 1.0);
244244
testIt('stdClass', 1.2);
245245

246246
testIt('Closure', $var = function () {}, $var);
247+
248+
249+
testIt('int|array', null);
250+
testIt('int|array', [], []);
251+
testIt('int|array', $obj);
252+
testIt('int|array', function () {});
253+
testIt('int|array', '');
254+
testIt('int|array', 'a');
255+
testIt('int|array', '1', 1);
256+
testIt('int|array', '1.0');
257+
testIt('int|array', '1.1');
258+
testIt('int|array', '1a');
259+
testIt('int|array', true, 1);
260+
testIt('int|array', false, 0);
261+
testIt('int|array', 0, 0);
262+
testIt('int|array', 1, 1);
263+
testIt('int|array', 1.0, 1);
264+
testIt('int|array', 1.2);

0 commit comments

Comments
 (0)