Skip to content

Commit

Permalink
implemented TypedPropertyFromStrictConstructorReadonlyClassRector (#4552
Browse files Browse the repository at this point in the history
)
  • Loading branch information
staabm committed Jul 23, 2023
1 parent c12703d commit a8ae2d8
Show file tree
Hide file tree
Showing 14 changed files with 465 additions and 27 deletions.
2 changes: 2 additions & 0 deletions config/set/type-declaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use Rector\TypeDeclaration\Rector\FunctionLike\AddReturnTypeDeclarationFromYieldsRector;
use Rector\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictGetterMethodReturnTypeRector;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictSetUpRector;
Expand All @@ -52,6 +53,7 @@
AddReturnTypeDeclarationBasedOnParentClassMethodRector::class,
ReturnTypeFromStrictTypedPropertyRector::class,
TypedPropertyFromStrictConstructorRector::class,
TypedPropertyFromStrictConstructorReadonlyClassRector::class,
ParamTypeFromStrictTypedPropertyRector::class,
AddVoidReturnTypeWhereNoReturnRector::class,
ReturnTypeFromReturnNewRector::class,
Expand Down
12 changes: 12 additions & 0 deletions packages/PHPStanStaticTypeMapper/DoctrineTypeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\PHPStanStaticTypeMapper;

use PHPStan\Type\ArrayType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
Expand Down Expand Up @@ -44,4 +45,15 @@ private function isCollectionObjectType(Type $type): bool

return $type->getClassName() === 'Doctrine\Common\Collections\Collection';
}

public function isInstanceOfCollectionType(Type $type): bool
{
if (! $type instanceof ObjectType) {
return false;
}

return $type->isInstanceOf('Doctrine\Common\Collections\Collection')
->yes();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

/**
* @immutable
*/
class ImmutableClassPublicProperty
{
public $config;

public function __construct(string $s)
{
$this->config = $s;
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

/**
* @immutable
*/
class ImmutableClassPublicProperty
{
public string $config;

public function __construct(string $s)
{
$this->config = $s;
}
}

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

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

/**
* @immutable
*/
class ImmutableClassPublicPropertyUselessVar
{
/**
* @var string
*/
public $config;

public function __construct(string $s)
{
$this->config = $s;
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

/**
* @immutable
*/
class ImmutableClassPublicPropertyUselessVar
{
public string $config;

public function __construct(string $s)
{
$this->config = $s;
}
}

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

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

class ReadonlyPublicProperty
{
/** @readonly */
public $config;

public function __construct(string $s)
{
$this->config = $s;
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

class ReadonlyPublicProperty
{
/** @readonly */
public string $config;

public function __construct(string $s)
{
$this->config = $s;
}
}

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

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

final class SkipDefaultFalseInParam
{
public $someString = false;

public function __construct(string $someString)
{
if (mt_rand(0, 1)) {
$this->someString = $someString;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

class SkipDoc
{
private $name;

/**
* @param string $name
*/
public function __construct($name)
{
$this->name = $name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

use Doctrine\Common\Collections\ArrayCollection;

final class SkipDoctrineCollection
{
private $items;

public function __construct()
{
$this->items = new ArrayCollection();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector\Fixture;

/**
* @immutable
*/
class SkipNonPublicProperty
{
protected $config; // non-public properties are handled by other rules

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

declare(strict_types=1);

namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector;

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

final class TypedPropertyFromStrictConstructorReadonlyClassRectorTest 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,14 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorReadonlyClassRector;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(TypedPropertyFromStrictConstructorReadonlyClassRector::class);

$rectorConfig->phpVersion(PhpVersionFeature::TYPED_PROPERTIES);
};

0 comments on commit a8ae2d8

Please sign in to comment.