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

Don’t check newly-scoped vars in conditional

This commit is contained in:
Matt Brown 2018-02-08 14:46:06 -05:00
parent 30ca2ad65f
commit 78cc1786c8
9 changed files with 49 additions and 10 deletions

View File

@ -62,6 +62,8 @@ class IfChecker
$context->inside_conditional = true;
$pre_condition_vars_in_scope = $context->vars_in_scope;
$referenced_var_ids = $context->referenced_var_ids;
$context->referenced_var_ids = [];
@ -144,6 +146,20 @@ class IfChecker
// get all the var ids that were referened in the conditional, but not assigned in it
$cond_referenced_var_ids = array_diff_key($cond_referenced_var_ids, $cond_assigned_var_ids);
// remove all newly-asserted var ids too
$cond_referenced_var_ids = array_filter(
$cond_referenced_var_ids,
/**
* @param string $var_id
*
* @return bool
*/
function ($var_id) use ($pre_condition_vars_in_scope) {
return isset($pre_condition_vars_in_scope[$var_id]);
},
ARRAY_FILTER_USE_KEY
);
$if_context->inside_conditional = false;
$mixed_var_ids = [];

View File

@ -55,6 +55,7 @@ class BinaryOpChecker
$pre_referenced_var_ids = $context->referenced_var_ids;
$context->referenced_var_ids = [];
$original_vars_in_scope = $context->vars_in_scope;
$pre_assigned_var_ids = $context->assigned_var_ids;
@ -69,6 +70,20 @@ class BinaryOpChecker
$new_referenced_var_ids = array_diff_key($new_referenced_var_ids, $new_assigned_var_ids);
// remove all newly-asserted var ids too
$new_referenced_var_ids = array_filter(
$new_referenced_var_ids,
/**
* @param string $var_id
*
* @return bool
*/
function ($var_id) use ($original_vars_in_scope) {
return isset($original_vars_in_scope[$var_id]);
},
ARRAY_FILTER_USE_KEY
);
$simplified_clauses = AlgebraChecker::simplifyCNF(array_merge($context->clauses, $if_clauses));
$left_type_assertions = AlgebraChecker::getTruthsFromFormula($simplified_clauses);

View File

@ -3,7 +3,6 @@ namespace Psalm;
use Psalm\Exception\TypeParseTreeException;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\Generic;
use Psalm\Type\Atomic\ObjectLike;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TBool;

View File

@ -4,6 +4,9 @@ namespace Psalm\Type\Atomic;
use Psalm\FunctionLikeParameter;
use Psalm\Type\Union;
/**
* Represents a closure where we know the return type and params
*/
class Fn extends TNamedObject
{
/**

View File

@ -1,6 +0,0 @@
<?php
namespace Psalm\Type\Atomic;
interface Generic
{
}

View File

@ -1,7 +1,7 @@
<?php
namespace Psalm\Type\Atomic;
class TArray extends \Psalm\Type\Atomic implements Generic
class TArray extends \Psalm\Type\Atomic
{
use GenericTrait;

View File

@ -1,7 +1,7 @@
<?php
namespace Psalm\Type\Atomic;
class TGenericObject extends TNamedObject implements Generic
class TGenericObject extends TNamedObject
{
use GenericTrait;

View File

@ -283,7 +283,7 @@ class Union
public function hasGeneric()
{
foreach ($this->types as $type) {
if ($type instanceof Atomic\Generic) {
if ($type instanceof Atomic\TGenericObject || $type instanceof Atomic\TArray) {
return true;
}
}

View File

@ -303,6 +303,18 @@ class RedundantConditionTest extends TestCase
'assertions' => [],
'error_levels' => ['RedundantConditionGivenDocblockType'],
],
'nullToMixedWithNullCheckNoContinue' => [
'<?php
function getStrings(): array {
return ["hello", "world", 50];
}
$a = getStrings();
if (is_string($a[0]) && strlen($a[0]) > 3) {}',
'assignments' => [],
'error_levels' => [],
],
];
}