1--TEST--
2Union types in reflection
3--FILE--
4<?php
5
6function dumpType(ReflectionUnionType $rt) {
7    echo "Type $rt:\n";
8    echo "Allows null: " . ($rt->allowsNull() ? "true" : "false") . "\n";
9    foreach ($rt->getTypes() as $type) {
10        echo "  Name: " . $type->getName() . "\n";
11        echo "  String: " . (string) $type . "\n";
12        echo "  Allows Null: " . ($type->allowsNull() ? "true" : "false") . "\n";
13    }
14}
15
16function test1(): X|Y|int|float|false|null { }
17function test2(): X|iterable|bool { }
18
19class Test {
20    public X|Y|int $prop;
21}
22
23dumpType((new ReflectionFunction('test1'))->getReturnType());
24dumpType((new ReflectionFunction('test2'))->getReturnType());
25
26$rc = new ReflectionClass(Test::class);
27$rp = $rc->getProperty('prop');
28dumpType($rp->getType());
29
30/* Force CE resolution of the property type */
31
32class x {}
33$test = new Test;
34$test->prop = new x;
35
36$rp = $rc->getProperty('prop');
37dumpType($rp->getType());
38
39class y {}
40$test->prop = new y;
41
42$rp = $rc->getProperty('prop');
43dumpType($rp->getType());
44
45?>
46--EXPECT--
47Type X|Y|int|float|false|null:
48Allows null: true
49  Name: X
50  String: X
51  Allows Null: false
52  Name: Y
53  String: Y
54  Allows Null: false
55  Name: int
56  String: int
57  Allows Null: false
58  Name: float
59  String: float
60  Allows Null: false
61  Name: false
62  String: false
63  Allows Null: false
64  Name: null
65  String: null
66  Allows Null: true
67Type X|iterable|bool:
68Allows null: false
69  Name: X
70  String: X
71  Allows Null: false
72  Name: iterable
73  String: iterable
74  Allows Null: false
75  Name: bool
76  String: bool
77  Allows Null: false
78Type X|Y|int:
79Allows null: false
80  Name: X
81  String: X
82  Allows Null: false
83  Name: Y
84  String: Y
85  Allows Null: false
86  Name: int
87  String: int
88  Allows Null: false
89Type X|Y|int:
90Allows null: false
91  Name: X
92  String: X
93  Allows Null: false
94  Name: Y
95  String: Y
96  Allows Null: false
97  Name: int
98  String: int
99  Allows Null: false
100Type X|Y|int:
101Allows null: false
102  Name: X
103  String: X
104  Allows Null: false
105  Name: Y
106  String: Y
107  Allows Null: false
108  Name: int
109  String: int
110  Allows Null: false
111