mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Fix #2554 - treat templated class string as proper subtype of class string
This commit is contained in:
parent
eaae84c7f8
commit
2cd7f74efb
@ -21,6 +21,7 @@ use Psalm\Type\Atomic\TFloat;
|
||||
use Psalm\Type\Atomic\TGenericObject;
|
||||
use Psalm\Type\Atomic\TList;
|
||||
use Psalm\Type\Atomic\TTemplateParam;
|
||||
use Psalm\Type\Atomic\TTemplateParamClass;
|
||||
use Psalm\Type\Atomic\GetClassT;
|
||||
use Psalm\Type\Atomic\GetTypeT;
|
||||
use Psalm\Type\Atomic\THtmlEscapedString;
|
||||
@ -891,11 +892,22 @@ class TypeAnalyzer
|
||||
if ($input_type_part instanceof GetClassT) {
|
||||
$first_type = array_values($input_type_part->as_type->getAtomicTypes())[0];
|
||||
|
||||
if ($first_type instanceof TTemplateParam) {
|
||||
$object_type = array_values($first_type->as->getAtomicTypes())[0];
|
||||
|
||||
$input_type_part = new TTemplateParamClass(
|
||||
$first_type->param_name,
|
||||
$first_type->as->getId(),
|
||||
$object_type instanceof TNamedObject ? $object_type : null,
|
||||
$first_type->defining_class
|
||||
);
|
||||
} else {
|
||||
$input_type_part = new TClassString(
|
||||
'object',
|
||||
$first_type instanceof TNamedObject ? $first_type : null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($input_type_part instanceof GetTypeT) {
|
||||
$input_type_part = new TString();
|
||||
@ -1219,6 +1231,16 @@ class TypeAnalyzer
|
||||
return $container_type_part->value === $input_type_part->value;
|
||||
}
|
||||
|
||||
if ($container_type_part instanceof TTemplateParamClass
|
||||
&& get_class($input_type_part) === TClassString::class
|
||||
) {
|
||||
if ($atomic_comparison_result) {
|
||||
$atomic_comparison_result->type_coerced = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($container_type_part instanceof TClassString
|
||||
&& $container_type_part->as === 'object'
|
||||
&& !$container_type_part->as_type
|
||||
|
@ -2241,7 +2241,40 @@ class ClassTemplateTest extends TestCase
|
||||
}
|
||||
);
|
||||
}'
|
||||
]
|
||||
],
|
||||
'assertionOnTemplatedClassString' => [
|
||||
'<?php
|
||||
class TEM {
|
||||
/**
|
||||
* @template Entity
|
||||
* @psalm-param class-string<Entity> $type
|
||||
* @psalm-return EQB<Entity>
|
||||
*/
|
||||
public function createEQB(string $type) {
|
||||
if (!class_exists($type)) {
|
||||
throw new InvalidArgumentException();
|
||||
}
|
||||
return new EQB($type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template Entity
|
||||
*/
|
||||
class EQB {
|
||||
/**
|
||||
* @psalm-var class-string<Entity>
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @psalm-param class-string<Entity> $type
|
||||
*/
|
||||
public function __construct(string $type) {
|
||||
$this->type = $type;
|
||||
}
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user