Skip to content
Permalink
Browse files

Improve reasoning around try/catch possibly-undefined vars

  • Loading branch information
muglug committed Nov 11, 2019
1 parent 1a54aa5 commit f22266b2ff31e34f07dc9769ed2379739044dc5a
Showing with 28 additions and 10 deletions.
  1. +10 −10 src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php
  2. +18 −0 tests/TryCatchTest.php
@@ -109,9 +109,6 @@ public static function analyze(
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 @@ public static function analyze(
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 @@ function ($fq_catch_class) use ($codebase) {
}
}
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 @@ function ($fq_catch_class) use ($codebase) {
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;
}
}
@@ -128,6 +128,24 @@ function test(): string {
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 {

0 comments on commit f22266b

Please sign in to comment.
You can’t perform that action at this time.