mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix #2208 - handle templated property types appropriately
This commit is contained in:
parent
27961045a0
commit
94001aad4a
@ -683,6 +683,20 @@ class PropertyAssignmentAnalyzer
|
||||
$class_storage->parent_class
|
||||
);
|
||||
|
||||
$class_property_type = \Psalm\Internal\Codebase\Methods::localizeType(
|
||||
$codebase,
|
||||
$class_property_type,
|
||||
$fq_class_name,
|
||||
$declaring_property_class
|
||||
);
|
||||
|
||||
$assignment_value_type = \Psalm\Internal\Codebase\Methods::localizeType(
|
||||
$codebase,
|
||||
$assignment_value_type,
|
||||
$fq_class_name,
|
||||
$declaring_property_class
|
||||
);
|
||||
|
||||
if (!$class_property_type->hasMixed() && $assignment_value_type->hasMixed()) {
|
||||
if (IssueBuffer::accepts(
|
||||
new MixedAssignment(
|
||||
|
@ -408,7 +408,7 @@ class Methods
|
||||
|
||||
if ($source) {
|
||||
$overridden_class_storage = $this->classlike_storage_provider->get($overriding_fq_class_name);
|
||||
$params[$i]->type = self::localizeParamType(
|
||||
$params[$i]->type = self::localizeType(
|
||||
$source->getCodebase(),
|
||||
$params[$i]->type,
|
||||
$appearing_fq_class_name,
|
||||
@ -432,7 +432,7 @@ class Methods
|
||||
throw new \UnexpectedValueException('Cannot get method params for ' . $method_id);
|
||||
}
|
||||
|
||||
private static function localizeParamType(
|
||||
public static function localizeType(
|
||||
Codebase $codebase,
|
||||
Type\Union $type,
|
||||
string $appearing_fq_class_name,
|
||||
@ -470,7 +470,7 @@ class Methods
|
||||
|| $atomic_type instanceof Type\Atomic\TGenericObject
|
||||
) {
|
||||
foreach ($atomic_type->type_params as &$type_param) {
|
||||
$type_param = self::localizeParamType(
|
||||
$type_param = self::localizeType(
|
||||
$codebase,
|
||||
$type_param,
|
||||
$appearing_fq_class_name,
|
||||
@ -485,7 +485,7 @@ class Methods
|
||||
if ($atomic_type->params) {
|
||||
foreach ($atomic_type->params as $param) {
|
||||
if ($param->type) {
|
||||
$param->type = self::localizeParamType(
|
||||
$param->type = self::localizeType(
|
||||
$codebase,
|
||||
$param->type,
|
||||
$appearing_fq_class_name,
|
||||
@ -496,7 +496,7 @@ class Methods
|
||||
}
|
||||
|
||||
if ($atomic_type->return_type) {
|
||||
$atomic_type->return_type = self::localizeParamType(
|
||||
$atomic_type->return_type = self::localizeType(
|
||||
$codebase,
|
||||
$atomic_type->return_type,
|
||||
$appearing_fq_class_name,
|
||||
|
@ -69,7 +69,9 @@ class TTemplateParam extends \Psalm\Type\Atomic
|
||||
. ')&' . implode('&', $this->extra_types);
|
||||
}
|
||||
|
||||
return $this->param_name . ' as ' . $this->as->getId();
|
||||
return $this->param_name
|
||||
. ($this->defining_class ? ':' . $this->defining_class : '')
|
||||
. ' as ' . $this->as->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2265,7 +2265,56 @@ class ClassTemplateExtendsTest extends TestCase
|
||||
class Bar implements Foo {
|
||||
use FooTrait;
|
||||
}',
|
||||
],
|
||||
'extendedPropertyType' => [
|
||||
'<?php
|
||||
interface I {}
|
||||
|
||||
/** @template T of I */
|
||||
abstract class C {
|
||||
/** @var ?T */
|
||||
protected $m;
|
||||
}
|
||||
|
||||
class Impl implements I {}
|
||||
|
||||
/** @template-extends C<Impl> */
|
||||
class Test extends C {
|
||||
protected function foo() : void {
|
||||
$this->m = new Impl();
|
||||
}
|
||||
}'
|
||||
],
|
||||
'constructorCheckInChildClassArrayType' => [
|
||||
'<?php
|
||||
interface I {}
|
||||
|
||||
/** @template T of I */
|
||||
abstract class C
|
||||
{
|
||||
/** @var array<string, T> */
|
||||
protected $items = [];
|
||||
|
||||
// added to trigger constructor initialisation checks
|
||||
// in descendant classes
|
||||
public int $i;
|
||||
|
||||
/** @param array<string, T> $items */
|
||||
public function __construct($items = []) {
|
||||
$this->i = 5;
|
||||
|
||||
foreach ($items as $k => $v) {
|
||||
$this->items[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Impl implements I {}
|
||||
|
||||
/**
|
||||
* @template-extends C<Impl>
|
||||
*/
|
||||
class Test extends C {}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user