Skip to content

Commit

Permalink
PHP 8.1: Report missing typehints in overridden native methods
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Jan 11, 2022
1 parent 00ab5b7 commit 11b14c8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/Psalm/Internal/Analyzer/MethodComparator.php
Expand Up @@ -27,6 +27,7 @@
use Psalm\Issue\ParamNameMismatch;
use Psalm\Issue\TraitMethodSignatureMismatch;
use Psalm\IssueBuffer;
use Psalm\Storage\AttributeStorage;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\MethodStorage;
Expand All @@ -35,6 +36,7 @@
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;

use function array_filter;
use function in_array;
use function strpos;
use function strtolower;
Expand Down Expand Up @@ -113,6 +115,27 @@ public static function compare(
);
}

if (!$guide_classlike_storage->user_defined
&& $implementer_classlike_storage->user_defined
&& $codebase->analysis_php_version_id >= 8_01_00
&& ($guide_method_storage->return_type
|| $guide_method_storage->signature_return_type
)
&& !$implementer_method_storage->signature_return_type
&& !array_filter(
$implementer_method_storage->attributes,
fn (AttributeStorage $s) => $s->fq_class_name === 'ReturnTypeWillChange'
)
) {
IssueBuffer::maybeAdd(
new MethodSignatureMismatch(
'Method ' . $cased_implementer_method_id . ' is missing a return type signature!',
$implementer_method_storage->location ?: $code_location
),
$suppressed_issues + $implementer_classlike_storage->suppressed_issues
);
}

if ($guide_method_storage->return_type
&& $implementer_method_storage->return_type
&& !$implementer_method_storage->inherited_return_type
Expand Down Expand Up @@ -862,7 +885,11 @@ private static function compareMethodSignatureReturnTypes(
$implementer_signature_return_type,
$guide_signature_return_type
)
: UnionTypeComparator::isContainedByInPhp($implementer_signature_return_type, $guide_signature_return_type);
: (!$implementer_signature_return_type
&& $guide_signature_return_type->isMixed()
? false
: UnionTypeComparator::isContainedByInPhp($implementer_signature_return_type, $guide_signature_return_type)
);

if (!$is_contained_by) {
if ($codebase->php_major_version >= 8
Expand Down
31 changes: 31 additions & 0 deletions tests/MethodSignatureTest.php
Expand Up @@ -1569,6 +1569,37 @@ public function bar(string ...$_args): void {}
',
'error_message' => 'MethodSignatureMismatch',
],
'noMixedTypehintInDescendant' => [
'<?php
class a {
public function test(): mixed {
return 0;
}
}
class b extends a {
public function test() {
return 0;
}
}
',
'error_message' => 'MethodSignatureMismatch',
[],
false,
'8.0'
],
'noTypehintInNativeDescendant' => [
'<?php
class a implements JsonSerializable {
public function jsonSerialize() {
return 0;
}
}
',
'error_message' => 'MethodSignatureMismatch',
[],
false,
'8.1'
],
];
}
}

0 comments on commit 11b14c8

Please sign in to comment.