|
4 | 4 |
|
5 | 5 | namespace Bug14550; |
6 | 6 |
|
7 | | -use function PHPStan\Testing\assertType; |
8 | | - |
9 | | -// Standalone assignments trigger TypeSpecifier via NodeScopeResolver null-context call |
10 | 7 | function testArrayKeyFirstAssign(): void |
11 | 8 | { |
12 | 9 | $fn = array_key_first(...); |
13 | | - assertType('Closure(array): (int|string|null)', $fn); |
14 | 10 | } |
15 | 11 |
|
16 | 12 | function testArrayKeyLastAssign(): void |
17 | 13 | { |
18 | 14 | $fn = array_key_last(...); |
19 | | - assertType('Closure(array): (int|string|null)', $fn); |
20 | 15 | } |
21 | 16 |
|
22 | 17 | function testArrayRandAssign(): void |
23 | 18 | { |
24 | 19 | $fn = array_rand(...); |
25 | | - assertType('(Closure(non-empty-array): (int|string))|(Closure(non-empty-array, int<1, max>): (array<int, int|string>|int|string))', $fn); |
26 | 20 | } |
27 | 21 |
|
28 | 22 | function testCountMinusOneAssign(): void |
29 | 23 | { |
30 | 24 | $idx = count(...) - 1; |
31 | | - assertType('Closure(array|Countable, 0|1=): int<0, max>', count(...)); |
32 | 25 | } |
33 | 26 |
|
34 | | -// array_search guard needs true context, so it must be in a condition |
35 | 27 | function testArraySearchInCondition(): void |
36 | 28 | { |
37 | 29 | if ($key = array_search(...)) { |
38 | | - assertType('Closure(mixed, array, bool=): (int|string|false)', $key); |
39 | 30 | } |
40 | 31 | } |
41 | 32 |
|
42 | | -// Comparison guards in TypeSpecifier (Smaller/SmallerOrEqual) |
43 | 33 | function testCountInComparisons(): void |
44 | 34 | { |
45 | 35 | if (count(...) < 1) {} |
46 | 36 | if (0 < count(...)) {} |
47 | | - assertType('Closure(array|Countable, 0|1=): int<0, max>', count(...)); |
48 | 37 | } |
49 | 38 |
|
50 | 39 | function testSizeofInComparisons(): void |
51 | 40 | { |
52 | 41 | if (sizeof(...) < 1) {} |
53 | 42 | if (0 < sizeof(...)) {} |
54 | | - assertType('Closure(array|Countable, int=): int', sizeof(...)); |
55 | 43 | } |
56 | 44 |
|
57 | 45 | function testCountMinusOneInComparison(): void |
58 | 46 | { |
59 | 47 | $i = 0; |
60 | 48 | if ($i < count(...) - 1) {} |
61 | | - assertType('Closure(array|Countable, 0|1=): int<0, max>', count(...)); |
62 | 49 | } |
63 | 50 |
|
64 | 51 | function testStrlenInComparisons(): void |
65 | 52 | { |
66 | 53 | if (strlen(...) < 1) {} |
67 | 54 | if (0 < strlen(...)) {} |
68 | | - assertType('Closure(string): int<0, max>', strlen(...)); |
69 | 55 | } |
70 | 56 |
|
71 | 57 | function testMbStrlenInComparisons(): void |
72 | 58 | { |
73 | 59 | if (mb_strlen(...) < 1) {} |
74 | 60 | if (0 < mb_strlen(...)) {} |
75 | | - assertType('Closure(string, string|null=): int<0, max>', mb_strlen(...)); |
76 | 61 | } |
77 | 62 |
|
78 | 63 | function testPregMatchInComparisons(): void |
79 | 64 | { |
80 | 65 | if (preg_match(...) < 1) {} |
81 | 66 | if (0 < preg_match(...)) {} |
82 | | - assertType('Closure(string, string, array<string>|null=, TFlags=, int=): (0|1|false)', preg_match(...)); |
83 | 67 | } |
84 | 68 |
|
85 | | -// Identical/NotIdentical guards in resolveNormalizedIdentical |
86 | 69 | function testCountIdentical(): void |
87 | 70 | { |
88 | 71 | if (count(...) === 0) {} |
89 | | - assertType('Closure(array|Countable, 0|1=): int<0, max>', count(...)); |
90 | 72 | } |
91 | 73 |
|
92 | 74 | function testStrlenIdentical(): void |
93 | 75 | { |
94 | 76 | if (strlen(...) === 0) {} |
95 | 77 | if (mb_strlen(...) === 0) {} |
96 | | - assertType('Closure(string): int<0, max>', strlen(...)); |
97 | 78 | } |
98 | 79 |
|
99 | 80 | function testArrayKeyFirstNullComparison(): void |
100 | 81 | { |
101 | 82 | if (array_key_first(...) !== null) {} |
102 | 83 | if (array_key_last(...) !== null) {} |
103 | | - assertType('Closure(array): (int|string|null)', array_key_first(...)); |
104 | 84 | } |
105 | 85 |
|
106 | 86 | function testGetClassIdentical(): void |
107 | 87 | { |
108 | 88 | if (get_class(...) === 'stdClass') {} |
109 | 89 | if (get_debug_type(...) === 'string') {} |
110 | | - assertType('Closure(object=): class-string', get_class(...)); |
111 | 90 | } |
112 | 91 |
|
113 | 92 | function testStringFuncIdentical(): void |
114 | 93 | { |
115 | 94 | if (strtolower(...) === 'test') {} |
116 | | - assertType('Closure(string): lowercase-string', strtolower(...)); |
117 | 95 | } |
118 | 96 |
|
119 | | -// String equality guards in specifyTypesForConstantStringBinaryExpression |
120 | 97 | function testGettypeEquality(): void |
121 | 98 | { |
122 | 99 | if (gettype(...) === 'string') {} |
123 | 100 | if (gettype(...) == 'string') {} |
124 | | - assertType('Closure(mixed): string', gettype(...)); |
125 | 101 | } |
126 | 102 |
|
127 | 103 | function testGetClassEquality(): void |
128 | 104 | { |
129 | 105 | if (get_class(...) == 'stdClass') {} |
130 | 106 | if (get_debug_type(...) == 'string') {} |
131 | | - assertType('Closure(object=): class-string', get_class(...)); |
132 | 107 | } |
133 | 108 |
|
134 | 109 | function testGetParentClassEquality(): void |
135 | 110 | { |
136 | 111 | if (get_parent_class(...) === 'stdClass') {} |
137 | | - assertType('Closure(object|string=): (class-string|false)', get_parent_class(...)); |
138 | 112 | } |
139 | 113 |
|
140 | 114 | function testTrimEquality(): void |
141 | 115 | { |
142 | 116 | if (trim(...) !== '') {} |
143 | 117 | if (ltrim(...) !== '') {} |
144 | 118 | if (rtrim(...) !== '') {} |
145 | | - assertType('Closure(string, string=): string', trim(...)); |
146 | 119 | } |
147 | 120 |
|
148 | | -// NodeScopeResolver guards |
149 | 121 | function testArrayKeysInForeach(): void |
150 | 122 | { |
151 | 123 | foreach (array_keys(...) as $key) {} |
152 | | - assertType('Closure(array, mixed=, bool=): list<int|string>', array_keys(...)); |
153 | 124 | } |
154 | 125 |
|
155 | 126 | function testCountInForLoop(): void |
156 | 127 | { |
157 | 128 | for ($i = 0; $i < count(...); $i++) {} |
158 | 129 | for ($i = 0; count(...) > $i; $i++) {} |
159 | | - assertType('Closure(array|Countable, 0|1=): int<0, max>', count(...)); |
160 | 130 | } |
0 commit comments