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

Check return statement types for inherited docblocks

This commit is contained in:
Brown 2020-03-24 17:59:48 -04:00
parent 1e480ade12
commit f6759c3d16
5 changed files with 36 additions and 8 deletions

View File

@ -120,7 +120,7 @@ class Config
];
/**
* @var self|null
* @var static|null
*/
private static $instance;

View File

@ -202,8 +202,21 @@ class ReturnAnalyzer
$storage
);
if ($storage->return_type && !$storage->return_type->hasMixed()) {
$local_return_type = $source->getLocalReturnType($storage->return_type);
if ($storage instanceof \Psalm\Storage\MethodStorage && $context->self) {
$self_class = $context->self;
$declared_return_type = $codebase->methods->getMethodReturnType(
\Psalm\Internal\MethodIdentifier::wrap($cased_method_id),
$self_class,
$statements_analyzer,
null
);
} else {
$declared_return_type = $storage->return_type;
}
if ($declared_return_type && !$declared_return_type->hasMixed()) {
$local_return_type = $source->getLocalReturnType($declared_return_type);
if ($storage instanceof \Psalm\Storage\MethodStorage) {
list($fq_class_name, $method_name) = explode('::', $cased_method_id);
@ -385,6 +398,18 @@ class ReturnAnalyzer
return false;
}
}
} elseif ($local_return_type->fromStatic() && !$inferred_type->fromStatic()) {
if (IssueBuffer::accepts(
new LessSpecificReturnStatement(
'The type \'' . $stmt_type->getId() . '\' is more general than the'
. ' declared return type \'' . $declared_return_type->getId() . '\''
. ' for ' . $cased_method_id,
new CodeLocation($source, $stmt->expr)
),
$statements_analyzer->getSuppressedIssues()
)) {
return false;
}
}
if (!$stmt_type->ignore_nullable_issues

View File

@ -768,7 +768,7 @@ class ArrayAssignmentTest extends TestCase
}
}',
'assertions' => [],
'error_levels' => ['MixedAssignment'],
'error_levels' => ['MixedAssignment', 'MixedReturnStatement'],
],
'assignToNullDontDie' => [
'<?php

View File

@ -1696,6 +1696,9 @@ class ClassTemplateExtendsTest extends TestCase
public function getIterator()
{
/**
* @psalm-suppress InvalidReturnStatement
*/
return new ArrayIterator($this->elements);
}
@ -4020,7 +4023,7 @@ class ClassTemplateExtendsTest extends TestCase
return ["foo"];
}
}',
'error_message' => 'InvalidReturnType',
'error_message' => 'InvalidReturnStatement',
],
'implementsAndExtendsWithTemplateReturningInvalid' => [
'<?php
@ -4050,7 +4053,7 @@ class ClassTemplateExtendsTest extends TestCase
return ["foo"];
}
}',
'error_message' => 'InvalidReturnType',
'error_message' => 'InvalidReturnStatement',
],
'implementsChildClassWithNonExtendedTemplate' => [
'<?php
@ -4374,7 +4377,7 @@ class ClassTemplateExtendsTest extends TestCase
return new OtherConcreteView;
}
}',
'error_message' => 'InvalidReturnType'
'error_message' => 'InvalidReturnStatement'
],
'preventExplicitMethodClassTemplateReturn' => [
'<?php

View File

@ -2138,7 +2138,7 @@ class ClassTemplateTest extends TestCase
class Base {
/** @return static */
public static function factory(): self {
return new self();
return new static();
}
}