mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 12:24:49 +01:00
Resolve class aliases when accessing properties (#5068)
* Resolve class aliases when accessing properties * Moved Properties::getClasslikeStorage() to ClassLikes::getStorageFor()
This commit is contained in:
parent
df5b3418b0
commit
2b39ab02a0
@ -309,11 +309,6 @@ class Codebase
|
||||
|
||||
$this->functions = new Internal\Codebase\Functions($providers->file_storage_provider, $reflection);
|
||||
|
||||
$this->properties = new Internal\Codebase\Properties(
|
||||
$providers->classlike_storage_provider,
|
||||
$providers->file_reference_provider
|
||||
);
|
||||
|
||||
$this->classlikes = new Internal\Codebase\ClassLikes(
|
||||
$this->config,
|
||||
$providers->classlike_storage_provider,
|
||||
@ -322,6 +317,12 @@ class Codebase
|
||||
$this->scanner
|
||||
);
|
||||
|
||||
$this->properties = new Internal\Codebase\Properties(
|
||||
$providers->classlike_storage_provider,
|
||||
$providers->file_reference_provider,
|
||||
$this->classlikes
|
||||
);
|
||||
|
||||
$this->methods = new Internal\Codebase\Methods(
|
||||
$providers->classlike_storage_provider,
|
||||
$providers->file_reference_provider,
|
||||
|
@ -2076,4 +2076,15 @@ class ClassLikes
|
||||
$this->existing_interfaces = array_merge($existing_interfaces, $this->existing_interfaces);
|
||||
$this->existing_classes = array_merge($existing_classes, $this->existing_classes);
|
||||
}
|
||||
|
||||
public function getStorageFor(string $fq_class_name): ?ClassLikeStorage
|
||||
{
|
||||
$fq_class_name = $this->getUnAliasedName($fq_class_name);
|
||||
|
||||
try {
|
||||
return $this->classlike_storage_provider->get($fq_class_name);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ use Psalm\Internal\Provider\PropertyExistenceProvider;
|
||||
use Psalm\Internal\Provider\PropertyTypeProvider;
|
||||
use Psalm\Internal\Provider\PropertyVisibilityProvider;
|
||||
use Psalm\StatementsSource;
|
||||
use Psalm\Storage\ClassLikeStorage;
|
||||
use Psalm\Type;
|
||||
use function strtolower;
|
||||
|
||||
@ -26,6 +27,9 @@ class Properties
|
||||
*/
|
||||
private $classlike_storage_provider;
|
||||
|
||||
/** @var ClassLikes */
|
||||
private $classlikes;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@ -51,15 +55,18 @@ class Properties
|
||||
*/
|
||||
public $property_visibility_provider;
|
||||
|
||||
|
||||
public function __construct(
|
||||
ClassLikeStorageProvider $storage_provider,
|
||||
FileReferenceProvider $file_reference_provider
|
||||
FileReferenceProvider $file_reference_provider,
|
||||
ClassLikes $classlikes
|
||||
) {
|
||||
$this->classlike_storage_provider = $storage_provider;
|
||||
$this->file_reference_provider = $file_reference_provider;
|
||||
$this->property_existence_provider = new PropertyExistenceProvider();
|
||||
$this->property_visibility_provider = new PropertyVisibilityProvider();
|
||||
$this->property_type_provider = new PropertyTypeProvider();
|
||||
$this->classlikes = $classlikes;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,7 +101,11 @@ class Properties
|
||||
}
|
||||
}
|
||||
|
||||
$class_storage = $this->classlike_storage_provider->get($fq_class_name);
|
||||
$class_storage = $this->classlikes->getStorageFor($fq_class_name);
|
||||
|
||||
if (!$class_storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($source
|
||||
&& $context
|
||||
@ -174,9 +185,9 @@ class Properties
|
||||
}
|
||||
}
|
||||
|
||||
$class_storage = $this->classlike_storage_provider->get($fq_class_name);
|
||||
$class_storage = $this->classlikes->getStorageFor($fq_class_name);
|
||||
|
||||
if (isset($class_storage->declaring_property_ids[$property_name])) {
|
||||
if ($class_storage && isset($class_storage->declaring_property_ids[$property_name])) {
|
||||
return $class_storage->declaring_property_ids[$property_name];
|
||||
}
|
||||
|
||||
@ -205,9 +216,9 @@ class Properties
|
||||
}
|
||||
}
|
||||
|
||||
$class_storage = $this->classlike_storage_provider->get($fq_class_name);
|
||||
$class_storage = $this->classlikes->getStorageFor($fq_class_name);
|
||||
|
||||
if (isset($class_storage->appearing_property_ids[$property_name])) {
|
||||
if ($class_storage && isset($class_storage->appearing_property_ids[$property_name])) {
|
||||
$appearing_property_id = $class_storage->appearing_property_ids[$property_name];
|
||||
|
||||
return explode('::$', $appearing_property_id)[0];
|
||||
@ -262,9 +273,9 @@ class Properties
|
||||
}
|
||||
}
|
||||
|
||||
$class_storage = $this->classlike_storage_provider->get($fq_class_name);
|
||||
$class_storage = $this->classlikes->getStorageFor($fq_class_name);
|
||||
|
||||
if (isset($class_storage->declaring_property_ids[$property_name])) {
|
||||
if ($class_storage && isset($class_storage->declaring_property_ids[$property_name])) {
|
||||
$declaring_property_class = $class_storage->declaring_property_ids[$property_name];
|
||||
$declaring_class_storage = $this->classlike_storage_provider->get($declaring_property_class);
|
||||
|
||||
|
@ -481,6 +481,15 @@ class ClassTest extends TestCase
|
||||
action(new OldA());
|
||||
action(new OldAChild());'
|
||||
],
|
||||
'classAliasStaticProperty' => [
|
||||
'<?php
|
||||
class A {
|
||||
/** @var int */
|
||||
public static $prop = 1;
|
||||
}
|
||||
class_alias(A::class, B::class);
|
||||
B::$prop = 123;'
|
||||
],
|
||||
'resourceAndNumericSoftlyReserved' => [
|
||||
'<?php
|
||||
namespace {
|
||||
|
Loading…
Reference in New Issue
Block a user