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:
parent
df5b3418b0
commit
2b39ab02a0
@ -309,11 +309,6 @@ class Codebase
|
|||||||
|
|
||||||
$this->functions = new Internal\Codebase\Functions($providers->file_storage_provider, $reflection);
|
$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->classlikes = new Internal\Codebase\ClassLikes(
|
||||||
$this->config,
|
$this->config,
|
||||||
$providers->classlike_storage_provider,
|
$providers->classlike_storage_provider,
|
||||||
@ -322,6 +317,12 @@ class Codebase
|
|||||||
$this->scanner
|
$this->scanner
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->properties = new Internal\Codebase\Properties(
|
||||||
|
$providers->classlike_storage_provider,
|
||||||
|
$providers->file_reference_provider,
|
||||||
|
$this->classlikes
|
||||||
|
);
|
||||||
|
|
||||||
$this->methods = new Internal\Codebase\Methods(
|
$this->methods = new Internal\Codebase\Methods(
|
||||||
$providers->classlike_storage_provider,
|
$providers->classlike_storage_provider,
|
||||||
$providers->file_reference_provider,
|
$providers->file_reference_provider,
|
||||||
|
@ -2076,4 +2076,15 @@ class ClassLikes
|
|||||||
$this->existing_interfaces = array_merge($existing_interfaces, $this->existing_interfaces);
|
$this->existing_interfaces = array_merge($existing_interfaces, $this->existing_interfaces);
|
||||||
$this->existing_classes = array_merge($existing_classes, $this->existing_classes);
|
$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\PropertyTypeProvider;
|
||||||
use Psalm\Internal\Provider\PropertyVisibilityProvider;
|
use Psalm\Internal\Provider\PropertyVisibilityProvider;
|
||||||
use Psalm\StatementsSource;
|
use Psalm\StatementsSource;
|
||||||
|
use Psalm\Storage\ClassLikeStorage;
|
||||||
use Psalm\Type;
|
use Psalm\Type;
|
||||||
use function strtolower;
|
use function strtolower;
|
||||||
|
|
||||||
@ -26,6 +27,9 @@ class Properties
|
|||||||
*/
|
*/
|
||||||
private $classlike_storage_provider;
|
private $classlike_storage_provider;
|
||||||
|
|
||||||
|
/** @var ClassLikes */
|
||||||
|
private $classlikes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
@ -51,15 +55,18 @@ class Properties
|
|||||||
*/
|
*/
|
||||||
public $property_visibility_provider;
|
public $property_visibility_provider;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ClassLikeStorageProvider $storage_provider,
|
ClassLikeStorageProvider $storage_provider,
|
||||||
FileReferenceProvider $file_reference_provider
|
FileReferenceProvider $file_reference_provider,
|
||||||
|
ClassLikes $classlikes
|
||||||
) {
|
) {
|
||||||
$this->classlike_storage_provider = $storage_provider;
|
$this->classlike_storage_provider = $storage_provider;
|
||||||
$this->file_reference_provider = $file_reference_provider;
|
$this->file_reference_provider = $file_reference_provider;
|
||||||
$this->property_existence_provider = new PropertyExistenceProvider();
|
$this->property_existence_provider = new PropertyExistenceProvider();
|
||||||
$this->property_visibility_provider = new PropertyVisibilityProvider();
|
$this->property_visibility_provider = new PropertyVisibilityProvider();
|
||||||
$this->property_type_provider = new PropertyTypeProvider();
|
$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
|
if ($source
|
||||||
&& $context
|
&& $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];
|
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];
|
$appearing_property_id = $class_storage->appearing_property_ids[$property_name];
|
||||||
|
|
||||||
return explode('::$', $appearing_property_id)[0];
|
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_property_class = $class_storage->declaring_property_ids[$property_name];
|
||||||
$declaring_class_storage = $this->classlike_storage_provider->get($declaring_property_class);
|
$declaring_class_storage = $this->classlike_storage_provider->get($declaring_property_class);
|
||||||
|
|
||||||
|
@ -481,6 +481,15 @@ class ClassTest extends TestCase
|
|||||||
action(new OldA());
|
action(new OldA());
|
||||||
action(new OldAChild());'
|
action(new OldAChild());'
|
||||||
],
|
],
|
||||||
|
'classAliasStaticProperty' => [
|
||||||
|
'<?php
|
||||||
|
class A {
|
||||||
|
/** @var int */
|
||||||
|
public static $prop = 1;
|
||||||
|
}
|
||||||
|
class_alias(A::class, B::class);
|
||||||
|
B::$prop = 123;'
|
||||||
|
],
|
||||||
'resourceAndNumericSoftlyReserved' => [
|
'resourceAndNumericSoftlyReserved' => [
|
||||||
'<?php
|
'<?php
|
||||||
namespace {
|
namespace {
|
||||||
|
Loading…
Reference in New Issue
Block a user