Skip to content

Commit 3dbf8a8

Browse files
[1.x] Fixes switch cases namespace resolution (#80)
* Adds tests * Apply fixes from StyleCI * Fixes `instanceof` within switch cases * Apply fixes from StyleCI * Prefixes PHP version * Apply fixes from StyleCI * Adds PHP 8.0 tests * Apply fixes from StyleCI * Fixes existing tests * Adds tests against namespaced class * Adds reflection closure tests * Apply fixes from StyleCI * Fixes issue after style changes * Fixes `:` namespace resolution * Apply fixes from StyleCI * Fixes test on PHP 7.4 * Apply fixes from StyleCI * Space * Another test * More tests --------- Co-authored-by: StyleCI Bot <bot@styleci.io>
1 parent ed9e590 commit 3dbf8a8

File tree

6 files changed

+491
-5
lines changed

6 files changed

+491
-5
lines changed

src/Support/ReflectionClosure.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,7 @@ public function getCode()
508508
break;
509509
case 'id_name':
510510
switch ($token[0]) {
511-
// named arguments...
512-
case ':':
511+
case $token[0] === ':' && $context !== 'instanceof':
513512
if ($lastState === 'closure' && $context === 'root') {
514513
$state = 'closure';
515514
$code .= $id_start.$token;

tests/ReflectionClosure1Test.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,90 @@
297297

298298
expect($f1)->toBeCode($e1);
299299
});
300+
301+
function reflection_closure_php_74_switch_statement_test_is_two($a)
302+
{
303+
return $a === 2;
304+
}
305+
306+
class ReflectionClosurePhp74InstanceOfTest
307+
{
308+
}
309+
310+
class ReflectionClosurePhp74SwitchStatementTest
311+
{
312+
}
313+
314+
test('instanceof', function () {
315+
$f1 = function ($a) {
316+
$b = $a instanceof DateTime || $a instanceof ReflectionClosurePhp74InstanceOfTest || $a instanceof RegularClass;
317+
318+
return [
319+
$b,
320+
$a instanceof DateTime || $a instanceof ReflectionClosurePhp74InstanceOfTest || $a instanceof RegularClass,
321+
(function ($a) {
322+
return ($a instanceof DateTime || $a instanceof ReflectionClosurePhp74InstanceOfTest || $a instanceof RegularClass) === true;
323+
})($a),
324+
];
325+
};
326+
327+
$e1 = 'function ($a) {
328+
$b = $a instanceof \DateTime || $a instanceof \ReflectionClosurePhp74InstanceOfTest || $a instanceof \Tests\Fixtures\RegularClass;
329+
330+
return [
331+
$b,
332+
$a instanceof \DateTime || $a instanceof \ReflectionClosurePhp74InstanceOfTest || $a instanceof \Tests\Fixtures\RegularClass,
333+
(function ($a) {
334+
return ($a instanceof \DateTime || $a instanceof \ReflectionClosurePhp74InstanceOfTest || $a instanceof \Tests\Fixtures\RegularClass) === true;
335+
})($a),
336+
];
337+
}';
338+
339+
expect($f1)->toBeCode($e1);
340+
});
341+
342+
test('switch statement', function () {
343+
$f1 = function ($a) {
344+
switch (true) {
345+
case $a === 1:
346+
return 'one';
347+
case reflection_closure_php_74_switch_statement_test_is_two($a):
348+
return 'two';
349+
case ReflectionClosurePhp74SwitchStatementTest::isThree($a):
350+
return 'three';
351+
case (new ReflectionClosurePhp74SwitchStatementTest)->isFour($a):
352+
return 'four';
353+
case $a instanceof ReflectionClosurePhp74SwitchStatementTest:
354+
return 'five';
355+
case $a instanceof DateTime:
356+
return 'six';
357+
case $a instanceof RegularClass:
358+
return 'seven';
359+
default:
360+
return 'other';
361+
}
362+
};
363+
364+
$e1 = 'function ($a) {
365+
switch (true) {
366+
case $a === 1:
367+
return \'one\';
368+
case \reflection_closure_php_74_switch_statement_test_is_two($a):
369+
return \'two\';
370+
case \ReflectionClosurePhp74SwitchStatementTest::isThree($a):
371+
return \'three\';
372+
case (new \ReflectionClosurePhp74SwitchStatementTest)->isFour($a):
373+
return \'four\';
374+
case $a instanceof \ReflectionClosurePhp74SwitchStatementTest:
375+
return \'five\';
376+
case $a instanceof \DateTime:
377+
return \'six\';
378+
case $a instanceof \Tests\Fixtures\RegularClass:
379+
return \'seven\';
380+
default:
381+
return \'other\';
382+
}
383+
}';
384+
385+
expect($f1)->toBeCode($e1);
386+
});

tests/ReflectionClosurePhp80Test.php

Lines changed: 161 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
// Fake
44
use Some\ClassName as ClassAlias;
5+
use Tests\Fixtures\RegularClass;
56

67
test('union types', function () {
78
$f1 = fn (): string|int|false|Bar|null => 1;
@@ -86,7 +87,7 @@
8687
}";
8788

8889
expect($f1)->toBeCode($e1);
89-
})->with('serializers');
90+
});
9091

9192
test('single named argument within closures', function () {
9293
$f1 = function () {
@@ -98,7 +99,7 @@
9899
}";
99100

100101
expect($f1)->toBeCode($e1);
101-
})->with('serializers');
102+
});
102103

103104
test('multiple named arguments within closures', function () {
104105
$f1 = function () {
@@ -110,7 +111,29 @@
110111
}";
111112

112113
expect($f1)->toBeCode($e1);
113-
})->with('serializers');
114+
});
115+
116+
test('named arguments with switch cases and instanceof', function () {
117+
$f1 = function ($a) {
118+
switch (true) {
119+
case (new RegularClass(a2: $a))->a2 instanceof RegularClass:
120+
return (new RegularClass(a2: $a))->a2;
121+
default:
122+
return new RegularClass(a2: RegularClass::C);
123+
}
124+
};
125+
126+
$e1 = 'function ($a) {
127+
switch (true) {
128+
case (new \Tests\Fixtures\RegularClass(a2: $a))->a2 instanceof \Tests\Fixtures\RegularClass:
129+
return (new \Tests\Fixtures\RegularClass(a2: $a))->a2;
130+
default:
131+
return new \Tests\Fixtures\RegularClass(a2: \Tests\Fixtures\RegularClass::C);
132+
}
133+
}';
134+
135+
expect($f1)->toBeCode($e1);
136+
});
114137

115138
test('multiple named arguments within nested closures', function () {
116139
$f1 = function () {
@@ -159,3 +182,138 @@ public function getPrivate(): string
159182
return $this->private;
160183
}
161184
}
185+
186+
function reflection_closure_php_80_switch_statement_test_is_two($a)
187+
{
188+
return $a === 2;
189+
}
190+
191+
class ReflectionClosurePhp80InstanceOfTest
192+
{
193+
};
194+
195+
class ReflectionClosurePhp80SwitchStatementTest
196+
{
197+
}
198+
199+
test('instanceof', function () {
200+
$f1 = function (object $a): array {
201+
$b = $a instanceof DateTime || $a instanceof ReflectionClosurePhp80InstanceOfTest || $a instanceof RegularClass;
202+
203+
return [
204+
$b,
205+
($a instanceof DateTime || $a instanceof ReflectionClosurePhp80InstanceOfTest || $a instanceof RegularClass),
206+
(function (object $a): bool {
207+
return ($a instanceof DateTime || $a instanceof ReflectionClosurePhp80InstanceOfTest || $a instanceof RegularClass) === true;
208+
})(a: $a),
209+
];
210+
};
211+
212+
$e1 = 'function (object $a): array {
213+
$b = $a instanceof \DateTime || $a instanceof \ReflectionClosurePhp80InstanceOfTest || $a instanceof \Tests\Fixtures\RegularClass;
214+
215+
return [
216+
$b,
217+
($a instanceof \DateTime || $a instanceof \ReflectionClosurePhp80InstanceOfTest || $a instanceof \Tests\Fixtures\RegularClass),
218+
(function (object $a): bool {
219+
return ($a instanceof \DateTime || $a instanceof \ReflectionClosurePhp80InstanceOfTest || $a instanceof \Tests\Fixtures\RegularClass) === true;
220+
})(a: $a),
221+
];
222+
}';
223+
224+
expect($f1)->toBeCode($e1);
225+
});
226+
227+
test('switch statement', function () {
228+
$f1 = function ($a) {
229+
switch (true) {
230+
case $a === 1:
231+
return 'one';
232+
case reflection_closure_php_80_switch_statement_test_is_two(a: $a):
233+
return 'two';
234+
case ReflectionClosurePhp80SwitchStatementTest::isThree(a: $a):
235+
return 'three';
236+
case (new ReflectionClosurePhp80SwitchStatementTest)->isFour(a: $a):
237+
return 'four';
238+
case ($a instanceof ReflectionClosurePhp80SwitchStatementTest):
239+
return 'five';
240+
case ($a instanceof DateTime):
241+
return 'six';
242+
case ($a instanceof RegularClass):
243+
return 'seven';
244+
default:
245+
return 'other';
246+
}
247+
};
248+
249+
$e1 = 'function ($a) {
250+
switch (true) {
251+
case $a === 1:
252+
return \'one\';
253+
case \reflection_closure_php_80_switch_statement_test_is_two(a: $a):
254+
return \'two\';
255+
case \ReflectionClosurePhp80SwitchStatementTest::isThree(a: $a):
256+
return \'three\';
257+
case (new \ReflectionClosurePhp80SwitchStatementTest)->isFour(a: $a):
258+
return \'four\';
259+
case ($a instanceof \ReflectionClosurePhp80SwitchStatementTest):
260+
return \'five\';
261+
case ($a instanceof \DateTime):
262+
return \'six\';
263+
case ($a instanceof \Tests\Fixtures\RegularClass):
264+
return \'seven\';
265+
default:
266+
return \'other\';
267+
}
268+
}';
269+
270+
expect($f1)->toBeCode($e1);
271+
});
272+
273+
function reflection_closure_php_80_match_statement_test_is_two($a)
274+
{
275+
return $a === 2;
276+
}
277+
278+
class ReflectionClosurePhp80MatchStatementTest
279+
{
280+
public static function isThree($a)
281+
{
282+
return $a === 3;
283+
}
284+
285+
public function isFour($a)
286+
{
287+
return $a === 4;
288+
}
289+
}
290+
291+
test('match statement', function () {
292+
$f1 = function ($a) {
293+
return match (true) {
294+
$a === 1 => 'one',
295+
reflection_closure_php_80_match_statement_test_is_two($a) => 'two',
296+
ReflectionClosurePhp80MatchStatementTest::isThree(a: $a) => 'three',
297+
(new ReflectionClosurePhp80MatchStatementTest)->isFour($a) => 'four',
298+
$a instanceof ReflectionClosurePhp80MatchStatementTest => 'five',
299+
$a instanceof DateTime => 'six',
300+
$a instanceof RegularClass => 'seven',
301+
default => 'other',
302+
};
303+
};
304+
305+
$e1 = 'function ($a) {
306+
return match (true) {
307+
$a === 1 => \'one\',
308+
\reflection_closure_php_80_match_statement_test_is_two($a) => \'two\',
309+
\ReflectionClosurePhp80MatchStatementTest::isThree(a: $a) => \'three\',
310+
(new \ReflectionClosurePhp80MatchStatementTest)->isFour($a) => \'four\',
311+
$a instanceof \ReflectionClosurePhp80MatchStatementTest => \'five\',
312+
$a instanceof \DateTime => \'six\',
313+
$a instanceof \Tests\Fixtures\RegularClass => \'seven\',
314+
default => \'other\',
315+
};
316+
}';
317+
318+
expect($f1)->toBeCode($e1);
319+
});

tests/ReflectionClosurePhp81Test.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ enum GlobalEnum {
144144
a18: reflection_closure_my_function(),
145145
a19: reflection_closure_my_function(ReflectionClosureGlobalEnum::Guest),
146146
a20: reflection_closure_my_function(enum: ReflectionClosureGlobalEnum::Guest),
147+
a21: match (true) {
148+
true => new RegularClass(),
149+
false => (new RegularClass()) instanceof RegularClass,
150+
default => reflection_closure_my_function(enum: ReflectionClosureGlobalEnum::Guest),
151+
},
147152
);
148153
};
149154

@@ -276,6 +281,11 @@ enum GlobalEnum {
276281
a18: \\reflection_closure_my_function(),
277282
a19: \\reflection_closure_my_function(\ReflectionClosureGlobalEnum::Guest),
278283
a20: \\reflection_closure_my_function(enum: \ReflectionClosureGlobalEnum::Guest),
284+
a21: match (true) {
285+
true => new \Tests\Fixtures\RegularClass(),
286+
false => (new \Tests\Fixtures\RegularClass()) instanceof \Tests\Fixtures\RegularClass,
287+
default => \\reflection_closure_my_function(enum: \ReflectionClosureGlobalEnum::Guest),
288+
},
279289
);
280290
}";
281291

0 commit comments

Comments
 (0)