From d04e21ee5a3a74c1bfbb84602c9a0d6db60aff7c Mon Sep 17 00:00:00 2001 From: Brown Date: Tue, 26 May 2020 23:29:37 -0400 Subject: [PATCH] Define mixin declaring classname --- src/Psalm/Internal/Analyzer/ClassAnalyzer.php | 6 +++--- .../Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php | 2 +- .../Expression/Call/ClassTemplateParamCollector.php | 4 ++-- .../Expression/Call/Method/AtomicMethodCallAnalyzer.php | 6 ++++-- .../Statements/Expression/Call/StaticCallAnalyzer.php | 2 +- src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php | 2 +- src/Psalm/Internal/Codebase/Populator.php | 1 + src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php | 1 + src/Psalm/Storage/ClassLikeStorage.php | 5 +++++ 9 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php index b14d8ab53b2..1372e2ad69b 100644 --- a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php @@ -487,7 +487,7 @@ public function analyze( } } - if ($storage->mixin) { + if ($storage->mixin && $storage->mixin_declaring_fqcln === $storage->name) { $union = new Type\Union([$storage->mixin]); $union->check( $this, @@ -1052,7 +1052,7 @@ public static function addContextProperties( $class_template_params = ClassTemplateParamCollector::collect( $codebase, $property_class_storage, - $fq_class_name, + $codebase->classlike_storage_provider->get($fq_class_name), null, new Type\Atomic\TNamedObject($fq_class_name), '$this' @@ -1878,7 +1878,7 @@ public static function analyzeClassMethodReturnType( $class_template_params = ClassTemplateParamCollector::collect( $codebase, $class_storage, - $original_fq_classlike_name, + $codebase->classlike_storage_provider->get($original_fq_classlike_name), strtolower($stmt->name->name), $this_object_type ) ?: []; diff --git a/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php index 31d12d5e3b0..60750770c08 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php @@ -784,7 +784,7 @@ public static function checkReturnType( $class_template_params = ClassTemplateParamCollector::collect( $codebase, $classlike_storage, - $context->self, + $codebase->classlike_storage_provider->get($context->self), strtolower($function->name->name), new Type\Atomic\TNamedObject($context->self), '$this' diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php index e326a9b5301..797cf13125b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php @@ -18,12 +18,12 @@ class ClassTemplateParamCollector public static function collect( Codebase $codebase, ClassLikeStorage $class_storage, - string $static_fq_class_name, + ClassLikeStorage $static_class_storage, string $method_name = null, Type\Atomic $lhs_type_part = null, string $lhs_var_id = null ) { - $static_class_storage = $codebase->classlike_storage_provider->get($static_fq_class_name); + $static_fq_class_name = $static_class_storage->name; $non_trait_class_storage = $class_storage->is_trait ? $static_class_storage diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php index cf4b4c72f19..e45679907c1 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php @@ -511,12 +511,14 @@ public static function analyze( $fq_class_name = $codebase->classlikes->getUnAliasedName($fq_class_name); + $class_storage = $codebase->classlike_storage_provider->get($fq_class_name); + $parent_source = $statements_analyzer->getSource(); $class_template_params = ClassTemplateParamCollector::collect( $codebase, $codebase->methods->getClassLikeStorageForMethod($method_id), - $fq_class_name, + $class_storage, $method_name_lc, $lhs_type_part, $lhs_var_id @@ -538,7 +540,7 @@ public static function analyze( $class_template_params = ClassTemplateParamCollector::collect( $codebase, $codebase->methods->getClassLikeStorageForMethod($trait_method_id), - $fq_class_name, + $class_storage, $method_name_lc, $lhs_type_part, $lhs_var_id diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php index ace6272d8f2..3dd0f2c53c1 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php @@ -791,7 +791,7 @@ function (PhpParser\Node\Arg $arg) { $found_generic_params = ClassTemplateParamCollector::collect( $codebase, $class_storage, - $fq_class_name, + $class_storage, $method_name_lc, $lhs_type_part, null diff --git a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php index 29235088acf..d6fc70af7c5 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php @@ -231,7 +231,7 @@ public static function analyze( $found_generic_params = ClassTemplateParamCollector::collect( $codebase, $class_storage, - $fq_class_name, + $class_storage, strtolower($method_name), null, '$this' diff --git a/src/Psalm/Internal/Codebase/Populator.php b/src/Psalm/Internal/Codebase/Populator.php index d79ca4334bc..c3f6ad5241d 100644 --- a/src/Psalm/Internal/Codebase/Populator.php +++ b/src/Psalm/Internal/Codebase/Populator.php @@ -580,6 +580,7 @@ private function populateDataFromParentClass( ); if ($parent_storage->mixin && !$storage->mixin) { + $storage->mixin_declaring_fqcln = $parent_storage->mixin_declaring_fqcln; $storage->mixin = $parent_storage->mixin; } diff --git a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php index e7f50bff8ce..267bee80a28 100644 --- a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php +++ b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php @@ -1335,6 +1335,7 @@ function (array $l, array $r) : int { || $mixin_type instanceof Type\Atomic\TTemplateParam ) { $storage->mixin = $mixin_type; + $storage->mixin_declaring_fqcln = $storage->name; } } } diff --git a/src/Psalm/Storage/ClassLikeStorage.php b/src/Psalm/Storage/ClassLikeStorage.php index b4d76302e2e..e355464eab9 100644 --- a/src/Psalm/Storage/ClassLikeStorage.php +++ b/src/Psalm/Storage/ClassLikeStorage.php @@ -102,6 +102,11 @@ class ClassLikeStorage */ public $mixin = null; + /** + * @var ?string + */ + public $mixin_declaring_fqcln = null; + /** * @var array */