1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #4333 - don’t get tripped up on try with no catches

This commit is contained in:
Matt Brown 2020-10-15 10:15:55 -04:00
parent 8a2983e5e9
commit 8d2e88ef41
8 changed files with 43 additions and 22 deletions

View File

@ -135,7 +135,7 @@ class ReturnTypeAnalyzer
}
if ((!$return_type || $return_type->from_docblock)
&& ScopeAnalyzer::getFinalControlActions(
&& ScopeAnalyzer::getControlActions(
$function_stmts,
$type_provider,
$codebase->config->exit_functions
@ -166,7 +166,7 @@ class ReturnTypeAnalyzer
&& !$return_type->isVoid()
&& !$inferred_yield_types
&& (!$function_like_storage || !$function_like_storage->has_yield)
&& ScopeAnalyzer::getFinalControlActions(
&& ScopeAnalyzer::getControlActions(
$function_stmts,
$type_provider,
$codebase->config->exit_functions
@ -189,7 +189,7 @@ class ReturnTypeAnalyzer
if ($return_type
&& $return_type->isNever()
&& !$inferred_yield_types
&& ScopeAnalyzer::getFinalControlActions(
&& ScopeAnalyzer::getControlActions(
$function_stmts,
$type_provider,
$codebase->config->exit_functions,

View File

@ -76,7 +76,7 @@ class ScopeAnalyzer
*
* @return list<value-of<self::ACTIONS>>
*/
public static function getFinalControlActions(
public static function getControlActions(
array $stmts,
?\Psalm\Internal\Provider\NodeDataProvider $nodes,
array $exit_functions,
@ -177,7 +177,7 @@ class ScopeAnalyzer
}
if ($stmt instanceof PhpParser\Node\Stmt\If_) {
$if_statement_actions = self::getFinalControlActions(
$if_statement_actions = self::getControlActions(
$stmt->stmts,
$nodes,
$exit_functions,
@ -185,7 +185,7 @@ class ScopeAnalyzer
);
$else_statement_actions = $stmt->else
? self::getFinalControlActions($stmt->else->stmts, $nodes, $exit_functions, $break_types)
? self::getControlActions($stmt->else->stmts, $nodes, $exit_functions, $break_types)
: [];
$all_same = count($if_statement_actions) === 1
@ -196,7 +196,7 @@ class ScopeAnalyzer
if ($stmt->elseifs) {
foreach ($stmt->elseifs as $elseif) {
$elseif_control_actions = self::getFinalControlActions(
$elseif_control_actions = self::getControlActions(
$elseif->stmts,
$nodes,
$exit_functions,
@ -237,7 +237,7 @@ class ScopeAnalyzer
for ($d = count($stmt->cases) - 1; $d >= 0; --$d) {
$case = $stmt->cases[$d];
$case_actions = self::getFinalControlActions($case->stmts, $nodes, $exit_functions, ['switch']);
$case_actions = self::getControlActions($case->stmts, $nodes, $exit_functions, ['switch']);
if (array_intersect([
self::ACTION_LEAVE_SWITCH,
@ -277,7 +277,7 @@ class ScopeAnalyzer
|| $stmt instanceof PhpParser\Node\Stmt\Foreach_
|| $stmt instanceof PhpParser\Node\Stmt\For_
) {
$do_actions = self::getFinalControlActions(
$do_actions = self::getControlActions(
$stmt->stmts,
$nodes,
$exit_functions,
@ -296,7 +296,7 @@ class ScopeAnalyzer
}
if ($stmt instanceof PhpParser\Node\Stmt\TryCatch) {
$try_statement_actions = self::getFinalControlActions(
$try_statement_actions = self::getControlActions(
$stmt->stmts,
$nodes,
$exit_functions,
@ -307,7 +307,7 @@ class ScopeAnalyzer
$all_same = count($try_statement_actions) === 1;
foreach ($stmt->catches as $catch) {
$catch_actions = self::getFinalControlActions(
$catch_actions = self::getControlActions(
$catch->stmts,
$nodes,
$exit_functions,
@ -322,13 +322,15 @@ class ScopeAnalyzer
}
if ($all_same && $try_statement_actions !== [self::ACTION_NONE]) {
return $try_statement_actions;
return \array_values(array_unique(array_merge($control_actions, $try_statement_actions)));
}
} elseif (!in_array(self::ACTION_NONE, $try_statement_actions, true)) {
return \array_values(array_unique(array_merge($control_actions, $try_statement_actions)));
}
if ($stmt->finally) {
if ($stmt->finally->stmts) {
$finally_statement_actions = self::getFinalControlActions(
$finally_statement_actions = self::getControlActions(
$stmt->finally->stmts,
$nodes,
$exit_functions,

View File

@ -756,7 +756,7 @@ class IfAnalyzer
return false;
}
$final_actions = ScopeAnalyzer::getFinalControlActions(
$final_actions = ScopeAnalyzer::getControlActions(
$stmt->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
@ -1252,7 +1252,7 @@ class IfAnalyzer
}
}
$final_actions = ScopeAnalyzer::getFinalControlActions(
$final_actions = ScopeAnalyzer::getControlActions(
$elseif->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
@ -1559,7 +1559,7 @@ class IfAnalyzer
}
$final_actions = $else
? ScopeAnalyzer::getFinalControlActions(
? ScopeAnalyzer::getControlActions(
$else->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,

View File

@ -87,7 +87,7 @@ class LoopAnalyzer
);
}
$final_actions = ScopeAnalyzer::getFinalControlActions(
$final_actions = ScopeAnalyzer::getControlActions(
$stmts,
$statements_analyzer->node_data,
Config::getInstance()->exit_functions,

View File

@ -72,7 +72,7 @@ class SwitchAnalyzer
for ($i = count($stmt->cases) - 1; $i >= 0; --$i) {
$case = $stmt->cases[$i];
$case_actions = $case_action_map[$i] = ScopeAnalyzer::getFinalControlActions(
$case_actions = $case_action_map[$i] = ScopeAnalyzer::getControlActions(
$case->stmts,
$statements_analyzer->node_data,
$config->exit_functions,

View File

@ -44,7 +44,7 @@ class TryAnalyzer
/** @var int $i */
foreach ($stmt->catches as $i => $catch) {
$catch_actions[$i] = ScopeAnalyzer::getFinalControlActions(
$catch_actions[$i] = ScopeAnalyzer::getControlActions(
$catch->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions
@ -102,7 +102,7 @@ class TryAnalyzer
$context->has_returned = false;
$stmt_control_actions = ScopeAnalyzer::getFinalControlActions(
$stmt_control_actions = ScopeAnalyzer::getControlActions(
$stmt->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
@ -355,7 +355,7 @@ class TryAnalyzer
$statements_analyzer->analyze($catch->stmts, $catch_context);
// recalculate in case there's a no-return clause
$catch_actions[$i] = ScopeAnalyzer::getFinalControlActions(
$catch_actions[$i] = ScopeAnalyzer::getControlActions(
$catch->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,

View File

@ -2182,7 +2182,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
foreach ($stmt->stmts as $function_stmt) {
if ($function_stmt instanceof PhpParser\Node\Stmt\If_) {
$final_actions = \Psalm\Internal\Analyzer\ScopeAnalyzer::getFinalControlActions(
$final_actions = \Psalm\Internal\Analyzer\ScopeAnalyzer::getControlActions(
$function_stmt->stmts,
null,
$this->config->exit_functions,

View File

@ -372,6 +372,25 @@ class TryCatchTest extends TestCase
$event->end = null;
}',
],
'returnsInTry' => [
'<?php
final class A
{
private ?string $property = null;
public function handle(string $arg): string
{
if (null !== $this->property) {
return $arg;
}
try {
return $arg;
} finally {
}
}
}'
],
];
}