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:
parent
c0fda0ef1e
commit
dea5d92e9b
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user