1--TEST--
2ReflectionParameter::get/hasType and ReflectionType tests
3--FILE--
4<?php
5function foo(stdClass $a, array $b, callable $c, stdClass $d = null, $e = null, string $f, bool $g, int $h, float $i, NotExisting $j) { }
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(true)
124bool(false)
125string(8) "stdClass"
126** Function 0 - Parameter 4
127bool(false)
128** Function 0 - Parameter 5
129bool(true)
130bool(false)
131bool(true)
132string(6) "string"
133** Function 0 - Parameter 6
134bool(true)
135bool(false)
136bool(true)
137string(4) "bool"
138** Function 0 - Parameter 7
139bool(true)
140bool(false)
141bool(true)
142string(3) "int"
143** Function 0 - Parameter 8
144bool(true)
145bool(false)
146bool(true)
147string(5) "float"
148** Function 0 - Parameter 9
149bool(true)
150bool(false)
151bool(false)
152string(11) "NotExisting"
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