1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #908 - dont’t emit UnresolvableInclude after file_exists check

This commit is contained in:
Matthew Brown 2018-08-09 23:29:30 -04:00
parent a32273b2b8
commit 2fee699d25
7 changed files with 46 additions and 35 deletions

View File

@ -365,7 +365,7 @@ class FunctionCallChecker extends \Psalm\Checker\Statements\Expression\CallCheck
$statements_checker,
new CodeLocation($statements_checker->getSource(), $stmt),
$statements_checker->getSuppressedIssues(),
$context->getPhantomClasses()
$context->phantom_classes
);
}
}
@ -481,10 +481,16 @@ class FunctionCallChecker extends \Psalm\Checker\Statements\Expression\CallCheck
$context->check_methods = false;
} elseif ($function->parts === ['class_exists']) {
if ($first_arg && $first_arg->value instanceof PhpParser\Node\Scalar\String_) {
$context->addPhantomClass($first_arg->value->value);
$context->phantom_classes[strtolower($first_arg->value->value)] = true;
} else {
$context->check_classes = false;
}
} elseif ($function->parts === ['file_exists'] && $first_arg) {
$var_id = ExpressionChecker::getArrayVarId($first_arg->value, null);
if ($var_id) {
$context->phantom_files[$var_id] = true;
}
} elseif ($function->parts === ['extension_loaded']) {
$context->check_classes = false;
} elseif ($function->parts === ['function_exists']) {

View File

@ -657,7 +657,7 @@ class MethodCallChecker extends \Psalm\Checker\Statements\Expression\CallChecker
$statements_checker,
new CodeLocation($source, $stmt),
$statements_checker->getSuppressedIssues(),
$context->getPhantomClasses()
$context->phantom_classes
);
}
} else {

View File

@ -456,7 +456,7 @@ class StaticCallChecker extends \Psalm\Checker\Statements\Expression\CallChecker
$statements_checker,
new CodeLocation($source, $stmt),
$statements_checker->getSuppressedIssues(),
$context->getPhantomClasses()
$context->phantom_classes
);
}
}

View File

@ -150,16 +150,20 @@ class IncludeChecker
// fall through
}
} else {
$source = $statements_checker->getSource();
$var_id = ExpressionChecker::getArrayVarId($stmt->expr, null);
if (IssueBuffer::accepts(
new UnresolvableInclude(
'Cannot resolve the given expression to a file path',
new CodeLocation($source, $stmt)
),
$source->getSuppressedIssues()
)) {
// fall through
if (!$var_id || !isset($context->phantom_files[$var_id])) {
$source = $statements_checker->getSource();
if (IssueBuffer::accepts(
new UnresolvableInclude(
'Cannot resolve the given expression to a file path',
new CodeLocation($source, $stmt)
),
$source->getSuppressedIssues()
)) {
// fall through
}
}
}

View File

@ -71,7 +71,14 @@ class FileFilter
if ($e->directory) {
/** @var \SimpleXMLElement $directory */
foreach ($e->directory as $directory) {
$prospective_directory_path = ($base_dir . DIRECTORY_SEPARATOR . (string)$directory['name']);
$directory_path = (string) $directory['name'];
if ($directory_path[0] === '/' && DIRECTORY_SEPARATOR === '/') {
$prospective_directory_path = $directory_path;
} else {
$prospective_directory_path = $base_dir . DIRECTORY_SEPARATOR . $directory_path;
}
if (strpos($prospective_directory_path, '*') !== false) {
$globs = array_map(
'realpath',
@ -113,7 +120,13 @@ class FileFilter
if ($e->file) {
/** @var \SimpleXMLElement $file */
foreach ($e->file as $file) {
$prospective_file_path = $base_dir . DIRECTORY_SEPARATOR . (string)$file['name'];
$file_path = (string) $file['name'];
if ($file_path[0] === '/' && DIRECTORY_SEPARATOR === '/') {
$prospective_file_path = $file_path;
} else {
$prospective_file_path = $base_dir . DIRECTORY_SEPARATOR . $file_path;
}
if (strpos($prospective_file_path, '*') !== false) {
$globs = array_map(

View File

@ -105,7 +105,14 @@ class Context
*
* @var array<string,bool>
*/
private $phantom_classes = [];
public $phantom_classes = [];
/**
* A list of files checked with file_exists
*
* @var array<string,bool>
*/
public $phantom_files = [];
/**
* A list of clauses in Conjunctive Normal Form
@ -658,24 +665,6 @@ class Context
return isset($this->phantom_classes[strtolower($class_name)]);
}
/**
* @param string $class_name
*
* @return void
*/
public function addPhantomClass($class_name)
{
$this->phantom_classes[strtolower($class_name)] = true;
}
/**
* @return array<string, bool>
*/
public function getPhantomClasses()
{
return $this->phantom_classes;
}
/**
* @param string|null $var_name
*

View File

@ -7,7 +7,6 @@ error_reporting(E_ALL);
foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
if (file_exists($file)) {
/** @psalm-suppress UnresolvableInclude */
require $file;
break;
}