From 4d9188bc7b23a3dda07f97c929aace1811e76e45 Mon Sep 17 00:00:00 2001 From: Peter Fox Date: Mon, 5 Feb 2024 18:07:07 +0000 Subject: [PATCH] [CodeQuality] Adds rules for the with and value helpers (#175) * Adds rules for the with and value helpers * cs fixes --- docs/rector_rules_overview.md | 28 ++++++++- .../RemoveRedundantValueCallsRector.php | 61 ++++++++++++++++++ .../RemoveRedundantWithCallsRector.php | 63 +++++++++++++++++++ .../Fixture/fixture.php.inc | 35 +++++++++++ ...ips_object_without_an_obvious_type.php.inc | 11 ++++ .../RemoveRedundantValueCallsRectorTest.php | 31 +++++++++ .../Source/HelperObject.php | 10 +++ .../config/configured_rule.php | 12 ++++ .../Fixture/fixture.php.inc | 35 +++++++++++ ...lls_with_callables_as_a_second_arg.php.inc | 9 +++ ...ips_object_without_an_obvious_type.php.inc | 12 ++++ .../RemoveRedundantWithCallsRectorTest.php | 31 +++++++++ .../Source/HelperObject.php | 10 +++ .../config/configured_rule.php | 12 ++++ 14 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 src/Rector/FuncCall/RemoveRedundantValueCallsRector.php create mode 100644 src/Rector/FuncCall/RemoveRedundantWithCallsRector.php create mode 100644 tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/fixture.php.inc create mode 100644 tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc create mode 100644 tests/Rector/FuncCall/RemoveRedundantValueCallsRector/RemoveRedundantValueCallsRectorTest.php create mode 100644 tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Source/HelperObject.php create mode 100644 tests/Rector/FuncCall/RemoveRedundantValueCallsRector/config/configured_rule.php create mode 100644 tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/fixture.php.inc create mode 100644 tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_calls_with_callables_as_a_second_arg.php.inc create mode 100644 tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc create mode 100644 tests/Rector/FuncCall/RemoveRedundantWithCallsRector/RemoveRedundantWithCallsRectorTest.php create mode 100644 tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Source/HelperObject.php create mode 100644 tests/Rector/FuncCall/RemoveRedundantWithCallsRector/config/configured_rule.php diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md index 121d2922..700cf986 100644 --- a/docs/rector_rules_overview.md +++ b/docs/rector_rules_overview.md @@ -1,4 +1,4 @@ -# 51 Rules Overview +# 53 Rules Overview ## AddArgumentDefaultValueRector @@ -907,6 +907,32 @@ Removes the `$model` property from Factories.
+## RemoveRedundantValueCallsRector + +Removes redundant value helper calls + +- class: [`RectorLaravel\Rector\FuncCall\RemoveRedundantValueCallsRector`](../src/Rector/FuncCall/RemoveRedundantValueCallsRector.php) + +```diff +-value(new Object())->something(); ++(new Object())->something(); +``` + +
+ +## RemoveRedundantWithCallsRector + +Removes redundant with helper calls + +- class: [`RectorLaravel\Rector\FuncCall\RemoveRedundantWithCallsRector`](../src/Rector/FuncCall/RemoveRedundantWithCallsRector.php) + +```diff +-with(new Object())->something(); ++(new Object())->something(); +``` + +
+ ## ReplaceAssertTimesSendWithAssertSentTimesRector Replace assertTimesSent with assertSentTimes diff --git a/src/Rector/FuncCall/RemoveRedundantValueCallsRector.php b/src/Rector/FuncCall/RemoveRedundantValueCallsRector.php new file mode 100644 index 00000000..6b82a806 --- /dev/null +++ b/src/Rector/FuncCall/RemoveRedundantValueCallsRector.php @@ -0,0 +1,61 @@ +something();', + '(new Object())->something();' + ), + ]); + } + + public function getNodeTypes(): array + { + return [FuncCall::class]; + } + + public function refactorWithScope(Node $node, Scope $scope): ?Node + { + if (! $node instanceof FuncCall) { + return null; + } + + if (! $node->name instanceof Name) { + return null; + } + + if (! $this->isName($node->name, 'value')) { + return null; + } + + $args = $node->getArgs(); + + if (count($args) !== 1) { + return null; + } + + if ($scope->getType($args[0]->value)->isSuperTypeOf(new ClosureType([], new MixedType, true))->no() === false) { + return null; + } + + return $args[0]->value; + } +} diff --git a/src/Rector/FuncCall/RemoveRedundantWithCallsRector.php b/src/Rector/FuncCall/RemoveRedundantWithCallsRector.php new file mode 100644 index 00000000..2e01e579 --- /dev/null +++ b/src/Rector/FuncCall/RemoveRedundantWithCallsRector.php @@ -0,0 +1,63 @@ +something();', + '(new Object())->something();' + ), + ]); + } + + public function getNodeTypes(): array + { + return [FuncCall::class]; + } + + public function refactorWithScope(Node $node, Scope $scope): ?Node + { + if (! $node instanceof FuncCall) { + return null; + } + + if (! $node->name instanceof Name) { + return null; + } + + if (! $this->isName($node->name, 'with')) { + return null; + } + + $args = $node->getArgs(); + + if (count($args) < 1 || count($args) > 2) { + return null; + } + + if (count($args) === 2) { + $secondArgumentType = $scope->getType($args[1]->value); + + if ($secondArgumentType->isCallable()->no() === false) { + return null; + } + } + + return $args[0]->value; + } +} diff --git a/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/fixture.php.inc b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..5de84ae3 --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/fixture.php.inc @@ -0,0 +1,35 @@ +store(); + +$foo = value(new HelperObject()); + +$user = 'a'; + +value($user)->store(); + +$foo = value($user); + +?> +----- +store(); + +$foo = new HelperObject(); + +$user = 'a'; + +$user->store(); + +$foo = $user; + +?> diff --git a/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc new file mode 100644 index 00000000..82591b85 --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc @@ -0,0 +1,11 @@ +store(); + +$foo = value(new UndefinedClass()); + +$user = new UndefinedClass(); + +value($user)->store(); diff --git a/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/RemoveRedundantValueCallsRectorTest.php b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/RemoveRedundantValueCallsRectorTest.php new file mode 100644 index 00000000..cd4a4651 --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/RemoveRedundantValueCallsRectorTest.php @@ -0,0 +1,31 @@ +doTestFile($filePath); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Source/HelperObject.php b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Source/HelperObject.php new file mode 100644 index 00000000..4a024c74 --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantValueCallsRector/Source/HelperObject.php @@ -0,0 +1,10 @@ +import(__DIR__ . '/../../../../../config/config.php'); + + $rectorConfig->rule(RemoveRedundantValueCallsRector::class); +}; diff --git a/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/fixture.php.inc b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..85adc52e --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/fixture.php.inc @@ -0,0 +1,35 @@ +store(); + +$foo = with(new HelperObject()); + +$user = 'a'; + +with($user)->store(); + +$foo = with($user); + +?> +----- +store(); + +$foo = new HelperObject(); + +$user = 'a'; + +$user->store(); + +$foo = $user; + +?> diff --git a/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_calls_with_callables_as_a_second_arg.php.inc b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_calls_with_callables_as_a_second_arg.php.inc new file mode 100644 index 00000000..f9669e98 --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_calls_with_callables_as_a_second_arg.php.inc @@ -0,0 +1,9 @@ +store(); diff --git a/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc new file mode 100644 index 00000000..02d68a1f --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Fixture/skips_object_without_an_obvious_type.php.inc @@ -0,0 +1,12 @@ +store(); + +$foo = with(new UndefinedClass(), new AnotherUndefinedType()); + +$user = new UndefinedClass(); +$bar = new AnotherUndefinedType(); + +with($user, $bar)->store(); diff --git a/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/RemoveRedundantWithCallsRectorTest.php b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/RemoveRedundantWithCallsRectorTest.php new file mode 100644 index 00000000..ae184dcb --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/RemoveRedundantWithCallsRectorTest.php @@ -0,0 +1,31 @@ +doTestFile($filePath); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Source/HelperObject.php b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Source/HelperObject.php new file mode 100644 index 00000000..7f121aed --- /dev/null +++ b/tests/Rector/FuncCall/RemoveRedundantWithCallsRector/Source/HelperObject.php @@ -0,0 +1,10 @@ +import(__DIR__ . '/../../../../../config/config.php'); + + $rectorConfig->rule(RemoveRedundantWithCallsRector::class); +};