mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 13:28:18 +01:00
Updated Rector to commit 12b471059bc5717e3f87cf1e811f05396e3571cf
12b471059b
[DeadCode] Skip private dataProvider method on RemoveUnusedPrivateMethodRector (#6509)
This commit is contained in:
parent
3e6e8074c1
commit
c5a315e2c4
@ -8,9 +8,13 @@ use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\DeadCode\NodeAnalyzer\IsClassMethodUsedAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
|
||||
use Rector\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\PHPStan\ScopeFetcher;
|
||||
use Rector\Rector\AbstractRector;
|
||||
@ -35,11 +39,21 @@ final class RemoveUnusedPrivateMethodRector extends AbstractRector
|
||||
* @readonly
|
||||
*/
|
||||
private BetterNodeFinder $betterNodeFinder;
|
||||
public function __construct(IsClassMethodUsedAnalyzer $isClassMethodUsedAnalyzer, ReflectionResolver $reflectionResolver, BetterNodeFinder $betterNodeFinder)
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private PhpDocInfoFactory $phpDocInfoFactory;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private PhpAttributeAnalyzer $phpAttributeAnalyzer;
|
||||
public function __construct(IsClassMethodUsedAnalyzer $isClassMethodUsedAnalyzer, ReflectionResolver $reflectionResolver, BetterNodeFinder $betterNodeFinder, PhpDocInfoFactory $phpDocInfoFactory, PhpAttributeAnalyzer $phpAttributeAnalyzer)
|
||||
{
|
||||
$this->isClassMethodUsedAnalyzer = $isClassMethodUsedAnalyzer;
|
||||
$this->reflectionResolver = $reflectionResolver;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
$this->phpAttributeAnalyzer = $phpAttributeAnalyzer;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
@ -95,6 +109,7 @@ CODE_SAMPLE
|
||||
}
|
||||
$hasChanged = \false;
|
||||
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
|
||||
$collectionTestMethodsUsesPrivateProvider = $this->collectTestMethodsUsesPrivateDataProvider($classReflection, $node, $classMethods);
|
||||
foreach ($privateMethods as $privateMethod) {
|
||||
if ($this->shouldSkip($privateMethod, $classReflection)) {
|
||||
continue;
|
||||
@ -102,6 +117,9 @@ CODE_SAMPLE
|
||||
if ($this->isClassMethodUsedAnalyzer->isClassMethodUsed($node, $privateMethod, $scope)) {
|
||||
continue;
|
||||
}
|
||||
if (\in_array($this->getName($privateMethod), $collectionTestMethodsUsesPrivateProvider, \true)) {
|
||||
continue;
|
||||
}
|
||||
unset($node->stmts[$privateMethod->getAttribute(AttributeKey::STMT_KEY)]);
|
||||
$hasChanged = \true;
|
||||
}
|
||||
@ -110,6 +128,50 @@ CODE_SAMPLE
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @param ClassMethod[] $classMethods
|
||||
* @return string[]
|
||||
*/
|
||||
private function collectTestMethodsUsesPrivateDataProvider(ClassReflection $classReflection, Class_ $class, array $classMethods) : array
|
||||
{
|
||||
if (!$classReflection->isSubClassOf('PHPUnit\\Framework\\TestCase')) {
|
||||
return [];
|
||||
}
|
||||
$privateMethods = [];
|
||||
foreach ($classMethods as $classMethod) {
|
||||
// test method only public, but may use private data provider
|
||||
// so verify @dataProvider and #[\PHPUnit\Framework\Attributes\DataProvider] only on public methods
|
||||
if (!$classMethod->isPublic()) {
|
||||
continue;
|
||||
}
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
|
||||
if ($phpDocInfo->hasByName('dataProvider')) {
|
||||
$dataProvider = $phpDocInfo->getByName('dataProvider');
|
||||
if ($dataProvider instanceof PhpDocTagNode && $dataProvider->value instanceof GenericTagValueNode) {
|
||||
$dataProviderMethod = $class->getMethod($dataProvider->value->value);
|
||||
if ($dataProviderMethod instanceof ClassMethod && $dataProviderMethod->isPrivate()) {
|
||||
$privateMethods[] = $dataProvider->value->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'PHPUnit\\Framework\\Attributes\\DataProvider')) {
|
||||
foreach ($classMethod->attrGroups as $attrGroup) {
|
||||
foreach ($attrGroup->attrs as $attr) {
|
||||
if ($attr->name->toString() === 'PHPUnit\\Framework\\Attributes\\DataProvider') {
|
||||
$argValue = $attr->args[0]->value->value ?? '';
|
||||
if (\is_string($argValue)) {
|
||||
$dataProviderMethod = $class->getMethod($argValue);
|
||||
if ($dataProviderMethod instanceof ClassMethod && $dataProviderMethod->isPrivate()) {
|
||||
$privateMethods[] = $argValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $privateMethods;
|
||||
}
|
||||
private function shouldSkip(ClassMethod $classMethod, ?ClassReflection $classReflection) : bool
|
||||
{
|
||||
if (!$classReflection instanceof ClassReflection) {
|
||||
|
@ -19,12 +19,12 @@ final class VersionResolver
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = '1ec42bcc33f0607533e08d75c47b589d89e7649e';
|
||||
public const PACKAGE_VERSION = '12b471059bc5717e3f87cf1e811f05396e3571cf';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2024-11-24 18:23:37';
|
||||
public const RELEASE_DATE = '2024-11-25 21:20:15';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user