1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Improve reasoning around try/catch possibly-undefined vars

This commit is contained in:
Brown 2019-11-11 17:42:46 -05:00
parent 1a54aa5752
commit f22266b2ff
2 changed files with 28 additions and 10 deletions

View File

@ -109,9 +109,6 @@ class TryAnalyzer
if (!isset($try_context->vars_in_scope[$var_id])) {
$try_context->vars_in_scope[$var_id] = clone $type;
$try_context->vars_in_scope[$var_id]->from_docblock = true;
$type = clone $type;
$type->possibly_undefined_from_try = true;
$context->vars_in_scope[$var_id] = $type;
} else {
$try_context->vars_in_scope[$var_id] = Type::combineUnionTypes(
$try_context->vars_in_scope[$var_id],
@ -172,7 +169,9 @@ class TryAnalyzer
foreach ($catch_context->vars_in_scope as $var_id => $type) {
if (!isset($old_context->vars_in_scope[$var_id])) {
$type = clone $type;
$type->possibly_undefined_from_try = true;
$catch_context->vars_in_scope[$var_id] = $type;
} else {
$catch_context->vars_in_scope[$var_id] = Type::combineUnionTypes(
$type,
@ -403,21 +402,20 @@ class TryAnalyzer
}
}
if ($catch_actions[$i] !== [ScopeAnalyzer::ACTION_END]) {
if ($catch_actions[$i] !== [ScopeAnalyzer::ACTION_END]
&& $catch_actions[$i] !== [ScopeAnalyzer::ACTION_CONTINUE]
&& $catch_actions[$i] !== [ScopeAnalyzer::ACTION_BREAK]
) {
$definitely_newly_assigned_var_ids = array_intersect_key(
$new_catch_assigned_var_ids,
$definitely_newly_assigned_var_ids
);
foreach ($catch_context->vars_in_scope as $var_id => $type) {
if (!isset($old_context->vars_in_scope[$var_id])) {
$type->possibly_undefined_from_try = false;
}
if ($stmt_control_actions === [ScopeAnalyzer::ACTION_END]) {
$context->vars_in_scope[$var_id] = $type;
} elseif (isset($context->vars_in_scope[$var_id])
&& $context->vars_in_scope[$var_id]->getId() !== $type->getId()
&& !$context->vars_in_scope[$var_id]->equals($type)
) {
$context->vars_in_scope[$var_id] = Type::combineUnionTypes(
$context->vars_in_scope[$var_id],
@ -442,7 +440,9 @@ class TryAnalyzer
foreach ($definitely_newly_assigned_var_ids as $var_id => $_) {
if (isset($context->vars_in_scope[$var_id])) {
$context->vars_in_scope[$var_id]->possibly_undefined_from_try = false;
$new_type = clone $context->vars_in_scope[$var_id];
$new_type->possibly_undefined_from_try = false;
$context->vars_in_scope[$var_id] = $new_type;
}
}

View File

@ -128,6 +128,24 @@ class TryCatchTest extends TestCase
echo $a;',
],
'issetAfterTryCatchWithoutAssignmentInCatchButReturn' => [
'<?php
function test(): string {
throw new Exception("bad");
}
$a = "foo";
try {
$var = test();
} catch (Exception $e) {
return;
}
echo $var;
echo $a;',
],
'issetAfterTryCatchWithAssignmentInCatch' => [
'<?php
function test(): string {