1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Add support for static::class

This commit is contained in:
Matt Brown 2018-01-23 15:46:14 -05:00
parent c0fda0ef1e
commit dea5d92e9b
3 changed files with 59 additions and 9 deletions

View File

@ -826,9 +826,28 @@ class AssertionFinder
}
} elseif (self::hasIsACheck($expr)) {
if ($first_var_name) {
/** @var PhpParser\Node\Scalar\String_ */
$is_a_type = $expr->args[1]->value;
$if_types[$first_var_name] = $prefix . $is_a_type->value;
$first_arg = $expr->args[1]->value;
if ($first_arg instanceof PhpParser\Node\Scalar\String_) {
$if_types[$first_var_name] = $prefix . $first_arg->value;
} elseif ($first_arg instanceof PhpParser\Node\Expr\ClassConstFetch
&& $first_arg->class instanceof PhpParser\Node\Name
&& is_string($first_arg->name)
&& strtolower($first_arg->name) === 'class'
) {
$class_node = $first_arg->class;
if ($class_node->parts === ['static'] || $class_node->parts === ['self']) {
$if_types[$first_var_name] = $prefix . $this_class_name;
} elseif ($class_node->parts === ['parent']) {
// do nothing
} else {
$if_types[$first_var_name] = $prefix . ClassLikeChecker::getFQCLNFromNameObject(
$class_node,
$source->getAliases()
);
}
}
}
} elseif (self::hasArrayCheck($expr)) {
if ($first_var_name) {
@ -1080,9 +1099,22 @@ class AssertionFinder
*/
protected static function hasIsACheck(PhpParser\Node\Expr\FuncCall $stmt)
{
if ($stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'is_a' &&
$stmt->args[1]->value instanceof PhpParser\Node\Scalar\String_) {
return true;
if ($stmt->name instanceof PhpParser\Node\Name
&& strtolower($stmt->name->parts[0]) === 'is_a'
&& isset($stmt->args[1])
) {
$first_arg = $stmt->args[1]->value;
if ($first_arg instanceof PhpParser\Node\Scalar\String_
|| (
$first_arg instanceof PhpParser\Node\Expr\ClassConstFetch
&& $first_arg->class instanceof PhpParser\Node\Name
&& is_string($first_arg->name)
&& strtolower($first_arg->name) === 'class'
)
) {
return true;
}
}
return false;

View File

@ -88,16 +88,17 @@ class ConstFetchChecker
) {
if ($context->check_consts &&
$stmt->class instanceof PhpParser\Node\Name &&
strtolower($stmt->class->parts[0]) !== 'static' &&
is_string($stmt->name)
) {
if (strtolower($stmt->class->parts[0]) === 'self') {
$first_part_lc = strtolower($stmt->class->parts[0]);
if ($first_part_lc === 'self' || $first_part_lc === 'static') {
if (!$context->self) {
throw new \UnexpectedValueException('$context->self cannot be null');
}
$fq_class_name = (string)$context->self;
} elseif ($stmt->class->parts[0] === 'parent') {
} elseif ($first_part_lc === 'parent') {
$fq_class_name = $statements_checker->getParentFQCLN();
if ($fq_class_name === null) {

View File

@ -699,6 +699,23 @@ class TypeReconciliationTest extends TestCase
}
}',
],
'isaStaticClass' => [
'<?php
abstract class Foo {
/**
* @return static[]
*/
abstract public static function getArr() : array;
/**
* @return static|null
*/
public static function getOne() {
$one = current(static::getArr());
return is_a($one, static::class, false) ? $one : null;
}
}',
],
];
}