mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Improve handling of default extended params
This commit is contained in:
parent
70b8df268d
commit
b693b726c7
@ -145,6 +145,7 @@ class TypeAnalyzer
|
|||||||
|
|
||||||
if ($input_type_part instanceof TMixed
|
if ($input_type_part instanceof TMixed
|
||||||
&& $input_type->from_template_default
|
&& $input_type->from_template_default
|
||||||
|
&& $input_type->from_docblock
|
||||||
&& $atomic_comparison_result
|
&& $atomic_comparison_result
|
||||||
&& $atomic_comparison_result->type_coerced_from_mixed
|
&& $atomic_comparison_result->type_coerced_from_mixed
|
||||||
) {
|
) {
|
||||||
@ -250,7 +251,9 @@ class TypeAnalyzer
|
|||||||
if ($all_type_coerced_from_mixed) {
|
if ($all_type_coerced_from_mixed) {
|
||||||
$union_comparison_result->type_coerced_from_mixed = true;
|
$union_comparison_result->type_coerced_from_mixed = true;
|
||||||
|
|
||||||
if ($input_type->from_template_default || $all_type_coerced_from_as_mixed) {
|
if (($input_type->from_template_default && $input_type->from_docblock)
|
||||||
|
|| $all_type_coerced_from_as_mixed
|
||||||
|
) {
|
||||||
$union_comparison_result->type_coerced_from_as_mixed = true;
|
$union_comparison_result->type_coerced_from_as_mixed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,7 +268,9 @@ class TypeAnalyzer
|
|||||||
if ($some_type_coerced_from_mixed) {
|
if ($some_type_coerced_from_mixed) {
|
||||||
$union_comparison_result->type_coerced_from_mixed = true;
|
$union_comparison_result->type_coerced_from_mixed = true;
|
||||||
|
|
||||||
if ($input_type->from_template_default || $all_type_coerced_from_as_mixed) {
|
if (($input_type->from_template_default && $input_type->from_docblock)
|
||||||
|
|| $all_type_coerced_from_as_mixed
|
||||||
|
) {
|
||||||
$union_comparison_result->type_coerced_from_as_mixed = true;
|
$union_comparison_result->type_coerced_from_as_mixed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,8 +403,10 @@ class Populator
|
|||||||
|
|
||||||
foreach ($trait_storage->template_types as $template_name => $template_type_map) {
|
foreach ($trait_storage->template_types as $template_name => $template_type_map) {
|
||||||
foreach ($template_type_map as $template_type) {
|
foreach ($template_type_map as $template_type) {
|
||||||
|
$default_param = clone $template_type[0];
|
||||||
|
$default_param->from_docblock = false;
|
||||||
$storage->template_type_extends[$trait_storage->name][$template_name]
|
$storage->template_type_extends[$trait_storage->name][$template_name]
|
||||||
= $template_type[0];
|
= $default_param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -517,8 +519,10 @@ class Populator
|
|||||||
|
|
||||||
foreach ($parent_storage->template_types as $template_name => $template_type_map) {
|
foreach ($parent_storage->template_types as $template_name => $template_type_map) {
|
||||||
foreach ($template_type_map as $template_type) {
|
foreach ($template_type_map as $template_type) {
|
||||||
|
$default_param = clone $template_type[0];
|
||||||
|
$default_param->from_docblock = false;
|
||||||
$storage->template_type_extends[$parent_storage->name][$template_name]
|
$storage->template_type_extends[$parent_storage->name][$template_name]
|
||||||
= $template_type[0];
|
= $default_param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,8 +659,10 @@ class Populator
|
|||||||
|
|
||||||
foreach ($parent_interface_storage->template_types as $template_name => $template_type_map) {
|
foreach ($parent_interface_storage->template_types as $template_name => $template_type_map) {
|
||||||
foreach ($template_type_map as $template_type) {
|
foreach ($template_type_map as $template_type) {
|
||||||
|
$default_param = clone $template_type[0];
|
||||||
|
$default_param->from_docblock = false;
|
||||||
$storage->template_type_extends[$parent_interface_storage->name][$template_name]
|
$storage->template_type_extends[$parent_interface_storage->name][$template_name]
|
||||||
= $template_type[0];
|
= $default_param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -747,8 +753,10 @@ class Populator
|
|||||||
|
|
||||||
foreach ($implemented_interface_storage->template_types as $template_name => $template_type_map) {
|
foreach ($implemented_interface_storage->template_types as $template_name => $template_type_map) {
|
||||||
foreach ($template_type_map as $template_type) {
|
foreach ($template_type_map as $template_type) {
|
||||||
|
$default_param = clone $template_type[0];
|
||||||
|
$default_param->from_docblock = false;
|
||||||
$storage->template_type_extends[$implemented_interface_storage->name][$template_name]
|
$storage->template_type_extends[$implemented_interface_storage->name][$template_name]
|
||||||
= $template_type[0];
|
= $default_param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,6 +321,64 @@ class ClassTemplateCovarianceTest extends TestCase
|
|||||||
class CovariantFoo extends InvariantFoo {}',
|
class CovariantFoo extends InvariantFoo {}',
|
||||||
'error_message' => 'InvalidTemplateParam',
|
'error_message' => 'InvalidTemplateParam',
|
||||||
],
|
],
|
||||||
|
'expectsTemplatedObject' => [
|
||||||
|
'<?php
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @template-implements ArrayAccess<int,T>
|
||||||
|
*/
|
||||||
|
class MyArray implements ArrayAccess, IteratorAggregate {
|
||||||
|
/** @var array<int,T> */
|
||||||
|
private $values = [];
|
||||||
|
public function __construct() {
|
||||||
|
$this->values = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
* @param T $value
|
||||||
|
*/
|
||||||
|
public function offsetSet($offset, $value) {
|
||||||
|
$this->values[$offset] = $value;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
* @return T
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset) {
|
||||||
|
return $this->values[$offset];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset) {
|
||||||
|
return isset($this->values[$offset]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
*/
|
||||||
|
public function offsetUnset($offset) {
|
||||||
|
unset($this->values[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIterator() : Traversable {
|
||||||
|
return new ArrayObject($this->values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {}
|
||||||
|
class AChild extends A {}
|
||||||
|
|
||||||
|
/** @param IteratorAggregate<int, A> $i */
|
||||||
|
function expectsIteratorAggregateOfA(IteratorAggregate $i) : void {}
|
||||||
|
|
||||||
|
/** @param MyArray<AChild> $m */
|
||||||
|
function takesMyArrayOfAChild(MyArray $m) : void {
|
||||||
|
expectsIteratorAggregateOfA($m);
|
||||||
|
}',
|
||||||
|
'error_message' => 'MixedArgumentTypeCoercion',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user