1
0
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:
Matt Brown 2018-03-06 13:59:59 -05:00
parent b664c85642
commit fac5554e13
3 changed files with 85 additions and 14 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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',