1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Add better support for non-empty arrays when scanning constants

This commit is contained in:
Matthew Brown 2018-11-10 17:15:37 -05:00
parent 1d64f299e9
commit aa426aca03
3 changed files with 30 additions and 14 deletions

View File

@ -119,7 +119,7 @@ class ArrayChecker
}
if (isset($item->value->inferredType)) {
if ($item_key_value !== null) {
if ($item_key_value !== null && count($property_types) <= 50) {
$property_types[$item_key_value] = $item->value->inferredType;
} else {
$can_create_objectlike = false;
@ -133,7 +133,7 @@ class ArrayChecker
} else {
$item_value_type = Type::getMixed();
if ($item_key_value !== null) {
if ($item_key_value !== null && count($property_types) <= 50) {
$property_types[$item_key_value] = $item_value_type;
} else {
$can_create_objectlike = false;

View File

@ -1016,6 +1016,8 @@ class StatementsChecker extends SourceChecker implements StatementsSource
continue;
}
$single_item_key_type = null;
if ($item->key) {
$single_item_key_type = self::getSimpleType(
$codebase,
@ -1058,16 +1060,13 @@ class StatementsChecker extends SourceChecker implements StatementsSource
|| $item->key instanceof PhpParser\Node\Scalar\LNumber
|| !$item->key
) {
$property_types[$item->key ? $item->key->value : $int_offset] = $single_item_value_type;
if (count($property_types) <= 50) {
$property_types[$item->key ? $item->key->value : $int_offset] = $single_item_value_type;
} else {
$can_create_objectlike = false;
}
} else {
$dim_type = self::getSimpleType(
$codebase,
$item->key,
$aliases,
$file_source,
$existing_class_constants,
$fq_classlike_name
);
$dim_type = $single_item_key_type;
if (!$dim_type) {
return null;
@ -1075,7 +1074,7 @@ class StatementsChecker extends SourceChecker implements StatementsSource
$dim_atomic_types = $dim_type->getTypes();
if (count($dim_atomic_types) > 1 || $dim_type->isMixed()) {
if (count($dim_atomic_types) > 1 || $dim_type->isMixed() || count($property_types) > 50) {
$can_create_objectlike = false;
} else {
$atomic_type = array_shift($dim_atomic_types);
@ -1107,7 +1106,9 @@ class StatementsChecker extends SourceChecker implements StatementsSource
&& ($item_key_type->hasString() || $item_key_type->hasInt())
&& $can_create_objectlike
) {
return new Type\Union([new Type\Atomic\ObjectLike($property_types, $class_strings)]);
$objectlike = new Type\Atomic\ObjectLike($property_types, $class_strings);
$objectlike->sealed = true;
return new Type\Union([$objectlike]);
}
if (!$item_key_type || !$item_value_type) {
@ -1115,7 +1116,7 @@ class StatementsChecker extends SourceChecker implements StatementsSource
}
return new Type\Union([
new Type\Atomic\TArray([
new Type\Atomic\TNonEmptyArray([
$item_key_type,
$item_value_type,
]),

View File

@ -734,6 +734,21 @@ class ForeachTest extends \Psalm\Tests\TestCase
$c = null;
foreach ($c as $i) {}',
],
'iterateOverNonEmptyConstant' => [
'<?php
class A {
const ARR = [0, 1, 2];
public function test() : int
{
foreach (self::ARR as $val) {
$max = $val;
}
return $max;
}
}'
],
];
}