1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Merge pull request #6946 from sebkehr/fix_cannot_extend_constrained_with_imported_alias

This commit is contained in:
Bruce Weirdan 2021-11-19 22:24:40 +02:00 committed by GitHub
commit cd489407a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 2 deletions

View File

@ -13,6 +13,7 @@ use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTypeAlias;
use function array_merge;
@ -59,7 +60,7 @@ class UnionTypeComparator
$container_has_template = $container_type->hasTemplateOrStatic();
$input_atomic_types = \array_reverse($input_type->getAtomicTypes());
$input_atomic_types = \array_reverse(self::getTypeParts($codebase, $input_type));
while ($input_type_part = \array_pop($input_atomic_types)) {
if ($input_type_part instanceof TNull && $ignore_null) {
@ -134,7 +135,7 @@ class UnionTypeComparator
}
}
foreach ($container_type->getAtomicTypes() as $container_type_part) {
foreach (self::getTypeParts($codebase, $container_type) as $container_type_part) {
if ($ignore_null
&& $container_type_part instanceof TNull
&& !$input_type_part instanceof TNull
@ -469,4 +470,37 @@ class UnionTypeComparator
return false;
}
/**
* @return list<Type\Atomic>
*/
private static function getTypeParts(
Codebase $codebase,
Type\Union $union_type
): array {
$atomic_types = [];
foreach ($union_type->getAtomicTypes() as $atomic_type) {
if (!$atomic_type instanceof TTypeAlias) {
\array_push($atomic_types, $atomic_type);
continue;
}
$expanded = TypeExpander::expandAtomic(
$codebase,
$atomic_type,
$atomic_type->declaring_fq_classlike_name,
$atomic_type->declaring_fq_classlike_name,
null,
true,
true
);
if ($expanded instanceof Type\Atomic) {
\array_push($atomic_types, $expanded);
continue;
}
\array_push($atomic_types, ...$expanded);
}
return $atomic_types;
}
}

View File

@ -426,6 +426,25 @@ class TypeAnnotationTest extends TestCase
*/
class C implements A {}',
],
'importedTypeAliasAsConstrainedTypeParameterForImplementation' => [
'<?php
namespace Bar;
/** @template T of string */
interface A {}
/**
* @psalm-type Foo = "foo"
*/
class B {}
/**
* @psalm-import-type Foo from B
* @implements A<Foo>
*/
class C implements A {}
'
],
'importedTypeAliasAsTypeParameterForExtendedClass' => [
'<?php
namespace Bar;