1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +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:
Bruce Weirdan 2021-01-22 02:38:17 +02:00 committed by Daniil Gentili
parent df5b3418b0
commit 2b39ab02a0
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
4 changed files with 45 additions and 13 deletions

View File

@ -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,

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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 {