mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Merge pull request #9647 from tuqqu/match-branch-flattening
Flatten `match` arm conditions to check conditions independently
This commit is contained in:
commit
cb6508e63c
@ -128,18 +128,27 @@ class MatchAnalyzer
|
||||
}
|
||||
|
||||
$arms = $stmt->arms;
|
||||
$flattened_arms = [];
|
||||
$last_arm = null;
|
||||
|
||||
foreach ($arms as $i => $arm) {
|
||||
// move default to the end
|
||||
foreach ($arms as $arm) {
|
||||
if ($arm->conds === null) {
|
||||
unset($arms[$i]);
|
||||
$arms[] = $arm;
|
||||
$last_arm = $arm;
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($arm->conds as $cond) {
|
||||
$flattened_arms[] = new PhpParser\Node\MatchArm(
|
||||
[$cond],
|
||||
$arm->body,
|
||||
$arm->getAttributes(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$arms = $flattened_arms;
|
||||
$arms = array_reverse($arms);
|
||||
|
||||
$last_arm = array_shift($arms);
|
||||
$last_arm ??= array_shift($arms);
|
||||
|
||||
if (!$last_arm) {
|
||||
IssueBuffer::maybeAdd(
|
||||
|
@ -95,6 +95,44 @@ class MatchTest extends TestCase
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.1',
|
||||
],
|
||||
'multipleInstanceOfConditionsInOneArm' => [
|
||||
'code' => '<?php
|
||||
interface Foo {}
|
||||
class A implements Foo {}
|
||||
class B implements Foo {}
|
||||
class C {}
|
||||
|
||||
function baz(A|B $_): int {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function bar(Foo $foo): int {
|
||||
return match (true) {
|
||||
$foo instanceof A, $foo instanceof B => baz($foo),
|
||||
$foo instanceof C => 3,
|
||||
default => 0,
|
||||
};
|
||||
}',
|
||||
'assertions' => [],
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.0',
|
||||
],
|
||||
'multipleTypeCheckConditionsInOneArm' => [
|
||||
'code' => '<?php
|
||||
function baz(int|string $_): int {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function bar(mixed $foo): int {
|
||||
return match (true) {
|
||||
is_string($foo), is_int($foo) => baz($foo),
|
||||
default => 0,
|
||||
};
|
||||
}',
|
||||
'assertions' => [],
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.0',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -243,6 +281,28 @@ class MatchTest extends TestCase
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.0',
|
||||
],
|
||||
'multipleInstanceOfConditionsNotMetInOneArm' => [
|
||||
'code' => '<?php
|
||||
interface Foo {}
|
||||
class A implements Foo {}
|
||||
class B implements Foo {}
|
||||
class C {}
|
||||
|
||||
function baz(C $_): int {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function bar(Foo $foo): int {
|
||||
return match (true) {
|
||||
$foo instanceof A, $foo instanceof B => baz($foo),
|
||||
$foo instanceof C => 3,
|
||||
default => 0,
|
||||
};
|
||||
}',
|
||||
'error_message' => 'InvalidArgument',
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.0',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user