From 16510f00e22efd9cef9f55671714102c46db5cd5 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 23 Oct 2018 17:13:13 -0300 Subject: [PATCH] [CodeQuality] Create SimplifyEmptyArrayCheckRector --- docs/AllRectorsOverview.md | 11 +++ .../SimplifyEmptyArrayCheckRector.php | 88 +++++++++++++++++++ .../Correct/correct.php.inc | 34 +++++++ .../Correct/correct2.php.inc | 6 ++ .../SimplifyEmptyArrayCheckRectorTest.php | 31 +++++++ .../Wrong/wrong.php.inc | 34 +++++++ .../Wrong/wrong2.php.inc | 6 ++ .../SimplifyEmptyArrayCheckRector/config.yml | 2 + 8 files changed, 212 insertions(+) create mode 100644 packages/CodeQuality/src/Rector/FuncCall/SimplifyEmptyArrayCheckRector.php create mode 100644 packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct.php.inc create mode 100644 packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct2.php.inc create mode 100644 packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/SimplifyEmptyArrayCheckRectorTest.php create mode 100644 packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong.php.inc create mode 100644 packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong2.php.inc create mode 100644 packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/config.yml diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md index d1ce451154d..2e559e9b256 100644 --- a/docs/AllRectorsOverview.md +++ b/docs/AllRectorsOverview.md @@ -146,6 +146,17 @@ Simplify `in_array` and `array_keys` functions combination into `array_key_exist +array_key_exists("key", $array); ``` +### `SimplifyEmptyArrayCheckRector` + +- class: `Rector\CodeQuality\Rector\FuncCall\SimplifyEmptyArrayCheckRector` + +Simplify `is_array` and `empty` functions combination into a simple identical check for an empty array + +```diff +-is_array($values) && empty($values) ++$values === [] +``` + ### `SimplifyStrposLowerRector` - class: `Rector\CodeQuality\Rector\FuncCall\SimplifyStrposLowerRector` diff --git a/packages/CodeQuality/src/Rector/FuncCall/SimplifyEmptyArrayCheckRector.php b/packages/CodeQuality/src/Rector/FuncCall/SimplifyEmptyArrayCheckRector.php new file mode 100644 index 00000000000..49869a3770e --- /dev/null +++ b/packages/CodeQuality/src/Rector/FuncCall/SimplifyEmptyArrayCheckRector.php @@ -0,0 +1,88 @@ +left; + $rightValue = $booleanAndNode->right; + if (! $this->isPreferableCheck($leftValue, $rightValue)) { + return null; + } + + if (! $rightValue instanceof BooleanNot && ! $leftValue instanceof BooleanNot) { + /** @var FuncCall $variable */ + $variable = $leftValue instanceof Empty_ ? $leftValue->expr : $rightValue->expr; + + return new Identical($variable, new Array_()); + } + + $booleanNotExpr = $rightValue instanceof BooleanNot ? $rightValue->expr : $leftValue->expr; + if (! $this->isName($booleanNotExpr, 'is_array') && ! $booleanNotExpr instanceof Empty_) { + return null; + } + + $variable = $booleanNotExpr->expr ?? $booleanNotExpr; + + return new NotIdentical($variable, new Array_()); + } + + /** + * @param mixed $node + */ + public function isNoneOfPreferableNodes($node): bool + { + return ! $this->isName($node, 'is_array') && ! $node instanceof Empty_ && ! $node instanceof BooleanNot; + } + + /** + * @param mixed $leftValue + * @param mixed $rightValue + */ + private function isPreferableCheck($leftValue, $rightValue): bool + { + if ($this->isNoneOfPreferableNodes($leftValue) || $this->isNoneOfPreferableNodes($rightValue)) { + return false; + } + + // special case + if ($leftValue instanceof BooleanNot && $rightValue instanceof BooleanNot) { + return false; + } + + return true; + } +} diff --git a/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct.php.inc b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct.php.inc new file mode 100644 index 00000000000..2d82a42592c --- /dev/null +++ b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct.php.inc @@ -0,0 +1,34 @@ +foo) && ! is_array($values->bar); + } + + public function functionCallInsideEmpty($values): bool + { + return array_filter($values) === []; + } +} diff --git a/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct2.php.inc b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct2.php.inc new file mode 100644 index 00000000000..73c07ced0b7 --- /dev/null +++ b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Correct/correct2.php.inc @@ -0,0 +1,6 @@ + 0; +$invalid2 = isset($this->events[$event]) && ! empty($this->events[$event]); +$completelyInvalid = ! $value instanceof Foo && ! $value instanceof Bar; diff --git a/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/SimplifyEmptyArrayCheckRectorTest.php b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/SimplifyEmptyArrayCheckRectorTest.php new file mode 100644 index 00000000000..ff53d8a4ef1 --- /dev/null +++ b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/SimplifyEmptyArrayCheckRectorTest.php @@ -0,0 +1,31 @@ +doTestFileMatchesExpectedContent($wrong, $fixed); + } + + public function provideWrongToFixedFiles(): Iterator + { + yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc']; + yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc']; + } + + protected function provideConfig(): string + { + return __DIR__ . '/config.yml'; + } +} diff --git a/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong.php.inc b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong.php.inc new file mode 100644 index 00000000000..18cbf5af161 --- /dev/null +++ b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong.php.inc @@ -0,0 +1,34 @@ +foo) && ! is_array($values->bar); + } + + public function functionCallInsideEmpty($values): bool + { + return is_array($values) && empty(array_filter($values)); + } +} diff --git a/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong2.php.inc b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong2.php.inc new file mode 100644 index 00000000000..73c07ced0b7 --- /dev/null +++ b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/Wrong/wrong2.php.inc @@ -0,0 +1,6 @@ + 0; +$invalid2 = isset($this->events[$event]) && ! empty($this->events[$event]); +$completelyInvalid = ! $value instanceof Foo && ! $value instanceof Bar; diff --git a/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/config.yml b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/config.yml new file mode 100644 index 00000000000..d08b166ad79 --- /dev/null +++ b/packages/CodeQuality/tests/Rector/FuncCall/SimplifyEmptyArrayCheckRector/config.yml @@ -0,0 +1,2 @@ +services: + Rector\CodeQuality\Rector\FuncCall\SimplifyEmptyArrayCheckRector: ~