Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove exitFunctions for Psalm5 #6808

Merged
merged 1 commit into from Jan 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 0 additions & 8 deletions config.xsd
Expand Up @@ -16,14 +16,6 @@
<xs:element name="mockClasses" type="MockClassesType" minOccurs="0" maxOccurs="1" />
<xs:element name="stubs" type="StubsType" minOccurs="0" maxOccurs="1" />
<xs:element name="plugins" type="PluginsType" minOccurs="0" maxOccurs="1" />
<xs:element name="exitFunctions" type="ExitFunctionsType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<!-- note: for PHPStorm to mark the attribute as deprecated the doc entry has to be *single line* and start with the word `deprecated` -->
<xs:documentation xml:lang="en">
Deprecated. Replaced by documenting never as a return type. It is going to be removed in Psalm 5.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="forbiddenFunctions" type="ExitFunctionsType" minOccurs="0" maxOccurs="1" />
<xs:element name="issueHandlers" type="IssueHandlersType" minOccurs="0" maxOccurs="1" />
<xs:element name="ignoreExceptions" type="ExceptionsType" minOccurs="0" maxOccurs="1" />
Expand Down
14 changes: 0 additions & 14 deletions src/Psalm/Config.php
Expand Up @@ -502,13 +502,6 @@ class Config
/** @var ClassLoader|null */
private $composer_class_loader;

/**
* Custom functions that always exit
*
* @var array<lowercase-string, bool>
*/
public $exit_functions = [];

/**
* @var string
*/
Expand Down Expand Up @@ -1114,13 +1107,6 @@ private static function fromXmlAndPaths(
}
}

if (isset($config_xml->exitFunctions) && isset($config_xml->exitFunctions->function)) {
/** @var SimpleXMLElement $exit_function */
foreach ($config_xml->exitFunctions->function as $exit_function) {
$config->exit_functions[strtolower((string) $exit_function['name'])] = true;
}
}

if (isset($config_xml->stubs) && isset($config_xml->stubs->file)) {
/** @var SimpleXMLElement $stub_file */
foreach ($config_xml->stubs->file as $stub_file) {
Expand Down
Expand Up @@ -156,7 +156,6 @@ public static function verifyReturnType(
&& ScopeAnalyzer::getControlActions(
$function_stmts,
$type_provider,
$codebase->config->exit_functions,
[]
) !== [ScopeAnalyzer::ACTION_END]
&& !$inferred_yield_types
Expand All @@ -177,7 +176,6 @@ public static function verifyReturnType(
$control_actions = ScopeAnalyzer::getControlActions(
$function_stmts,
$type_provider,
$codebase->config->exit_functions,
[],
false
);
Expand Down
Expand Up @@ -31,8 +31,6 @@ class ReturnTypeCollector
* @return list<Union> a list of return types
*
* @psalm-suppress ComplexMethod to be refactored
*
* TODO: This would probably benefit from using the list of exit_functions
*/
public static function getReturnTypes(
Codebase $codebase,
Expand Down
1 change: 0 additions & 1 deletion src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php
Expand Up @@ -533,7 +533,6 @@ public function analyze(
$final_actions = ScopeAnalyzer::getControlActions(
$this->function->getStmts() ?: [],
null,
$codebase->config->exit_functions,
[]
);

Expand Down
37 changes: 0 additions & 37 deletions src/Psalm/Internal/Analyzer/ScopeAnalyzer.php
Expand Up @@ -14,7 +14,6 @@
use function array_values;
use function count;
use function in_array;
use function strtolower;

/**
* @internal
Expand Down Expand Up @@ -67,7 +66,6 @@ public static function doesEverBreak(array $stmts): bool

/**
* @param array<PhpParser\Node> $stmts
* @param array<lowercase-string, bool> $exit_functions
* @param list<'loop'|'switch'> $break_types
* @param bool $return_is_exit Exit and Throw statements are treated differently from return if this is false
*
Expand All @@ -78,7 +76,6 @@ public static function doesEverBreak(array $stmts): bool
public static function getControlActions(
array $stmts,
?NodeDataProvider $nodes,
array $exit_functions,
array $break_types,
bool $return_is_exit = true
): array {
Expand Down Expand Up @@ -109,32 +106,6 @@ public static function getControlActions(
return array_values(array_unique(array_merge($control_actions, [self::ACTION_END])));
}

if ($exit_functions) {
if ($stmt->expr instanceof PhpParser\Node\Expr\FuncCall
|| $stmt->expr instanceof PhpParser\Node\Expr\StaticCall
) {
if ($stmt->expr instanceof PhpParser\Node\Expr\FuncCall) {
/** @var string|null */
$resolved_name = $stmt->expr->name->getAttribute('resolvedName');

if ($resolved_name && isset($exit_functions[strtolower($resolved_name)])) {
return array_values(array_unique(array_merge($control_actions, [self::ACTION_END])));
}
} elseif ($stmt->expr->class instanceof PhpParser\Node\Name
&& $stmt->expr->name instanceof PhpParser\Node\Identifier
) {
/** @var string|null */
$resolved_class_name = $stmt->expr->class->getAttribute('resolvedName');

if ($resolved_class_name
&& isset($exit_functions[strtolower($resolved_class_name . '::' . $stmt->expr->name)])
) {
return array_values(array_unique(array_merge($control_actions, [self::ACTION_END])));
}
}
}
}

continue;
}

Expand Down Expand Up @@ -174,7 +145,6 @@ public static function getControlActions(
$if_statement_actions = self::getControlActions(
$stmt->stmts,
$nodes,
$exit_functions,
$break_types,
$return_is_exit
);
Expand All @@ -190,7 +160,6 @@ function ($action) {
? self::getControlActions(
$stmt->else->stmts,
$nodes,
$exit_functions,
$break_types,
$return_is_exit
) : [];
Expand All @@ -211,7 +180,6 @@ function ($action) {
$elseif_control_actions = self::getControlActions(
$elseif->stmts,
$nodes,
$exit_functions,
$break_types,
$return_is_exit
);
Expand Down Expand Up @@ -268,7 +236,6 @@ function ($action) {
$case_actions = self::getControlActions(
$case->stmts,
$nodes,
$exit_functions,
array_merge($break_types, ['switch']),
$return_is_exit
);
Expand Down Expand Up @@ -334,7 +301,6 @@ function ($action) {
$loop_actions = self::getControlActions(
$stmt->stmts,
$nodes,
$exit_functions,
array_merge($break_types, ['loop']),
$return_is_exit
);
Expand Down Expand Up @@ -393,7 +359,6 @@ function ($action) {
$try_statement_actions = self::getControlActions(
$stmt->stmts,
$nodes,
$exit_functions,
$break_types,
$return_is_exit
);
Expand All @@ -414,7 +379,6 @@ function ($action) {
$catch_actions = self::getControlActions(
$catch->stmts,
$nodes,
$exit_functions,
$break_types,
$return_is_exit
);
Expand Down Expand Up @@ -453,7 +417,6 @@ function ($action) {
$finally_statement_actions = self::getControlActions(
$stmt->finally->stmts,
$nodes,
$exit_functions,
$break_types,
$return_is_exit
);
Expand Down
Expand Up @@ -154,7 +154,6 @@ public static function analyze(
? ScopeAnalyzer::getControlActions(
$else->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
[]
)
: [ScopeAnalyzer::ACTION_NONE];
Expand Down
Expand Up @@ -312,7 +312,6 @@ function (array $carry, Clause $clause): array {
$final_actions = ScopeAnalyzer::getControlActions(
$elseif->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
[]
);
// has a return/throw at end
Expand Down
Expand Up @@ -75,7 +75,6 @@ public static function analyze(
$final_actions = ScopeAnalyzer::getControlActions(
$stmt->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
[]
);

Expand Down
Expand Up @@ -85,7 +85,6 @@ public static function analyze(
$final_actions = ScopeAnalyzer::getControlActions(
$stmt->stmts,
null,
$codebase->config->exit_functions,
[]
);

Expand Down
2 changes: 0 additions & 2 deletions src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php
Expand Up @@ -4,7 +4,6 @@

use PhpParser;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Internal\Algebra;
Expand Down Expand Up @@ -96,7 +95,6 @@ public static function analyze(
$final_actions = ScopeAnalyzer::getControlActions(
$stmts,
$statements_analyzer->node_data,
Config::getInstance()->exit_functions,
[]
);

Expand Down
Expand Up @@ -3,7 +3,6 @@
namespace Psalm\Internal\Analyzer\Statements\Block;

use PhpParser;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
Expand Down Expand Up @@ -73,16 +72,13 @@ public static function analyze(

$case_action_map = [];

$config = Config::getInstance();

// create a map of case statement -> ultimate exit type
for ($i = count($stmt->cases) - 1; $i >= 0; --$i) {
$case = $stmt->cases[$i];

$case_actions = $case_action_map[$i] = ScopeAnalyzer::getControlActions(
$case->stmts,
$statements_analyzer->node_data,
$config->exit_functions,
['switch']
);

Expand Down
3 changes: 0 additions & 3 deletions src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php
Expand Up @@ -52,7 +52,6 @@ public static function analyze(
$catch_actions[$i] = ScopeAnalyzer::getControlActions(
$catch->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
[]
);
$all_catches_leave = $all_catches_leave && !in_array(ScopeAnalyzer::ACTION_NONE, $catch_actions[$i], true);
Expand Down Expand Up @@ -105,7 +104,6 @@ public static function analyze(
$try_block_control_actions = ScopeAnalyzer::getControlActions(
$stmt->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
[]
);

Expand Down Expand Up @@ -359,7 +357,6 @@ function (string $fq_catch_class) use ($codebase): TNamedObject {
$catch_actions[$i] = ScopeAnalyzer::getControlActions(
$catch->stmts,
$statements_analyzer->node_data,
$codebase->config->exit_functions,
[]
);

Expand Down
Expand Up @@ -300,7 +300,6 @@ public function start(PhpParser\Node\FunctionLike $stmt, bool $fake_method = fal
$final_actions = ScopeAnalyzer::getControlActions(
$function_stmt->stmts,
null,
$this->config->exit_functions,
[],
false
);
Expand Down
67 changes: 0 additions & 67 deletions tests/Config/ConfigTest.php
Expand Up @@ -869,73 +869,6 @@ class MyMockClass {}
$this->analyzeFile($file_path, new Context());
}

public function testExitFunctions(): void
{
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
TestConfig::loadFromXML(
dirname(__DIR__, 2),
'<?xml version="1.0"?>
<psalm>
<exitFunctions>
<function name="leave" />
<function name="Foo\namespacedLeave" />
<function name="Foo\Bar::staticLeave" />
</exitFunctions>
</psalm>'
)
);

$file_path = getcwd() . '/src/somefile.php';

$this->addFile(
$file_path,
'<?php
namespace {
function leave() : void {
exit();
}

function mightLeave() : string {
if (rand(0, 1)) {
leave();
} else {
return "here";
}
}

function mightLeaveWithNamespacedFunction() : string {
if (rand(0, 1)) {
\Foo\namespacedLeave();
} else {
return "here";
}
}

function mightLeaveWithStaticMethod() : string {
if (rand(0, 1)) {
Foo\Bar::staticLeave();
} else {
return "here";
}
}
}

namespace Foo {
function namespacedLeave() : void {
exit();
}

class Bar {
public static function staticLeave() : void {
exit();
}
}
}'
);

$this->analyzeFile($file_path, new Context());
}

public function testValidThrowInvalidCatch(): void
{
$this->expectExceptionMessage('InvalidCatch');
Expand Down