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:
parent
a2b6326a84
commit
f0a5bd74b6
@ -393,7 +393,7 @@ class ReturnTypeAnalyzer
|
|||||||
return null;
|
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
|
// if there's a single throw statement, it's presumably an exception saying this method is not to be
|
||||||
// used
|
// used
|
||||||
return null;
|
return null;
|
||||||
|
@ -346,7 +346,7 @@ class ScopeAnalyzer
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function onlyThrowsOrExits(array $stmts)
|
public static function onlyThrowsOrExits(\Psalm\NodeTypeProvider $type_provider, array $stmts)
|
||||||
{
|
{
|
||||||
if (empty($stmts)) {
|
if (empty($stmts)) {
|
||||||
return false;
|
return false;
|
||||||
@ -361,6 +361,14 @@ class ScopeAnalyzer
|
|||||||
) {
|
) {
|
||||||
return true;
|
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;
|
return false;
|
||||||
|
@ -814,6 +814,35 @@ class ReturnTypeTest extends TestCase
|
|||||||
echo "$k\n";
|
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"];
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user