1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Add better support for inheriting docblocks

This commit is contained in:
Brown 2019-06-11 11:19:57 -04:00
parent 7cf8c362f0
commit 9c4599a0f0
7 changed files with 46 additions and 17 deletions

View File

@ -1585,7 +1585,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
: [];
if ($actual_method_storage->overridden_downstream) {
$overridden_method_ids[] = 'overridden::downstream';
$overridden_method_ids['overridden::downstream'] = 'overridden::downstream';
}
if (!$return_type && isset($class_storage->interface_method_ids[strtolower($stmt->name->name)])) {

View File

@ -264,13 +264,11 @@ class TypeAnalyzer
*
* @param Type\Union $input_type
* @param Type\Union $container_type
*
* @return bool
*/
public static function isSimplyContainedBy(
Type\Union $input_type,
Type\Union $container_type
) {
) : bool {
if ($input_type->getId() === $container_type->getId()) {
return true;
}
@ -285,10 +283,26 @@ class TypeAnalyzer
$container_type_not_null = clone $container_type;
$container_type_not_null->removeType('null');
return !array_diff_key(
$input_type_not_null->getTypes(),
$container_type_not_null->getTypes()
);
foreach ($input_type->getTypes() as $input_key => $input_type_part) {
foreach ($container_type->getTypes() as $container_key => $container_type_part) {
if (get_class($container_type_part) === TNamedObject::class
&& $input_type_part instanceof TNamedObject
&& $input_type_part->value === $container_type_part->value
) {
continue 2;
}
if ($input_key === $container_key) {
continue 2;
}
}
return false;
}
return true;
}
/**

View File

@ -554,7 +554,7 @@ class Methods
$class_storage = $this->classlike_storage_provider->get($fq_class_name);
if ($class_storage->abstract && isset($class_storage->overridden_method_ids[$method_name])) {
$appearing_method_id = $class_storage->overridden_method_ids[$method_name][0];
$appearing_method_id = reset($class_storage->overridden_method_ids[$method_name]);
} else {
return null;
}
@ -757,7 +757,7 @@ class Methods
}
if ($class_storage->abstract && isset($class_storage->overridden_method_ids[$method_name])) {
return $class_storage->overridden_method_ids[$method_name][0];
return reset($class_storage->overridden_method_ids[$method_name]);
}
}

View File

@ -293,13 +293,13 @@ class Populator
&& $method_storage->inheritdoc
&& $declaring_method_storage->throws
) {
$method_storage->throws = $declaring_method_storage->throws;
}
if (count($storage->overridden_method_ids[$method_name]) === 1
&& $method_storage->signature_return_type
&& !$method_storage->signature_return_type->isVoid()
&& $method_storage->return_type === $method_storage->signature_return_type
&& ($method_storage->return_type === $method_storage->signature_return_type
|| $method_storage->inherited_return_type)
) {
if (isset($declaring_class_storage->methods[$method_name])) {
$declaring_method_storage = $declaring_class_storage->methods[$method_name];
@ -768,7 +768,7 @@ class Populator
}
}
}
$storage->overridden_method_ids[$method_name][] = $interface_method_ids[0];
$storage->overridden_method_ids[$method_name][$interface_method_ids[0]] = $interface_method_ids[0];
} else {
$storage->interface_method_ids[$method_name] = $interface_method_ids;
}
@ -1006,10 +1006,10 @@ class Populator
if (isset($declaring_class_storage->methods[$method_name])
&& $declaring_class_storage->methods[$method_name]->abstract
) {
$storage->overridden_method_ids[$method_name][] = $declaring_method_id;
$storage->overridden_method_ids[$method_name][$declaring_method_id] = $declaring_method_id;
}
} else {
$storage->overridden_method_ids[$method_name][] = $declaring_method_id;
$storage->overridden_method_ids[$method_name][$declaring_method_id] = $declaring_method_id;
}
}

View File

@ -418,7 +418,7 @@ class Reflection
$storage->declaring_method_ids[$method_name] = $declaring_method_id;
$storage->inheritable_method_ids[$method_name] = $declaring_method_id;
$storage->overridden_method_ids[$method_name][] = $declaring_method_id;
$storage->overridden_method_ids[$method_name][$declaring_method_id] = $declaring_method_id;
}
}

View File

@ -242,7 +242,7 @@ class ClassLikeStorage
public $appearing_method_ids = [];
/**
* @var array<string, array<string>>
* @var array<string, array<string, string>>
*/
public $overridden_method_ids = [];

View File

@ -1975,6 +1975,21 @@ class TemplateExtendsTest extends TestCase
echo (new F())->getValue();'
],
'lessSpecificNonGenericReturnType' => [
'<?php
/**
* @template-implements IteratorAggregate<int, int>
*/
class Bar implements IteratorAggregate {
public function getIterator() : Traversable {
yield from range(0, 100);
}
}
$bat = new Bar();
foreach ($bat as $num) {}',
],
];
}