Skip to content

Commit d4e87d0

Browse files
committed
enable rule
1 parent ce32d57 commit d4e87d0

File tree

6 files changed

+110
-35
lines changed

6 files changed

+110
-35
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector\Fixture;
6+
7+
use PhpParser\NodeTraverser;
8+
use Rector\Comments\NodeVisitor\CommentRemovingNodeVisitor;
9+
10+
final class SkipDifferntType extends NodeTraverser
11+
{
12+
public function __construct(CommentRemovingNodeVisitor $commentRemovingNodeVisitor)
13+
{
14+
parent::__construct($commentRemovingNodeVisitor);
15+
}
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector\Fixture;
4+
5+
use PhpParser\Node\Scalar\String_;
6+
7+
final class SomeDifferentArgs extends String_
8+
{
9+
public function __construct($value, $attributes)
10+
{
11+
parent::__construct($value, []);
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector\Fixture;
4+
5+
use PhpParser\Node\Scalar\String_;
6+
7+
final class SkipDifferntCount extends String_
8+
{
9+
public function __construct($value)
10+
{
11+
parent::__construct($value, []);
12+
}
13+
}

rules/DeadCode/Rector/ClassMethod/RemoveParentDelegatingConstructorRector.php

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
namespace Rector\DeadCode\Rector\ClassMethod;
66

77
use PhpParser\Node;
8+
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr\StaticCall;
10+
use PhpParser\Node\Expr\Variable;
11+
use PhpParser\Node\Stmt;
812
use PhpParser\Node\Stmt\ClassMethod;
13+
use PhpParser\Node\Stmt\Expression;
914
use PhpParser\NodeVisitor;
1015
use PHPStan\Reflection\ClassReflection;
1116
use Rector\Enum\ObjectReference;
12-
use Rector\NodeAnalyzer\ArgsAnalyzer;
13-
use Rector\NodeAnalyzer\ExprAnalyzer;
14-
use Rector\PhpParser\Node\Value\ValueResolver;
1517
use Rector\PHPStan\ScopeFetcher;
1618
use Rector\Rector\AbstractRector;
17-
use Rector\Reflection\ReflectionResolver;
1819
use Rector\ValueObject\MethodName;
1920
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
2021
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -24,14 +25,6 @@
2425
*/
2526
final class RemoveParentDelegatingConstructorRector extends AbstractRector
2627
{
27-
public function __construct(
28-
private readonly ReflectionResolver $reflectionResolver,
29-
private readonly ArgsAnalyzer $argsAnalyzer,
30-
private readonly ValueResolver $valueResolver,
31-
private readonly ExprAnalyzer $exprAnalyzer
32-
) {
33-
}
34-
3528
public function getRuleDefinition(): RuleDefinition
3629
{
3730
return new RuleDefinition(
@@ -89,48 +82,89 @@ public function refactor(Node $node): ?int
8982
return null;
9083
}
9184

92-
if (count($node->stmts) !== 1) {
85+
if ($node->stmts === null || count($node->stmts) !== 1) {
9386
return null;
9487
}
9588

96-
$scope = ScopeFetcher::fetch($node);
97-
$classReflection = $scope->getClassReflection();
98-
if (! $classReflection->getParentClass() instanceof ClassReflection) {
89+
if (! $this->hasParentClassWithConstructor($node)) {
9990
return null;
10091
}
10192

102-
$parentClassReflection = $classReflection->getParentClass();
103-
if (! $parentClassReflection->hasConstructor()) {
93+
$soleStmt = $node->stmts[0];
94+
$parentCallArgs = $this->matchParentConstructorCallArgs($soleStmt);
95+
if ($parentCallArgs === null) {
10496
return null;
10597
}
10698

107-
// $parentClassReflectionConstructor = $parentClassReflection->getConstructor();
108-
109-
$soleStmt = $node->stmts[0];
110-
if (! $soleStmt instanceof Node\Stmt\Expression) {
99+
$constructorParams = $node->getParams();
100+
if (count($constructorParams) !== count($parentCallArgs)) {
111101
return null;
112102
}
113103

114-
if (! $soleStmt->expr instanceof Node\Expr\StaticCall) {
104+
// match passed names in the same order
105+
$paramNames = [];
106+
foreach ($constructorParams as $constructorParam) {
107+
$paramNames[] = $this->getName($constructorParam->var);
108+
}
109+
110+
$argNames = [];
111+
foreach ($parentCallArgs as $parentCallArg) {
112+
$argValue = $parentCallArg->value;
113+
if (! $argValue instanceof Variable) {
114+
return null;
115+
}
116+
117+
$argNames[] = $this->getName($argValue);
118+
}
119+
120+
if ($paramNames !== $argNames) {
115121
return null;
116122
}
117123

118-
$staticCall = $soleStmt->expr;
119-
if (! $this->isName($staticCall->class, ObjectReference::PARENT)) {
124+
return NodeVisitor::REMOVE_NODE;
125+
}
126+
127+
private function hasParentClassWithConstructor(ClassMethod $classMethod): bool
128+
{
129+
$scope = ScopeFetcher::fetch($classMethod);
130+
131+
$classReflection = $scope->getClassReflection();
132+
if (! $classReflection instanceof ClassReflection) {
133+
return false;
134+
}
135+
136+
$parentClassReflection = $classReflection->getParentClass();
137+
if (! $parentClassReflection instanceof ClassReflection) {
138+
return false;
139+
}
140+
141+
return $parentClassReflection->hasConstructor();
142+
}
143+
144+
/**
145+
* Looking for parent::__construct()
146+
*
147+
* @return Arg[]|null
148+
*/
149+
private function matchParentConstructorCallArgs(Stmt $stmt): ?array
150+
{
151+
if (! $stmt instanceof Expression) {
120152
return null;
121153
}
122154

123-
if (! $this->isName($staticCall->name, MethodName::CONSTRUCT)) {
155+
if (! $stmt->expr instanceof StaticCall) {
124156
return null;
125157
}
126158

127-
$constructorParams = $node->getParams();
128-
$parentCallArgs = $staticCall->getArgs();
159+
$staticCall = $stmt->expr;
160+
if (! $this->isName($staticCall->class, ObjectReference::PARENT)) {
161+
return null;
162+
}
129163

130-
if (count($constructorParams) !== count($parentCallArgs)) {
164+
if (! $this->isName($staticCall->name, MethodName::CONSTRUCT)) {
131165
return null;
132166
}
133167

134-
return NodeVisitor::REMOVE_NODE;
168+
return $staticCall->getArgs();
135169
}
136170
}

src/Comments/NodeTraverser/CommentRemovingNodeTraverser.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@
55
namespace Rector\Comments\NodeTraverser;
66

77
use PhpParser\NodeTraverser;
8-
use Rector\Comments\NodeVisitor\CommentRemovingNodeVisitor;
98

109
final class CommentRemovingNodeTraverser extends NodeTraverser
1110
{
12-
public function __construct(CommentRemovingNodeVisitor $commentRemovingNodeVisitor)
13-
{
14-
parent::__construct($commentRemovingNodeVisitor);
15-
}
1611
}

src/Config/Level/DeadCodeLevel.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Rector\DeadCode\Rector\ClassMethod\RemoveArgumentFromDefaultParentCallRector;
1818
use Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector;
1919
use Rector\DeadCode\Rector\ClassMethod\RemoveNullTagValueNodeRector;
20+
use Rector\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector;
2021
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedConstructorParamRector;
2122
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodParameterRector;
2223
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
@@ -132,7 +133,10 @@ final class DeadCodeLevel
132133
RemoveConditionExactReturnRector::class,
133134
RemoveDeadStmtRector::class,
134135
UnwrapFutureCompatibleIfPhpVersionRector::class,
136+
135137
RemoveParentCallWithoutParentRector::class,
138+
RemoveParentDelegatingConstructorRector::class,
139+
136140
RemoveDeadConditionAboveReturnRector::class,
137141
RemoveDeadLoopRector::class,
138142

0 commit comments

Comments
 (0)