dead code detector
0.7.0
PHPSTAN擴展程序可以輕鬆找到您項目中未使用的PHP代碼!
composer require --dev shipmonk/dead-code-detector使用官方擴展安裝程序或僅加載規則:
# phpstan.neon.dist
includes :
- vendor/shipmonk/dead-code-detector/rules.neon phpstan/phpstan-symfony帶有containerXmlPath#[AsEventListener]屬性#[AsController]屬性#[AsCommand]屬性#[Required]屬性#[Route]屬性EventSubscriberInterface::getSubscribedEventsonKernelResponse , onKernelRequest等#[AsEntityListener]屬性DoctrineORMEvents::*事件DoctrineCommonEventSubscriber方法#[PreFlush] , #[PostLoad] ,... testXxx方法@test , @before , @afterClass等註釋#[Test] , #[Before] , #[AfterClass]等屬性handleXxx , renderXxx , actionXxx , injectXxx , createComponentXxxSmartObject Magic需要@property註釋當您的作曲家依賴項中發現時,所有這些庫都是自動啟用的。如果您想強制啟用/禁用其中的一些,則可以:
# phpstan.neon.dist
parameters :
shipmonkDeadCode :
usageProviders :
phpunit :
enabled : true ReflectionClass的任何常數或方法被檢測到$reflection->getConstructor() , $reflection->getConstant('NAME') , $reflection->getMethods() ,... vendor的覆蓋方法均未報告為死亡PsrLogLoggerInterface::log自動考慮使用默認情況下啟用了這些提供商,但是您可以在需要時禁用它們。
shipmonk.deadCode.memberUsageProvider標記並實現ShipMonkPHPStanDeadCodeProviderMemberUsageProvider # phpstan.neon.dist
services :
-
class : AppApiOutputUsageProvider
tags :
- shipmonk.deadCode.memberUsageProvider 重要的
接口和標籤在0.7中更改。如果您使用的是phpstan 1.x,則使用這些使用方式不同。
ShipMonkPHPStanDeadCodeProviderReflectionBasedMemberUsageProvider : use ReflectionMethod ;
use ShipMonk PHPStan DeadCode Provider ReflectionBasedMemberUsageProvider ;
class ApiOutputUsageProvider extends ReflectionBasedMemberUsageProvider
{
public function shouldMarkMethodAsUsed ( ReflectionMethod $ method ): bool
{
// all methods from our ApiOutput interface are called automatically (e.g. during serialization)
return $ method -> getDeclaringClass ()-> implementsInterface (ApiOutput::class);
}
}MemberUsageProvider界面: use ReflectionMethod ;
use ShipMonk PHPStan DeadCode Graph ClassMethodRef ;
use ShipMonk PHPStan DeadCode Graph ClassMethodUsage ;
use ShipMonk PHPStan DeadCode Provider MemberUsageProvider ;
use Symfony Component Serializer SerializerInterface ;
class DeserializationUsageProvider implements MemberUsageProvider
{
/**
* @return list<ClassMemberUsage>
*/
public function getUsages ( Node $ node , Scope $ scope ): array
{
if (! $ node instanceof MethodCall) {
return [];
}
if (
// our deserialization calls constructor
$ scope -> getType ( $ node -> var )-> getObjectClassNames () === [SerializerInterface::class] &&
$ node -> name -> toString () === ' deserialize '
) {
$ secondArgument = $ node -> getArgs ()[ 1 ]-> value ;
$ serializedClass = $ scope -> getType ( $ secondArgument )-> getConstantStrings ()[ 0 ];
// record the method it was called from (needed for proper transitive dead code elimination)
$ originRef = $ this -> getOriginMethodRef ( $ scope );
// record the hidden constructor call
$ constructorRef = new ClassMethodRef ( $ serializedClass -> getValue (), ' __construct ' , false );
return [ new ClassMethodUsage ( $ originRef , $ constructorRef )];
}
return [];
}
private function getOriginMethodRef ( Scope $ scope ): ? ClassMethodRef
{
return new ClassMethodRef (
$ scope -> getClassReflection ()-> getName (),
$ scope -> getFunction ()-> getName (),
false ,
);
}
} ------ ------------------------------------------------------------------------
Line src/App/Facade/UserFacade.php
------ ------------------------------------------------------------------------
26 Unused AppFacadeUserFacade::updateUserAddress
? shipmonk.deadMethod
Thus AppEntityUser::updateAddress is transitively also unused
Thus AppEntityAddress::setPostalCode is transitively also unused
Thus AppEntityAddress::setCountry is transitively also unused
Thus AppEntityAddress::setStreet is transitively also unused
Thus AppEntityAddress::MAX_STREET_CHARS is transitively also unused
------ ------------------------------------------------------------------------
phpstan.neon.dist中啟用它: parameters :
shipmonkDeadCode :
reportTransitivelyDeadMethodAsSeparateError : true removeDeadCode錯誤格式運行Phpstan自動將其刪除: vendor/bin/phpstan analyse --error-format removeDeadCodeclass UserFacade
{
- public const TRANSITIVELY_DEAD = 1;
-
- public function deadMethod(): void
- {
- echo self::TRANSITIVELY_DEAD;
- }
}method $unknown->method()的方法標記為使用new $unknown()將標記所有使用的構造函數phpstan.neon.dist中禁用此功能:$unknown::CONSTANT ) parameters :
shipmonkDeadCode :
trackMixedAccess : false-vvv運行Phpstan分析,並且您會看到一些診斷: Found 2 usages over unknown type:
• setCountry method, for example in AppEntityUser::updateAddress
• setStreet method, for example in AppEntityUser::updateAddress
__get , __set等)從未報告為死亡__construct , __clone parameters :
ignoreErrors :
- ' # ^Unused .*?::__construct$ # ' MemberUsageProvider : use ShipMonk PHPStan DeadCode Provider ReflectionBasedMemberUsageProvider ;
class IgnoreDeadInterfaceUsageProvider extends ReflectionBasedMemberUsageProvider
{
public function shouldMarkMethodAsUsed ( ReflectionMethod $ method ): bool
{
return $ method -> getDeclaringClass ()-> isInterface ();
}
}composer check檢查您的代碼composer fix:cs自動編碼風格