mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-31 16:30:51 +00:00
Updated Rector to commit f13207737e25fef30190c1746a314b7e1dec6eb2
f13207737e
[CodingStyle] Add NullifyUnionNullableRector (#3231)
This commit is contained in:
parent
705057ef68
commit
f4f085ed27
|
@ -1,4 +1,4 @@
|
|||
# 415 Rules Overview
|
||||
# 416 Rules Overview
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
- [CodeQuality](#codequality) (79)
|
||||
|
||||
- [CodingStyle](#codingstyle) (38)
|
||||
- [CodingStyle](#codingstyle) (39)
|
||||
|
||||
- [Compatibility](#compatibility) (1)
|
||||
|
||||
|
@ -2182,6 +2182,23 @@ Changes negate of empty comparison of nullable value to explicit === or !== comp
|
|||
|
||||
<br>
|
||||
|
||||
### NullifyUnionNullableRector
|
||||
|
||||
Changes already typed Type|null to ?Type
|
||||
|
||||
- class: [`Rector\CodingStyle\Rector\Property\NullifyUnionNullableRector`](../rules/CodingStyle/Rector/Property/NullifyUnionNullableRector.php)
|
||||
|
||||
```diff
|
||||
final class SomeClass
|
||||
{
|
||||
|
||||
- private null|stdClass $property;
|
||||
+ private ?stdClass $property;
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### OrderAttributesRector
|
||||
|
||||
Order attributes by desired names
|
||||
|
|
|
@ -39,6 +39,8 @@ use Rector\PHPStanStaticTypeMapper\TypeAnalyzer\UnionTypeCommonTypeNarrower;
|
|||
use Rector\PHPStanStaticTypeMapper\ValueObject\UnionTypeAnalysis;
|
||||
use function RectorPrefix202212\Symfony\Component\String\b;
|
||||
use RectorPrefix202212\Symfony\Contracts\Service\Attribute\Required;
|
||||
use RectorPrefix202212\Webmozart\Assert\Assert;
|
||||
use RectorPrefix202212\Webmozart\Assert\InvalidArgumentException;
|
||||
/**
|
||||
* @implements TypeMapperInterface<UnionType>
|
||||
*/
|
||||
|
@ -141,6 +143,35 @@ final class UnionTypeMapper implements TypeMapperInterface
|
|||
}
|
||||
return $this->mapNullabledType($nullabledType, $typeKind);
|
||||
}
|
||||
/**
|
||||
* @return PhpParserUnionType|\PhpParser\Node\NullableType|null
|
||||
*/
|
||||
public function resolveTypeWithNullablePHPParserUnionType(PhpParserUnionType $phpParserUnionType)
|
||||
{
|
||||
if (\count($phpParserUnionType->types) === 2) {
|
||||
$phpParserUnionType->types = \array_values($phpParserUnionType->types);
|
||||
$firstType = $phpParserUnionType->types[0];
|
||||
$secondType = $phpParserUnionType->types[1];
|
||||
try {
|
||||
Assert::isAnyOf($firstType, [Name::class, Identifier::class]);
|
||||
Assert::isAnyOf($secondType, [Name::class, Identifier::class]);
|
||||
} catch (InvalidArgumentException $exception) {
|
||||
return $this->resolveUnionTypes($phpParserUnionType);
|
||||
}
|
||||
$firstTypeValue = $firstType->toString();
|
||||
$secondTypeValue = $secondType->toString();
|
||||
if ($firstTypeValue === $secondTypeValue) {
|
||||
return $this->resolveUnionTypes($phpParserUnionType);
|
||||
}
|
||||
if ($firstTypeValue === 'null') {
|
||||
return $this->resolveNullableType(new NullableType($secondType));
|
||||
}
|
||||
if ($secondTypeValue === 'null') {
|
||||
return $this->resolveNullableType(new NullableType($firstType));
|
||||
}
|
||||
}
|
||||
return $this->resolveUnionTypes($phpParserUnionType);
|
||||
}
|
||||
private function resolveNullableType(NullableType $nullableType) : ?NullableType
|
||||
{
|
||||
if (!$this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::NULLABLE_TYPE)) {
|
||||
|
@ -196,22 +227,8 @@ final class UnionTypeMapper implements TypeMapperInterface
|
|||
}
|
||||
return new Name($type);
|
||||
}
|
||||
/**
|
||||
* @return PhpParserUnionType|\PhpParser\Node\NullableType|null
|
||||
*/
|
||||
private function resolveTypeWithNullablePHPParserUnionType(PhpParserUnionType $phpParserUnionType)
|
||||
private function resolveUnionTypes(PhpParserUnionType $phpParserUnionType) : ?PhpParserUnionType
|
||||
{
|
||||
if (\count($phpParserUnionType->types) === 2) {
|
||||
$phpParserUnionType->types = \array_values($phpParserUnionType->types);
|
||||
$firstType = $phpParserUnionType->types[0];
|
||||
$secondType = $phpParserUnionType->types[1];
|
||||
if ($firstType instanceof Name && $firstType->toString() === 'null' && !$secondType instanceof PHPParserNodeIntersectionType) {
|
||||
return $this->resolveNullableType(new NullableType($secondType));
|
||||
}
|
||||
if ($secondType instanceof Name && $secondType->toString() === 'null' && !$firstType instanceof PHPParserNodeIntersectionType) {
|
||||
return $this->resolveNullableType(new NullableType($firstType));
|
||||
}
|
||||
}
|
||||
if (!$this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::UNION_TYPES)) {
|
||||
return null;
|
||||
}
|
||||
|
|
114
rules/CodingStyle/Rector/Property/NullifyUnionNullableRector.php
Normal file
114
rules/CodingStyle/Rector/Property/NullifyUnionNullableRector.php
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\CodingStyle\Rector\Property;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ArrowFunction;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\UnionType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\PHPStanStaticTypeMapper\TypeMapper\UnionTypeMapper;
|
||||
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\Tests\CodingStyle\Rector\Property\NullifyUnionNullableRector\NullifyUnionNullableRectorTest
|
||||
*/
|
||||
final class NullifyUnionNullableRector extends AbstractRector implements MinPhpVersionInterface
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\PHPStanStaticTypeMapper\TypeMapper\UnionTypeMapper
|
||||
*/
|
||||
private $unionTypeMapper;
|
||||
public function __construct(UnionTypeMapper $unionTypeMapper)
|
||||
{
|
||||
$this->unionTypeMapper = $unionTypeMapper;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Changes already typed Type|null to ?Type', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
|
||||
private null|stdClass $property;
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
|
||||
private ?stdClass $property;
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Property::class, Param::class, ClassMethod::class, Closure::class, Function_::class, ArrowFunction::class];
|
||||
}
|
||||
/**
|
||||
* @param Property|Param|ClassMethod|Closure|Function_|ArrowFunction $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
if ($node instanceof Property || $node instanceof Param) {
|
||||
return $this->processNullablePropertyParamType($node);
|
||||
}
|
||||
return $this->processNullableFunctionLikeReturnType($node);
|
||||
}
|
||||
public function provideMinPhpVersion() : int
|
||||
{
|
||||
return PhpVersionFeature::UNION_TYPES;
|
||||
}
|
||||
private function resolveNullableType(?Node $node) : ?NullableType
|
||||
{
|
||||
if (!$node instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
if (!$node instanceof UnionType) {
|
||||
return null;
|
||||
}
|
||||
$nullableType = $this->unionTypeMapper->resolveTypeWithNullablePHPParserUnionType($node);
|
||||
if (!$nullableType instanceof NullableType) {
|
||||
return null;
|
||||
}
|
||||
return $nullableType;
|
||||
}
|
||||
/**
|
||||
* @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node
|
||||
* @return null|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Param
|
||||
*/
|
||||
private function processNullablePropertyParamType($node)
|
||||
{
|
||||
$nullableType = $this->resolveNullableType($node->type);
|
||||
if (!$nullableType instanceof NullableType) {
|
||||
return null;
|
||||
}
|
||||
$node->type = $nullableType;
|
||||
return $node;
|
||||
}
|
||||
/**
|
||||
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\ArrowFunction $functionLike
|
||||
*/
|
||||
private function processNullableFunctionLikeReturnType($functionLike) : ?FunctionLike
|
||||
{
|
||||
$nullableType = $this->resolveNullableType($functionLike->returnType);
|
||||
if (!$nullableType instanceof NullableType) {
|
||||
return null;
|
||||
}
|
||||
$functionLike->returnType = $nullableType;
|
||||
return $functionLike;
|
||||
}
|
||||
}
|
|
@ -17,12 +17,12 @@ final class VersionResolver
|
|||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = 'b1fff57b7bdd56bff43211412483d6c33880533b';
|
||||
public const PACKAGE_VERSION = 'f13207737e25fef30190c1746a314b7e1dec6eb2';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2022-12-21 10:30:05';
|
||||
public const RELEASE_DATE = '2022-12-21 12:02:22';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
|
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
|||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInite6a2fa32a1cc64a3fef0c04459b73d39::getLoader();
|
||||
return ComposerAutoloaderInit857f6c6fc247aa34acd4c7e654127a54::getLoader();
|
||||
|
|
1
vendor/composer/autoload_classmap.php
vendored
1
vendor/composer/autoload_classmap.php
vendored
|
@ -1308,6 +1308,7 @@ return array(
|
|||
'Rector\\CodingStyle\\Rector\\PostInc\\PostIncDecToPreIncDecRector' => $baseDir . '/rules/CodingStyle/Rector/PostInc/PostIncDecToPreIncDecRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\AddFalseDefaultToBoolPropertyRector' => $baseDir . '/rules/CodingStyle/Rector/Property/AddFalseDefaultToBoolPropertyRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\InlineSimplePropertyAnnotationRector' => $baseDir . '/rules/CodingStyle/Rector/Property/InlineSimplePropertyAnnotationRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\NullifyUnionNullableRector' => $baseDir . '/rules/CodingStyle/Rector/Property/NullifyUnionNullableRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\SplitGroupedPropertiesRector' => $baseDir . '/rules/CodingStyle/Rector/Property/SplitGroupedPropertiesRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Stmt\\NewlineAfterStatementRector' => $baseDir . '/rules/CodingStyle/Rector/Stmt/NewlineAfterStatementRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\String_\\SymplifyQuoteEscapeRector' => $baseDir . '/rules/CodingStyle/Rector/String_/SymplifyQuoteEscapeRector.php',
|
||||
|
|
10
vendor/composer/autoload_real.php
vendored
10
vendor/composer/autoload_real.php
vendored
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInite6a2fa32a1cc64a3fef0c04459b73d39
|
||||
class ComposerAutoloaderInit857f6c6fc247aa34acd4c7e654127a54
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
|
@ -22,17 +22,17 @@ class ComposerAutoloaderInite6a2fa32a1cc64a3fef0c04459b73d39
|
|||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInite6a2fa32a1cc64a3fef0c04459b73d39', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit857f6c6fc247aa34acd4c7e654127a54', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInite6a2fa32a1cc64a3fef0c04459b73d39', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit857f6c6fc247aa34acd4c7e654127a54', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit857f6c6fc247aa34acd4c7e654127a54::getInitializer($loader));
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39::$files;
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit857f6c6fc247aa34acd4c7e654127a54::$files;
|
||||
$requireFile = static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
|
9
vendor/composer/autoload_static.php
vendored
9
vendor/composer/autoload_static.php
vendored
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39
|
||||
class ComposerStaticInit857f6c6fc247aa34acd4c7e654127a54
|
||||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
|
@ -1553,6 +1553,7 @@ class ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39
|
|||
'Rector\\CodingStyle\\Rector\\PostInc\\PostIncDecToPreIncDecRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/PostInc/PostIncDecToPreIncDecRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\AddFalseDefaultToBoolPropertyRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Property/AddFalseDefaultToBoolPropertyRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\InlineSimplePropertyAnnotationRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Property/InlineSimplePropertyAnnotationRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\NullifyUnionNullableRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Property/NullifyUnionNullableRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Property\\SplitGroupedPropertiesRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Property/SplitGroupedPropertiesRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\Stmt\\NewlineAfterStatementRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/Stmt/NewlineAfterStatementRector.php',
|
||||
'Rector\\CodingStyle\\Rector\\String_\\SymplifyQuoteEscapeRector' => __DIR__ . '/../..' . '/rules/CodingStyle/Rector/String_/SymplifyQuoteEscapeRector.php',
|
||||
|
@ -3059,9 +3060,9 @@ class ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39
|
|||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInite6a2fa32a1cc64a3fef0c04459b73d39::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit857f6c6fc247aa34acd4c7e654127a54::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit857f6c6fc247aa34acd4c7e654127a54::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit857f6c6fc247aa34acd4c7e654127a54::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user