From ed2285f50a6f4c231dbf1ae018a4fa7c3a952063 Mon Sep 17 00:00:00 2001 From: tuqqu Date: Thu, 13 Apr 2023 01:30:14 +0200 Subject: [PATCH] Flatten match arm conditions to check conditions independently --- .../Statements/Expression/MatchAnalyzer.php | 21 +++++-- tests/MatchTest.php | 60 +++++++++++++++++++ 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php index c16948048..c0b614ae4 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php @@ -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( diff --git a/tests/MatchTest.php b/tests/MatchTest.php index 0d00e62df..8350f7b96 100644 --- a/tests/MatchTest.php +++ b/tests/MatchTest.php @@ -95,6 +95,44 @@ class MatchTest extends TestCase 'ignored_issues' => [], 'php_version' => '8.1', ], + 'multipleInstanceOfConditionsInOneArm' => [ + 'code' => ' baz($foo), + $foo instanceof C => 3, + default => 0, + }; + }', + 'assertions' => [], + 'ignored_issues' => [], + 'php_version' => '8.0', + ], + 'multipleTypeCheckConditionsInOneArm' => [ + 'code' => ' 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' => ' baz($foo), + $foo instanceof C => 3, + default => 0, + }; + }', + 'error_message' => 'InvalidArgument', + 'ignored_issues' => [], + 'php_version' => '8.0', + ], ]; } }