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

Don’t complain about repeat isset calls on array keys

Fixes #347
This commit is contained in:
Matt Brown 2017-11-28 16:52:52 -05:00
parent 4b7d4f9015
commit 33f003f427
4 changed files with 23 additions and 7 deletions

View File

@ -97,7 +97,7 @@ class AlgebraChecker
$base = array_shift($key_parts); $base = array_shift($key_parts);
$clauses[] = new Clause([$base => ['isset']]); $clauses[] = new Clause([$base => ['^isset']]);
if (count($key_parts)) { if (count($key_parts)) {
$clauses[] = new Clause([$base => ['!false']]); $clauses[] = new Clause([$base => ['!false']]);
@ -106,7 +106,7 @@ class AlgebraChecker
foreach ($key_parts as $i => $key_part_dim) { foreach ($key_parts as $i => $key_part_dim) {
$base .= '[' . $key_part_dim . ']'; $base .= '[' . $key_part_dim . ']';
$clauses[] = new Clause([$base => ['isset']]); $clauses[] = new Clause([$base => ['^isset']]);
if ($i < count($key_parts) - 1) { if ($i < count($key_parts) - 1) {
$clauses[] = new Clause([$base => ['!false']]); $clauses[] = new Clause([$base => ['!false']]);
@ -208,7 +208,9 @@ class AlgebraChecker
// remove impossible types // remove impossible types
foreach ($negated_formula2 as $clause_a) { foreach ($negated_formula2 as $clause_a) {
foreach ($clause_a->possibilities as $key => $values) { 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( if (IssueBuffer::accepts(
new RedundantCondition( new RedundantCondition(
'Found a redundant condition when evaluating ' . $key, 'Found a redundant condition when evaluating ' . $key,

View File

@ -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 // 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 => $_) { 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(); $if_scope->forced_new_vars[$var_id] = Type::getMixed();
} }
} }

View File

@ -113,7 +113,7 @@ class TypeChecker
return false; return false;
} }
$orred_type = $orred_type && $result_type_candidate $orred_type = $orred_type
? Type::combineUnionTypes($result_type_candidate, $orred_type) ? Type::combineUnionTypes($result_type_candidate, $orred_type)
: $result_type_candidate; : $result_type_candidate;
} }
@ -156,7 +156,7 @@ class TypeChecker
* @param array $suppressed_issues * @param array $suppressed_issues
* @param bool $failed_reconciliation if the types cannot be reconciled, we need to know * @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( public static function reconcileTypes(
$new_var_type, $new_var_type,
@ -171,7 +171,7 @@ class TypeChecker
if ($existing_var_type === null) { if ($existing_var_type === null) {
if ($new_var_type === '^isset') { if ($new_var_type === '^isset') {
return null; return Type::getMixed();
} }
if ($new_var_type === 'isset') { if ($new_var_type === 'isset') {

View File

@ -75,6 +75,18 @@ class IssetTest extends TestCase
'$foo' => \Psalm\Type::getArray(), '$foo' => \Psalm\Type::getArray(),
], ],
], ],
'noRedundantConditionOnMixed' => [
'<?php
function testarray(array $data) : void {
foreach ($data as $item) {
if (isset($item["a"]) && isset($item["b"]) && isset($item["b"]["c"])) {
echo "Found\n";
}
}
}',
'assertions' => [],
'error_levels' => ['MixedAssignment'],
],
]; ];
} }
} }