mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Use a better check for functional purity
This commit is contained in:
parent
3dbfedb51a
commit
a032978a85
@ -619,8 +619,10 @@ class FunctionCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expressio
|
||||
|| $codebase->find_unused_variables
|
||||
|| !$config->remember_property_assignments_after_call)
|
||||
) {
|
||||
$must_use = false;
|
||||
|
||||
$callmap_function_pure = $function_id && $in_call_map
|
||||
? $codebase->functions->isCallMapFunctionPure($codebase, $function_id, $stmt->args)
|
||||
? $codebase->functions->isCallMapFunctionPure($codebase, $function_id, $stmt->args, $must_use)
|
||||
: null;
|
||||
|
||||
if (($function_storage
|
||||
@ -643,7 +645,8 @@ class FunctionCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expressio
|
||||
$context->removeAllObjectVars();
|
||||
}
|
||||
} elseif ($function_id
|
||||
&& (($function_storage && $function_storage->pure) || $callmap_function_pure === true)
|
||||
&& (($function_storage && $function_storage->pure)
|
||||
|| ($callmap_function_pure === true && $must_use))
|
||||
&& $codebase->find_unused_variables
|
||||
&& !$context->inside_conditional
|
||||
&& !$context->inside_unset
|
||||
|
@ -264,8 +264,12 @@ class Functions
|
||||
/**
|
||||
* @param array<int, \PhpParser\Node\Arg> $args
|
||||
*/
|
||||
public function isCallMapFunctionPure(Codebase $codebase, string $function_id, array $args) : bool
|
||||
{
|
||||
public function isCallMapFunctionPure(
|
||||
Codebase $codebase,
|
||||
string $function_id,
|
||||
array $args,
|
||||
bool &$must_use
|
||||
) : bool {
|
||||
$impure_functions = [
|
||||
// file io
|
||||
'chdir', 'chgrp', 'chmod', 'chown', 'chroot', 'closedir', 'copy', 'file_put_contents',
|
||||
@ -309,7 +313,7 @@ class Functions
|
||||
'shell_exec', 'exec', 'system', 'passthru', 'pcntl_exec',
|
||||
|
||||
// well-known functions
|
||||
'libxml_use_internal_errors', 'array_map', 'curl_exec',
|
||||
'libxml_use_internal_errors', 'curl_exec',
|
||||
'mt_srand', 'openssl_pkcs7_sign', 'mysqli_select_db', 'preg_replace_callback',
|
||||
'mt_rand', 'rand',
|
||||
|
||||
@ -346,11 +350,6 @@ class Functions
|
||||
return false;
|
||||
}
|
||||
|
||||
// $matches is basically the (conditional) output of these functions
|
||||
if ($function_id === 'preg_match' || $function_id === 'preg_match_all') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$function_callable = \Psalm\Internal\Codebase\CallMap::getCallableFromCallMapById(
|
||||
$codebase,
|
||||
$function_id,
|
||||
@ -361,10 +360,16 @@ class Functions
|
||||
return false;
|
||||
}
|
||||
|
||||
$must_use = true;
|
||||
|
||||
foreach ($function_callable->params as $i => $param) {
|
||||
if ($param->by_ref && isset($args[$i])) {
|
||||
if ($param->type && $param->type->hasCallableType() && isset($args[$i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($param->by_ref && isset($args[$i])) {
|
||||
$must_use = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user