Skip to content

Commit 234de21

Browse files
authored
[DeadCode] Skip with different default param value child vs parent on RemoveParentDelegatingConstructorRector (#7776)
* [DeadCode] Skip with different default param value child vs parent on RemoveParentDelegatingConstructorRector * fix * eol * comment * extract logic to different method
1 parent 40d87af commit 234de21

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector\Fixture;
4+
5+
class SkipWithDefaultParams extends \DateTime
6+
{
7+
public function __construct(string $datetime = "tomorrow", ?\DateTimeZone $timezone = null)
8+
{
9+
parent::__construct($datetime, $timezone);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector\Fixture;
4+
5+
class WithEqualDefaultParamValue extends \DateTime
6+
{
7+
public function __construct(string $datetime = "now", ?\DateTimeZone $timezone = null)
8+
{
9+
parent::__construct($datetime, $timezone);
10+
}
11+
}
12+
13+
?>
14+
-----
15+
<?php
16+
17+
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveParentDelegatingConstructorRector\Fixture;
18+
19+
class WithEqualDefaultParamValue extends \DateTime
20+
{
21+
}
22+
23+
?>

rules/DeadCode/Rector/ClassMethod/RemoveParentDelegatingConstructorRector.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66

77
use PhpParser\Node;
88
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr;
910
use PhpParser\Node\Expr\StaticCall;
1011
use PhpParser\Node\Expr\Variable;
1112
use PhpParser\Node\Stmt;
1213
use PhpParser\Node\Stmt\ClassMethod;
1314
use PhpParser\Node\Stmt\Expression;
1415
use PhpParser\NodeVisitor;
16+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionParameter;
1517
use PHPStan\Reflection\ClassReflection;
1618
use PHPStan\Reflection\ExtendedMethodReflection;
1719
use Rector\Enum\ObjectReference;
20+
use Rector\PhpParser\Node\Value\ValueResolver;
1821
use Rector\PHPStan\ScopeFetcher;
1922
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
2023
use Rector\Rector\AbstractRector;
@@ -30,6 +33,7 @@ final class RemoveParentDelegatingConstructorRector extends AbstractRector
3033
{
3134
public function __construct(
3235
private readonly StaticTypeMapper $staticTypeMapper,
36+
private readonly ValueResolver $valueResolver
3337
) {
3438
}
3539

@@ -230,9 +234,43 @@ private function areConstructorAndParentParameterTypesMatching(
230234
if (! $this->nodeComparator->areNodesEqual($parameterType, $parentParameterType)) {
231235
return false;
232236
}
237+
238+
if (! $param->default instanceof Expr) {
239+
continue;
240+
}
241+
242+
if ($this->isDifferentDefaultValue($param->default, $extendedMethodReflection, $index)) {
243+
return false;
244+
}
233245
}
234246
}
235247

236248
return true;
237249
}
250+
251+
private function isDifferentDefaultValue(
252+
Expr $defaultExpr,
253+
ExtendedMethodReflection $extendedMethodReflection,
254+
int $index
255+
): bool {
256+
$methodName = $extendedMethodReflection->getName();
257+
// native reflection is needed to get exact default value
258+
if ($extendedMethodReflection->getDeclaringClass()->getNativeReflection()->hasMethod($methodName)) {
259+
$parentMethod = $extendedMethodReflection->getDeclaringClass()
260+
->getNativeReflection()
261+
->getMethod($methodName);
262+
$nativeParentParameterReflection = $parentMethod->getParameters()[$index] ?? null;
263+
264+
if (! $nativeParentParameterReflection instanceof ReflectionParameter) {
265+
return false;
266+
}
267+
268+
$parentDefault = $nativeParentParameterReflection->getDefaultValue();
269+
if (! $this->valueResolver->isValue($defaultExpr, $parentDefault)) {
270+
return true;
271+
}
272+
}
273+
274+
return false;
275+
}
238276
}

0 commit comments

Comments
 (0)