mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
Merge pull request #7363 from zoonru/81_returntypewillchange
PHP 8.1: Report missing typehints in overridden native methods
This commit is contained in:
commit
bbfdd57d5c
@ -325,6 +325,7 @@
|
|||||||
<xs:element name="LoopInvalidation" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="LoopInvalidation" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MethodSignatureMismatch" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MethodSignatureMismatch" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MethodSignatureMustOmitReturnType" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MethodSignatureMustOmitReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||||
|
<xs:element name="MethodSignatureMustProvideReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MismatchingDocblockParamType" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MismatchingDocblockParamType" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MismatchingDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MismatchingDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="MismatchingDocblockReturnType" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="MismatchingDocblockReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||||
|
@ -56,6 +56,7 @@ Level 5 and above allows a more non-verifiable code, and higher levels are even
|
|||||||
- [InvalidThrow](issues/InvalidThrow.md)
|
- [InvalidThrow](issues/InvalidThrow.md)
|
||||||
- [LoopInvalidation](issues/LoopInvalidation.md)
|
- [LoopInvalidation](issues/LoopInvalidation.md)
|
||||||
- [MethodSignatureMustOmitReturnType](issues/MethodSignatureMustOmitReturnType.md)
|
- [MethodSignatureMustOmitReturnType](issues/MethodSignatureMustOmitReturnType.md)
|
||||||
|
- [MethodSignatureMustProvideReturnType](issues/MethodSignatureMustProvideReturnType.md)
|
||||||
- [MissingDependency](issues/MissingDependency.md)
|
- [MissingDependency](issues/MissingDependency.md)
|
||||||
- [MissingFile](issues/MissingFile.md)
|
- [MissingFile](issues/MissingFile.md)
|
||||||
- [MissingImmutableAnnotation](issues/MissingImmutableAnnotation.md)
|
- [MissingImmutableAnnotation](issues/MissingImmutableAnnotation.md)
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
- [LoopInvalidation](issues/LoopInvalidation.md)
|
- [LoopInvalidation](issues/LoopInvalidation.md)
|
||||||
- [MethodSignatureMismatch](issues/MethodSignatureMismatch.md)
|
- [MethodSignatureMismatch](issues/MethodSignatureMismatch.md)
|
||||||
- [MethodSignatureMustOmitReturnType](issues/MethodSignatureMustOmitReturnType.md)
|
- [MethodSignatureMustOmitReturnType](issues/MethodSignatureMustOmitReturnType.md)
|
||||||
|
- [MethodSignatureMustProvideReturnType](issues/MethodSignatureMustProvideReturnType.md)
|
||||||
- [MismatchingDocblockParamType](issues/MismatchingDocblockParamType.md)
|
- [MismatchingDocblockParamType](issues/MismatchingDocblockParamType.md)
|
||||||
- [MismatchingDocblockPropertyType](issues/MismatchingDocblockPropertyType.md)
|
- [MismatchingDocblockPropertyType](issues/MismatchingDocblockPropertyType.md)
|
||||||
- [MismatchingDocblockReturnType](issues/MismatchingDocblockReturnType.md)
|
- [MismatchingDocblockReturnType](issues/MismatchingDocblockReturnType.md)
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
# MethodSignatureMustProvideReturnType
|
||||||
|
|
||||||
|
In PHP 8.1+, [most non-final internal methods now require overriding methods to declare a compatible return type, otherwise a deprecated notice is emitted during inheritance validation](https://www.php.net/manual/en/migration81.incompatible.php#migration81.incompatible.core.type-compatibility-internal).
|
||||||
|
|
||||||
|
This issue is emitted when a method overriding a native method is defined without a return type.
|
||||||
|
|
||||||
|
**Only if** the return type cannot be declared to keep support for PHP 7, a `#[ReturnTypeWillChange]` attribute can be added to silence the PHP deprecation notice and Psalm issue.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class A implements JsonSerializable {
|
||||||
|
public function jsonSerialize() {
|
||||||
|
return ['type' => 'A'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -21,12 +21,14 @@ use Psalm\Issue\ImplementedParamTypeMismatch;
|
|||||||
use Psalm\Issue\ImplementedReturnTypeMismatch;
|
use Psalm\Issue\ImplementedReturnTypeMismatch;
|
||||||
use Psalm\Issue\LessSpecificImplementedReturnType;
|
use Psalm\Issue\LessSpecificImplementedReturnType;
|
||||||
use Psalm\Issue\MethodSignatureMismatch;
|
use Psalm\Issue\MethodSignatureMismatch;
|
||||||
|
use Psalm\Issue\MethodSignatureMustProvideReturnType;
|
||||||
use Psalm\Issue\MissingImmutableAnnotation;
|
use Psalm\Issue\MissingImmutableAnnotation;
|
||||||
use Psalm\Issue\MoreSpecificImplementedParamType;
|
use Psalm\Issue\MoreSpecificImplementedParamType;
|
||||||
use Psalm\Issue\OverriddenMethodAccess;
|
use Psalm\Issue\OverriddenMethodAccess;
|
||||||
use Psalm\Issue\ParamNameMismatch;
|
use Psalm\Issue\ParamNameMismatch;
|
||||||
use Psalm\Issue\TraitMethodSignatureMismatch;
|
use Psalm\Issue\TraitMethodSignatureMismatch;
|
||||||
use Psalm\IssueBuffer;
|
use Psalm\IssueBuffer;
|
||||||
|
use Psalm\Storage\AttributeStorage;
|
||||||
use Psalm\Storage\ClassLikeStorage;
|
use Psalm\Storage\ClassLikeStorage;
|
||||||
use Psalm\Storage\FunctionLikeParameter;
|
use Psalm\Storage\FunctionLikeParameter;
|
||||||
use Psalm\Storage\MethodStorage;
|
use Psalm\Storage\MethodStorage;
|
||||||
@ -35,6 +37,7 @@ use Psalm\Type\Atomic\TNull;
|
|||||||
use Psalm\Type\Atomic\TTemplateParam;
|
use Psalm\Type\Atomic\TTemplateParam;
|
||||||
use Psalm\Type\Union;
|
use Psalm\Type\Union;
|
||||||
|
|
||||||
|
use function array_filter;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
use function strpos;
|
use function strpos;
|
||||||
use function strtolower;
|
use function strtolower;
|
||||||
@ -113,6 +116,29 @@ class MethodComparator
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$guide_classlike_storage->user_defined
|
||||||
|
&& $implementer_classlike_storage->user_defined
|
||||||
|
&& $codebase->analysis_php_version_id >= 80100
|
||||||
|
&& ($guide_method_storage->return_type
|
||||||
|
|| $guide_method_storage->signature_return_type
|
||||||
|
)
|
||||||
|
&& !$implementer_method_storage->signature_return_type
|
||||||
|
&& !array_filter(
|
||||||
|
$implementer_method_storage->attributes,
|
||||||
|
function (AttributeStorage $s) {
|
||||||
|
return $s->fq_class_name === 'ReturnTypeWillChange';
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
IssueBuffer::maybeAdd(
|
||||||
|
new MethodSignatureMustProvideReturnType(
|
||||||
|
'Method ' . $cased_implementer_method_id . ' must have a return type signature!',
|
||||||
|
$implementer_method_storage->location ?: $code_location
|
||||||
|
),
|
||||||
|
$suppressed_issues + $implementer_classlike_storage->suppressed_issues
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ($guide_method_storage->return_type
|
if ($guide_method_storage->return_type
|
||||||
&& $implementer_method_storage->return_type
|
&& $implementer_method_storage->return_type
|
||||||
&& !$implementer_method_storage->inherited_return_type
|
&& !$implementer_method_storage->inherited_return_type
|
||||||
@ -862,7 +888,14 @@ class MethodComparator
|
|||||||
$implementer_signature_return_type,
|
$implementer_signature_return_type,
|
||||||
$guide_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 (!$is_contained_by) {
|
||||||
if ($codebase->php_major_version >= 8
|
if ($codebase->php_major_version >= 8
|
||||||
|
9
src/Psalm/Issue/MethodSignatureMustProvideReturnType.php
Normal file
9
src/Psalm/Issue/MethodSignatureMustProvideReturnType.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Psalm\Issue;
|
||||||
|
|
||||||
|
class MethodSignatureMustProvideReturnType extends CodeIssue
|
||||||
|
{
|
||||||
|
public const ERROR_LEVEL = -1;
|
||||||
|
public const SHORTCODE = 282;
|
||||||
|
}
|
@ -218,6 +218,10 @@ class DocumentationTest extends TestCase
|
|||||||
$this->markTestSkipped();
|
$this->markTestSkipped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strpos($error_message, 'MethodSignatureMustProvideReturnType') !== false) {
|
||||||
|
$php_version = '8.1';
|
||||||
|
}
|
||||||
|
|
||||||
$this->project_analyzer->setPhpVersion($php_version, 'tests');
|
$this->project_analyzer->setPhpVersion($php_version, 'tests');
|
||||||
|
|
||||||
if ($check_references) {
|
if ($check_references) {
|
||||||
|
@ -1569,6 +1569,37 @@ class MethodSignatureTest extends TestCase
|
|||||||
',
|
',
|
||||||
'error_message' => 'MethodSignatureMismatch',
|
'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' => 'MethodSignatureMustProvideReturnType',
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
'8.1'
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user