From 33f003f427cbbe064e20c84233fea6a39374ef97 Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Tue, 28 Nov 2017 16:52:52 -0500 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20complain=20about=20repeat=20iss?= =?UTF-8?q?et=20calls=20on=20array=20keys?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #347 --- src/Psalm/Checker/AlgebraChecker.php | 8 +++++--- src/Psalm/Checker/Statements/Block/IfChecker.php | 4 +++- src/Psalm/Checker/TypeChecker.php | 6 +++--- tests/IssetTest.php | 12 ++++++++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Psalm/Checker/AlgebraChecker.php b/src/Psalm/Checker/AlgebraChecker.php index 16ec90af9..72474a875 100644 --- a/src/Psalm/Checker/AlgebraChecker.php +++ b/src/Psalm/Checker/AlgebraChecker.php @@ -97,7 +97,7 @@ class AlgebraChecker $base = array_shift($key_parts); - $clauses[] = new Clause([$base => ['isset']]); + $clauses[] = new Clause([$base => ['^isset']]); if (count($key_parts)) { $clauses[] = new Clause([$base => ['!false']]); @@ -106,7 +106,7 @@ class AlgebraChecker foreach ($key_parts as $i => $key_part_dim) { $base .= '[' . $key_part_dim . ']'; - $clauses[] = new Clause([$base => ['isset']]); + $clauses[] = new Clause([$base => ['^isset']]); if ($i < count($key_parts) - 1) { $clauses[] = new Clause([$base => ['!false']]); @@ -208,7 +208,9 @@ class AlgebraChecker // remove impossible types foreach ($negated_formula2 as $clause_a) { foreach ($clause_a->possibilities as $key => $values) { - if (count($values) > 1 && count(array_unique($values)) < count($values)) { + if (count($values) > 1 + && count(array_unique($values)) < count($values) + ) { if (IssueBuffer::accepts( new RedundantCondition( 'Found a redundant condition when evaluating ' . $key, diff --git a/src/Psalm/Checker/Statements/Block/IfChecker.php b/src/Psalm/Checker/Statements/Block/IfChecker.php index 21c935582..f4f331c10 100644 --- a/src/Psalm/Checker/Statements/Block/IfChecker.php +++ b/src/Psalm/Checker/Statements/Block/IfChecker.php @@ -404,7 +404,9 @@ class IfChecker // if we have a check like if (!isset($a)) { $a = true; } we want to make sure $a is always set foreach ($if_scope->new_vars as $var_id => $_) { - if (isset($if_scope->negated_types[$var_id]) && $if_scope->negated_types[$var_id] === 'isset') { + if (isset($if_scope->negated_types[$var_id]) + && ($if_scope->negated_types[$var_id] === 'isset' || $if_scope->negated_types[$var_id] === '^isset') + ) { $if_scope->forced_new_vars[$var_id] = Type::getMixed(); } } diff --git a/src/Psalm/Checker/TypeChecker.php b/src/Psalm/Checker/TypeChecker.php index 9541d8db6..0c2909213 100644 --- a/src/Psalm/Checker/TypeChecker.php +++ b/src/Psalm/Checker/TypeChecker.php @@ -113,7 +113,7 @@ class TypeChecker return false; } - $orred_type = $orred_type && $result_type_candidate + $orred_type = $orred_type ? Type::combineUnionTypes($result_type_candidate, $orred_type) : $result_type_candidate; } @@ -156,7 +156,7 @@ class TypeChecker * @param array $suppressed_issues * @param bool $failed_reconciliation if the types cannot be reconciled, we need to know * - * @return Type\Union|null|false + * @return Type\Union|false */ public static function reconcileTypes( $new_var_type, @@ -171,7 +171,7 @@ class TypeChecker if ($existing_var_type === null) { if ($new_var_type === '^isset') { - return null; + return Type::getMixed(); } if ($new_var_type === 'isset') { diff --git a/tests/IssetTest.php b/tests/IssetTest.php index 8507ef7ae..ea06d2529 100644 --- a/tests/IssetTest.php +++ b/tests/IssetTest.php @@ -75,6 +75,18 @@ class IssetTest extends TestCase '$foo' => \Psalm\Type::getArray(), ], ], + 'noRedundantConditionOnMixed' => [ + ' [], + 'error_levels' => ['MixedAssignment'], + ], ]; } }