mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Merge pull request #9658 from klimick/fix-list-template-replacement
Fix list<T> template replacement
This commit is contained in:
commit
2a6d9a8785
@ -549,7 +549,6 @@
|
||||
<PossiblyUndefinedIntArrayOffset>
|
||||
<code><![CDATA[$this->properties[0]]]></code>
|
||||
<code><![CDATA[$this->properties[0]]]></code>
|
||||
<code><![CDATA[$this->properties[0]]]></code>
|
||||
</PossiblyUndefinedIntArrayOffset>
|
||||
<PossiblyUnusedMethod>
|
||||
<code>getList</code>
|
||||
|
@ -149,15 +149,24 @@ class TKeyedArray extends Atomic
|
||||
return $this->fallback_params === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-assert-if-true list{Union} $this->properties
|
||||
* @psalm-assert-if-true list{Union, Union} $this->fallback_params
|
||||
*/
|
||||
public function isGenericList(): bool
|
||||
{
|
||||
return $this->is_list
|
||||
&& count($this->properties) === 1
|
||||
&& $this->fallback_params
|
||||
&& $this->properties[0]->equals($this->fallback_params[1], true, true, false);
|
||||
}
|
||||
|
||||
public function getId(bool $exact = true, bool $nested = false): string
|
||||
{
|
||||
$property_strings = [];
|
||||
|
||||
if ($this->is_list) {
|
||||
if (count($this->properties) === 1
|
||||
&& $this->fallback_params
|
||||
&& $this->properties[0]->equals($this->fallback_params[1], true, true, false)
|
||||
) {
|
||||
if ($this->isGenericList()) {
|
||||
$t = $this->properties[0]->possibly_undefined ? 'list' : 'non-empty-list';
|
||||
return "$t<".$this->fallback_params[1]->getId($exact).'>';
|
||||
}
|
||||
@ -415,7 +424,7 @@ class TKeyedArray extends Atomic
|
||||
|
||||
public function isNonEmpty(): bool
|
||||
{
|
||||
if ($this->is_list) {
|
||||
if ($this->isGenericList()) {
|
||||
return !$this->properties[0]->possibly_undefined;
|
||||
}
|
||||
foreach ($this->properties as $property) {
|
||||
@ -503,6 +512,35 @@ class TKeyedArray extends Atomic
|
||||
bool $add_lower_bound = false,
|
||||
int $depth = 0
|
||||
): self {
|
||||
if ($input_type instanceof TKeyedArray
|
||||
&& $input_type->is_list
|
||||
&& $input_type->isSealed()
|
||||
&& $this->isGenericList()
|
||||
) {
|
||||
$replaced_list_type = $this
|
||||
->getGenericArrayType()
|
||||
->replaceTemplateTypesWithStandins(
|
||||
$template_result,
|
||||
$codebase,
|
||||
$statements_analyzer,
|
||||
$input_type->getGenericArrayType(),
|
||||
$input_arg_offset,
|
||||
$calling_class,
|
||||
$calling_function,
|
||||
$replace,
|
||||
$add_lower_bound,
|
||||
$depth,
|
||||
)
|
||||
->type_params[1]
|
||||
->setPossiblyUndefined(!$this->isNonEmpty());
|
||||
|
||||
$cloned = clone $this;
|
||||
$cloned->properties = [$replaced_list_type];
|
||||
$cloned->fallback_params = [$this->fallback_params[1], $replaced_list_type];
|
||||
|
||||
return $cloned;
|
||||
}
|
||||
|
||||
$properties = $this->properties;
|
||||
|
||||
foreach ($properties as $offset => $property) {
|
||||
|
@ -17,6 +17,35 @@ class FunctionCallTest extends TestCase
|
||||
public function providerValidCodeParse(): iterable
|
||||
{
|
||||
return [
|
||||
'inferGenericListFromTuple' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
* @template A
|
||||
* @param list<A> $list
|
||||
* @return list<A>
|
||||
*/
|
||||
function testList(array $list): array { return $list; }
|
||||
/**
|
||||
* @template A
|
||||
* @param non-empty-list<A> $list
|
||||
* @return non-empty-list<A>
|
||||
*/
|
||||
function testNonEmptyList(array $list): array { return $list; }
|
||||
/**
|
||||
* @template A of list<mixed>
|
||||
* @param A $list
|
||||
* @return A
|
||||
*/
|
||||
function testGenericList(array $list): array { return $list; }
|
||||
$list = testList([1, 2, 3]);
|
||||
$nonEmptyList = testNonEmptyList([1, 2, 3]);
|
||||
$genericList = testGenericList([1, 2, 3]);',
|
||||
'assertions' => [
|
||||
'$list===' => 'list<1|2|3>',
|
||||
'$nonEmptyList===' => 'non-empty-list<1|2|3>',
|
||||
'$genericList===' => 'list{1, 2, 3}',
|
||||
],
|
||||
],
|
||||
'countShapedArrays' => [
|
||||
'code' => '<?php
|
||||
/** @var array{a?: int} */
|
||||
|
Loading…
Reference in New Issue
Block a user