mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 12:55:26 +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);
|
$statements_analyzer->node_data->setType($real_stmt, $stmt_type);
|
||||||
|
|
||||||
|
if ($stmt_type->isNever()) {
|
||||||
|
$context->has_returned = true;
|
||||||
|
}
|
||||||
|
|
||||||
$event = new AfterEveryFunctionCallAnalysisEvent(
|
$event = new AfterEveryFunctionCallAnalysisEvent(
|
||||||
$stmt,
|
$stmt,
|
||||||
$function_call_info->function_id,
|
$function_call_info->function_id,
|
||||||
|
@ -362,6 +362,10 @@ class MethodCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\
|
|||||||
|
|
||||||
if ($stmt_type) {
|
if ($stmt_type) {
|
||||||
$statements_analyzer->node_data->setType($stmt, $stmt_type);
|
$statements_analyzer->node_data->setType($stmt, $stmt_type);
|
||||||
|
|
||||||
|
if ($stmt_type->isNever()) {
|
||||||
|
$context->has_returned = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($result->returns_by_ref) {
|
if ($result->returns_by_ref) {
|
||||||
|
@ -139,6 +139,8 @@ class ExitAnalyzer
|
|||||||
|
|
||||||
$statements_analyzer->node_data->setType($stmt, Type::getEmpty());
|
$statements_analyzer->node_data->setType($stmt, Type::getEmpty());
|
||||||
|
|
||||||
|
$context->has_returned = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,6 @@ class BinaryOperationTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (class_exists('GMP') === false) {
|
if (class_exists('GMP') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "GMP" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "GMP" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
|
@ -15,8 +15,6 @@ class ClassTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (class_exists('mysqli') === false) {
|
if (class_exists('mysqli') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "mysqli" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "mysqli" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
|
@ -161,8 +161,6 @@ class ConfigTest extends \Psalm\Tests\TestCase
|
|||||||
|
|
||||||
if (is_array($last_error) && $no_symlinking_error === $last_error['message']) {
|
if (is_array($last_error) && $no_symlinking_error === $last_error['message']) {
|
||||||
$this->markTestSkipped($no_symlinking_error);
|
$this->markTestSkipped($no_symlinking_error);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@ class DestructiveAutoloaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (\version_compare(\PHP_VERSION, '7.2.0', '<')) {
|
if (\version_compare(\PHP_VERSION, '7.2.0', '<')) {
|
||||||
$this->markTestSkipped('Test case requires PHP 7.2.');
|
$this->markTestSkipped('Test case requires PHP 7.2.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->runPsalm(['--no-cache'], __DIR__ . '/' . '../fixtures/DestructiveAutoloader/', true);
|
$this->runPsalm(['--no-cache'], __DIR__ . '/' . '../fixtures/DestructiveAutoloader/', true);
|
||||||
|
@ -11,8 +11,6 @@ class SuicidalAutoloaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (\version_compare(\PHP_VERSION, '7.2.0', '<')) {
|
if (\version_compare(\PHP_VERSION, '7.2.0', '<')) {
|
||||||
$this->markTestSkipped('Test case requires PHP 7.2.');
|
$this->markTestSkipped('Test case requires PHP 7.2.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->runPsalm(['--no-cache'], __DIR__ . '/' . '../fixtures/SuicidalAutoloader/');
|
$this->runPsalm(['--no-cache'], __DIR__ . '/' . '../fixtures/SuicidalAutoloader/');
|
||||||
|
@ -17,8 +17,6 @@ class MethodCallTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (class_exists('SoapClient') === false) {
|
if (class_exists('SoapClient') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
|
@ -19,8 +19,6 @@ class MethodSignatureTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (class_exists('SoapClient') === false) {
|
if (class_exists('SoapClient') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
@ -58,8 +56,6 @@ class MethodSignatureTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (class_exists('SoapClient') === false) {
|
if (class_exists('SoapClient') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
@ -89,8 +85,6 @@ class MethodSignatureTest extends TestCase
|
|||||||
{
|
{
|
||||||
if (class_exists('SoapClient') === false) {
|
if (class_exists('SoapClient') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
@ -265,8 +259,6 @@ class MethodSignatureTest extends TestCase
|
|||||||
$this->expectException(\Psalm\Exception\CodeException::class);
|
$this->expectException(\Psalm\Exception\CodeException::class);
|
||||||
if (class_exists('SoapClient') === false) {
|
if (class_exists('SoapClient') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
@ -304,8 +296,6 @@ class MethodSignatureTest extends TestCase
|
|||||||
|
|
||||||
if (class_exists('SoapClient') === false) {
|
if (class_exists('SoapClient') === false) {
|
||||||
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
$this->markTestSkipped('Cannot run test, base class "SoapClient" does not exist!');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFile(
|
$this->addFile(
|
||||||
|
@ -40,14 +40,10 @@ trait InvalidCodeAnalysisTestTrait
|
|||||||
if (strpos($test_name, 'PHP71-') !== false) {
|
if (strpos($test_name, 'PHP71-') !== false) {
|
||||||
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
|
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
|
||||||
$this->markTestSkipped('Test case requires PHP 7.1.');
|
$this->markTestSkipped('Test case requires PHP 7.1.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} elseif (strpos($test_name, 'PHP80-') !== false) {
|
} elseif (strpos($test_name, 'PHP80-') !== false) {
|
||||||
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
|
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
|
||||||
$this->markTestSkipped('Test case requires PHP 8.0.');
|
$this->markTestSkipped('Test case requires PHP 8.0.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} elseif (strpos($test_name, 'SKIPPED-') !== false) {
|
} elseif (strpos($test_name, 'SKIPPED-') !== false) {
|
||||||
$this->markTestSkipped('Skipped due to a bug.');
|
$this->markTestSkipped('Skipped due to a bug.');
|
||||||
|
@ -40,20 +40,14 @@ trait ValidCodeAnalysisTestTrait
|
|||||||
if (strpos($test_name, 'PHP73-') !== false) {
|
if (strpos($test_name, 'PHP73-') !== false) {
|
||||||
if (version_compare(PHP_VERSION, '7.3.0', '<')) {
|
if (version_compare(PHP_VERSION, '7.3.0', '<')) {
|
||||||
$this->markTestSkipped('Test case requires PHP 7.3.');
|
$this->markTestSkipped('Test case requires PHP 7.3.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} elseif (strpos($test_name, 'PHP71-') !== false) {
|
} elseif (strpos($test_name, 'PHP71-') !== false) {
|
||||||
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
|
if (version_compare(PHP_VERSION, '7.1.0', '<')) {
|
||||||
$this->markTestSkipped('Test case requires PHP 7.1.');
|
$this->markTestSkipped('Test case requires PHP 7.1.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} elseif (strpos($test_name, 'PHP80-') !== false) {
|
} elseif (strpos($test_name, 'PHP80-') !== false) {
|
||||||
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
|
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
|
||||||
$this->markTestSkipped('Test case requires PHP 8.0.');
|
$this->markTestSkipped('Test case requires PHP 8.0.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} elseif (strpos($test_name, 'SKIPPED-') !== false) {
|
} elseif (strpos($test_name, 'SKIPPED-') !== false) {
|
||||||
$this->markTestSkipped('Skipped due to a bug.');
|
$this->markTestSkipped('Skipped due to a bug.');
|
||||||
|
@ -1491,6 +1491,45 @@ class UnusedCodeTest extends TestCase
|
|||||||
',
|
',
|
||||||
'error_message' => 'UnusedFunctionCall',
|
'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