Downgrade PHP7.1 features: nullable types and void return type (#4192)

This commit is contained in:
Leonardo Losoviz 2020-09-12 17:50:13 +08:00 committed by GitHub
parent 61da1015b0
commit abb9a3ef90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 539 additions and 11 deletions

View File

@ -149,6 +149,7 @@
"Rector\\NetteKdyby\\": "rules/nette-kdyby/src",
"Rector\\NetteUtilsCodeQuality\\": "rules/nette-utils-code-quality/src",
"Rector\\NetteCodeQuality\\": "rules/nette-code-quality/src",
"Rector\\DowngradePhp71\\": "rules/downgrade-php71/src",
"Rector\\DowngradePhp72\\": "rules/downgrade-php72/src",
"Rector\\DowngradePhp74\\": "rules/downgrade-php74/src",
"Rector\\DowngradePhp80\\": "rules/downgrade-php80/src",
@ -234,6 +235,7 @@
"Rector\\NetteKdyby\\Tests\\": "rules/nette-kdyby/tests",
"Rector\\NetteUtilsCodeQuality\\Tests\\": "rules/nette-utils-code-quality/tests",
"Rector\\NetteCodeQuality\\Tests\\": "rules/nette-code-quality/tests",
"Rector\\DowngradePhp71\\Tests\\": "rules/downgrade-php71/tests",
"Rector\\DowngradePhp72\\Tests\\": "rules/downgrade-php72/tests",
"Rector\\DowngradePhp74\\Tests\\": "rules/downgrade-php74/tests",
"Rector\\DowngradePhp80\\Tests\\": "rules/downgrade-php80/tests",

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
use Rector\DowngradePhp71\Rector\FunctionLike\DowngradeNullableTypeParamDeclarationRector;
use Rector\DowngradePhp71\Rector\FunctionLike\DowngradeNullableTypeReturnDeclarationRector;
use Rector\DowngradePhp71\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DowngradeNullableTypeParamDeclarationRector::class);
$services->set(DowngradeNullableTypeReturnDeclarationRector::class);
$services->set(DowngradeVoidTypeReturnDeclarationRector::class);
};

View File

@ -171,6 +171,11 @@ final class SetList
*/
public const DOCTRINE_SERVICES = __DIR__ . '/../../../../config/set/doctrine-services.php';
/**
* @var string
*/
public const DOWNGRADE_PHP71 = __DIR__ . '/../../../../config/set/downgrade-php71.php';
/**
* @var string
*/

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\DowngradePhp72\Contract\Rector;
namespace Rector\DowngradePhp71\Contract\Rector;
use PhpParser\Node\Param;

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\DowngradePhp72\Contract\Rector;
namespace Rector\DowngradePhp71\Contract\Rector;
use PhpParser\Node\FunctionLike;

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\DowngradePhp72\Rector\FunctionLike;
namespace Rector\DowngradePhp71\Rector\FunctionLike;
use PhpParser\Node;
use PhpParser\Node\FunctionLike;
@ -10,7 +10,7 @@ use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\DowngradePhp72\Contract\Rector\DowngradeParamDeclarationRectorInterface;
use Rector\DowngradePhp71\Contract\Rector\DowngradeParamDeclarationRectorInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
abstract class AbstractDowngradeParamDeclarationRector extends AbstractDowngradeRector implements DowngradeParamDeclarationRectorInterface

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\DowngradePhp72\Rector\FunctionLike;
namespace Rector\DowngradePhp71\Rector\FunctionLike;
abstract class AbstractDowngradeRector extends AbstractMaybeAddDocBlockRector
{

View File

@ -2,13 +2,13 @@
declare(strict_types=1);
namespace Rector\DowngradePhp72\Rector\FunctionLike;
namespace Rector\DowngradePhp71\Rector\FunctionLike;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\DowngradePhp72\Contract\Rector\DowngradeReturnDeclarationRectorInterface;
use Rector\DowngradePhp71\Contract\Rector\DowngradeReturnDeclarationRectorInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
abstract class AbstractDowngradeReturnDeclarationRector extends AbstractDowngradeRector implements DowngradeReturnDeclarationRectorInterface

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\DowngradePhp72\Rector\FunctionLike;
namespace Rector\DowngradePhp71\Rector\FunctionLike;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;

View File

@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
namespace Rector\DowngradePhp71\Rector\FunctionLike;
use PhpParser\Node\NullableType;
use PhpParser\Node\Param;
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
/**
* @see \Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeParamDeclarationRector\DowngradeNullableTypeParamDeclarationRectorTest
*/
final class DowngradeNullableTypeParamDeclarationRector extends AbstractDowngradeParamDeclarationRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
'Remove the nullable type params, add @param tags instead',
[
new ConfiguredCodeSample(
<<<'PHP'
<?php
class SomeClass
{
public function run(?string $input)
{
// do something
}
}
PHP
,
<<<'PHP'
<?php
class SomeClass
{
/**
* @param string|null $input
*/
public function run($input)
{
// do something
}
}
PHP
,
[
self::ADD_DOC_BLOCK => true,
]
),
]
);
}
public function shouldRemoveParamDeclaration(Param $param): bool
{
if ($param->variadic) {
return false;
}
if ($param->type === null) {
return false;
}
// Check it is the union type
return $param->type instanceof NullableType;
}
}

View File

@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace Rector\DowngradePhp71\Rector\FunctionLike;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
/**
* @see \Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeReturnDeclarationRector\DowngradeNullableTypeReturnDeclarationRectorTest
*/
final class DowngradeNullableTypeReturnDeclarationRector extends AbstractDowngradeReturnDeclarationRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
'Remove returning nullable types, add a @return tag instead',
[
new ConfiguredCodeSample(
<<<'PHP'
<?php
class SomeClass
{
public function getResponseOrNothing(bool $flag): ?string
{
if ($flag) {
return 'Hello world';
}
return null;
}
}
PHP
,
<<<'PHP'
<?php
class SomeClass
{
/**
* @return string|null
*/
public function getResponseOrNothing(bool $flag)
{
if ($flag) {
return 'Hello world';
}
return null;
}
}
PHP
,
[
self::ADD_DOC_BLOCK => true,
]
),
]
);
}
/**
* @param ClassMethod|Function_ $functionLike
*/
public function shouldRemoveReturnDeclaration(FunctionLike $functionLike): bool
{
if ($functionLike->returnType === null) {
return false;
}
// Check it is the union type
return $functionLike->returnType instanceof NullableType;
}
}

View File

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Rector\DowngradePhp71\Rector\FunctionLike;
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\DowngradePhp72\Rector\FunctionLike\AbstractDowngradeReturnTypeDeclarationRector;
/**
* @see \Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector\DowngradeVoidTypeReturnDeclarationRectorTest
*/
final class DowngradeVoidTypeReturnDeclarationRector extends AbstractDowngradeReturnTypeDeclarationRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
$this->getRectorDefinitionDescription(),
[
new ConfiguredCodeSample(
<<<'PHP'
<?php
class SomeClass
{
public function run(): void
{
// do something
}
}
PHP
,
<<<'PHP'
<?php
class SomeClass
{
/**
* @return void
*/
public function run()
{
// do something
}
}
PHP
,
[
self::ADD_DOC_BLOCK => true,
]
),
]
);
}
public function getTypeNameToRemove(): string
{
return 'void';
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeParamDeclarationRector;
use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\DowngradePhp71\Rector\FunctionLike\DowngradeNullableTypeParamDeclarationRector;
use Symplify\SmartFileSystem\SmartFileInfo;
final class DowngradeNullableTypeParamDeclarationRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
protected function getRectorClass(): string
{
return DowngradeNullableTypeParamDeclarationRector::class;
}
protected function getPhpVersion(): string
{
return PhpVersionFeature::BEFORE_NULLABLE_TYPE;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeParamDeclarationRector\Fixture;
class FunctionParam
{
public function run(?string $value)
{
}
}
?>
-----
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeParamDeclarationRector\Fixture;
class FunctionParam
{
/**
* @param string|null $value
*/
public function run($value)
{
}
}
?>

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeReturnDeclarationRector;
use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\DowngradePhp71\Rector\FunctionLike\DowngradeNullableTypeReturnDeclarationRector;
use Symplify\SmartFileSystem\SmartFileInfo;
final class DowngradeNullableTypeReturnDeclarationRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
protected function getRectorClass(): string
{
return DowngradeNullableTypeReturnDeclarationRector::class;
}
protected function getPhpVersion(): string
{
return PhpVersionFeature::BEFORE_NULLABLE_TYPE;
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeReturnDeclarationRector\Fixture;
class ClassMethod
{
public function run(): ?string
{
if (mt_rand()) {
return null;
}
return 'value';
}
}
?>
-----
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeNullableTypeReturnDeclarationRector\Fixture;
class ClassMethod
{
/**
* @return string|null
*/
public function run()
{
if (mt_rand()) {
return null;
}
return 'value';
}
}
?>

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector;
use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\DowngradePhp71\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector;
use Symplify\SmartFileSystem\SmartFileInfo;
final class DowngradeVoidTypeReturnDeclarationRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
/**
* @return array<string, mixed[]>
*/
protected function getRectorsWithConfiguration(): array
{
return [
DowngradeVoidTypeReturnDeclarationRector::class => [
DowngradeVoidTypeReturnDeclarationRector::ADD_DOC_BLOCK => true,
],
];
}
protected function getRectorClass(): string
{
return DowngradeVoidTypeReturnDeclarationRector::class;
}
protected function getPhpVersion(): string
{
return PhpVersionFeature::BEFORE_VOID_RETURN_TYPE;
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector\Fixture;
class DocBlockExists {
/**
* This property is the best one
*/
public function run(): void
{
// do something
}
}
?>
-----
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector\Fixture;
class DocBlockExists {
/**
* This property is the best one
* @return void
*/
public function run()
{
// do something
}
}
?>

View File

@ -0,0 +1,33 @@
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector\Fixture;
class DocBlockTagExists {
/**
* This property is the best one
* @return void
*/
public function run(): void
{
// do something
}
}
?>
-----
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector\Fixture;
class DocBlockTagExists {
/**
* This property is the best one
* @return void
*/
public function run()
{
// do something
}
}
?>

View File

@ -0,0 +1,30 @@
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector\Fixture;
class SomeClass
{
public function run(): void
{
// do something
}
}
?>
-----
<?php
namespace Rector\DowngradePhp71\Tests\Rector\FunctionLike\DowngradeVoidTypeReturnDeclarationRector\Fixture;
class SomeClass
{
/**
* @return void
*/
public function run()
{
// do something
}
}
?>

View File

@ -7,6 +7,7 @@ namespace Rector\DowngradePhp72\Rector\FunctionLike;
use PhpParser\Node\Identifier;
use PhpParser\Node\NullableType;
use PhpParser\Node\Param;
use Rector\DowngradePhp71\Rector\FunctionLike\AbstractDowngradeParamDeclarationRector;
use Rector\DowngradePhp72\Contract\Rector\DowngradeTypeRectorInterface;
abstract class AbstractDowngradeParamTypeDeclarationRector extends AbstractDowngradeParamDeclarationRector implements DowngradeTypeRectorInterface

View File

@ -8,6 +8,7 @@ use PhpParser\Node\FunctionLike;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use Rector\DowngradePhp71\Rector\FunctionLike\AbstractDowngradeReturnDeclarationRector;
use Rector\DowngradePhp72\Contract\Rector\DowngradeTypeRectorInterface;
abstract class AbstractDowngradeReturnTypeDeclarationRector extends AbstractDowngradeReturnDeclarationRector implements DowngradeTypeRectorInterface

View File

@ -7,7 +7,7 @@ namespace Rector\DowngradePhp74\Rector\Property;
use PhpParser\Node;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\DowngradePhp72\Rector\FunctionLike\AbstractDowngradeRector;
use Rector\DowngradePhp71\Rector\FunctionLike\AbstractDowngradeRector;
use Rector\DowngradePhp74\Contract\Rector\DowngradeTypedPropertyRectorInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;

View File

@ -8,7 +8,7 @@ use PhpParser\Node\Param;
use PhpParser\Node\UnionType;
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\DowngradePhp72\Rector\FunctionLike\AbstractDowngradeParamDeclarationRector;
use Rector\DowngradePhp71\Rector\FunctionLike\AbstractDowngradeParamDeclarationRector;
/**
* @see \Rector\DowngradePhp80\Tests\Rector\FunctionLike\DowngradeUnionTypeParamDeclarationRector\DowngradeUnionTypeParamDeclarationRectorTest

View File

@ -10,7 +10,7 @@ use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\UnionType;
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\DowngradePhp72\Rector\FunctionLike\AbstractDowngradeReturnDeclarationRector;
use Rector\DowngradePhp71\Rector\FunctionLike\AbstractDowngradeReturnDeclarationRector;
/**
* @see \Rector\DowngradePhp80\Tests\Rector\FunctionLike\DowngradeUnionTypeReturnDeclarationRector\DowngradeUnionTypeReturnDeclarationRectorTest

View File

@ -161,6 +161,16 @@ final class PhpVersionFeature
*/
public const BEFORE_OBJECT_TYPE = '7.1';
/**
* @var string
*/
public const BEFORE_VOID_RETURN_TYPE = '7.0';
/**
* @var string
*/
public const BEFORE_NULLABLE_TYPE = '7.0';
/**
* @see https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
* @var string