From 24b96cf371052b133cd9a7b9d39a9aa59383f893 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 17 Dec 2025 05:55:16 +0700 Subject: [PATCH 1/3] [Php85] Skip defined int or string on ArrayKeyExistsNullToEmptyStringRector --- .../skip_defined_int_or_string.php.inc | 39 +++++++++++++++++++ .../ArrayKeyExistsNullToEmptyStringRector.php | 13 ++++++- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc new file mode 100644 index 00000000000..0c8fdabc771 --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc @@ -0,0 +1,39 @@ + + */ + private array $todos = [ + 0 => [ + 'unique_key' => 1, + 'label' => 'test 1', + ], + 1 => [ + 'unique_key' => 'fallback_todo', + 'label' => 'fallback todo 1', + ], + ]; + + /** + * @var array + */ + public array $selectedTodos = []; + + public function run(int $index): string + { + if (!array_key_exists($index, $this->todos)) { + return 'Todo not found'; + } + + if (!array_key_exists($this->todos[$index]['unique_key'], $this->selectedTodos)) { + $this->selectedTodos[$this->todos[$index]['unique_key']] = $this->todos[$index]['label']; + return 'Todo selected !'; + } + + return 'Todo already selected !'; + } +} diff --git a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php index 9618aa6afed..d03704e7951 100644 --- a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php +++ b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php @@ -4,6 +4,8 @@ namespace Rector\Php85\Rector\FuncCall; +use PHPStan\Type\UnionType; +use PHPStan\Type\TypeCombinator; use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; @@ -89,11 +91,20 @@ public function refactor(Node $node): ?Node } $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); + $argPosition = $this->argsAnalyzer->resolveArgPosition($args, 'key', 0); + $originalType = $this->getType($args[$argPosition]->value); + + if ($originalType instanceof UnionType) { + $withoutNullParameterType = TypeCombinator::removeNull($originalType); + if ($withoutNullParameterType->equals($originalType)) { + return null; + } + } $result = $this->nullToStrictStringIntConverter->convertIfNull( $node, $args, - $this->argsAnalyzer->resolveArgPosition($args, 'key', 0), + $argPosition, $isTrait, $scope, $parametersAcceptor From dc9612350af7ae4d06fb213c99ab2da0d2a6feec Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 17 Dec 2025 05:58:20 +0700 Subject: [PATCH 2/3] early --- .../Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php index d03704e7951..f2f074fd338 100644 --- a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php +++ b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php @@ -90,7 +90,6 @@ public function refactor(Node $node): ?Node return null; } - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); $argPosition = $this->argsAnalyzer->resolveArgPosition($args, 'key', 0); $originalType = $this->getType($args[$argPosition]->value); @@ -101,6 +100,7 @@ public function refactor(Node $node): ?Node } } + $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); $result = $this->nullToStrictStringIntConverter->convertIfNull( $node, $args, From 2f320ba56ffd367c5098796d51159d53b7b67e97 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 25 Dec 2025 15:13:37 +0700 Subject: [PATCH 3/3] simplify fixture --- .../skip_defined_int_or_string.php.inc | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc index 0c8fdabc771..45222b039b5 100644 --- a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc +++ b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc @@ -5,35 +5,19 @@ namespace Rector\Tests\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRect final class SkipDefinedIntOrString { /** - * @var array + * @var array */ - private array $todos = [ - 0 => [ - 'unique_key' => 1, - 'label' => 'test 1', - ], - 1 => [ - 'unique_key' => 'fallback_todo', - 'label' => 'fallback todo 1', - ], + private array $shownTodos = [ + 0 => false, + 'fallback_todo' => true, ]; - /** - * @var array - */ - public array $selectedTodos = []; - - public function run(int $index): string + public function run(string|int $index): void { - if (!array_key_exists($index, $this->todos)) { - return 'Todo not found'; - } - - if (!array_key_exists($this->todos[$index]['unique_key'], $this->selectedTodos)) { - $this->selectedTodos[$this->todos[$index]['unique_key']] = $this->todos[$index]['label']; - return 'Todo selected !'; + if (! array_key_exists($index, $this->shownTodos)) { + return; } - return 'Todo already selected !'; + $this->shownTodos[$index] = true; } }