Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

final class NonNullDefault
{
private int $value = 5;

public function __construct(int $value)
{
$this->value = $value;
}
}

?>
-----
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

final class NonNullDefault
{
private int $value;

public function __construct(int $value)
{
$this->value = $value;
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

use stdClass;

final class NullableTypedProperty
{
private ?stdClass $value = null;

public function __construct(stdClass $value)
{
$this->value = $value;
}
}

?>
-----
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

use stdClass;

final class NullableTypedProperty
{
private ?stdClass $value;

public function __construct(stdClass $value)
{
$this->value = $value;
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

use stdClass;

final class SkipConditionallyAssigned
{
private ?stdClass $value = null;

public function __construct(?stdClass $value)
{
if ($value instanceof stdClass) {
$this->value = $value;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

use stdClass;

final class SkipNoConstructor
{
private ?stdClass $value = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

use stdClass;

final class SkipNotAssigned
{
private ?stdClass $value = null;

public function __construct()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\Fixture;

// untyped property is handled by RemoveNullPropertyInitializationRector
final class SkipUntypedProperty
{
private $value = null;

public function __construct(int $value)
{
$this->value = $value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class RemoveDefaultValueFromAssignedPropertyRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector;

return RectorConfig::configure()
->withRules([RemoveDefaultValueFromAssignedPropertyRector::class]);
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ final class RemovePhpVersionIdCheckRector extends AbstractRector
/**
* @var PhpVersion::*|null
*/
private int|null $phpVersion = null;
private int|null $phpVersion;

public function __construct(
private readonly PhpVersionProvider $phpVersionProvider,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

declare(strict_types=1);

namespace Rector\DeadCode\Rector\Property;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Rector\AbstractRector;
use Rector\TypeDeclaration\AlreadyAssignDetector\ConstructorAssignDetector;
use Rector\ValueObject\MethodName;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @see \Rector\Tests\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector\RemoveDefaultValueFromAssignedPropertyRectorTest
*/
final class RemoveDefaultValueFromAssignedPropertyRector extends AbstractRector
{
public function __construct(
private readonly ConstructorAssignDetector $constructorAssignDetector
) {
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Remove redundant default value from property that is always assigned in the constructor',
[
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
{
private ?SomeType $someType = null;

public function __construct(SomeType $someType)
{
$this->someType = $someType;
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeClass
{
private ?SomeType $someType;

public function __construct(SomeType $someType)
{
$this->someType = $someType;
}
}
CODE_SAMPLE
),
]
);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Class_::class];
}

/**
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
if (! $node->getMethod(MethodName::CONSTRUCT) instanceof ClassMethod) {
return null;
}

$hasChanged = false;

foreach ($node->getProperties() as $property) {
// untyped properties are handled by RemoveNullPropertyInitializationRector
if (! $property->type instanceof Node) {
continue;
}

if ($property->hooks !== []) {
continue;
}

foreach ($property->props as $propertyProperty) {
if (! $propertyProperty->default instanceof Expr) {
continue;
}

$propertyName = $this->getName($propertyProperty);
if (! $this->constructorAssignDetector->isPropertyAssigned($node, $propertyName)) {
continue;
}

$propertyProperty->default = null;
$hasChanged = true;
}
}

if ($hasChanged) {
return $node;
}

return null;
}
}
2 changes: 1 addition & 1 deletion rules/Php80/Rector/Identical/StrStartsWithRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class StrStartsWithRector extends AbstractRector implements MinPhpVersionI
/**
* @var StrStartWithMatchAndRefactorInterface[]
*/
private array $strStartWithMatchAndRefactors = [];
private readonly array $strStartWithMatchAndRefactors;

public function __construct(
StrncmpMatchAndRefactor $strncmpMatchAndRefactor,
Expand Down
2 changes: 1 addition & 1 deletion rules/Php80/ValueObject/NestedAnnotationToAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ final class NestedAnnotationToAttribute implements AnnotationToAttributeInterfac
/**
* @var AnnotationPropertyToAttributeClass[]
*/
private array $annotationPropertiesToAttributeClasses = [];
private array $annotationPropertiesToAttributeClasses;

/**
* @param array<string, string>|string[]|AnnotationPropertyToAttributeClass[] $annotationPropertiesToAttributeClasses
Expand Down
2 changes: 2 additions & 0 deletions src/Config/Level/DeadCodeLevel.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
use Rector\DeadCode\Rector\MethodCall\RemoveNullNamedArgOnNullDefaultParamRector;
use Rector\DeadCode\Rector\Node\RemoveNonExistingVarAnnotationRector;
use Rector\DeadCode\Rector\Plus\RemoveDeadZeroAndOneOperationRector;
use Rector\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector;
use Rector\DeadCode\Rector\Property\RemoveUnusedPrivatePropertyRector;
use Rector\DeadCode\Rector\Property\RemoveUselessReadOnlyTagRector;
use Rector\DeadCode\Rector\Property\RemoveUselessVarTagRector;
Expand Down Expand Up @@ -102,6 +103,7 @@ final class DeadCodeLevel
RemoveDeadContinueRector::class,
RemoveUnusedNonEmptyArrayBeforeForeachRector::class,
RemoveNullPropertyInitializationRector::class,
RemoveDefaultValueFromAssignedPropertyRector::class,
RemoveUselessReturnExprInConstructRector::class,
ReplaceBlockToItsStmtsRector::class,
RemoveFilterVarOnExactTypeRector::class,
Expand Down
2 changes: 1 addition & 1 deletion src/PhpParser/Node/AssignAndBinaryMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ final class AssignAndBinaryMap
/**
* @var array<class-string<BinaryOp>, class-string<AssignOp>>
*/
private array $binaryOpToAssignClasses = [];
private array $binaryOpToAssignClasses;

public function __construct(
private readonly NodeTypeResolver $nodeTypeResolver
Expand Down
Loading