mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Fix errors around static class constants in template vars
This commit is contained in:
parent
b664c85642
commit
fac5554e13
@ -218,7 +218,17 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
|
||||
$inferred = true
|
||||
) {
|
||||
if (empty($fq_class_name)) {
|
||||
throw new \InvalidArgumentException('$class cannot be empty');
|
||||
if (IssueBuffer::accepts(
|
||||
new UndefinedClass(
|
||||
'Class or interface <empty string> does not exist',
|
||||
$code_location
|
||||
),
|
||||
$suppressed_issues
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$project_checker = $statements_source->getFileChecker()->project_checker;
|
||||
|
@ -695,7 +695,9 @@ class CallChecker
|
||||
if ($offset_value_type) {
|
||||
foreach ($offset_value_type->getTypes() as $offset_value_type_part) {
|
||||
// register class if the class exists
|
||||
if ($offset_value_type_part instanceof TNamedObject) {
|
||||
if ($offset_value_type_part instanceof TNamedObject
|
||||
&& !in_array($offset_value_type, ['self', 'static', 'parent'])
|
||||
) {
|
||||
ClassLikeChecker::checkFullyQualifiedClassLikeName(
|
||||
$statements_checker,
|
||||
$offset_value_type_part->value,
|
||||
|
@ -59,18 +59,7 @@ class TemplateTest extends TestCase
|
||||
$cfoo_bar = $cfoo->bar();
|
||||
|
||||
$dt = "D";
|
||||
$dfoo = new Foo($dt);
|
||||
|
||||
class E {
|
||||
/**
|
||||
* @return Foo<self>
|
||||
*/
|
||||
public static function getFoo() {
|
||||
return new Foo(__CLASS__);
|
||||
}
|
||||
}
|
||||
|
||||
$efoo = E::getFoo();',
|
||||
$dfoo = new Foo($dt);',
|
||||
'assertions' => [
|
||||
'$afoo' => 'Foo<A>',
|
||||
'$afoo_bar' => 'A',
|
||||
@ -82,8 +71,78 @@ class TemplateTest extends TestCase
|
||||
'$cfoo_bar' => 'C',
|
||||
|
||||
'$dfoo' => 'Foo<mixed>',
|
||||
],
|
||||
'error_levels' => [
|
||||
'MixedReturnStatement',
|
||||
'LessSpecificReturnStatement',
|
||||
'RedundantConditionGivenDocblockType',
|
||||
],
|
||||
],
|
||||
'classTemplateSelfs' => [
|
||||
'<?php
|
||||
/**
|
||||
* @template T as object
|
||||
*/
|
||||
class Foo {
|
||||
/** @var string */
|
||||
public $T;
|
||||
|
||||
/**
|
||||
* @param string $T
|
||||
* @template-typeof T $T
|
||||
*/
|
||||
public function __construct(string $T) {
|
||||
$this->T = $T;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T
|
||||
*/
|
||||
public function bar() {
|
||||
$t = $this->T;
|
||||
return new $t();
|
||||
}
|
||||
}
|
||||
|
||||
class E {
|
||||
/**
|
||||
* @return Foo<self>
|
||||
*/
|
||||
public static function getFoo() {
|
||||
return new Foo(__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Foo<self>
|
||||
*/
|
||||
public static function getFoo2() {
|
||||
return new Foo(self::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Foo<static>
|
||||
*/
|
||||
public static function getFoo3() {
|
||||
return new Foo(static::class);
|
||||
}
|
||||
}
|
||||
|
||||
class G extends E {}
|
||||
|
||||
$efoo = E::getFoo();
|
||||
$efoo2 = E::getFoo2();
|
||||
$efoo3 = E::getFoo3();
|
||||
|
||||
$gfoo = G::getFoo();
|
||||
$gfoo2 = G::getFoo2();
|
||||
$gfoo3 = G::getFoo3();',
|
||||
'assertions' => [
|
||||
'$efoo' => 'Foo<E>',
|
||||
'$efoo2' => 'Foo<E>',
|
||||
'$efoo3' => 'Foo<E>',
|
||||
'$gfoo' => 'Foo<E>',
|
||||
'$gfoo2' => 'Foo<E>',
|
||||
'$gfoo3' => 'Foo<G>',
|
||||
],
|
||||
'error_levels' => [
|
||||
'MixedReturnStatement',
|
||||
|
Loading…
x
Reference in New Issue
Block a user