Skip to content

Commit

Permalink
Only works with final classes and private properties
Browse files Browse the repository at this point in the history
  • Loading branch information
peterfox committed Nov 28, 2023
1 parent e4c561d commit a6f3a3d
Show file tree
Hide file tree
Showing 14 changed files with 82 additions and 31 deletions.
2 changes: 1 addition & 1 deletion build/target-repository/docs/rector_rules_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5295,7 +5295,7 @@ Add const to type
- class: [`Rector\Php83\Rector\ClassConst\AddTypeToConstRector`](../rules/Php83/Rector/ClassConst/AddTypeToConstRector.php)

```diff
class SomeClass
final class SomeClass
{
- public const TYPE = 'some_type';
+ public const string TYPE = 'some_type';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class ApplyTypes
final class ApplyTypesWhenClassFinal
{
public const STRING = 'some_type';

Expand All @@ -23,7 +23,7 @@ class ApplyTypes

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class ApplyTypes
final class ApplyTypesWhenClassFinal
{
public const string STRING = 'some_type';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class ApplyTypesToPrivateConsts
{
private const STRING = 'some_type';

private const INT = 1;

private const FLOAT = 1.0;

private const BOOL = true;

private const NULL = null;

private const ARRAY = [];
}

?>
-----
<?php

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class ApplyTypesToPrivateConsts
{
private const string STRING = 'some_type';

private const int INT = 1;

private const float FLOAT = 1.0;

private const bool BOOL = true;

private const null NULL = null;

private const array ARRAY = [];
}

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

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

abstract class SkipAbstractClass
{
public const STRING = 'some_type';
}

?>

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class SkipExtendsNotAutoloadedInterfaceClass implements NotAutoloadedInterface
final class SkipExtendsNotAutoloadedInterfaceClass implements NotAutoloadedInterface
{
public const STRING = 'some_type';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

use Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Source\SomeInterface;

class SkipOnInterfaceImplements implements SomeInterface
final class SkipOnInterfaceImplements implements SomeInterface
{
public const STRING = 'some_type';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class SomeClass
final class SomeClass
{
public const string A = 'A';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

use Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Source\ParentClass;

class SomeClass extends ParentClass
final class SomeClass extends ParentClass
{
public const STRING_OR_INT = 'some_type';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class SkipExtendsNotAutoloadedClass extends NotAutoloadedClass
final class SkipExtendsNotAutoloadedClass extends NotAutoloadedClass
{
public const STRING = 'some_type';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

use Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Source\ParentClass;

class SomeClass
final class SomeClass
{
public const STRING = ParentClass::STRING_OR_INT;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

use Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Source\SomeTrait;

class SkipWhenTraitDefinesInterface
final class SkipWhenTraitDefinesInterface
{
use SomeTrait;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class SkipExtendsNotAutoloadedClass
final class SkipExtendsNotAutoloadedClass
{
use NotAutoloadedTrait;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\Fixture;

class SomeClass
final class SomeClass
{
public const string|int string = 'A';
}
Expand Down
37 changes: 18 additions & 19 deletions rules/Php83/Rector/ClassConst/AddTypeToConstRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
use PhpParser\Node;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Trait_;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MissingConstantFromReflectionException;
use PHPStan\Reflection\ReflectionProvider;
Expand All @@ -34,14 +32,14 @@ public function getRuleDefinition(): RuleDefinition
return new RuleDefinition('Add const to type', [
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
final class SomeClass
{
public const TYPE = 'some_type';
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeClass
final class SomeClass
{
public const string TYPE = 'some_type';
}
Expand All @@ -61,6 +59,10 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): Class_|null
{
if ($node->isAbstract()) {
return null;
}

$consts = array_filter($node->stmts, function (Node $stmt) {
return $stmt instanceof Node\Stmt\ClassConst;
});
Expand All @@ -70,20 +72,9 @@ public function refactor(Node $node): Class_|null
}

try {
/** @var ClassReflection[] $parents */
$parents = [];
if ($node instanceof Class_ || $node instanceof Interface_) {
$parents = $this->getParents($node);
}
/** @var ClassReflection[] $implementations */
$implementations = [];
if ($node instanceof Class_) {
$implementations = $this->getImplementations($node);
}
$traits = [];
if ($node instanceof Class_ || $node instanceof Trait_) {
$traits = $this->getTraits($node);
}
$parents = $this->getParents($node);
$implementations = $this->getImplementations($node);
$traits = $this->getTraits($node);
} catch (FullyQualifiedNameNotAutoloadedException) {
return null;
}
Expand All @@ -100,6 +91,9 @@ public function refactor(Node $node): Class_|null
if ($this->shouldSkipDueToInheritance($constNode, $parents, $implementations, $traits)) {
continue;
}
if ($this->canBeInheritied($const, $node)) {
continue;
}
$valueType = $this->findValueType($constNode->value);
}

Expand Down Expand Up @@ -179,7 +173,7 @@ private function findValueType(Node\Expr $value): ?Node\Identifier
*/
private function getParents(Class_ $class): array
{
$parents = array_filter(is_iterable($class->extends) ? $class->extends : [$class->extends]);
$parents = array_filter([$class->extends]);

return array_map(function (Node\Name $name): ClassReflection {
if (! $name instanceof FullyQualified) {
Expand Down Expand Up @@ -234,4 +228,9 @@ private function getTraits(Class_ $node): array
throw new FullyQualifiedNameNotAutoloadedException($name);
}, $traits);
}

private function canBeInheritied(Node\Stmt\ClassConst $constNode, Class_ $node): bool
{
return ! $node->isFinal() && ! $constNode->isPrivate();
}
}

0 comments on commit a6f3a3d

Please sign in to comment.