1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Add predefined functions to avoid throwing errors

This commit is contained in:
Matthew Brown 2017-01-15 20:11:02 -05:00
parent 6b95b84577
commit f614944b63
5 changed files with 61 additions and 4 deletions

View File

@ -86,6 +86,10 @@ class FunctionChecker extends FunctionLikeChecker
$file_storage = FileChecker::$storage[$file_path];
if (!isset($file_storage->functions[$function_id])) {
throw new \UnexpectedValueException('Not expecting ' . $function_id . ' to not have storage in ' . $file_path);
}
return $file_storage->functions[$function_id]->params;
}
@ -98,6 +102,10 @@ class FunctionChecker extends FunctionLikeChecker
{
$file_storage = FileChecker::$storage[$file_path];
if (!isset($file_storage->functions[$function_id])) {
return [];
}
return $file_storage->functions[$function_id]->defined_constants;
}

View File

@ -757,6 +757,7 @@ class ProjectChecker
}
$config->collectPredefinedConstants();
$config->collectPredefinedFunctions();
break;
}
@ -793,6 +794,7 @@ class ProjectChecker
}
$this->config->collectPredefinedConstants();
$this->config->collectPredefinedFunctions();
}
/**

View File

@ -12,6 +12,7 @@ use Psalm\Checker\Statements\ExpressionChecker;
use Psalm\Checker\TraitChecker;
use Psalm\Checker\TypeChecker;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\FunctionLikeParameter;
use Psalm\Issue\ForbiddenCode;
@ -178,6 +179,13 @@ class CallChecker
$in_call_map = FunctionChecker::inCallMap($method_id);
$is_predefined = true;
if (!$in_call_map) {
$predefined_functions = Config::getInstance()->getPredefinedFunctions();
$is_predefined = isset($predefined_functions[$method_id]);
}
if (!$in_call_map && !$stmt->name instanceof PhpParser\Node\Name\FullyQualified) {
$method_id = FunctionChecker::getFQFunctionNameFromString($method_id, $statements_checker);
}
@ -199,7 +207,7 @@ class CallChecker
$statements_checker->getFileChecker()
);
if (!$in_call_map) {
if (!$in_call_map && !$is_predefined) {
$defined_constants = FunctionChecker::getDefinedConstants(
$method_id,
$statements_checker->getFilePath()

View File

@ -1256,13 +1256,19 @@ class TypeChecker
continue;
}
if ($simple_declared_type === 'object' &&
ClassLikeChecker::classOrInterfaceExists($differing_type, $file_checker)
) {
if (!ClassLikeChecker::classOrInterfaceExists($differing_type, $file_checker)) {
break;
}
if ($simple_declared_type === 'object') {
$is_match = true;
break;
}
if (!ClassLikeChecker::classOrInterfaceExists($simple_declared_type, $file_checker)) {
break;
}
if (ClassChecker::classExtendsOrImplements($differing_type, $simple_declared_type)) {
$is_match = true;
break;

View File

@ -144,6 +144,9 @@ class Config
/** @var array<string, mixed> */
protected $predefined_constants;
/** @var array<string, bool> */
protected $predefined_functions = [];
protected function __construct()
{
self::$config = $this;
@ -542,4 +545,34 @@ class Config
{
$this->predefined_constants = get_defined_constants();
}
/**
* @return array<string, bool>
*/
public function getPredefinedFunctions()
{
return $this->predefined_functions;
}
/**
* @return void
* @psalm-suppress InvalidPropertyAssignment
* @psalm-suppress MixedAssignment
*/
public function collectPredefinedFunctions()
{
$defined_functions = get_defined_functions();
if (isset($defined_functions['user'])) {
foreach ($defined_functions['user'] as $function_name) {
$this->predefined_functions[$function_name] = true;
}
}
if (isset($defined_functions['internal'])) {
foreach ($defined_functions['internal'] as $function_name) {
$this->predefined_functions[$function_name] = true;
}
}
}
}