mirror of
https://github.com/danog/psalm.git
synced 2024-12-02 09:37:59 +01:00
Add support for $a::class
This commit is contained in:
parent
f5378bdca8
commit
8024b4e275
@ -90,9 +90,9 @@ class ConstFetchAnalyzer
|
|||||||
) {
|
) {
|
||||||
$codebase = $statements_analyzer->getCodebase();
|
$codebase = $statements_analyzer->getCodebase();
|
||||||
|
|
||||||
if (($context->check_consts
|
if ($stmt->class instanceof PhpParser\Node\Name) {
|
||||||
|| ($stmt->name instanceof PhpParser\Node\Identifier && $stmt->name->name === 'class'))
|
if ($context->check_consts
|
||||||
&& $stmt->class instanceof PhpParser\Node\Name
|
|| ($stmt->name instanceof PhpParser\Node\Identifier && $stmt->name->name === 'class')
|
||||||
) {
|
) {
|
||||||
$first_part_lc = strtolower($stmt->class->parts[0]);
|
$first_part_lc = strtolower($stmt->class->parts[0]);
|
||||||
|
|
||||||
@ -258,6 +258,16 @@ class ConstFetchAnalyzer
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
} elseif ($stmt->name instanceof PhpParser\Node\Identifier && $stmt->name->name === 'class') {
|
||||||
|
ExpressionAnalyzer::analyze($statements_analyzer, $stmt->class, $context);
|
||||||
|
$lhs_type = $stmt->class->inferredType;
|
||||||
|
|
||||||
|
$stmt->inferredType = new Type\Union([
|
||||||
|
new Type\Atomic\TClassString('object', $lhs_type)
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$stmt->inferredType = Type::getMixed();
|
$stmt->inferredType = Type::getMixed();
|
||||||
|
|
||||||
|
@ -311,6 +311,47 @@ class ClassStringTest extends TestCase
|
|||||||
|
|
||||||
foo(AChild::class);',
|
foo(AChild::class);',
|
||||||
],
|
],
|
||||||
|
'returnClassConstantClassStringParameterized' => [
|
||||||
|
'<?php
|
||||||
|
class A {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return class-string<A> $s
|
||||||
|
*/
|
||||||
|
function foo(A $a) : string {
|
||||||
|
return $a::class;
|
||||||
|
}',
|
||||||
|
],
|
||||||
|
'returnGetClassClassStringParameterized' => [
|
||||||
|
'<?php
|
||||||
|
class A {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return class-string<A> $s
|
||||||
|
*/
|
||||||
|
function foo(A $a) : string {
|
||||||
|
return get_class($a);
|
||||||
|
}',
|
||||||
|
],
|
||||||
|
'createClassOfTypeFromString' => [
|
||||||
|
'<?php
|
||||||
|
class A {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return class-string<A> $s
|
||||||
|
*/
|
||||||
|
function foo(string $s) : string {
|
||||||
|
if (!class_exists($s)) {
|
||||||
|
throw new \UnexpectedValueException("bad");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_a($s, A::class, true)) {
|
||||||
|
throw new \UnexpectedValueException("bad");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,6 +469,27 @@ class ClassStringTest extends TestCase
|
|||||||
foo(AChild::class);',
|
foo(AChild::class);',
|
||||||
'error_message' => 'InvalidArgument',
|
'error_message' => 'InvalidArgument',
|
||||||
],
|
],
|
||||||
|
'createClassOfWrongTypeFromString' => [
|
||||||
|
'<?php
|
||||||
|
class A {}
|
||||||
|
class B {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return class-string<A> $s
|
||||||
|
*/
|
||||||
|
function foo(string $s) : string {
|
||||||
|
if (!class_exists($s)) {
|
||||||
|
throw new \UnexpectedValueException("bad");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_a($s, B::class, true)) {
|
||||||
|
throw new \UnexpectedValueException("bad");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $s;
|
||||||
|
}',
|
||||||
|
'error_message' => 'InvalidReturnStatement',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user