1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Add DeprecatedInterface and emit DeprecatedClass in more places

Fixes #463
This commit is contained in:
Matthew Brown 2018-01-23 09:09:43 -05:00
parent fdadcd3a70
commit 507007a2bf
5 changed files with 64 additions and 0 deletions

View File

@ -91,6 +91,7 @@
<xs:element name="ContinueOutsideLoop" type="IssueHandlerType" minOccurs="0" />
<xs:element name="ConflictingReferenceConstraint" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DeprecatedClass" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DeprecatedInterface" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DeprecatedMethod" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DeprecatedProperty" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateArrayKey" type="IssueHandlerType" minOccurs="0" />

View File

@ -6,6 +6,8 @@ use Psalm\Checker\Statements\ExpressionChecker;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\DeprecatedInterface;
use Psalm\Issue\InaccessibleMethod;
use Psalm\Issue\InvalidReturnType;
use Psalm\Issue\MissingConstructor;
@ -195,6 +197,31 @@ class ClassChecker extends ClassLikeChecker
) === false) {
return false;
}
try {
$parent_class_storage = $classlike_storage_provider->get($this->parent_fq_class_name);
if ($parent_class_storage->deprecated) {
$code_location = new CodeLocation(
$this,
$this->class,
$class_context ? $class_context->include_location : null,
true
);
if (IssueBuffer::accepts(
new DeprecatedClass(
$this->parent_fq_class_name . ' is marked deprecated',
$code_location
),
$this->source->getSuppressedIssues()
)) {
// fall through
}
}
} catch (\InvalidArgumentException $e) {
// do nothing
}
}
foreach ($this->class->implements as $interface_name) {
@ -237,6 +264,18 @@ class ClassChecker extends ClassLikeChecker
true
);
if ($interface_storage->deprecated) {
if (IssueBuffer::accepts(
new DeprecatedInterface(
$interface_name . ' is marked deprecated',
$code_location
),
$this->source->getSuppressedIssues()
)) {
// fall through
}
}
foreach ($interface_storage->methods as $method_name => $interface_method_storage) {
if ($interface_method_storage->visibility === self::VISIBILITY_PUBLIC) {
$implementer_declaring_method_id = MethodChecker::getDeclaringMethodId(

View File

@ -0,0 +1,6 @@
<?php
namespace Psalm\Issue;
class DeprecatedInterface extends CodeIssue
{
}

View File

@ -362,6 +362,16 @@ class AnnotationTest extends TestCase
$a = new Foo();',
'error_message' => 'DeprecatedClass',
],
'deprecatedClassWithExtends' => [
'<?php
/**
* @deprecated
*/
class Foo { }
class Bar extends Foo {}',
'error_message' => 'DeprecatedClass',
],
'deprecatedPropertyGet' => [
'<?php
class A{

View File

@ -524,6 +524,14 @@ class InterfaceTest extends TestCase
foo(new C);',
'error_message' => 'InvalidReturnStatement',
],
'deprecatedInterface' => [
'<?php
/** @deprecated */
interface Container {}
class A implements Container {}',
'error_message' => 'DeprecatedInterface',
],
];
}
}