1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Detect never-return statement same as a throw

This commit is contained in:
Brown 2020-05-26 15:02:23 -04:00
parent a2b6326a84
commit f0a5bd74b6
3 changed files with 39 additions and 2 deletions

View File

@ -393,7 +393,7 @@ class ReturnTypeAnalyzer
return null;
}
if (ScopeAnalyzer::onlyThrowsOrExits($function_stmts)) {
if (ScopeAnalyzer::onlyThrowsOrExits($type_provider, $function_stmts)) {
// if there's a single throw statement, it's presumably an exception saying this method is not to be
// used
return null;

View File

@ -346,7 +346,7 @@ class ScopeAnalyzer
*
* @return bool
*/
public static function onlyThrowsOrExits(array $stmts)
public static function onlyThrowsOrExits(\Psalm\NodeTypeProvider $type_provider, array $stmts)
{
if (empty($stmts)) {
return false;
@ -361,6 +361,14 @@ class ScopeAnalyzer
) {
return true;
}
if ($stmt instanceof PhpParser\Node\Stmt\Expression) {
$stmt_type = $type_provider->getType($stmt->expr);
if ($stmt_type && $stmt_type->isNever()) {
return true;
}
}
}
return false;

View File

@ -814,6 +814,35 @@ class ReturnTypeTest extends TestCase
echo "$k\n";
}'
],
'allowImplicitNever' => [
'<?php
class TestCase
{
/** @psalm-return never-return */
public function markAsSkipped(): void
{
throw new \Exception();
}
}
class A extends TestCase
{
/**
* @return string[]
*/
public function foo(): array
{
$this->markAsSkipped();
}
}
class B extends A
{
public function foo(): array
{
return ["foo"];
}
}'
],
];
}