1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix #715 - no redundant condition for is_a(self::class,...) checks inside trait

This commit is contained in:
Matt Brown 2018-05-30 10:13:55 -04:00
parent 1a4891c2e0
commit 9227e61097
2 changed files with 60 additions and 15 deletions

View File

@ -937,7 +937,7 @@ class AssertionFinder
}
} elseif (self::hasIsACheck($expr)) {
if ($first_var_name) {
$first_arg = $expr->args[1]->value;
$second_arg = $expr->args[1]->value;
$is_a_prefix = '';
@ -953,24 +953,36 @@ class AssertionFinder
$is_a_prefix = strtolower($third_arg->name->parts[0]) === 'true' ? 'isa-' : '';
}
if ($first_arg instanceof PhpParser\Node\Scalar\String_) {
$if_types[$first_var_name] = $prefix . $is_a_prefix . $first_arg->value;
} elseif ($first_arg instanceof PhpParser\Node\Expr\ClassConstFetch
&& $first_arg->class instanceof PhpParser\Node\Name
&& $first_arg->name instanceof PhpParser\Node\Identifier
&& strtolower($first_arg->name->name) === 'class'
if ($second_arg instanceof PhpParser\Node\Scalar\String_) {
$if_types[$first_var_name] = $prefix . $is_a_prefix . $second_arg->value;
} elseif ($second_arg instanceof PhpParser\Node\Expr\ClassConstFetch
&& $second_arg->class instanceof PhpParser\Node\Name
&& $second_arg->name instanceof PhpParser\Node\Identifier
&& strtolower($second_arg->name->name) === 'class'
) {
$class_node = $first_arg->class;
$first_arg = $expr->args[0]->value;
if ($class_node->parts === ['static'] || $class_node->parts === ['self']) {
$if_types[$first_var_name] = $prefix . $is_a_prefix . $this_class_name;
} elseif ($class_node->parts === ['parent']) {
if (isset($first_arg->inferredType)
&& $first_arg->inferredType->isSingleStringLiteral()
&& $source instanceof StatementsChecker
&& $source->getSource()->getSource() instanceof \Psalm\Checker\TraitChecker
&& $first_arg->inferredType->getSingleStringLiteral() === $this_class_name
) {
// do nothing
} else {
$if_types[$first_var_name] = $prefix . $is_a_prefix . ClassLikeChecker::getFQCLNFromNameObject(
$class_node,
$source->getAliases()
);
$class_node = $second_arg->class;
if ($class_node->parts === ['static'] || $class_node->parts === ['self']) {
$if_types[$first_var_name] = $prefix . $is_a_prefix . $this_class_name;
} elseif ($class_node->parts === ['parent']) {
// do nothing
} else {
$if_types[$first_var_name] = $prefix . $is_a_prefix
. ClassLikeChecker::getFQCLNFromNameObject(
$class_node,
$source->getAliases()
);
}
}
}
}

View File

@ -536,6 +536,39 @@ class TraitTest extends TestCase
use A;
}'
],
'noRedundantConditionForTraitStatic' => [
'<?php
trait Foo {
public function bar() : array {
$type = static::class;
$r = new \ReflectionClass($type);
$values = $r->getConstants();
$callback =
/** @param mixed $v */
function ($v) : bool {
return \is_int($v) || \is_string($v);
};
if (is_a($type, \Bat::class, true)) {
$callback =
/** @param mixed $v */
function ($v) : bool {
return \is_int($v) && 0 === ($v & $v - 1) && $v > 0;
};
}
return array_filter($values, $callback);
}
}
class Bar {
use Foo;
}
class Bat {
use Foo;
}'
],
];
}