1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix inherited class methods as well

Ref #2478
This commit is contained in:
Matthew Brown 2019-12-18 14:39:37 +00:00
parent 49a3f89526
commit cb797c6159
2 changed files with 67 additions and 7 deletions

View File

@ -172,7 +172,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$method_id = (string)$this->getMethodId($context->self);
$fq_class_name = (string)$context->self;
$class_storage = $classlike_storage_provider->get($fq_class_name);
$appearing_class_storage = $classlike_storage_provider->get($fq_class_name);
if ($add_mutations) {
$hash = md5($real_method_id . '::' . $context->getScopeSummary());
@ -182,10 +182,10 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
return null;
}
} elseif ($context->self) {
if ($class_storage->template_types) {
if ($appearing_class_storage->template_types) {
$template_params = [];
foreach ($class_storage->template_types as $param_name => $template_map) {
foreach ($appearing_class_storage->template_types as $param_name => $template_map) {
$key = array_keys($template_map)[0];
$template_params[] = new Type\Union([
@ -220,7 +220,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$context->vars_possibly_in_scope['$this'] = true;
}
if ($class_storage->has_visitor_issues) {
if ($appearing_class_storage->has_visitor_issues) {
return null;
}
@ -256,6 +256,8 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$implementer_appearing_method_id = $codebase->methods->getAppearingMethodId($cased_method_id);
$implementer_declaring_method_id = $real_method_id;
$declaring_class_storage = $appearing_class_storage;
if ($implementer_appearing_method_id
&& $implementer_appearing_method_id !== $implementer_declaring_method_id
) {
@ -264,10 +266,19 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$implementer_appearing_method_id
);
list($declaring_fq_class_name) = explode(
'::',
$implementer_declaring_method_id
);
$appearing_class_storage = $classlike_storage_provider->get(
$appearing_fq_class_name
);
$declaring_class_storage = $classlike_storage_provider->get(
$declaring_fq_class_name
);
if (isset($appearing_class_storage->trait_visibility_map[$appearing_method_name])) {
$implementer_visibility
= $appearing_class_storage->trait_visibility_map[$appearing_method_name];
@ -275,10 +286,10 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
}
// we've already checked this in the class checker
if (!isset($class_storage->class_implements[strtolower($overridden_fq_class_name)])) {
if (!isset($appearing_class_storage->class_implements[strtolower($overridden_fq_class_name)])) {
MethodAnalyzer::compareMethods(
$codebase,
$class_storage,
$declaring_class_storage,
$parent_storage,
$storage,
$parent_method_storage,

View File

@ -2616,7 +2616,7 @@ class ClassTemplateExtendsTest extends TestCase
}
}'
],
'useTraitReturnType' => [
'useTraitReturnTypeForInheritedInterface' => [
'<?php
/**
* @template TValue
@ -2665,6 +2665,55 @@ class ClassTemplateExtendsTest extends TestCase
}
}'
],
'useTraitReturnTypeForInheritedClass' => [
'<?php
/**
* @template TValue
* @template TNormalizedValue
*/
abstract class Normalizer
{
/**
* @param TValue $v
* @return TNormalizedValue
*/
abstract function normalize($v);
}
/**
* @template TTraitValue
* @template TTraitNormalizedValue
*/
trait NormalizerTrait
{
/**
* @param TTraitValue $v
* @return TTraitNormalizedValue
*/
function normalize($v)
{
return $this->doNormalize($v);
}
/**
* @param TTraitValue $v
* @return TTraitNormalizedValue
*/
abstract protected function doNormalize($v);
}
/** @extends Normalizer<string, string> */
class StringNormalizer extends Normalizer
{
/** @use NormalizerTrait<string, string> */
use NormalizerTrait;
protected function doNormalize($v): string
{
return trim($v);
}
}'
]
];
}