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

Don’t remove clauses on mixed, just substitute for wedges

This commit is contained in:
Matt Brown 2018-03-15 16:40:22 -04:00
parent 651b375c62
commit e5e0c56abc
3 changed files with 38 additions and 13 deletions

View File

@ -177,29 +177,27 @@ class IfChecker
);
$if_clauses = array_values(
array_filter(
$if_clauses,
/** @return bool */
array_map(
/**
* @return Clause
*/
function (Clause $c) use ($mixed_var_ids) {
$keys = array_keys($c->possibilities);
foreach ($keys as $key) {
foreach ($mixed_var_ids as $mixed_var_id) {
if (preg_match('/^' . preg_quote($mixed_var_id, '/') . '(\[|-)/', $key)) {
return false;
return new Clause([], true);
}
}
}
return true;
}
return $c;
},
$if_clauses
)
);
if (!$if_clauses) {
$if_clauses = [new Clause([], true)];
}
// this will see whether any of the clauses in set A conflict with the clauses in set B
AlgebraChecker::checkForParadox(
$context->clauses,

View File

@ -475,21 +475,30 @@ class Union
foreach ($old_type->types as $old_type_part) {
if (!$this->removeType($old_type_part->getKey())) {
if ($old_type_part instanceof Type\Atomic\TFalse && isset($this->types['bool'])) {
if ($old_type_part instanceof Type\Atomic\TFalse
&& isset($this->types['bool'])
&& !isset($this->types['true'])
) {
$this->removeType('bool');
$this->types['true'] = new Type\Atomic\TTrue;
} elseif ($old_type_part instanceof Type\Atomic\TTrue && isset($this->types['bool'])) {
} elseif ($old_type_part instanceof Type\Atomic\TTrue
&& isset($this->types['bool'])
&& !isset($this->types['false'])
) {
$this->removeType('bool');
$this->types['false'] = new Type\Atomic\TFalse;
} elseif (isset($this->types['iterable'])) {
if ($old_type_part instanceof Type\Atomic\TNamedObject
&& $old_type_part->value === 'Traversable'
&& !isset($this->types['array'])
) {
$this->removeType('iterable');
$this->types['array'] = new Type\Atomic\TArray([Type::getMixed(), Type::getMixed()]);
}
if ($old_type_part instanceof Type\Atomic\TArray) {
if ($old_type_part instanceof Type\Atomic\TArray
&& !isset($this->types['traversable'])
) {
$this->removeType('iterable');
$this->types['traversable'] = new Type\Atomic\TNamedObject('Traversable');
}

View File

@ -315,6 +315,24 @@ class RedundantConditionTest extends TestCase
'assignments' => [],
'error_levels' => [],
],
'replaceFalseTypeWithTrueConditionalOnMixedEquality' => [
'<?php
function getData() {
return rand(0, 1) ? [1, 2, 3] : false;
}
$a = false;
while ($i = getData()) {
if (!$a && $i[0] === 2) {
$a = true;
}
if ($a === false) {}
}',
'assignments' => [],
'error_levels' => ['MixedAssignment', 'MissingReturnType', 'MixedArrayAccess'],
],
];
}