mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Check return statement types for inherited docblocks
This commit is contained in:
parent
1e480ade12
commit
f6759c3d16
@ -120,7 +120,7 @@ class Config
|
||||
];
|
||||
|
||||
/**
|
||||
* @var self|null
|
||||
* @var static|null
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
|
@ -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
|
||||
|
@ -768,7 +768,7 @@ class ArrayAssignmentTest extends TestCase
|
||||
}
|
||||
}',
|
||||
'assertions' => [],
|
||||
'error_levels' => ['MixedAssignment'],
|
||||
'error_levels' => ['MixedAssignment', 'MixedReturnStatement'],
|
||||
],
|
||||
'assignToNullDontDie' => [
|
||||
'<?php
|
||||
|
@ -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
|
||||
|
@ -2138,7 +2138,7 @@ class ClassTemplateTest extends TestCase
|
||||
class Base {
|
||||
/** @return static */
|
||||
public static function factory(): self {
|
||||
return new self();
|
||||
return new static();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user