diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php index 3f44397e065..3b9b9cbc7dd 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php @@ -30,11 +30,13 @@ use Psalm\Issue\UndefinedMethod; use Psalm\IssueBuffer; use Psalm\Type; +use Psalm\Type\Atomic\TConditional; use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TObject; use Psalm\Type\Atomic\TTemplateParam; use Psalm\Type\Union; +use function array_merge; use function array_reduce; use function count; use function is_string; @@ -177,6 +179,17 @@ public static function analyze( $lhs_types = $class_type->getAtomicTypes(); + foreach ($lhs_types as $k => $lhs_type_part) { + if ($lhs_type_part instanceof TConditional) { + $lhs_types = array_merge( + $lhs_types, + $lhs_type_part->if_type->getAtomicTypes(), + $lhs_type_part->else_type->getAtomicTypes(), + ); + unset($lhs_types[$k]); + } + } + $result = new AtomicMethodCallAnalysisResult(); $possible_new_class_types = []; @@ -400,7 +413,7 @@ public static function analyze( $types = $class_type->getAtomicTypes(); foreach ($types as $key => &$type) { - if (!$type instanceof TNamedObject && !$type instanceof TObject) { + if (!$type instanceof TNamedObject && !$type instanceof TObject && !$type instanceof TConditional) { unset($types[$key]); } else { $type = $type->setFromDocblock(false); diff --git a/tests/MethodCallTest.php b/tests/MethodCallTest.php index f29a2779897..2ea2d780217 100644 --- a/tests/MethodCallTest.php +++ b/tests/MethodCallTest.php @@ -1232,6 +1232,27 @@ public function bar(&$object): void {} $x = new Foo(); $x->bar($x);', ], + 'conditional' => [ + 'code' => 'x(); + } + }', + ], ]; }