-
Notifications
You must be signed in to change notification settings - Fork 461
/
Reflector.php
143 lines (124 loc) · 4.14 KB
/
Reflector.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
/**
* Mockery
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://github.com/padraic/mockery/blob/master/LICENSE
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to padraic@php.net so we can send you a copy immediately.
*
* @category Mockery
* @package Mockery
* @copyright Copyright (c) 2017 Dave Marshall https://github.com/davedevelopment
* @license http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
*/
namespace Mockery;
/**
* @internal
*/
class Reflector
{
/**
* Determine if the parameter is typed as an array.
*
* @param \ReflectionParameter $param
*
* @return bool
*/
public static function isArray(\ReflectionParameter $param)
{
$type = $param->getType();
return $type instanceof \ReflectionNamedType && $type->getName();
}
/**
* Compute the string representation for the paramater type.
*
* @param \ReflectionParameter $param
* @param bool $withoutNullable
*
* @return string|null
*/
public static function getTypeHint(\ReflectionParameter $param, $withoutNullable = false)
{
if (!$param->hasType()) {
return null;
}
$type = $param->getType();
$declaringClass = $param->getDeclaringClass();
$typeHint = self::typeToString($type, $declaringClass);
return (!$withoutNullable && $type->allowsNull()) ? self::formatNullableType($typeHint) : $typeHint;
}
/**
* Compute the string representation for the return type.
*
* @param \ReflectionParameter $param
* @param bool $withoutNullable
*
* @return string|null
*/
public static function getReturnType(\ReflectionMethod $method, $withoutNullable = false)
{
if (!$method->hasReturnType()) {
return null;
}
$type = $method->getReturnType();
$declaringClass = $method->getDeclaringClass();
$typeHint = self::typeToString($type, $declaringClass);
return (!$withoutNullable && $type->allowsNull()) ? self::formatNullableType($typeHint) : $typeHint;
}
/**
* Get the string representation of the given type.
*
* @param \ReflectionType $type
* @param string $declaringClass
*
* @return string|null
*/
private static function typeToString(\ReflectionType $type, \ReflectionClass $declaringClass)
{
// PHP 8 union types can be recursively processed
if ($type instanceof \ReflectionUnionType) {
return \implode('|', \array_filter(\array_map(function (\ReflectionType $type) use ($declaringClass) {
$typeHint = self::typeToString($type, $declaringClass);
return $typeHint === 'null' ? null : $typeHint;
}, $type->getTypes())));
}
// $type must be an instance of \ReflectionNamedType
$typeHint = $type->getName();
// builtins and 'static' can be returned as is
if (($type->isBuiltin() || $typeHint === 'static')) {
return $typeHint;
}
// 'self' needs to be resolved to the name of the declaring class
if ($typeHint === 'self') {
$typeHint = $declaringClass->getName();
}
// 'parent' needs to be resolved to the name of the parent class
if ($typeHint === 'parent') {
$typeHint = $declaringClass->getParentClass()->getName();
}
// class names need prefixing with a slash
return sprintf('\\%s', $typeHint);
}
/**
* Format the given type as a nullable type.
*
* This method MUST only be called on PHP 7.1+.
*
* @param string $typeHint
*
* @return string
*/
private static function formatNullableType($typeHint)
{
if (\PHP_VERSION_ID < 80000) {
return sprintf('?%s', $typeHint);
}
return $typeHint === 'mixed' ? 'mixed' : sprintf('%s|null', $typeHint);
}
}