mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Merge pull request #6793 from orklah/unevaluatedCode
emit UnevaluatedCode after exit or never returning functionlike
This commit is contained in:
commit
96ae8e7600
@ -209,6 +209,10 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
|
||||
$statements_analyzer->node_data->setType($real_stmt, $stmt_type);
|
||||
|
||||
if ($stmt_type->isNever()) {
|
||||
$context->has_returned = true;
|
||||
}
|
||||
|
||||
$event = new AfterEveryFunctionCallAnalysisEvent(
|
||||
$stmt,
|
||||
$function_call_info->function_id,
|
||||
|
@ -362,6 +362,10 @@ class MethodCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\
|
||||
|
||||
if ($stmt_type) {
|
||||
$statements_analyzer->node_data->setType($stmt, $stmt_type);
|
||||
|
||||
if ($stmt_type->isNever()) {
|
||||
$context->has_returned = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($result->returns_by_ref) {
|
||||
|
@ -139,6 +139,8 @@ class ExitAnalyzer
|
||||
|
||||
$statements_analyzer->node_data->setType($stmt, Type::getEmpty());
|
||||
|
||||
$context->has_returned = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,6 @@ class BinaryOperationTest extends TestCase
|
||||
{
|
||||
if (class_exists('GMP') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "GMP" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
|
@ -15,8 +15,6 @@ class ClassTest extends TestCase
|
||||
{
|
||||
if (class_exists('mysqli') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "mysqli" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
|
@ -161,8 +161,6 @@ class ConfigTest extends \Psalm\Tests\TestCase
|
||||
|
||||
if (is_array($last_error) && $no_symlinking_error === $last_error['message']) {
|
||||
$this->markTestSkipped($no_symlinking_error);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,6 @@ class DestructiveAutoloaderTest extends TestCase
|
||||
{
|
||||
if (\version_compare(\PHP_VERSION, '7.2.0', '<')) {
|
||||
$this->markTestSkipped('Test case requires PHP 7.2.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->runPsalm(['--no-cache'], __DIR__ . '/' . '../fixtures/DestructiveAutoloader/', true);
|
||||
|
@ -11,8 +11,6 @@ class SuicidalAutoloaderTest extends TestCase
|
||||
{
|
||||
if (\version_compare(\PHP_VERSION, '7.2.0', '<')) {
|
||||
$this->markTestSkipped('Test case requires PHP 7.2.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->runPsalm(['--no-cache'], __DIR__ . '/' . '../fixtures/SuicidalAutoloader/');
|
||||
|
@ -17,8 +17,6 @@ class MethodCallTest extends TestCase
|
||||
{
|
||||
if (class_exists('SoapClient') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
|
@ -19,8 +19,6 @@ class MethodSignatureTest extends TestCase
|
||||
{
|
||||
if (class_exists('SoapClient') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
@ -58,8 +56,6 @@ class MethodSignatureTest extends TestCase
|
||||
{
|
||||
if (class_exists('SoapClient') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
@ -89,8 +85,6 @@ class MethodSignatureTest extends TestCase
|
||||
{
|
||||
if (class_exists('SoapClient') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
@ -265,8 +259,6 @@ class MethodSignatureTest extends TestCase
|
||||
$this->expectException(\Psalm\Exception\CodeException::class);
|
||||
if (class_exists('SoapClient') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
@ -304,8 +296,6 @@ class MethodSignatureTest extends TestCase
|
||||
|
||||
if (class_exists('SoapClient') === false) {
|
||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addFile(
|
||||
|
@ -40,14 +40,10 @@ trait InvalidCodeAnalysisTestTrait
|
||||
if (strpos($test_name, 'PHP71-') !== false) {
|
||||
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
|
||||
$this->markTestSkipped('Test case requires PHP 7.1.');
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (strpos($test_name, 'PHP80-') !== false) {
|
||||
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
|
||||
$this->markTestSkipped('Test case requires PHP 8.0.');
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (strpos($test_name, 'SKIPPED-') !== false) {
|
||||
$this->markTestSkipped('Skipped due to a bug.');
|
||||
|
@ -40,20 +40,14 @@ trait ValidCodeAnalysisTestTrait
|
||||
if (strpos($test_name, 'PHP73-') !== false) {
|
||||
if (version_compare(PHP_VERSION, '7.3.0', '<')) {
|
||||
$this->markTestSkipped('Test case requires PHP 7.3.');
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (strpos($test_name, 'PHP71-') !== false) {
|
||||
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
|
||||
$this->markTestSkipped('Test case requires PHP 7.1.');
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (strpos($test_name, 'PHP80-') !== false) {
|
||||
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
|
||||
$this->markTestSkipped('Test case requires PHP 8.0.');
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (strpos($test_name, 'SKIPPED-') !== false) {
|
||||
$this->markTestSkipped('Skipped due to a bug.');
|
||||
|
@ -1491,6 +1491,45 @@ class UnusedCodeTest extends TestCase
|
||||
',
|
||||
'error_message' => 'UnusedFunctionCall',
|
||||
],
|
||||
'functionNeverUnevaluatedCode' => [
|
||||
'<?php
|
||||
/** @return never */
|
||||
function neverReturns() {
|
||||
die();
|
||||
}
|
||||
|
||||
function f(): void {
|
||||
neverReturns();
|
||||
echo "hello";
|
||||
}
|
||||
',
|
||||
'error_message' => 'UnevaluatedCode',
|
||||
],
|
||||
'methodNeverUnevaluatedCode' => [
|
||||
'<?php
|
||||
class A{
|
||||
/** @return never */
|
||||
function neverReturns() {
|
||||
die();
|
||||
}
|
||||
|
||||
function f(): void {
|
||||
$this->neverReturns();
|
||||
echo "hello";
|
||||
}
|
||||
}
|
||||
',
|
||||
'error_message' => 'UnevaluatedCode',
|
||||
],
|
||||
'exitNeverUnevaluatedCode' => [
|
||||
'<?php
|
||||
function f(): void {
|
||||
exit();
|
||||
echo "hello";
|
||||
}
|
||||
',
|
||||
'error_message' => 'UnevaluatedCode',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user