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

Use more accurate means of determining whether function did return

This commit is contained in:
Matthew Brown 2020-03-28 23:37:42 -04:00
parent 7195ea6842
commit 5395183837
7 changed files with 23 additions and 15 deletions

View File

@ -1761,7 +1761,8 @@ class ClassAnalyzer extends ClassLikeAnalyzer
$class_storage,
$class_context->self,
$analyzed_method_id,
$actual_method_id
$actual_method_id,
$method_context->has_returned
);
}
@ -1785,7 +1786,8 @@ class ClassAnalyzer extends ClassLikeAnalyzer
ClassLikeStorage $class_storage,
string $fq_classlike_name,
\Psalm\Internal\MethodIdentifier $analyzed_method_id,
\Psalm\Internal\MethodIdentifier $actual_method_id
\Psalm\Internal\MethodIdentifier $actual_method_id,
bool $did_explicitly_return
) : void {
$secondary_return_type_location = null;
@ -1892,7 +1894,8 @@ class ClassAnalyzer extends ClassLikeAnalyzer
$interface_return_type,
$interface_class,
$interface_return_type_location,
[$analyzed_method_id]
[$analyzed_method_id],
$did_explicitly_return
);
}
}
@ -1910,7 +1913,8 @@ class ClassAnalyzer extends ClassLikeAnalyzer
$return_type,
$fq_classlike_name,
$return_type_location,
$overridden_method_ids
$overridden_method_ids,
$did_explicitly_return
);
}

View File

@ -67,6 +67,7 @@ class ReturnTypeAnalyzer
$fq_class_name = null,
CodeLocation $return_type_location = null,
array $compatible_method_ids = [],
bool $did_explicitly_return = false,
bool $closure_inside_call = false
) {
$suppressed_issues = $function_like_analyzer->getSuppressedIssues();
@ -137,6 +138,10 @@ class ReturnTypeAnalyzer
true
);
if (!$inferred_return_type_parts) {
$did_explicitly_return = true;
}
if ((!$return_type || $return_type->from_docblock)
&& ScopeAnalyzer::getFinalControlActions(
$function_stmts,
@ -145,6 +150,7 @@ class ReturnTypeAnalyzer
) !== [ScopeAnalyzer::ACTION_END]
&& !$inferred_yield_types
&& count($inferred_return_type_parts)
&& !$did_explicitly_return
) {
// only add null if we have a return statement elsewhere and it wasn't void
foreach ($inferred_return_type_parts as $inferred_return_type_part) {
@ -324,6 +330,7 @@ class ReturnTypeAnalyzer
$source,
$function_like_analyzer,
$compatible_method_ids
|| !$did_explicitly_return
|| (($project_analyzer->only_replace_php_types_with_non_docblock_types
|| $unsafe_return_type)
&& $inferred_return_type->from_docblock),

View File

@ -35,12 +35,8 @@ class ReturnTypeCollector
) {
$return_types = [];
$had_explicit_return = [];
foreach ($stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\Return_) {
$had_explicit_return = true;
if ($stmt->expr instanceof PhpParser\Node\Expr\Yield_ ||
$stmt->expr instanceof PhpParser\Node\Expr\YieldFrom) {
$yield_types = array_merge($yield_types, self::getYieldTypeFromExpression($stmt->expr, $nodes));
@ -305,10 +301,6 @@ class ReturnTypeCollector
),
];
}
if (!$had_explicit_return) {
$return_types[] = new Atomic\TVoid();
}
}
return $return_types;

View File

@ -588,6 +588,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$storage->return_type,
$this->source->getFQCLN(),
$storage->return_type_location,
$context->has_returned,
$global_context && $global_context->inside_call
);
@ -1309,6 +1310,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
Type\Union $return_type = null,
$fq_class_name = null,
CodeLocation $return_type_location = null,
bool $did_explicitly_return = false,
bool $closure_inside_call = false
) {
ReturnTypeAnalyzer::verifyReturnType(
@ -1321,6 +1323,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$fq_class_name,
$return_type_location,
[],
$did_explicitly_return,
$closure_inside_call
);
}

View File

@ -116,7 +116,8 @@ class InterfaceAnalyzer extends ClassLikeAnalyzer
$class_storage,
$fq_interface_name,
$actual_method_id,
$actual_method_id
$actual_method_id,
false
);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Property) {

View File

@ -704,7 +704,8 @@ class StatementsAnalyzer extends SourceAnalyzer implements StatementsSource
$this,
$return_type,
$this->getFQCLN(),
$return_type_location
$return_type_location,
$function_context->has_returned
);
}
}

View File

@ -405,7 +405,7 @@ class ReturnTypeManipulationTest extends FileManipulationTest
/**
* @return void
*/
protected function foo(): void {}
protected function foo() {}
}',
'7.3',
['InvalidReturnType'],