1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Support intersections on LHS of static calls

This commit is contained in:
Matthew Brown 2019-01-19 23:25:23 -05:00
parent 394d6509c6
commit 7dfcefd35d
2 changed files with 32 additions and 7 deletions

View File

@ -257,12 +257,18 @@ class StaticCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\
$has_mock = false;
foreach ($lhs_type->getTypes() as $lhs_type_part) {
$intersection_types = [];
if ($lhs_type_part instanceof TNamedObject) {
$fq_class_name = $lhs_type_part->value;
$intersection_types = $lhs_type_part->extra_types;
} elseif ($lhs_type_part instanceof Type\Atomic\TClassString
&& $lhs_type_part->as_type
) {
$fq_class_name = $lhs_type_part->as_type->value;
$intersection_types = $lhs_type_part->as_type->extra_types;
} elseif ($lhs_type_part instanceof Type\Atomic\TLiteralClassString) {
$fq_class_name = $lhs_type_part->value;
} elseif ($lhs_type_part instanceof Type\Atomic\TGenericParam
@ -365,6 +371,25 @@ class StaticCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\
$args = $stmt->args;
if ($intersection_types
&& !$codebase->methods->methodExists($method_id)
) {
foreach ($intersection_types as $intersection_type) {
if (!$intersection_type instanceof TNamedObject) {
continue;
}
$intersection_method_id = $intersection_type->value . '::' . $method_name_lc;
if ($codebase->methods->methodExists($intersection_method_id)) {
$method_id = $intersection_method_id;
$fq_class_name = $intersection_type->value;
$cased_method_id = $fq_class_name . '::' . $stmt->name->name;
break;
}
}
}
if (!$codebase->methods->methodExists($method_id)
|| !MethodAnalyzer::isMethodVisible(
$method_id,
@ -455,7 +480,7 @@ class StaticCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\
$does_method_exist = MethodAnalyzer::checkMethodExists(
$codebase,
$cased_method_id,
$method_id,
new CodeLocation($source, $stmt),
$statements_analyzer->getSuppressedIssues(),
$context->calling_method_id

View File

@ -434,22 +434,22 @@ class ClassStringTest extends TestCase
return false;
}',
],
'intersectionClassString' => [
'explicitIntersectionClassString' => [
'<?php
interface Foo {
public static function one() : bool;
public static function one() : void;
};
interface Bar {
public static function two() : bool;
public static function two() : void;
}
/**
* @param class-string<Foo&Bar> $className
*/
function foo($className) : bool {
return $className::one();
return $className::two();
function foo($className) : void {
$className::one();
$className::two();
}'
],
];