Skip to content

Commit

Permalink
Allow nested template unwrapping inside reset, end
Browse files Browse the repository at this point in the history
Fixes #5208
  • Loading branch information
muglug committed Mar 28, 2021
1 parent 2f5bec3 commit 54ac13b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,43 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev

$first_arg = isset($call_args[0]->value) ? $call_args[0]->value : null;

$first_arg_array = $first_arg
&& ($first_arg_type = $statements_source->node_data->getType($first_arg))
&& $first_arg_type->hasType('array')
&& ($array_atomic_type = $first_arg_type->getAtomicTypes()['array'])
&& ($array_atomic_type instanceof Type\Atomic\TArray
|| $array_atomic_type instanceof Type\Atomic\TKeyedArray
|| $array_atomic_type instanceof Type\Atomic\TList)
? $array_atomic_type
: null;

if (!$first_arg_array) {
if (!$first_arg) {
return Type::getMixed();
}

if ($first_arg_array instanceof Type\Atomic\TArray) {
$value_type = clone $first_arg_array->type_params[1];
$definitely_has_items = $first_arg_array instanceof Type\Atomic\TNonEmptyArray;
} elseif ($first_arg_array instanceof Type\Atomic\TList) {
$value_type = clone $first_arg_array->type_param;
$definitely_has_items = $first_arg_array instanceof Type\Atomic\TNonEmptyList;
} else {
$value_type = $first_arg_array->getGenericValueType();
$definitely_has_items = $first_arg_array->getGenericArrayType() instanceof Type\Atomic\TNonEmptyArray;
$first_arg_type = $statements_source->node_data->getType($first_arg);

if (!$first_arg_type) {
return Type::getMixed();
}

$atomic_types = $first_arg_type->getAtomicTypes();

$value_type = null;
$definitely_has_items = false;

while ($atomic_type = array_shift($atomic_types)) {
if ($atomic_type instanceof Type\Atomic\TTemplateParam) {
$atomic_types = \array_merge($atomic_types, $atomic_type->as->getAtomicTypes());
continue;
}

if ($atomic_type instanceof Type\Atomic\TArray) {
$value_type = clone $atomic_type->type_params[1];
$definitely_has_items = $atomic_type instanceof Type\Atomic\TNonEmptyArray;
} elseif ($atomic_type instanceof Type\Atomic\TList) {
$value_type = clone $atomic_type->type_param;
$definitely_has_items = $atomic_type instanceof Type\Atomic\TNonEmptyList;
} elseif ($atomic_type instanceof Type\Atomic\TKeyedArray) {
$value_type = $atomic_type->getGenericValueType();
$definitely_has_items = $atomic_type->getGenericArrayType() instanceof Type\Atomic\TNonEmptyArray;
} else {
return Type::getMixed();
}
}

if (!$value_type) {
throw new \UnexpectedValueException('This should never happen');
}

if ($value_type->isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Psalm\Tests\TestCase;
use Psalm\Tests\Traits;

class NestedClassTemplateTest extends TestCase
class NestedTemplateTest extends TestCase
{
use Traits\InvalidCodeAnalysisTestTrait;
use Traits\ValidCodeAnalysisTestTrait;
Expand Down Expand Up @@ -107,6 +107,18 @@ function load(string $class) {
$result = load(StringWrapper::class);'
],
'unwrapNestedTemplateWithReset' => [
'<?php
/**
* @template TValue
* @template TArray of non-empty-array<TValue>
* @param TArray $arr
* @return TValue
*/
function toList(array $arr): array {
return reset($arr);
}'
],
];
}

Expand Down

0 comments on commit 54ac13b

Please sign in to comment.