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

Fix issue with possibly-redefined switch vars

This commit is contained in:
Matthew Brown 2017-03-14 02:00:38 -04:00
parent 50b629e88e
commit 9dd94d099f
3 changed files with 24 additions and 4 deletions

View File

@ -594,7 +594,11 @@ class IfChecker
$negated_keys = [];
foreach ($negated_elseif_types as $var_id => $type) {
if (!$has_leaving_statements || $type !== '!empty') {
if (!$has_leaving_statements ||
$type !== '!empty' ||
!isset($elseif_context->vars_in_scope[$var_id]) ||
$elseif_context->vars_in_scope[$var_id]->hasObjectType()
) {
$negated_keys[] = $var_id;
}
}

View File

@ -45,6 +45,7 @@ class SwitchChecker
$new_vars_possibly_in_scope = [];
$redefined_vars = null;
$possibly_redefined_vars = null;
// the last statement always breaks, by default
$last_case_exit_type = 'break';
@ -148,6 +149,21 @@ class SwitchChecker
Type::redefineGenericUnionTypes($case_redefined_vars, $context);
if ($possibly_redefined_vars === null) {
$possibly_redefined_vars = $case_redefined_vars;
} else {
foreach ($case_redefined_vars as $var_id => $type) {
if (!isset($possibly_redefined_vars[$var_id])) {
$possibly_redefined_vars[$var_id] = $type;
} else {
$possibly_redefined_vars[$var_id] = Type::combineUnionTypes(
$type,
$possibly_redefined_vars[$var_id]
);
}
}
}
if ($redefined_vars === null) {
$redefined_vars = $case_redefined_vars;
} else {
@ -206,8 +222,8 @@ class SwitchChecker
if ($redefined_vars) {
$context->vars_in_scope = array_merge($context->vars_in_scope, $redefined_vars);
}
} elseif ($redefined_vars) {
foreach ($redefined_vars as $var_id => $type) {
} elseif ($possibly_redefined_vars) {
foreach ($possibly_redefined_vars as $var_id => $type) {
$context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $context->vars_in_scope[$var_id]);
}
}

View File

@ -169,7 +169,7 @@ class ArrayAssignmentTest extends PHPUnit_Framework_TestCase
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
$context = new Context();
$file_checker->visitAndAnalyzeMethods($context);
$this->assertEquals('array<int, string|int>', (string) $context->vars_in_scope['$out']);
$this->assertEquals('array<int, int|string>', (string) $context->vars_in_scope['$out']);
}
/**