mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Apply psalm-inheritors to interfaces too
This commit is contained in:
parent
e23971ca29
commit
d0c4d170b0
@ -11,9 +11,13 @@ use Psalm\FileManipulation;
|
||||
use Psalm\Internal\Analyzer\Statements\Expression\ClassConstAnalyzer;
|
||||
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
|
||||
use Psalm\Internal\Provider\NodeDataProvider;
|
||||
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
|
||||
use Psalm\Issue\InheritorViolation;
|
||||
use Psalm\Issue\ParseError;
|
||||
use Psalm\Issue\UndefinedInterface;
|
||||
use Psalm\IssueBuffer;
|
||||
use Psalm\Type\Atomic\TNamedObject;
|
||||
use Psalm\Type\Union;
|
||||
use UnexpectedValueException;
|
||||
|
||||
use function strtolower;
|
||||
@ -109,6 +113,23 @@ class InterfaceAnalyzer extends ClassLikeAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
$class_union = new Union([new TNamedObject($fq_interface_name)]);
|
||||
foreach ($class_storage->direct_interface_parents as $parent_interface) {
|
||||
$parent_storage = $codebase->classlikes->getStorageFor($parent_interface);
|
||||
if ($parent_storage && $parent_storage->inheritors) {
|
||||
if (!UnionTypeComparator::isContainedBy($codebase, $class_union, $parent_storage->inheritors)) {
|
||||
IssueBuffer::maybeAdd(
|
||||
new InheritorViolation(
|
||||
'Interface ' . $fq_interface_name . '
|
||||
is not an allowed inheritor of parent interface ' . $parent_interface,
|
||||
new CodeLocation($this, $this->class),
|
||||
),
|
||||
$this->getSuppressedIssues(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fq_interface_name = $this->getFQCLN();
|
||||
|
||||
if (!$fq_interface_name) {
|
||||
|
@ -857,7 +857,6 @@ class ClassTest extends TestCase
|
||||
*/
|
||||
class BaseClass {}
|
||||
class FooClass extends BaseClass {}
|
||||
$a = new FooClass();
|
||||
PHP,
|
||||
],
|
||||
'unionInheritorIsAllowed' => [
|
||||
@ -868,9 +867,7 @@ class ClassTest extends TestCase
|
||||
*/
|
||||
class BaseClass {}
|
||||
class FooClass extends BaseClass {}
|
||||
$a = new FooClass();
|
||||
class BarClass extends FooClass {}
|
||||
$b = new BarClass();
|
||||
PHP,
|
||||
],
|
||||
'multiInheritorIsAllowed' => [
|
||||
@ -881,9 +878,7 @@ class ClassTest extends TestCase
|
||||
*/
|
||||
class BaseClass {}
|
||||
class FooClass extends BaseClass {}
|
||||
$a = new FooClass();
|
||||
class BarClass extends FooClass {}
|
||||
$b = new BarClass();
|
||||
PHP,
|
||||
],
|
||||
'skippedInheritorIsAllowed' => [
|
||||
@ -894,9 +889,7 @@ class ClassTest extends TestCase
|
||||
*/
|
||||
class BaseClass {}
|
||||
class FooClass extends BaseClass {}
|
||||
$a = new FooClass();
|
||||
class BarClass extends FooClass {}
|
||||
$b = new BarClass();
|
||||
PHP,
|
||||
],
|
||||
'CompositeInheritorIsAllowed' => [
|
||||
@ -908,7 +901,6 @@ class ClassTest extends TestCase
|
||||
class BaseClass {}
|
||||
interface FooInterface {}
|
||||
class BarClass extends BaseClass implements FooInterface {}
|
||||
$b = new BarClass();
|
||||
PHP,
|
||||
],
|
||||
'InterfaceInheritorIsAllowed' => [
|
||||
@ -919,12 +911,10 @@ class ClassTest extends TestCase
|
||||
*/
|
||||
interface BaseInterface {}
|
||||
class FooClass implements BaseInterface {}
|
||||
$a = new FooClass();
|
||||
class BarClass implements BaseInterface {}
|
||||
$b = new BarClass();
|
||||
PHP,
|
||||
],
|
||||
'MultiInterfaceInheritorIsAllowed' => [
|
||||
],
|
||||
'MultiInterfaceInheritorIsAllowed' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
/**
|
||||
@ -936,7 +926,16 @@ class ClassTest extends TestCase
|
||||
*/
|
||||
interface InterfaceB {}
|
||||
class FooClass implements InterfaceA, InterfaceB {}
|
||||
$a = new FooClass();
|
||||
PHP,
|
||||
],
|
||||
'InterfaceOfInterfaceInheritorIsAllowed' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
/**
|
||||
* @psalm-inheritors InterfaceB
|
||||
*/
|
||||
interface InterfaceA {}
|
||||
interface InterfaceB extends InterfaceA {}
|
||||
PHP,
|
||||
],
|
||||
];
|
||||
@ -1409,6 +1408,18 @@ class ClassTest extends TestCase
|
||||
'error_message' => 'InheritorViolation',
|
||||
'ignored_issues' => [],
|
||||
],
|
||||
'interfaceCannotImplementIfNotInInheritors' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
/**
|
||||
* @psalm-inheritors FooClass|BarClass
|
||||
*/
|
||||
interface BaseInterface {}
|
||||
interface BazInterface extends BaseInterface {}
|
||||
PHP,
|
||||
'error_message' => 'InheritorViolation',
|
||||
'ignored_issues' => [],
|
||||
],
|
||||
'UnfulfilledInterfaceInheritors' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
|
Loading…
Reference in New Issue
Block a user