mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-22 16:32:27 +02:00
Updated Rector to commit 52b665436c0f2161619b265caa3f2a65be5604dc
52b665436c
[PHP83] Implements a rule to add types to class constants (#5290)
This commit is contained in:
parent
1bcbe800e1
commit
f9c1f58ffc
@ -4,7 +4,6 @@ declare (strict_types=1);
|
||||
namespace RectorPrefix202312;
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector;
|
||||
return static function (RectorConfig $rectorConfig) : void {
|
||||
$rectorConfig->rules([AddOverrideAttributeToOverriddenMethodsRector::class]);
|
||||
$rectorConfig->rules([\Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector::class, \Rector\Php83\Rector\ClassConst\AddTypeToConstRector::class]);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 351 Rules Overview
|
||||
# 353 Rules Overview
|
||||
|
||||
<br>
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
- [Php82](#php82) (4)
|
||||
|
||||
- [Php83](#php83) (1)
|
||||
- [Php83](#php83) (2)
|
||||
|
||||
- [Privatization](#privatization) (4)
|
||||
|
||||
@ -5263,6 +5263,22 @@ Add override attribute to overridden methods
|
||||
|
||||
<br>
|
||||
|
||||
### AddTypeToConstRector
|
||||
|
||||
Add const to type
|
||||
|
||||
- class: [`Rector\Php83\Rector\ClassConst\AddTypeToConstRector`](../rules/Php83/Rector/ClassConst/AddTypeToConstRector.php)
|
||||
|
||||
```diff
|
||||
final class SomeClass
|
||||
{
|
||||
- public const TYPE = 'some_type';
|
||||
+ public const string TYPE = 'some_type';
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Privatization
|
||||
|
||||
### FinalizeClassesWithoutChildrenRector
|
||||
|
200
rules/Php83/Rector/ClassConst/AddTypeToConstRector.php
Normal file
200
rules/Php83/Rector/ClassConst/AddTypeToConstRector.php
Normal file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Php83\Rector\ClassConst;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\MissingConstantFromReflectionException;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\Core\Exception\FullyQualifiedNameNotAutoloadedException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\Tests\Php83\Rector\ClassConst\AddTypeToConstRector\AddTypeToConstRectorTest
|
||||
*/
|
||||
class AddTypeToConstRector extends AbstractRector implements MinPhpVersionInterface
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \PHPStan\Reflection\ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
public function __construct(ReflectionProvider $reflectionProvider)
|
||||
{
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Add const to type', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public const TYPE = 'some_type';
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public const string TYPE = 'some_type';
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?\PhpParser\Node\Stmt\Class_
|
||||
{
|
||||
if ($node->isAbstract()) {
|
||||
return null;
|
||||
}
|
||||
$consts = \array_filter($node->stmts, function (Node $stmt) {
|
||||
return $stmt instanceof Node\Stmt\ClassConst;
|
||||
});
|
||||
if ($consts === []) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
$parents = $this->getParents($node);
|
||||
$implementations = $this->getImplementations($node);
|
||||
$traits = $this->getTraits($node);
|
||||
} catch (FullyQualifiedNameNotAutoloadedException $exception) {
|
||||
return null;
|
||||
}
|
||||
$changes = \false;
|
||||
foreach ($consts as $const) {
|
||||
// If a type is set, skip
|
||||
if ($const->type !== null) {
|
||||
continue;
|
||||
}
|
||||
foreach ($const->consts as $constNode) {
|
||||
if ($this->shouldSkipDueToInheritance($constNode, $parents, $implementations, $traits)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->canBeInheritied($const, $node)) {
|
||||
continue;
|
||||
}
|
||||
$valueType = $this->findValueType($constNode->value);
|
||||
}
|
||||
if (($valueType ?? null) === null) {
|
||||
continue;
|
||||
}
|
||||
$const->type = $valueType;
|
||||
$changes = \true;
|
||||
}
|
||||
if (!$changes) {
|
||||
return null;
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
public function provideMinPhpVersion() : int
|
||||
{
|
||||
return PhpVersionFeature::TYPED_CLASS_CONSTANTS;
|
||||
}
|
||||
/**
|
||||
* @param ClassReflection[] $parents
|
||||
* @param ClassReflection[] $implementations
|
||||
* @param ClassReflection[] $traits
|
||||
*/
|
||||
public function shouldSkipDueToInheritance(Node\Const_ $constNode, array $parents, array $implementations, array $traits) : bool
|
||||
{
|
||||
foreach ([$parents, $implementations, $traits] as $inheritance) {
|
||||
foreach ($inheritance as $inheritanceItem) {
|
||||
if ($constNode->name->name === '') {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$inheritanceItem->getConstant($constNode->name->name);
|
||||
return \true;
|
||||
} catch (MissingConstantFromReflectionException $exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
private function findValueType(Node\Expr $value) : ?Node\Identifier
|
||||
{
|
||||
if ($value instanceof Node\Scalar\String_) {
|
||||
return new Node\Identifier('string');
|
||||
}
|
||||
if ($value instanceof Node\Scalar\LNumber) {
|
||||
return new Node\Identifier('int');
|
||||
}
|
||||
if ($value instanceof Node\Scalar\DNumber) {
|
||||
return new Node\Identifier('float');
|
||||
}
|
||||
if ($value instanceof Node\Expr\ConstFetch && $value->name->toLowerString() !== 'null') {
|
||||
return new Node\Identifier('bool');
|
||||
}
|
||||
if ($value instanceof Node\Expr\ConstFetch && $value->name->toLowerString() === 'null') {
|
||||
return new Node\Identifier('null');
|
||||
}
|
||||
if ($value instanceof Node\Expr\Array_) {
|
||||
return new Node\Identifier('array');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @return ClassReflection[]
|
||||
*/
|
||||
private function getParents(Class_ $class) : array
|
||||
{
|
||||
$parents = \array_filter([$class->extends]);
|
||||
return \array_map(function (Node\Name $name) : ClassReflection {
|
||||
if (!$name instanceof FullyQualified) {
|
||||
throw new FullyQualifiedNameNotAutoloadedException($name);
|
||||
}
|
||||
if ($this->reflectionProvider->hasClass($name->toString())) {
|
||||
return $this->reflectionProvider->getClass($name->toString());
|
||||
}
|
||||
throw new FullyQualifiedNameNotAutoloadedException($name);
|
||||
}, $parents);
|
||||
}
|
||||
/**
|
||||
* @return ClassReflection[]
|
||||
*/
|
||||
private function getImplementations(Class_ $class) : array
|
||||
{
|
||||
return \array_map(function (Node\Name $name) : ClassReflection {
|
||||
if (!$name instanceof FullyQualified) {
|
||||
throw new FullyQualifiedNameNotAutoloadedException($name);
|
||||
}
|
||||
if ($this->reflectionProvider->hasClass($name->toString())) {
|
||||
return $this->reflectionProvider->getClass($name->toString());
|
||||
}
|
||||
throw new FullyQualifiedNameNotAutoloadedException($name);
|
||||
}, $class->implements);
|
||||
}
|
||||
/**
|
||||
* @return ClassReflection[]
|
||||
*/
|
||||
private function getTraits(Class_ $node) : array
|
||||
{
|
||||
$traits = [];
|
||||
foreach ($node->getTraitUses() as $traitUse) {
|
||||
$traits = \array_merge($traits, $traitUse->traits);
|
||||
}
|
||||
return \array_map(function (Node\Name $name) : ClassReflection {
|
||||
if (!$name instanceof FullyQualified) {
|
||||
throw new FullyQualifiedNameNotAutoloadedException($name);
|
||||
}
|
||||
if ($this->reflectionProvider->hasClass($name->toString())) {
|
||||
return $this->reflectionProvider->getClass($name->toString());
|
||||
}
|
||||
throw new FullyQualifiedNameNotAutoloadedException($name);
|
||||
}, $traits);
|
||||
}
|
||||
private function canBeInheritied(Node\Stmt\ClassConst $constNode, Class_ $node) : bool
|
||||
{
|
||||
return !$node->isFinal() && !$constNode->isPrivate();
|
||||
}
|
||||
}
|
@ -19,12 +19,12 @@ final class VersionResolver
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = 'ea5b331e7ea67a03b4c3f162c566a8dbfd74d55d';
|
||||
public const PACKAGE_VERSION = '52b665436c0f2161619b265caa3f2a65be5604dc';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2023-12-03 13:22:40';
|
||||
public const RELEASE_DATE = '2023-12-03 15:57:42';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
19
src/Exception/FullyQualifiedNameNotAutoloadedException.php
Normal file
19
src/Exception/FullyQualifiedNameNotAutoloadedException.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Core\Exception;
|
||||
|
||||
use PhpParser\Node\Name;
|
||||
use RuntimeException;
|
||||
class FullyQualifiedNameNotAutoloadedException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var \PhpParser\Node\Name
|
||||
*/
|
||||
protected $name;
|
||||
public function __construct(Name $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
parent::__construct(\sprintf('%s was not autoloaded', $name->toString()));
|
||||
}
|
||||
}
|
@ -527,4 +527,9 @@ final class PhpVersionFeature
|
||||
* @var int
|
||||
*/
|
||||
public const OVERRIDE_ATTRIBUTE = \Rector\Core\ValueObject\PhpVersion::PHP_83;
|
||||
/**
|
||||
* @see https://wiki.php.net/rfc/typed_class_constants
|
||||
* @var int
|
||||
*/
|
||||
public const TYPED_CLASS_CONSTANTS = \Rector\Core\ValueObject\PhpVersion::PHP_83;
|
||||
}
|
||||
|
2
vendor/composer/autoload_classmap.php
vendored
2
vendor/composer/autoload_classmap.php
vendored
@ -1204,6 +1204,7 @@ return array(
|
||||
'Rector\\Core\\Error\\ExceptionCorrector' => $baseDir . '/src/Error/ExceptionCorrector.php',
|
||||
'Rector\\Core\\Exception\\Cache\\CachingException' => $baseDir . '/src/Exception/Cache/CachingException.php',
|
||||
'Rector\\Core\\Exception\\Configuration\\InvalidConfigurationException' => $baseDir . '/src/Exception/Configuration/InvalidConfigurationException.php',
|
||||
'Rector\\Core\\Exception\\FullyQualifiedNameNotAutoloadedException' => $baseDir . '/src/Exception/FullyQualifiedNameNotAutoloadedException.php',
|
||||
'Rector\\Core\\Exception\\NotImplementedYetException' => $baseDir . '/src/Exception/NotImplementedYetException.php',
|
||||
'Rector\\Core\\Exception\\Reflection\\MissingPrivatePropertyException' => $baseDir . '/src/Exception/Reflection/MissingPrivatePropertyException.php',
|
||||
'Rector\\Core\\Exception\\ShouldNotHappenException' => $baseDir . '/src/Exception/ShouldNotHappenException.php',
|
||||
@ -1914,6 +1915,7 @@ return array(
|
||||
'Rector\\Php82\\Rector\\FuncCall\\Utf8DecodeEncodeToMbConvertEncodingRector' => $baseDir . '/rules/Php82/Rector/FuncCall/Utf8DecodeEncodeToMbConvertEncodingRector.php',
|
||||
'Rector\\Php82\\Rector\\New_\\FilesystemIteratorSkipDotsRector' => $baseDir . '/rules/Php82/Rector/New_/FilesystemIteratorSkipDotsRector.php',
|
||||
'Rector\\Php82\\Rector\\Param\\AddSensitiveParameterAttributeRector' => $baseDir . '/rules/Php82/Rector/Param/AddSensitiveParameterAttributeRector.php',
|
||||
'Rector\\Php83\\Rector\\ClassConst\\AddTypeToConstRector' => $baseDir . '/rules/Php83/Rector/ClassConst/AddTypeToConstRector.php',
|
||||
'Rector\\Php83\\Rector\\ClassMethod\\AddOverrideAttributeToOverriddenMethodsRector' => $baseDir . '/rules/Php83/Rector/ClassMethod/AddOverrideAttributeToOverriddenMethodsRector.php',
|
||||
'Rector\\PhpAttribute\\AnnotationToAttributeMapper' => $baseDir . '/packages/PhpAttribute/AnnotationToAttributeMapper.php',
|
||||
'Rector\\PhpAttribute\\AnnotationToAttributeMapper\\ArrayAnnotationToAttributeMapper' => $baseDir . '/packages/PhpAttribute/AnnotationToAttributeMapper/ArrayAnnotationToAttributeMapper.php',
|
||||
|
2
vendor/composer/autoload_static.php
vendored
2
vendor/composer/autoload_static.php
vendored
@ -1422,6 +1422,7 @@ class ComposerStaticInita55c41c7fa52abd86138c6f32df1d185
|
||||
'Rector\\Core\\Error\\ExceptionCorrector' => __DIR__ . '/../..' . '/src/Error/ExceptionCorrector.php',
|
||||
'Rector\\Core\\Exception\\Cache\\CachingException' => __DIR__ . '/../..' . '/src/Exception/Cache/CachingException.php',
|
||||
'Rector\\Core\\Exception\\Configuration\\InvalidConfigurationException' => __DIR__ . '/../..' . '/src/Exception/Configuration/InvalidConfigurationException.php',
|
||||
'Rector\\Core\\Exception\\FullyQualifiedNameNotAutoloadedException' => __DIR__ . '/../..' . '/src/Exception/FullyQualifiedNameNotAutoloadedException.php',
|
||||
'Rector\\Core\\Exception\\NotImplementedYetException' => __DIR__ . '/../..' . '/src/Exception/NotImplementedYetException.php',
|
||||
'Rector\\Core\\Exception\\Reflection\\MissingPrivatePropertyException' => __DIR__ . '/../..' . '/src/Exception/Reflection/MissingPrivatePropertyException.php',
|
||||
'Rector\\Core\\Exception\\ShouldNotHappenException' => __DIR__ . '/../..' . '/src/Exception/ShouldNotHappenException.php',
|
||||
@ -2132,6 +2133,7 @@ class ComposerStaticInita55c41c7fa52abd86138c6f32df1d185
|
||||
'Rector\\Php82\\Rector\\FuncCall\\Utf8DecodeEncodeToMbConvertEncodingRector' => __DIR__ . '/../..' . '/rules/Php82/Rector/FuncCall/Utf8DecodeEncodeToMbConvertEncodingRector.php',
|
||||
'Rector\\Php82\\Rector\\New_\\FilesystemIteratorSkipDotsRector' => __DIR__ . '/../..' . '/rules/Php82/Rector/New_/FilesystemIteratorSkipDotsRector.php',
|
||||
'Rector\\Php82\\Rector\\Param\\AddSensitiveParameterAttributeRector' => __DIR__ . '/../..' . '/rules/Php82/Rector/Param/AddSensitiveParameterAttributeRector.php',
|
||||
'Rector\\Php83\\Rector\\ClassConst\\AddTypeToConstRector' => __DIR__ . '/../..' . '/rules/Php83/Rector/ClassConst/AddTypeToConstRector.php',
|
||||
'Rector\\Php83\\Rector\\ClassMethod\\AddOverrideAttributeToOverriddenMethodsRector' => __DIR__ . '/../..' . '/rules/Php83/Rector/ClassMethod/AddOverrideAttributeToOverriddenMethodsRector.php',
|
||||
'Rector\\PhpAttribute\\AnnotationToAttributeMapper' => __DIR__ . '/../..' . '/packages/PhpAttribute/AnnotationToAttributeMapper.php',
|
||||
'Rector\\PhpAttribute\\AnnotationToAttributeMapper\\ArrayAnnotationToAttributeMapper' => __DIR__ . '/../..' . '/packages/PhpAttribute/AnnotationToAttributeMapper/ArrayAnnotationToAttributeMapper.php',
|
||||
|
Loading…
x
Reference in New Issue
Block a user