Skip to content

Commit 19b3057

Browse files
committed
Reflection: added getReturnTypes(), getParameterTypes() and getPropertyTypes()
1 parent 21a840d commit 19b3057

File tree

4 files changed

+58
-3
lines changed

4 files changed

+58
-3
lines changed

src/Utils/Reflection.php

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ public static function getReturnType(\ReflectionFunctionAbstract $func): ?string
4545
}
4646

4747

48+
/**
49+
* Returns the types of return value of given function or method and normalizes `self`, `static`, and `parent` to actual class names.
50+
*/
51+
public static function getReturnTypes(\ReflectionFunctionAbstract $func): array
52+
{
53+
return self::getType($func, $func->getReturnType(), true);
54+
}
55+
56+
4857
/**
4958
* Returns the type of given parameter and normalizes `self` and `parent` to the actual class names.
5059
* If the parameter does not have a type, it returns null.
@@ -56,6 +65,15 @@ public static function getParameterType(\ReflectionParameter $param): ?string
5665
}
5766

5867

68+
/**
69+
* Returns the types of given parameter and normalizes `self` and `parent` to the actual class names.
70+
*/
71+
public static function getParameterTypes(\ReflectionParameter $param): array
72+
{
73+
return self::getType($param, $param->getType(), true);
74+
}
75+
76+
5977
/**
6078
* Returns the type of given property and normalizes `self` and `parent` to the actual class names.
6179
* If the property does not have a type, it returns null.
@@ -67,18 +85,41 @@ public static function getPropertyType(\ReflectionProperty $prop): ?string
6785
}
6886

6987

88+
/**
89+
* Returns the types of given property and normalizes `self` and `parent` to the actual class names.
90+
*/
91+
public static function getPropertyTypes(\ReflectionProperty $prop): array
92+
{
93+
return self::getType($prop, PHP_VERSION_ID >= 70400 ? $prop->getType() : null, true);
94+
}
95+
96+
7097
/**
7198
* @param \ReflectionFunction|\ReflectionMethod|\ReflectionParameter|\ReflectionProperty $reflection
99+
* @return string|array|null
72100
*/
73-
private static function getType($reflection, ?\ReflectionType $type): ?string
101+
private static function getType($reflection, ?\ReflectionType $type, bool $asArray = false)
74102
{
75103
if ($type === null) {
76-
return null;
104+
return $asArray ? [] : null;
77105

78106
} elseif ($type instanceof \ReflectionNamedType) {
79-
return self::normalizeType($type->getName(), $reflection);
107+
$name = self::normalizeType($type->getName(), $reflection);
108+
if ($asArray) {
109+
return $type->allowsNull() && $type->getName() !== 'mixed'
110+
? [$name, 'null']
111+
: [$name];
112+
}
113+
return $name;
80114

81115
} elseif ($type instanceof \ReflectionUnionType) {
116+
if ($asArray) {
117+
$types = [];
118+
foreach ($type->getTypes() as $type) {
119+
$types[] = self::normalizeType($type->getName(), $reflection);
120+
}
121+
return $types;
122+
}
82123
throw new Nette\InvalidStateException('The ' . self::toString($reflection) . ' is not expected to have a union type.');
83124

84125
} else {

tests/Utils/Reflection.getParameterType.80.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ Assert::same('callable', Reflection::getParameterType($params[3]));
4949
Assert::same('A', Reflection::getParameterType($params[4]));
5050
Assert::null(Reflection::getParameterType($params[5]));
5151
Assert::same('Test\B', Reflection::getParameterType($params[6]));
52+
Assert::same(['Test\B', 'null'], Reflection::getParameterTypes($params[6]));
5253
Assert::same('mixed', Reflection::getParameterType($params[7]));
54+
Assert::same(['mixed'], Reflection::getParameterTypes($params[7]));
55+
Assert::same(['A', 'array'], Reflection::getParameterTypes($params[8]));
56+
Assert::same(['A', 'array', 'null'], Reflection::getParameterTypes($params[9]));
5357

5458
Assert::exception(function () use ($params) {
5559
Reflection::getParameterType($params[8]);

tests/Utils/Reflection.getPropertyType.80.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ Assert::same('array', Reflection::getPropertyType($props[2]));
4242
Assert::same('A', Reflection::getPropertyType($props[3]));
4343
Assert::null(Reflection::getPropertyType($props[4]));
4444
Assert::same('Test\B', Reflection::getPropertyType($props[5]));
45+
Assert::same(['Test\B', 'null'], Reflection::getPropertyTypes($props[5]));
4546
Assert::same('mixed', Reflection::getPropertyType($props[6]));
47+
Assert::same(['mixed'], Reflection::getPropertyTypes($props[6]));
48+
Assert::same(['A', 'array'], Reflection::getPropertyTypes($props[7]));
49+
Assert::same(['A', 'array', 'null'], Reflection::getPropertyTypes($props[8]));
4650

4751
Assert::exception(function () use ($props) {
4852
Reflection::getPropertyType($props[7]);

tests/Utils/Reflection.getReturnType.80.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ namespace
115115

116116
Assert::same('NS\A', Reflection::getReturnType(new \ReflectionMethod(NS\A::class, 'nullableSelfType')));
117117

118+
Assert::same(['NS\A', 'array'], Reflection::getReturnTypes(new \ReflectionMethod(NS\A::class, 'unionType')));
119+
120+
Assert::same(['NS\A', 'array', 'null'], Reflection::getReturnTypes(new \ReflectionMethod(NS\A::class, 'nullableUnionType')));
121+
118122
Assert::exception(function () {
119123
Reflection::getReturnType(new \ReflectionMethod(NS\A::class, 'unionType'));
120124
}, Nette\InvalidStateException::class, 'The NS\A::unionType is not expected to have a union type.');
@@ -131,6 +135,8 @@ namespace
131135

132136
Assert::same('string', Reflection::getReturnType(new \ReflectionFunction('NS\nativeType')));
133137

138+
Assert::same(['NS\A', 'array'], Reflection::getReturnTypes(new \ReflectionFunction('NS\unionType')));
139+
134140
Assert::exception(function () {
135141
Reflection::getReturnType(new \ReflectionFunction('NS\unionType'));
136142
}, Nette\InvalidStateException::class, 'The NS\unionType is not expected to have a union type.');

0 commit comments

Comments
 (0)