From 73fc7d9491644c169d24bfbe51a374e3eed719f7 Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Fri, 4 Dec 2020 01:19:51 -0500 Subject: [PATCH] Fix #4767 - rescan directly-affected class-interface relationships --- src/Psalm/Internal/Codebase/Populator.php | 4 +- src/Psalm/Storage/ClassLikeStorage.php | 2 +- tests/Template/ClassTemplateExtendsTest.php | 49 +++++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/Psalm/Internal/Codebase/Populator.php b/src/Psalm/Internal/Codebase/Populator.php index f63936dea..eb1e48559 100644 --- a/src/Psalm/Internal/Codebase/Populator.php +++ b/src/Psalm/Internal/Codebase/Populator.php @@ -603,7 +603,7 @@ class Populator ): void { $parent_interfaces = []; - foreach ($storage->parent_interfaces as $parent_interface_lc => $_) { + foreach ($storage->direct_interface_parents as $parent_interface_lc => $_) { try { $parent_interface_lc = strtolower( $this->classlikes->getUnAliasedName( @@ -696,7 +696,7 @@ class Populator ): void { $extra_interfaces = []; - foreach ($storage->class_implements as $implemented_interface_lc => $_) { + foreach ($storage->direct_class_interfaces as $implemented_interface_lc => $_) { try { $implemented_interface_lc = strtolower( $this->classlikes->getUnAliasedName( diff --git a/src/Psalm/Storage/ClassLikeStorage.php b/src/Psalm/Storage/ClassLikeStorage.php index 0709350ee..a69eea550 100644 --- a/src/Psalm/Storage/ClassLikeStorage.php +++ b/src/Psalm/Storage/ClassLikeStorage.php @@ -102,7 +102,7 @@ class ClassLikeStorage /** * Interfaces this class implements directly * - * @var array + * @var array */ public $direct_class_interfaces = []; diff --git a/tests/Template/ClassTemplateExtendsTest.php b/tests/Template/ClassTemplateExtendsTest.php index 7971c1f8f..79f09835e 100644 --- a/tests/Template/ClassTemplateExtendsTest.php +++ b/tests/Template/ClassTemplateExtendsTest.php @@ -1556,8 +1556,14 @@ class ClassTemplateExtendsTest extends TestCase $this->elements = $elements; } + /** + * @psalm-suppress InvalidReturnType + */ public function getIterator() { + /** + * @psalm-suppress InvalidReturnStatement + */ return new ArrayIterator($this->elements); } @@ -4173,6 +4179,49 @@ class ClassTemplateExtendsTest extends TestCase return $foo->map($function); }' ], + 'extendStubbedInterfaceTwice' => [ + ' + */ + interface A extends ArrayAccess { + /** + * @psalm-param Tk $k + * @psalm-return Tv + */ + public function at($k); + } + + /** + * @template Tk of array-key + * @template Tv + * + * @extends A + */ + interface B extends A {} + + /** + * @template Tk of array-key + * @template Tv + * + * @implements B + */ + abstract class C implements B + { + /** + * @psalm-param Tk $k + * @psalm-return Tv + */ + public function at($k) { /** @var Tv */ return 1; } + }' + ], ]; }