1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #2012 - count(callable-array) is fine and always equals 2

This commit is contained in:
Brown 2019-08-12 16:17:55 -04:00
parent 10b8a94564
commit 58b6d8bed4
3 changed files with 39 additions and 13 deletions

View File

@ -112,19 +112,23 @@ class FunctionAnalyzer extends FunctionLikeAnalyzer
if (isset($call_args[0]->value->inferredType)) {
$atomic_types = $call_args[0]->value->inferredType->getTypes();
if (count($atomic_types) === 1 && isset($atomic_types['array'])) {
if ($atomic_types['array'] instanceof Type\Atomic\TNonEmptyArray) {
return new Type\Union([
$atomic_types['array']->count !== null
? new Type\Atomic\TLiteralInt($atomic_types['array']->count)
: new Type\Atomic\TInt
]);
} elseif ($atomic_types['array'] instanceof Type\Atomic\ObjectLike
&& $atomic_types['array']->sealed
) {
return new Type\Union([
new Type\Atomic\TLiteralInt(count($atomic_types['array']->properties))
]);
if (count($atomic_types) === 1) {
if (isset($atomic_types['array'])) {
if ($atomic_types['array'] instanceof Type\Atomic\TNonEmptyArray) {
return new Type\Union([
$atomic_types['array']->count !== null
? new Type\Atomic\TLiteralInt($atomic_types['array']->count)
: new Type\Atomic\TInt
]);
} elseif ($atomic_types['array'] instanceof Type\Atomic\ObjectLike
&& $atomic_types['array']->sealed
) {
return new Type\Union([
new Type\Atomic\TLiteralInt(count($atomic_types['array']->properties))
]);
}
} elseif (isset($atomic_types['callable-array'])) {
return Type::getInt(false, 2);
}
}
}

View File

@ -724,6 +724,8 @@ class TypeAnalyzer
}
if ($input_type_part->shallowEquals($container_type_part)
|| ($input_type_part instanceof Type\Atomic\TCallableObjectLikeArray
&& $container_type_part instanceof TArray)
|| (($input_type_part instanceof TNamedObject
|| ($input_type_part instanceof TTemplateParam
&& $input_type_part->as->hasObjectType())

View File

@ -1698,6 +1698,15 @@ class FunctionCallTest extends TestCase
$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><a><b></b><b></b></a>");
echo count($xml);',
],
'countableCallableArray' => [
'<?php
/** @param callable|false $x */
function example($x) : void {
if (is_array($x)) {
echo "Count is: " . count($x);
}
}'
],
'refineWithTraitExists' => [
'<?php
function foo(string $s) : void {
@ -2358,6 +2367,17 @@ class FunctionCallTest extends TestCase
}',
'error_message' => 'UndefinedVariable',
],
'countCallableArrayShouldBeTwo' => [
'<?php
/** @param callable|false $x */
function example($x) : void {
if (is_array($x)) {
$c = count($x);
if ($c !== 2) {}
}
}',
'error_message' => 'TypeDoesNotContainType',
],
];
}
}