1--TEST--
2ReflectionParameter::get/hasType and ReflectionType tests
3--FILE--
4<?php
5function foo(stdClass $a, array $b, callable $c, string $f, bool $g, int $h, float $i, NotExisting $j, stdClass $d = null, $e = null) { }
6
7function bar(): stdClass { return new stdClass; }
8
9class c extends stdClass {
10  function bar(self $x): int { return 1; }
11  function pbar(parent $x): int { return 1; }
12  function factory(): self { return new c; }
13  function pfactory(): parent { return new stdClass; }
14}
15
16$closure = function (Test $a): Test { return $a; };
17
18echo "*** functions\n";
19
20foreach ([
21  new ReflectionFunction('foo'),
22  new ReflectionFunction($closure),
23] as $idx => $rf) {
24  foreach ($rf->getParameters() as $idx2 => $rp) {
25    echo "** Function $idx - Parameter $idx2\n";
26    var_dump($rp->hasType());
27    $ra = $rp->getType();
28    if ($ra) {
29      var_dump($ra->allowsNull());
30      var_dump($ra->isBuiltin());
31      var_dump($ra->getName());
32    }
33  }
34}
35
36echo "\n*** methods\n";
37
38foreach ([
39  new ReflectionMethod('SplObserver', 'update'),
40  new ReflectionMethod('c', 'bar'),
41  new ReflectionMethod('c', 'pbar'),
42  new ReflectionMethod($closure, '__invoke'),
43] as $idx => $rm) {
44  foreach ($rm->getParameters() as $idx2 => $rp) {
45    echo "** Method $idx - parameter $idx2\n";
46    var_dump($rp->hasType());
47    $ra = $rp->getType();
48    if ($ra) {
49      var_dump($ra->allowsNull());
50      var_dump($ra->isBuiltin());
51      var_dump($ra->getName());
52    }
53  }
54}
55
56echo "\n*** return types\n";
57
58foreach ([
59  new ReflectionMethod('SplObserver', 'update'),
60  new ReflectionFunction('bar'),
61  new ReflectionMethod('c', 'bar'),
62  new ReflectionMethod('c', 'factory'),
63  new ReflectionMethod('c', 'pfactory'),
64  new ReflectionFunction($closure),
65  new ReflectionMethod($closure, '__invoke'),
66] as $idx => $rf) {
67  echo "** Function/method return type $idx\n";
68  var_dump($rf->hasReturnType());
69  $ra = $rf->getReturnType();
70  if ($ra) {
71    var_dump($ra->allowsNull());
72    var_dump($ra->isBuiltin());
73    var_dump($ra->getName());
74  }
75}
76
77echo "\n*** property types\n";
78
79class PropTypeTest {
80    public int $int;
81    public string $string;
82    public array $arr;
83    public iterable $iterable;
84    public stdClass $std;
85    public OtherThing $other;
86    public $mixed;
87}
88
89$reflector = new ReflectionClass(PropTypeTest::class);
90
91foreach ($reflector->getProperties() as $name => $property) {
92    if ($property->hasType()) {
93        printf("public %s $%s;\n",
94            $property->getType()->getName(), $property->getName());
95    } else printf("public $%s;\n", $property->getName());
96}
97
98echo "*** resolved property types\n";
99$obj = new PropTypeTest;
100$obj->std = new stdClass;
101$r = (new ReflectionProperty($obj, 'std'))->getType();
102var_dump($r->getName());
103?>
104--EXPECT--
105*** functions
106** Function 0 - Parameter 0
107bool(true)
108bool(false)
109bool(false)
110string(8) "stdClass"
111** Function 0 - Parameter 1
112bool(true)
113bool(false)
114bool(true)
115string(5) "array"
116** Function 0 - Parameter 2
117bool(true)
118bool(false)
119bool(true)
120string(8) "callable"
121** Function 0 - Parameter 3
122bool(true)
123bool(false)
124bool(true)
125string(6) "string"
126** Function 0 - Parameter 4
127bool(true)
128bool(false)
129bool(true)
130string(4) "bool"
131** Function 0 - Parameter 5
132bool(true)
133bool(false)
134bool(true)
135string(3) "int"
136** Function 0 - Parameter 6
137bool(true)
138bool(false)
139bool(true)
140string(5) "float"
141** Function 0 - Parameter 7
142bool(true)
143bool(false)
144bool(false)
145string(11) "NotExisting"
146** Function 0 - Parameter 8
147bool(true)
148bool(true)
149bool(false)
150string(8) "stdClass"
151** Function 0 - Parameter 9
152bool(false)
153** Function 1 - Parameter 0
154bool(true)
155bool(false)
156bool(false)
157string(4) "Test"
158
159*** methods
160** Method 0 - parameter 0
161bool(true)
162bool(false)
163bool(false)
164string(10) "SplSubject"
165** Method 1 - parameter 0
166bool(true)
167bool(false)
168bool(false)
169string(4) "self"
170** Method 2 - parameter 0
171bool(true)
172bool(false)
173bool(false)
174string(6) "parent"
175** Method 3 - parameter 0
176bool(true)
177bool(false)
178bool(false)
179string(4) "Test"
180
181*** return types
182** Function/method return type 0
183bool(false)
184** Function/method return type 1
185bool(true)
186bool(false)
187bool(false)
188string(8) "stdClass"
189** Function/method return type 2
190bool(true)
191bool(false)
192bool(true)
193string(3) "int"
194** Function/method return type 3
195bool(true)
196bool(false)
197bool(false)
198string(4) "self"
199** Function/method return type 4
200bool(true)
201bool(false)
202bool(false)
203string(6) "parent"
204** Function/method return type 5
205bool(true)
206bool(false)
207bool(false)
208string(4) "Test"
209** Function/method return type 6
210bool(true)
211bool(false)
212bool(false)
213string(4) "Test"
214
215*** property types
216public int $int;
217public string $string;
218public array $arr;
219public iterable $iterable;
220public stdClass $std;
221public OtherThing $other;
222public $mixed;
223*** resolved property types
224string(8) "stdClass"
225