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 stdClass $std;
84    public OtherThing $other;
85    public $mixed;
86}
87
88$reflector = new ReflectionClass(PropTypeTest::class);
89
90foreach ($reflector->getProperties() as $name => $property) {
91    if ($property->hasType()) {
92        printf("public %s $%s;\n",
93            $property->getType()->getName(), $property->getName());
94    } else printf("public $%s;\n", $property->getName());
95}
96
97echo "*** resolved property types\n";
98$obj = new PropTypeTest;
99$obj->std = new stdClass;
100$r = (new ReflectionProperty($obj, 'std'))->getType();
101var_dump($r->getName());
102?>
103--EXPECT--
104*** functions
105** Function 0 - Parameter 0
106bool(true)
107bool(false)
108bool(false)
109string(8) "stdClass"
110** Function 0 - Parameter 1
111bool(true)
112bool(false)
113bool(true)
114string(5) "array"
115** Function 0 - Parameter 2
116bool(true)
117bool(false)
118bool(true)
119string(8) "callable"
120** Function 0 - Parameter 3
121bool(true)
122bool(false)
123bool(true)
124string(6) "string"
125** Function 0 - Parameter 4
126bool(true)
127bool(false)
128bool(true)
129string(4) "bool"
130** Function 0 - Parameter 5
131bool(true)
132bool(false)
133bool(true)
134string(3) "int"
135** Function 0 - Parameter 6
136bool(true)
137bool(false)
138bool(true)
139string(5) "float"
140** Function 0 - Parameter 7
141bool(true)
142bool(false)
143bool(false)
144string(11) "NotExisting"
145** Function 0 - Parameter 8
146bool(true)
147bool(true)
148bool(false)
149string(8) "stdClass"
150** Function 0 - Parameter 9
151bool(false)
152** Function 1 - Parameter 0
153bool(true)
154bool(false)
155bool(false)
156string(4) "Test"
157
158*** methods
159** Method 0 - parameter 0
160bool(true)
161bool(false)
162bool(false)
163string(10) "SplSubject"
164** Method 1 - parameter 0
165bool(true)
166bool(false)
167bool(false)
168string(4) "self"
169** Method 2 - parameter 0
170bool(true)
171bool(false)
172bool(false)
173string(6) "parent"
174** Method 3 - parameter 0
175bool(true)
176bool(false)
177bool(false)
178string(4) "Test"
179
180*** return types
181** Function/method return type 0
182bool(false)
183** Function/method return type 1
184bool(true)
185bool(false)
186bool(false)
187string(8) "stdClass"
188** Function/method return type 2
189bool(true)
190bool(false)
191bool(true)
192string(3) "int"
193** Function/method return type 3
194bool(true)
195bool(false)
196bool(false)
197string(4) "self"
198** Function/method return type 4
199bool(true)
200bool(false)
201bool(false)
202string(6) "parent"
203** Function/method return type 5
204bool(true)
205bool(false)
206bool(false)
207string(4) "Test"
208** Function/method return type 6
209bool(true)
210bool(false)
211bool(false)
212string(4) "Test"
213
214*** property types
215public int $int;
216public string $string;
217public array $arr;
218public stdClass $std;
219public OtherThing $other;
220public $mixed;
221*** resolved property types
222string(8) "stdClass"
223