diff --git a/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/offset_exists_dim_fetch.php.inc b/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/offset_exists_dim_fetch.php.inc new file mode 100644 index 00000000000..0dd67d1648d --- /dev/null +++ b/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/offset_exists_dim_fetch.php.inc @@ -0,0 +1,59 @@ +> + */ + private static $groups = []; + + public static function knownOffset(): array + { + $group = 'default'; + + self::$groups[$group] = ["foo"]; + + if (! empty(self::$groups[$group])) { + foreach (self::$groups[$group] as $group) { + echo "hello"; + } + } + + return []; + } +} + +?> +----- +> + */ + private static $groups = []; + + public static function knownOffset(): array + { + $group = 'default'; + + self::$groups[$group] = ["foo"]; + + foreach (self::$groups[$group] as $group) { + echo "hello"; + } + + return []; + } +} + +?> diff --git a/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/skip_phpdoc_offset_dim_fetch.php.inc b/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/skip_phpdoc_offset_dim_fetch.php.inc new file mode 100644 index 00000000000..e3d1921c90a --- /dev/null +++ b/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/skip_phpdoc_offset_dim_fetch.php.inc @@ -0,0 +1,24 @@ + diff --git a/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/skip_property_dim_fetch.php.inc b/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/skip_property_dim_fetch.php.inc new file mode 100644 index 00000000000..72c5a88e688 --- /dev/null +++ b/rules-tests/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture/skip_property_dim_fetch.php.inc @@ -0,0 +1,24 @@ +> + */ + private static $groups = []; + + public static function getFootnotes($group = self::DEFAULT_GROUP): array + { + if (! empty(self::$groups[$group])) { + foreach (self::$groups[$group] as $note) { + echo "hello"; + } + } + + return []; + } +} diff --git a/rules/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector.php b/rules/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector.php index ab0af89b99f..bcdd6c41bed 100644 --- a/rules/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector.php +++ b/rules/DeadCode/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector.php @@ -106,16 +106,8 @@ private function isUselessBeforeForeachCheck(If_ $if, Scope $scope): bool $foreach = $if->stmts[0]; $foreachExpr = $foreach->expr; - if ($foreachExpr instanceof Variable) { - $variableName = $this->nodeNameResolver->getName($foreachExpr); - if (is_string($variableName) && $this->reservedKeywordAnalyzer->isNativeVariable($variableName)) { - return false; - } - - $ifType = $scope->getNativeType($foreachExpr); - if (!$ifType->isArray()->yes()) { - return false; - } + if ($this->shouldSkipForeachExpr($foreachExpr, $scope)) { + return false; } $ifCond = $if->cond; @@ -208,4 +200,29 @@ private function refactorIf(If_ $if, Scope $scope): ?Foreach_ return $stmt; } + + private function shouldSkipForeachExpr(Expr $foreachExpr, Scope $scope): bool + { + if ($foreachExpr instanceof Expr\ArrayDimFetch && $foreachExpr->dim !== null) { + $exprType = $this->nodeTypeResolver->getNativeType($foreachExpr->var); + $dimType = $this->nodeTypeResolver->getNativeType($foreachExpr->dim); + if (!$exprType->hasOffsetValueType($dimType)->yes()) { + return true; + } + } + + if ($foreachExpr instanceof Variable) { + $variableName = $this->nodeNameResolver->getName($foreachExpr); + if (is_string($variableName) && $this->reservedKeywordAnalyzer->isNativeVariable($variableName)) { + return true; + } + + $ifType = $scope->getNativeType($foreachExpr); + if (!$ifType->isArray()->yes()) { + return true; + } + } + + return false; + } }