From 85bf63bf2772aa24a40ef8e0f72da359e6e39bdc Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Fri, 31 Dec 2021 12:33:45 +0100 Subject: [PATCH] [Downgrade PHP 7.0] Move Throwable out of type hints It is only available on PHP 7.0+: https://www.php.net/manual/en/class.throwable.php --- config/set/downgrade-php70.php | 2 + .../PhpDocFromTypeDeclarationDecorator.php | 3 + ...radeThrowableTypeDeclarationRectorTest.php | 34 ++++++++ .../arrow_function_param_throwable.php.inc | 27 ++++++ .../arrow_function_return_throwable.php.inc | 27 ++++++ .../Fixture/docblock_exists.php.inc | 30 +++++++ .../Fixture/docblock_tag_exists.php.inc | 31 +++++++ .../Fixture/fixture.php.inc | 28 ++++++ .../Fixture/multiple_matching_params.php.inc | 29 +++++++ .../Fixture/multiple_params.php.inc | 28 ++++++ .../Fixture/nullable.php.inc | 29 +++++++ .../Fixture/on_closure.php.inc | 37 ++++++++ .../Fixture/return_docblock_exists.php.inc | 32 +++++++ .../return_docblock_tag_exists.php.inc | 33 +++++++ .../Fixture/return_fixture.php.inc | 30 +++++++ .../config/configured_rule.php | 11 +++ ...owngradeThrowableTypeDeclarationRector.php | 87 +++++++++++++++++++ 17 files changed, 498 insertions(+) create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/DowngradeThrowableTypeDeclarationRectorTest.php create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_param_throwable.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_return_throwable.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_exists.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_tag_exists.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/fixture.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_matching_params.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_params.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/nullable.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/on_closure.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_exists.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_tag_exists.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_fixture.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/config/configured_rule.php create mode 100644 rules/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector.php diff --git a/config/set/downgrade-php70.php b/config/set/downgrade-php70.php index 8aa97d7e178..0763d6ffde1 100644 --- a/config/set/downgrade-php70.php +++ b/config/set/downgrade-php70.php @@ -12,6 +12,7 @@ use Rector\DowngradePhp70\Rector\FuncCall\DowngradeDirnameLevelsRector; use Rector\DowngradePhp70\Rector\FuncCall\DowngradeSessionStartArrayOptionsRector; use Rector\DowngradePhp70\Rector\FunctionLike\DowngradeScalarTypeDeclarationRector; +use Rector\DowngradePhp70\Rector\FunctionLike\DowngradeThrowableTypeDeclarationRector; use Rector\DowngradePhp70\Rector\GroupUse\SplitGroupedUseImportsRector; use Rector\DowngradePhp70\Rector\MethodCall\DowngradeClosureCallRector; use Rector\DowngradePhp70\Rector\MethodCall\DowngradeMethodCallOnCloneRector; @@ -26,6 +27,7 @@ $services = $containerConfigurator->services(); $services->set(DowngradeScalarTypeDeclarationRector::class); + $services->set(DowngradeThrowableTypeDeclarationRector::class); $services->set(DowngradeStrictTypeDeclarationRector::class); $services->set(DowngradeSelfTypeDeclarationRector::class); $services->set(DowngradeAnonymousClassRector::class); diff --git a/packages/BetterPhpDocParser/PhpDocParser/PhpDocFromTypeDeclarationDecorator.php b/packages/BetterPhpDocParser/PhpDocParser/PhpDocFromTypeDeclarationDecorator.php index 0728dd3eae1..6ab54261803 100644 --- a/packages/BetterPhpDocParser/PhpDocParser/PhpDocFromTypeDeclarationDecorator.php +++ b/packages/BetterPhpDocParser/PhpDocParser/PhpDocFromTypeDeclarationDecorator.php @@ -182,6 +182,9 @@ private function isTypeMatch(ComplexType|Identifier|Name $typeNode, Type $requir if ($returnType instanceof UnionType) { $returnType = $this->typeUnwrapper->unwrapNullableType($returnType); } + if ($returnType instanceof ObjectType) { + return $returnType->equals($requireType); + } return $returnType::class === $requireType::class; } diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/DowngradeThrowableTypeDeclarationRectorTest.php b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/DowngradeThrowableTypeDeclarationRectorTest.php new file mode 100644 index 00000000000..7c346229fcd --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/DowngradeThrowableTypeDeclarationRectorTest.php @@ -0,0 +1,34 @@ +doTestFileInfo($fileInfo); + } + + /** + * @return Iterator + */ + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_param_throwable.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_param_throwable.php.inc new file mode 100644 index 00000000000..977bd3a44af --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_param_throwable.php.inc @@ -0,0 +1,27 @@ + true; + } +} + +?> +----- + true; + } +} + +?> diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_return_throwable.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_return_throwable.php.inc new file mode 100644 index 00000000000..d10af155467 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/arrow_function_return_throwable.php.inc @@ -0,0 +1,27 @@ + new \Exception('Yikes!'); + } +} + +?> +----- + new \Exception('Yikes!'); + } +} + +?> diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_exists.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_exists.php.inc new file mode 100644 index 00000000000..b0df69b2604 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_exists.php.inc @@ -0,0 +1,30 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_tag_exists.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_tag_exists.php.inc new file mode 100644 index 00000000000..dcbe8d454ea --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/docblock_tag_exists.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/fixture.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/fixture.php.inc new file mode 100644 index 00000000000..ca04c1455e8 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/fixture.php.inc @@ -0,0 +1,28 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_matching_params.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_matching_params.php.inc new file mode 100644 index 00000000000..ca6a8caf408 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_matching_params.php.inc @@ -0,0 +1,29 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_params.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_params.php.inc new file mode 100644 index 00000000000..b1892b69c26 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/multiple_params.php.inc @@ -0,0 +1,28 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/nullable.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/nullable.php.inc new file mode 100644 index 00000000000..5361b7966a7 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/nullable.php.inc @@ -0,0 +1,29 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/on_closure.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/on_closure.php.inc new file mode 100644 index 00000000000..f07e0fc976f --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/on_closure.php.inc @@ -0,0 +1,37 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_exists.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_exists.php.inc new file mode 100644 index 00000000000..d54002e2457 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_exists.php.inc @@ -0,0 +1,32 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_tag_exists.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_tag_exists.php.inc new file mode 100644 index 00000000000..f19f8db1288 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_docblock_tag_exists.php.inc @@ -0,0 +1,33 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_fixture.php.inc b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_fixture.php.inc new file mode 100644 index 00000000000..83a51c1e5d2 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/Fixture/return_fixture.php.inc @@ -0,0 +1,30 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/config/configured_rule.php b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/config/configured_rule.php new file mode 100644 index 00000000000..97b3725e0eb --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector/config/configured_rule.php @@ -0,0 +1,11 @@ +services(); + $services->set(DowngradeThrowableTypeDeclarationRector::class); +}; diff --git a/rules/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector.php b/rules/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector.php new file mode 100644 index 00000000000..be0d56cfb13 --- /dev/null +++ b/rules/DowngradePhp70/Rector/FunctionLike/DowngradeThrowableTypeDeclarationRector.php @@ -0,0 +1,87 @@ +> + */ + public function getNodeTypes(): array + { + return [Function_::class, ClassMethod::class, Closure::class, ArrowFunction::class]; + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Replace `Throwable` type hints by PHPDoc tags', + [ + new CodeSample( + <<<'CODE_SAMPLE' +class SomeClass +{ + public function foo(\Throwable $e): ?\Throwable + { + return new \Exception("Troubles"); + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +class SomeClass +{ + /** + * @param \Throwable $e + * @return \Throwable|null + */ + public function foo($e) + { + return new \Exception("Troubles"); + } +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @param ClassMethod|Function_ $node + */ + public function refactor(Node $node): ?Node + { + $throwableType = new ObjectType('Throwable'); + + foreach ($node->getParams() as $param) { + $this->phpDocFromTypeDeclarationDecorator->decorateParamWithSpecificType($param, $node, $throwableType); + } + + if (! $this->phpDocFromTypeDeclarationDecorator->decorateReturnWithSpecificType($node, $throwableType)) { + return null; + } + + return $node; + } +}