1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix checks around array empty checks

This commit is contained in:
Brown 2018-12-11 13:50:26 -05:00
parent f9753e1517
commit 970ea48b25
3 changed files with 27 additions and 3 deletions

View File

@ -146,9 +146,8 @@ class BinaryOpAnalyzer
if ($context->inside_conditional) {
foreach ($op_context->vars_in_scope as $var => $type) {
if (!isset($context->vars_in_scope[$var])) {
if (!isset($context->vars_in_scope[$var]) && !$type->possibly_undefined) {
$context->vars_in_scope[$var] = $type;
continue;
}
}

View File

@ -137,7 +137,13 @@ class Reconciler
foreach ($new_types as $key => $new_type_parts) {
$result_type = isset($existing_types[$key])
? clone $existing_types[$key]
: self::getValueForKey($codebase, $key, $existing_types, $code_location);
: self::getValueForKey(
$codebase,
$key,
$existing_types,
$new_type_parts,
$code_location
);
if ($result_type && empty($result_type->getTypes())) {
throw new \InvalidArgumentException('Union::$types cannot be empty after get value for ' . $key);
@ -2076,6 +2082,7 @@ class Reconciler
Codebase $codebase,
$key,
array &$existing_keys,
array $new_type_parts,
CodeLocation $code_location = null
) {
$key_parts = self::breakUpPathIntoParts($key);
@ -2105,6 +2112,10 @@ class Reconciler
foreach ($existing_keys[$base_key]->getTypes() as $existing_key_type_part) {
if ($existing_key_type_part instanceof Type\Atomic\TArray) {
$new_base_type_candidate = clone $existing_key_type_part->type_params[1];
if ($new_type_parts[0][0] === 'empty' || $new_type_parts[0][0] === '=empty') {
$new_base_type_candidate->possibly_undefined = true;
}
} elseif (!$existing_key_type_part instanceof Type\Atomic\ObjectLike) {
return Type::getMixed();
} elseif ($array_key[0] === '$') {

View File

@ -219,6 +219,20 @@ class EmptyTest extends TestCase
'assertions' => [],
'error_levels' => ['MixedAssignment', 'MissingParamType', 'MixedArgument'],
],
'multipleEmptiesInCondition' => [
'<?php
/** @param array<int, int> $o */
function foo(array $o) : void {
if (empty($o[0]) && empty($o[1])) {}
}',
],
'multipleEmptiesInConditionWithMixedOffset' => [
'<?php
/** @param array $o */
function foo(array $o) : void {
if (empty($o[0]) && empty($o[1])) {}
}',
],
];
}