mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Fix #194 - carry over const definitions
This commit is contained in:
parent
c8ec0dc650
commit
22b6dafe3c
@ -643,6 +643,11 @@ class ProjectChecker
|
||||
$included_file_storage->declaring_function_ids,
|
||||
$storage->declaring_function_ids
|
||||
);
|
||||
|
||||
$storage->declaring_constants = array_merge(
|
||||
$included_file_storage->declaring_constants,
|
||||
$storage->declaring_constants
|
||||
);
|
||||
}
|
||||
|
||||
$storage->populated = true;
|
||||
|
@ -392,6 +392,7 @@ class FetchChecker
|
||||
|
||||
default:
|
||||
$const_type = $statements_checker->getConstType(
|
||||
$statements_checker,
|
||||
$const_name,
|
||||
$stmt->name instanceof PhpParser\Node\Name\FullyQualified,
|
||||
$context
|
||||
|
@ -35,11 +35,6 @@ class StatementsChecker extends SourceChecker implements StatementsSource
|
||||
*/
|
||||
private $all_vars = [];
|
||||
|
||||
/**
|
||||
* @var array<string, array<string, Type\Union>>
|
||||
*/
|
||||
public static $user_constants = [];
|
||||
|
||||
/**
|
||||
* @var array<string, Type\Union>
|
||||
*/
|
||||
@ -737,8 +732,12 @@ class StatementsChecker extends SourceChecker implements StatementsSource
|
||||
*
|
||||
* @return Type\Union|null
|
||||
*/
|
||||
public function getConstType($const_name, $is_fully_qualified, Context $context)
|
||||
{
|
||||
public function getConstType(
|
||||
StatementsChecker $statements_checker,
|
||||
$const_name,
|
||||
$is_fully_qualified,
|
||||
Context $context
|
||||
) {
|
||||
$fq_const_name = null;
|
||||
|
||||
$aliased_constants = $this->getAliases()->constants;
|
||||
@ -769,6 +768,16 @@ class StatementsChecker extends SourceChecker implements StatementsSource
|
||||
return $context->vars_in_scope[$const_name];
|
||||
}
|
||||
|
||||
$file_path = $statements_checker->getFilePath();
|
||||
|
||||
$file_storage = FileChecker::$storage[strtolower($file_path)];
|
||||
|
||||
if (isset($file_storage->declaring_constants[$const_name])) {
|
||||
$constant_file_path = $file_storage->declaring_constants[$const_name];
|
||||
|
||||
return FileChecker::$storage[strtolower($constant_file_path)]->constants[$const_name];
|
||||
}
|
||||
|
||||
$predefined_constants = Config::getInstance()->getPredefinedConstants();
|
||||
|
||||
if (isset($predefined_constants[$fq_const_name ?: $const_name])) {
|
||||
@ -796,8 +805,6 @@ class StatementsChecker extends SourceChecker implements StatementsSource
|
||||
|
||||
if ($this->source instanceof NamespaceChecker) {
|
||||
$this->source->setConstType($const_name, $const_type);
|
||||
} else {
|
||||
self::$user_constants[$this->getFilePath()][$const_name] = $const_type;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1060,7 +1067,6 @@ class StatementsChecker extends SourceChecker implements StatementsSource
|
||||
*/
|
||||
public static function clearCache()
|
||||
{
|
||||
self::$user_constants = [];
|
||||
self::$stub_constants = [];
|
||||
|
||||
ExpressionChecker::clearCache();
|
||||
|
@ -12,13 +12,21 @@ class FileStorage
|
||||
public $file_path;
|
||||
|
||||
/**
|
||||
* @var array<FunctionLikeStorage>
|
||||
* @var array<string, FunctionLikeStorage>
|
||||
*/
|
||||
public $functions = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
public $declaring_function_ids = [];
|
||||
|
||||
/**
|
||||
* @var array<string, \Psalm\Type\Union>
|
||||
*/
|
||||
public $constants = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
public $declaring_constants = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
public $included_file_paths = [];
|
||||
|
||||
|
@ -299,12 +299,20 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
|
||||
$this->queue_strings_as_possible_type = true;
|
||||
}
|
||||
|
||||
if ($function_id === 'define' && $this->functionlike_storage) {
|
||||
if ($function_id === 'define') {
|
||||
$first_arg_value = isset($node->args[0]) ? $node->args[0]->value : null;
|
||||
$second_arg_value = isset($node->args[1]) ? $node->args[1]->value : null;
|
||||
if ($first_arg_value instanceof PhpParser\Node\Scalar\String_ && $second_arg_value) {
|
||||
$this->functionlike_storage->defined_constants[$first_arg_value->value] =
|
||||
StatementsChecker::getSimpleType($second_arg_value) ?: Type::getMixed();
|
||||
$const_type = StatementsChecker::getSimpleType($second_arg_value) ?: Type::getMixed();
|
||||
$const_name = $first_arg_value->value;
|
||||
|
||||
if ($this->functionlike_storage) {
|
||||
$this->functionlike_storage->defined_constants[$const_name] = $const_type;
|
||||
} else {
|
||||
$file_storage = FileChecker::$storage[strtolower($this->file_path)];
|
||||
$file_storage->constants[$const_name] = $const_type;
|
||||
$file_storage->declaring_constants[$const_name] = $this->file_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -363,10 +371,16 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
|
||||
}
|
||||
}
|
||||
} elseif ($node instanceof PhpParser\Node\Stmt\Const_) {
|
||||
if ($this->project_checker->register_global_functions) {
|
||||
foreach ($node->consts as $const) {
|
||||
StatementsChecker::$stub_constants[$const->name] =
|
||||
StatementsChecker::getSimpleType($const->value) ?: Type::getMixed();
|
||||
foreach ($node->consts as $const) {
|
||||
$const_type = StatementsChecker::getSimpleType($const->value) ?: Type::getMixed();
|
||||
|
||||
if ($this->project_checker->register_global_functions) {
|
||||
StatementsChecker::$stub_constants[$const->name] = $const_type;
|
||||
} else {
|
||||
$file_storage = FileChecker::$storage[strtolower($this->file_path)];
|
||||
|
||||
$file_storage->constants[$const->name] = $const_type;
|
||||
$file_storage->declaring_constants[$const->name] = $this->file_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +143,21 @@ class IncludeTest extends TestCase
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file2.php',
|
||||
],
|
||||
],
|
||||
'requireConstant' => [
|
||||
'files' => [
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file1.php' => '<?php
|
||||
const FOO = 5;
|
||||
define("BAR", "bat");',
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file2.php' => '<?php
|
||||
require("file1.php");
|
||||
|
||||
echo FOO;
|
||||
echo BAR;',
|
||||
],
|
||||
'files_to_check' => [
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file2.php',
|
||||
],
|
||||
],
|
||||
'requireNamespacedWithUse' => [
|
||||
'files' => [
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file1.php' => '<?php
|
||||
|
Loading…
x
Reference in New Issue
Block a user