From 33a41ddb4a8f153e9cbc1980b69c9fcb73aac9c0 Mon Sep 17 00:00:00 2001 From: Jonas Elfering Date: Thu, 10 Oct 2019 15:34:56 +0200 Subject: [PATCH] Add ConsoleExecuteReturnIntRector Fixes: https://github.com/rectorphp/rector/issues/2119 --- config/set/symfony/symfony44.yaml | 5 + .../Console/ConsoleExecuteReturnIntRector.php | 125 ++++++++++++++++++ .../ConsoleExecuteReturnIntRectorTest.php | 33 +++++ .../Fixture/add-return-type.php.inc | 35 +++++ .../Fixture/empty-return.php.inc | 35 +++++ .../Fixture/explicit-return-null.php.inc | 37 ++++++ .../Fixture/multiple-returns.php.inc | 48 +++++++ .../Fixture/no-return.php.inc | 36 +++++ .../Fixture/return-function-call.php.inc | 45 +++++++ 9 files changed, 399 insertions(+) create mode 100644 config/set/symfony/symfony44.yaml create mode 100644 packages/Symfony/src/Rector/Console/ConsoleExecuteReturnIntRector.php create mode 100644 packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/ConsoleExecuteReturnIntRectorTest.php create mode 100644 packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/add-return-type.php.inc create mode 100644 packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/empty-return.php.inc create mode 100644 packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/explicit-return-null.php.inc create mode 100644 packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/multiple-returns.php.inc create mode 100644 packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/no-return.php.inc create mode 100644 packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/return-function-call.php.inc diff --git a/config/set/symfony/symfony44.yaml b/config/set/symfony/symfony44.yaml new file mode 100644 index 00000000000..f4ecbb44eca --- /dev/null +++ b/config/set/symfony/symfony44.yaml @@ -0,0 +1,5 @@ +services: + # https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.4.md + + # https://github.com/symfony/symfony/pull/33775 + Rector\Symfony\Rector\Console\ConsoleExecuteReturnIntRector: ~ diff --git a/packages/Symfony/src/Rector/Console/ConsoleExecuteReturnIntRector.php b/packages/Symfony/src/Rector/Console/ConsoleExecuteReturnIntRector.php new file mode 100644 index 00000000000..479eb58f92e --- /dev/null +++ b/packages/Symfony/src/Rector/Console/ConsoleExecuteReturnIntRector.php @@ -0,0 +1,125 @@ +getName($node) !== 'execute') { + return null; + } + + $class = $node->getAttribute(AttributeKey::CLASS_NODE); + if (! $class || ! $class instanceof Class_) { + return null; + } + + if (!$class->extends || $class->extends->toCodeString() !== self::COMMAND_CLASS) { + return null; + } + + $node->returnType = new Identifier('int'); + + return $this->addReturn0ToMethod($node); + } + + private function setReturnTo0InsteadOfNull(Return_ $return) + { + if (! $return->expr ) { + $return->expr = new LNumber(0); + } + + if ($return->expr instanceof ConstFetch && $this->getName($return->expr) === 'null') { + $return->expr = new LNumber(0); + } + + if ($return->expr instanceof MethodCall || $return->expr instanceof StaticCall) { + // how to get the Node of teh called method?! + } + } + + private function addReturn0ToMethod(FunctionLike $node): FunctionLike + { + $hasReturn = false; + $this->traverseNodesWithCallable($node->getStmts(), function (Node &$stmt) use ($node, &$hasReturn) { + if (!$stmt instanceof Return_) { + return; + } + + if ($this->areNodesEqual($stmt->getAttribute(AttributeKey::PARENT_NODE), $node)) { + $hasReturn = true; + } + + $this->setReturnTo0InsteadOfNull($stmt); + }); + + if ($hasReturn) { + return $node; + } + + $node->stmts[] = new Return_(new LNumber(0)); + + return $node; + } +} diff --git a/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/ConsoleExecuteReturnIntRectorTest.php b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/ConsoleExecuteReturnIntRectorTest.php new file mode 100644 index 00000000000..ec860dd29c3 --- /dev/null +++ b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/ConsoleExecuteReturnIntRectorTest.php @@ -0,0 +1,33 @@ +doTestFile($file); + } + + public function provideDataForTest(): Iterator + { + yield [__DIR__ . '/Fixture/explicit-return-null.php.inc']; + yield [__DIR__ . '/Fixture/no-return.php.inc']; + yield [__DIR__ . '/Fixture/empty-return.php.inc']; + yield [__DIR__ . '/Fixture/multiple-returns.php.inc']; + yield [__DIR__ . '/Fixture/add-return-type.php.inc']; + yield [__DIR__ . '/Fixture/return-function-call.php.inc']; + } + + protected function getRectorClass(): string + { + return ConsoleExecuteReturnIntRector::class; + } +} diff --git a/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/add-return-type.php.inc b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/add-return-type.php.inc new file mode 100644 index 00000000000..90e680d407e --- /dev/null +++ b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/add-return-type.php.inc @@ -0,0 +1,35 @@ + +----- + diff --git a/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/empty-return.php.inc b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/empty-return.php.inc new file mode 100644 index 00000000000..f423b0f912d --- /dev/null +++ b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/empty-return.php.inc @@ -0,0 +1,35 @@ + +----- + diff --git a/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/explicit-return-null.php.inc b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/explicit-return-null.php.inc new file mode 100644 index 00000000000..ff4bd0044e4 --- /dev/null +++ b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/explicit-return-null.php.inc @@ -0,0 +1,37 @@ + +----- + diff --git a/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/multiple-returns.php.inc b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/multiple-returns.php.inc new file mode 100644 index 00000000000..769b854605e --- /dev/null +++ b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/multiple-returns.php.inc @@ -0,0 +1,48 @@ + +----- + diff --git a/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/no-return.php.inc b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/no-return.php.inc new file mode 100644 index 00000000000..7716fd04696 --- /dev/null +++ b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/no-return.php.inc @@ -0,0 +1,36 @@ +doSomething(); + } +} + +?> +----- +doSomething(); + return 0; + } +} + +?> diff --git a/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/return-function-call.php.inc b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/return-function-call.php.inc new file mode 100644 index 00000000000..8d8b7086d51 --- /dev/null +++ b/packages/Symfony/tests/Rector/Console/ConsoleExecuteReturnIntRector/Fixture/return-function-call.php.inc @@ -0,0 +1,45 @@ +doSomething(); + } + + private function doSomething() + { + return null; + } +} + +?> +----- +doSomething(); + } + + private function doSomething() + { + return 0; + } +} + +?>