diff --git a/src/Rules/Deprecations/RestrictedDeprecatedMethodUsageExtension.php b/src/Rules/Deprecations/RestrictedDeprecatedMethodUsageExtension.php index d8bb035..67039f4 100644 --- a/src/Rules/Deprecations/RestrictedDeprecatedMethodUsageExtension.php +++ b/src/Rules/Deprecations/RestrictedDeprecatedMethodUsageExtension.php @@ -3,6 +3,7 @@ namespace PHPStan\Rules\Deprecations; use PHPStan\Analyser\Scope; +use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ExtendedMethodReflection; use PHPStan\Rules\RestrictedUsage\RestrictedMethodUsageExtension; use PHPStan\Rules\RestrictedUsage\RestrictedUsage; @@ -63,6 +64,34 @@ public function isRestrictedMethodUsage( ); } + $deprecatedDeclaringTrait = $this->findDeprecatedDeclaringTrait( + $methodReflection->getDeclaringClass(), + $methodReflection->getName(), + ); + if ($deprecatedDeclaringTrait !== null) { + $traitDescription = $deprecatedDeclaringTrait->getDeprecatedDescription(); + if ($traitDescription === null) { + return RestrictedUsage::create( + sprintf( + 'Call to method %s() of deprecated trait %s.', + $methodReflection->getName(), + $deprecatedDeclaringTrait->getName(), + ), + sprintf('%s.deprecatedTrait', $methodReflection->isStatic() ? 'staticMethod' : 'method'), + ); + } + + return RestrictedUsage::create( + sprintf( + "Call to method %s() of deprecated trait %s:\n%s", + $methodReflection->getName(), + $deprecatedDeclaringTrait->getName(), + $traitDescription, + ), + sprintf('%s.deprecatedTrait', $methodReflection->isStatic() ? 'staticMethod' : 'method'), + ); + } + if (!$methodReflection->isDeprecated()->yes()) { return null; } @@ -113,4 +142,17 @@ public function isRestrictedMethodUsage( ); } + private function findDeprecatedDeclaringTrait(ClassReflection $declaringClass, string $methodName): ?ClassReflection + { + foreach ($declaringClass->getTraits() as $trait) { + if (!$trait->hasNativeMethod($methodName) || !$trait->isDeprecated()) { + continue; + } + + return $trait; + } + + return null; + } + } diff --git a/tests/Rules/Deprecations/CallToDeprecatedMethodRuleTest.php b/tests/Rules/Deprecations/CallToDeprecatedMethodRuleTest.php index c3f47b1..e8f760e 100644 --- a/tests/Rules/Deprecations/CallToDeprecatedMethodRuleTest.php +++ b/tests/Rules/Deprecations/CallToDeprecatedMethodRuleTest.php @@ -47,6 +47,14 @@ public function testDeprecatedMethodCall(): void "Call to deprecated method prophesize() of class CheckDeprecatedMethodCall\\UsingDeprecatedMethodFromTrait:\nUse TraitReplacingDeprecatedMethod::prophesize()", 64, ], + [ + 'Call to method methodFromDeprecatedTrait() of deprecated trait CheckDeprecatedMethodCall\DeprecatedTrait.', + 79, + ], + [ + "Call to method methodFromDeprecatedTraitWithDescription() of deprecated trait CheckDeprecatedMethodCall\\DeprecatedTraitWithDescription:\nUse something else.", + 80, + ], ], ); } diff --git a/tests/Rules/Deprecations/CallToDeprecatedStaticMethodRuleTest.php b/tests/Rules/Deprecations/CallToDeprecatedStaticMethodRuleTest.php index f744664..7d91192 100644 --- a/tests/Rules/Deprecations/CallToDeprecatedStaticMethodRuleTest.php +++ b/tests/Rules/Deprecations/CallToDeprecatedStaticMethodRuleTest.php @@ -71,6 +71,14 @@ public function testDeprecatedStaticMethodCall(): void 'Call to method doDeprecatedBar() of deprecated class CheckDeprecatedStaticMethodCall\DeprecatedBar.', 81, ], + [ + 'Call to method staticMethodFromDeprecatedTrait() of deprecated trait CheckDeprecatedStaticMethodCall\DeprecatedTrait.', + 83, + ], + [ + "Call to method staticMethodFromDeprecatedTraitWithDescription() of deprecated trait CheckDeprecatedStaticMethodCall\\DeprecatedTraitWithDescription:\nUse something else.", + 84, + ], ], ); } diff --git a/tests/Rules/Deprecations/data/call-to-deprecated-method-definition.php b/tests/Rules/Deprecations/data/call-to-deprecated-method-definition.php index 77ce2d1..19d8347 100644 --- a/tests/Rules/Deprecations/data/call-to-deprecated-method-definition.php +++ b/tests/Rules/Deprecations/data/call-to-deprecated-method-definition.php @@ -94,3 +94,39 @@ protected function prophesize(): void } } +/** + * @deprecated + */ +trait DeprecatedTrait +{ + + public function methodFromDeprecatedTrait(): void + { + } + + public static function staticMethodFromDeprecatedTrait(): void + { + } + +} + +/** + * @deprecated Use something else. + */ +trait DeprecatedTraitWithDescription +{ + + public function methodFromDeprecatedTraitWithDescription(): void + { + } + +} + +class ClassUsingDeprecatedTrait +{ + + use DeprecatedTrait; + use DeprecatedTraitWithDescription; + +} + diff --git a/tests/Rules/Deprecations/data/call-to-deprecated-method.php b/tests/Rules/Deprecations/data/call-to-deprecated-method.php index 8dd78b2..145cc3a 100644 --- a/tests/Rules/Deprecations/data/call-to-deprecated-method.php +++ b/tests/Rules/Deprecations/data/call-to-deprecated-method.php @@ -74,3 +74,17 @@ public function callProphesize(): void $this->prophesize(); } } + +$obj = new ClassUsingDeprecatedTrait(); +$obj->methodFromDeprecatedTrait(); +$obj->methodFromDeprecatedTraitWithDescription(); + +/** + * @deprecated + */ +function deprecated_scope_for_deprecated_trait(): void +{ + $obj = new ClassUsingDeprecatedTrait(); + $obj->methodFromDeprecatedTrait(); + $obj->methodFromDeprecatedTraitWithDescription(); +} diff --git a/tests/Rules/Deprecations/data/call-to-deprecated-static-method-definition.php b/tests/Rules/Deprecations/data/call-to-deprecated-static-method-definition.php index 017c13a..7f2aa73 100644 --- a/tests/Rules/Deprecations/data/call-to-deprecated-static-method-definition.php +++ b/tests/Rules/Deprecations/data/call-to-deprecated-static-method-definition.php @@ -66,3 +66,35 @@ class DeprecatedBaz extends Foo { } + +/** + * @deprecated + */ +trait DeprecatedTrait +{ + + public static function staticMethodFromDeprecatedTrait(): void + { + } + +} + +/** + * @deprecated Use something else. + */ +trait DeprecatedTraitWithDescription +{ + + public static function staticMethodFromDeprecatedTraitWithDescription(): void + { + } + +} + +class ClassUsingDeprecatedTrait +{ + + use DeprecatedTrait; + use DeprecatedTraitWithDescription; + +} diff --git a/tests/Rules/Deprecations/data/call-to-deprecated-static-method.php b/tests/Rules/Deprecations/data/call-to-deprecated-static-method.php index b03eac3..40bd8d2 100644 --- a/tests/Rules/Deprecations/data/call-to-deprecated-static-method.php +++ b/tests/Rules/Deprecations/data/call-to-deprecated-static-method.php @@ -79,3 +79,15 @@ public static function foo() } DeprecatedBar::doDeprecatedBar(); + +ClassUsingDeprecatedTrait::staticMethodFromDeprecatedTrait(); +ClassUsingDeprecatedTrait::staticMethodFromDeprecatedTraitWithDescription(); + +/** + * @deprecated + */ +function deprecated_scope_for_deprecated_trait(): void +{ + ClassUsingDeprecatedTrait::staticMethodFromDeprecatedTrait(); + ClassUsingDeprecatedTrait::staticMethodFromDeprecatedTraitWithDescription(); +}