diff --git a/config/set/downgrade-php80.php b/config/set/downgrade-php80.php index 9e13c73c..f19fc2d3 100644 --- a/config/set/downgrade-php80.php +++ b/config/set/downgrade-php80.php @@ -18,6 +18,7 @@ use Rector\DowngradePhp80\Rector\Enum_\DowngradeEnumToConstantListClassRector; use Rector\DowngradePhp80\Rector\Expression\DowngradeMatchToSwitchRector; use Rector\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector; +use Rector\DowngradePhp80\Rector\Foreach_\DowngradeDomNodeChildNodesForeachRector; use Rector\DowngradePhp80\Rector\FuncCall\DowngradeArrayFilterNullableCallbackRector; use Rector\DowngradePhp80\Rector\FuncCall\DowngradeNumberFormatNoFourthArgRector; use Rector\DowngradePhp80\Rector\FuncCall\DowngradeStrContainsRector; @@ -80,6 +81,7 @@ DowngradeStrEndsWithRector::class, DowngradePhpTokenRector::class, DowngradeThrowExprRector::class, + DowngradeDomNodeChildNodesForeachRector::class, DowngradePhp80ResourceReturnToObjectRector::class, DowngradeReflectionGetAttributesRector::class, DowngradeRecursiveDirectoryIteratorHasChildrenRector::class, diff --git a/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/DowngradeDomNodeChildNodesForeachRectorTest.php b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/DowngradeDomNodeChildNodesForeachRectorTest.php new file mode 100644 index 00000000..a701ad0a --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/DowngradeDomNodeChildNodesForeachRectorTest.php @@ -0,0 +1,28 @@ +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/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/dom_element_subtype.php.inc b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/dom_element_subtype.php.inc new file mode 100644 index 00000000..b0c81b02 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/dom_element_subtype.php.inc @@ -0,0 +1,31 @@ +childNodes as $childNode) { + echo $childNode->nodeValue; + } + } +} + +?> +----- +childNodes ?? [] as $childNode) { + echo $childNode->nodeValue; + } + } +} + +?> diff --git a/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/fixture.php.inc b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..72251096 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/fixture.php.inc @@ -0,0 +1,31 @@ +childNodes as $childNode) { + echo $childNode->nodeValue; + } + } +} + +?> +----- +childNodes ?? [] as $childNode) { + echo $childNode->nodeValue; + } + } +} + +?> diff --git a/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_already_coalesced.php.inc b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_already_coalesced.php.inc new file mode 100644 index 00000000..ebf9efb6 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_already_coalesced.php.inc @@ -0,0 +1,13 @@ +childNodes ?? [] as $childNode) { + echo $childNode->nodeValue; + } + } +} diff --git a/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_non_dom_object.php.inc b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_non_dom_object.php.inc new file mode 100644 index 00000000..29333df3 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_non_dom_object.php.inc @@ -0,0 +1,15 @@ +childNodes as $childNode) { + echo $childNode; + } + } +} diff --git a/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_other_property.php.inc b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_other_property.php.inc new file mode 100644 index 00000000..0a1ebbc9 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Fixture/skip_other_property.php.inc @@ -0,0 +1,13 @@ +attributes as $attribute) { + echo $attribute->nodeValue; + } + } +} diff --git a/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Source/SomeChildAware.php b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Source/SomeChildAware.php new file mode 100644 index 00000000..ce629732 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector/Source/SomeChildAware.php @@ -0,0 +1,13 @@ +rule(DowngradeDomNodeChildNodesForeachRector::class); +}; diff --git a/rules/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector.php b/rules/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector.php new file mode 100644 index 00000000..0566418d --- /dev/null +++ b/rules/DowngradePhp80/Rector/Foreach_/DowngradeDomNodeChildNodesForeachRector.php @@ -0,0 +1,91 @@ +childNodes as $childNode) { + echo $childNode->nodeValue; + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +function run(\DOMNode $node) +{ + foreach ($node->childNodes ?? [] as $childNode) { + echo $childNode->nodeValue; + } +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [Foreach_::class]; + } + + /** + * @param Foreach_ $node + */ + public function refactor(Node $node): ?Node + { + $iteratedExpr = $node->expr; + if (! $iteratedExpr instanceof PropertyFetch) { + return null; + } + + if (! $this->isName($iteratedExpr->name, 'childNodes')) { + return null; + } + + $callerType = $this->nodeTypeResolver->getType($iteratedExpr->var); + if (! $callerType instanceof ObjectType) { + return null; + } + + if (! $callerType->isInstanceOf('DOMNode')->yes()) { + return null; + } + + $node->expr = new Coalesce($iteratedExpr, new Array_([])); + + return $node; + } +}