From 65c84a14220df652c5616016b9a6b8deb76541e4 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 28 Feb 2026 23:29:21 +0700 Subject: [PATCH 1/5] [CodingStyle] Add StrictInArrayRector --- .../Fixture/both_integers.php.inc | 25 +++++ .../Fixture/both_strings.php.inc | 25 +++++ .../Fixture/skip_different_types.php.inc | 12 +++ .../Fixture/skip_docblock_array.php.inc | 14 +++ .../StrictInArrayRectorTest.php | 28 ++++++ .../config/configured_rule.php | 9 ++ .../Rector/FuncCall/StrictInArrayRector.php | 94 +++++++++++++++++++ src/Config/Level/CodingStyleLevel.php | 2 + 8 files changed, 209 insertions(+) create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_integers.php.inc create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_strings.php.inc create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_different_types.php.inc create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_docblock_array.php.inc create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/StrictInArrayRectorTest.php create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/config/configured_rule.php create mode 100644 rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php diff --git a/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_integers.php.inc b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_integers.php.inc new file mode 100644 index 00000000000..08bd7af21a9 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_integers.php.inc @@ -0,0 +1,25 @@ + +----- + diff --git a/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_strings.php.inc b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_strings.php.inc new file mode 100644 index 00000000000..473f297fc56 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/both_strings.php.inc @@ -0,0 +1,25 @@ + +----- + diff --git a/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_different_types.php.inc b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_different_types.php.inc new file mode 100644 index 00000000000..0d059efead8 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_different_types.php.inc @@ -0,0 +1,12 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/config/configured_rule.php b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/config/configured_rule.php new file mode 100644 index 00000000000..40d23d5523a --- /dev/null +++ b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/config/configured_rule.php @@ -0,0 +1,9 @@ +withRules([StrictInArrayRector::class]); diff --git a/rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php b/rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php new file mode 100644 index 00000000000..ba3a5bf20ab --- /dev/null +++ b/rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php @@ -0,0 +1,94 @@ +> + */ + public function getNodeTypes(): array + { + return [FuncCall::class]; + } + + /** + * @param FuncCall $node + */ + public function refactor(Node $node): ?Node + { + if (! $this->isName($node, 'in_array')) { + return null; + } + + if ($node->isFirstClassCallable()) { + return null; + } + + $args = $node->getArgs(); + if (count($args) !== 2) { + return null; + } + + $firstArgType = $this->nodeTypeResolver->getNativeType($args[0]->value); + $secondArgType = $this->nodeTypeResolver->getNativeType($args[1]->value); + + if (! $secondArgType->isArray()->yes()) { + return null; + } + + if ($this->typeComparator->isSubtype($secondArgType->getItemType(), $firstArgType)) { + $node->args[] = new Arg($this->nodeFactory->createTrue()); + return $node; + } + + return null; + } +} diff --git a/src/Config/Level/CodingStyleLevel.php b/src/Config/Level/CodingStyleLevel.php index 718feff2505..c8afe373dc0 100644 --- a/src/Config/Level/CodingStyleLevel.php +++ b/src/Config/Level/CodingStyleLevel.php @@ -20,6 +20,7 @@ use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector; use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector; use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector; +use Rector\CodingStyle\Rector\FuncCall\StrictInArrayRector; use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector; use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector; use Rector\CodingStyle\Rector\Property\SplitGroupedPropertiesRector; @@ -75,6 +76,7 @@ final class CodingStyleLevel CallUserFuncToMethodCallRector::class, FuncGetArgsToVariadicParamRector::class, StrictArraySearchRector::class, + StrictInArrayRector::class, UseClassKeywordForClassNameResolutionRector::class, SplitGroupedPropertiesRector::class, SplitGroupedClassConstantsRector::class, From 3b57d688fe3343613c66b4014c8f00e506f7d26b Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 28 Feb 2026 23:31:04 +0700 Subject: [PATCH 2/5] add fixture skip mixed type --- .../Fixture/skip_mixed_type.php.inc | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_mixed_type.php.inc diff --git a/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_mixed_type.php.inc b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_mixed_type.php.inc new file mode 100644 index 00000000000..0267377d802 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_mixed_type.php.inc @@ -0,0 +1,12 @@ + Date: Sat, 28 Feb 2026 16:31:36 +0000 Subject: [PATCH 3/5] [ci-review] Rector Rectify --- .../Rector/FuncCall/RemoveFilterVarOnExactTypeRector.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/DeadCode/Rector/FuncCall/RemoveFilterVarOnExactTypeRector.php b/rules/DeadCode/Rector/FuncCall/RemoveFilterVarOnExactTypeRector.php index e646656e6e8..482c0b9a152 100644 --- a/rules/DeadCode/Rector/FuncCall/RemoveFilterVarOnExactTypeRector.php +++ b/rules/DeadCode/Rector/FuncCall/RemoveFilterVarOnExactTypeRector.php @@ -84,7 +84,8 @@ public function refactor(Node $node): ?Node if (in_array( $constantFilterName, - ['FILTER_VALIDATE_BOOLEAN', 'FILTER_VALIDATE_BOOL'] + ['FILTER_VALIDATE_BOOLEAN', 'FILTER_VALIDATE_BOOL'], + true ) && $valueType->isBoolean() ->yes()) { return $firstArgValue; From 4c4454a5334f89c6d4ba7421d3bc5be6694a7b7c Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 28 Feb 2026 23:31:56 +0700 Subject: [PATCH 4/5] add fixture both mixed types --- .../Fixture/skip_both_mixed_type.php.inc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_both_mixed_type.php.inc diff --git a/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_both_mixed_type.php.inc b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_both_mixed_type.php.inc new file mode 100644 index 00000000000..e00a59754b0 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/FuncCall/StrictInArrayRector/Fixture/skip_both_mixed_type.php.inc @@ -0,0 +1,14 @@ + Date: Sat, 28 Feb 2026 23:34:43 +0700 Subject: [PATCH 5/5] fix phpstan --- rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php b/rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php index ba3a5bf20ab..d15bb8097f4 100644 --- a/rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php +++ b/rules/CodingStyle/Rector/FuncCall/StrictInArrayRector.php @@ -84,7 +84,7 @@ public function refactor(Node $node): ?Node return null; } - if ($this->typeComparator->isSubtype($secondArgType->getItemType(), $firstArgType)) { + if ($this->typeComparator->isSubtype($secondArgType->getIterableValueType(), $firstArgType)) { $node->args[] = new Arg($this->nodeFactory->createTrue()); return $node; }