mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Fix #2874 - understand doubly-inherited interface templates
This commit is contained in:
parent
234a6ba4b4
commit
712806b452
@ -753,12 +753,17 @@ class Populator
|
||||
}
|
||||
|
||||
if ($implemented_interface_storage->template_type_extends) {
|
||||
foreach ($implemented_interface_storage->template_type_extends as $e_i => $type) {
|
||||
if (isset($storage->template_type_extends[$e_i])) {
|
||||
continue;
|
||||
}
|
||||
foreach ($implemented_interface_storage->template_type_extends as $e_i => $type_map) {
|
||||
foreach ($type_map as $i => $type) {
|
||||
if (is_int($i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$storage->template_type_extends[$e_i] = $type;
|
||||
$storage->template_type_extends[$e_i][$i] = self::extendType(
|
||||
$type,
|
||||
$storage
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -3021,6 +3021,72 @@ class ClassTemplateExtendsTest extends TestCase
|
||||
}
|
||||
}'
|
||||
],
|
||||
'extendsTemplatedInterface' => [
|
||||
'<?php
|
||||
class Animal {}
|
||||
|
||||
/**
|
||||
* @template DC1 of Animal
|
||||
*/
|
||||
interface IStroker {
|
||||
/**
|
||||
* @psalm-param DC1 $animal
|
||||
*/
|
||||
public function stroke(Animal $animal): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template DC2 of Animal
|
||||
* @template-extends IStroker<DC2>
|
||||
*/
|
||||
interface IStroker2 extends IStroker {}
|
||||
|
||||
class Dog extends Animal {}
|
||||
|
||||
/**
|
||||
* @implements IStroker2<Dog>
|
||||
*/
|
||||
class DogStroker implements IStroker2 {
|
||||
public function stroke(Animal $animal): void {
|
||||
$this->doDeletePerson($animal);
|
||||
}
|
||||
|
||||
private function doDeletePerson(Dog $animal): void {}
|
||||
}'
|
||||
],
|
||||
'extendsTemplatedClass' => [
|
||||
'<?php
|
||||
class Animal {}
|
||||
|
||||
/**
|
||||
* @template DC1 of Animal
|
||||
*/
|
||||
class IStroker {
|
||||
/**
|
||||
* @psalm-param DC1 $animal
|
||||
*/
|
||||
public function stroke(Animal $animal): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template DC2 of Animal
|
||||
* @template-extends IStroker<DC2>
|
||||
*/
|
||||
class IStroker2 extends IStroker {}
|
||||
|
||||
class Dog extends Animal {}
|
||||
|
||||
/**
|
||||
* @extends IStroker2<Dog>
|
||||
*/
|
||||
class DogStroker extends IStroker2 {
|
||||
public function stroke(Animal $animal): void {
|
||||
$this->doDeletePerson($animal);
|
||||
}
|
||||
|
||||
private function doDeletePerson(Dog $animal): void {}
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user