diff --git a/phpstan.neon b/phpstan.neon index 696f79f9..cb9573f4 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -43,15 +43,8 @@ parameters: # see https://github.com/rectorphp/rector-src/actions/runs/11798721617/job/32865546672?pr=6422#step:5:110 - '#Doing instanceof PHPStan\\Type\\.+ is error\-prone and deprecated#' - - identifier: instanceof.alwaysTrue - # false positive - identifier: assign.propertyType message: '#Property PhpParser\\Node\\Identifier\:\:\$name \(non\-empty\-string\) does not accept string#' path: rules/CodeQuality/Rector/ClassMethod/ReplaceTestFunctionPrefixWithAttributeRector.php - - # handle next - - - identifier: symplify.forbiddenNode - message: '#switch#' diff --git a/rules/AnnotationsToAttributes/NodeFactory/RequiresAttributeFactory.php b/rules/AnnotationsToAttributes/NodeFactory/RequiresAttributeFactory.php index fb1f4075..156bbbaa 100644 --- a/rules/AnnotationsToAttributes/NodeFactory/RequiresAttributeFactory.php +++ b/rules/AnnotationsToAttributes/NodeFactory/RequiresAttributeFactory.php @@ -6,6 +6,7 @@ use PhpParser\Node\AttributeGroup; use Rector\PhpAttribute\NodeFactory\PhpAttributeGroupFactory; +use Rector\PHPUnit\AnnotationsToAttributes\ValueObject\RequiresAttributeAndValue; use Rector\PHPUnit\Enum\PHPUnitAttribute; final readonly class RequiresAttributeFactory @@ -22,58 +23,74 @@ public function create(string $annotationValue): ?AttributeGroup $type = array_shift($annotationValues); $attributeValue = array_shift($annotationValues); - switch ($type) { - case 'PHP': - $attributeClass = PHPUnitAttribute::REQUIRES_PHP; + $requiresAttributeAndValue = $this->matchRequiresAttributeAndValue($type, $attributeValue); + if (! $requiresAttributeAndValue instanceof RequiresAttributeAndValue) { + return null; + } - // only version is used, we need to prefix with >= - if (is_string($attributeValue) && is_numeric($attributeValue[0])) { - $attributeValue = '>= ' . $attributeValue; - } + return $this->phpAttributeGroupFactory->createFromClassWithItems( + $requiresAttributeAndValue->getAttributeClass(), + $requiresAttributeAndValue->getValue() + ); + } - $attributeValue = [$attributeValue]; - break; - case 'PHPUnit': - $attributeClass = PHPUnitAttribute::REQUIRES_PHPUNIT; + private function matchRequiresAttributeAndValue(string $type, mixed $attributeValue): ?RequiresAttributeAndValue + { + if ($type === 'PHP') { + // only version is used, we need to prefix with >= + if (is_string($attributeValue) && is_numeric($attributeValue[0])) { + $attributeValue = '>= ' . $attributeValue; + } + + return new RequiresAttributeAndValue(PHPUnitAttribute::REQUIRES_PHP, [$attributeValue]); + } - // only version is used, we need to prefix with >= - if (is_string($attributeValue) && is_numeric($attributeValue[0])) { - $attributeValue = '>= ' . $attributeValue; - } + if ($type === 'PHPUnit') { + // only version is used, we need to prefix with >= + if (is_string($attributeValue) && is_numeric($attributeValue[0])) { + $attributeValue = '>= ' . $attributeValue; + } + return new RequiresAttributeAndValue(PHPUnitAttribute::REQUIRES_PHPUNIT, [$attributeValue]); + } + + if ($type === 'OS') { + return new RequiresAttributeAndValue(PHPUnitAttribute::REQUIRES_OS, [$attributeValue]); + } + + if ($type === 'OSFAMILY') { + return new RequiresAttributeAndValue(PHPUnitAttribute::REQUIRES_OS_FAMILY, [$attributeValue]); + } + + if ($type === 'function') { + if (str_contains((string) $attributeValue, '::')) { + $attributeClass = PHPUnitAttribute::REQUIRES_METHOD; + $attributeValue = explode('::', (string) $attributeValue); + $attributeValue[0] .= '::class'; + } else { + $attributeClass = PHPUnitAttribute::REQUIRES_FUNCTION; $attributeValue = [$attributeValue]; - break; - case 'OS': - $attributeClass = PHPUnitAttribute::REQUIRES_OS; - $attributeValue = [$attributeValue]; - break; - case 'OSFAMILY': - $attributeClass = PHPUnitAttribute::REQUIRES_OS_FAMILY; - $attributeValue = [$attributeValue]; - break; - case 'function': - if (str_contains((string) $attributeValue, '::')) { - $attributeClass = PHPUnitAttribute::REQUIRES_METHOD; - $attributeValue = explode('::', (string) $attributeValue); - $attributeValue[0] .= '::class'; - } else { - $attributeClass = PHPUnitAttribute::REQUIRES_FUNCTION; - $attributeValue = [$attributeValue]; - } - - break; - case 'extension': - $attributeClass = PHPUnitAttribute::REQUIRES_PHP_EXTENSION; - $attributeValue = explode(' ', (string) $attributeValue, 2); - break; - case 'setting': - $attributeClass = PHPUnitAttribute::REQUIRES_SETTING; - $attributeValue = explode(' ', (string) $attributeValue, 2); - break; - default: - return null; + } + + return new RequiresAttributeAndValue($attributeClass, $attributeValue); + } + + if ($type === 'extension') { + return new RequiresAttributeAndValue(PHPUnitAttribute::REQUIRES_PHP_EXTENSION, explode( + ' ', + (string) $attributeValue, + 2 + )); + } + + if ($type === 'setting') { + return new RequiresAttributeAndValue(PHPUnitAttribute::REQUIRES_SETTING, explode( + ' ', + (string) $attributeValue, + 2 + )); } - return $this->phpAttributeGroupFactory->createFromClassWithItems($attributeClass, [...$attributeValue]); + return null; } } diff --git a/rules/AnnotationsToAttributes/Rector/Class_/RequiresAnnotationWithValueToAttributeRector.php b/rules/AnnotationsToAttributes/Rector/Class_/RequiresAnnotationWithValueToAttributeRector.php index f0a097d5..402517f3 100644 --- a/rules/AnnotationsToAttributes/Rector/Class_/RequiresAnnotationWithValueToAttributeRector.php +++ b/rules/AnnotationsToAttributes/Rector/Class_/RequiresAnnotationWithValueToAttributeRector.php @@ -104,20 +104,22 @@ public function refactor(Node $node): ?Node $hasChanged = false; - if ($node instanceof Class_) { - $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); - if ($phpDocInfo instanceof PhpDocInfo) { - $requiresAttributeGroups = $this->handleRequires($phpDocInfo); - if ($requiresAttributeGroups !== []) { - $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); - $node->attrGroups = array_merge($node->attrGroups, $requiresAttributeGroups); - $this->removeMethodRequiresAnnotations($phpDocInfo); - $hasChanged = true; - } + $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); + if ($phpDocInfo instanceof PhpDocInfo) { + $requiresAttributeGroups = $this->handleRequires($phpDocInfo); + if ($requiresAttributeGroups !== []) { + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + $node->attrGroups = array_merge($node->attrGroups, $requiresAttributeGroups); + $this->removeMethodRequiresAnnotations($phpDocInfo); + $hasChanged = true; } } - return $hasChanged ? $node : null; + if ($hasChanged) { + return $node; + } + + return null; } /** diff --git a/rules/AnnotationsToAttributes/ValueObject/RequiresAttributeAndValue.php b/rules/AnnotationsToAttributes/ValueObject/RequiresAttributeAndValue.php new file mode 100644 index 00000000..60727bbb --- /dev/null +++ b/rules/AnnotationsToAttributes/ValueObject/RequiresAttributeAndValue.php @@ -0,0 +1,36 @@ +attributeClass; + } + + /** + * @return string[] + */ + public function getValue(): array + { + return $this->value; + } +} diff --git a/rules/CodeQuality/Rector/ClassMethod/DataProviderArrayItemsNewLinedRector.php b/rules/CodeQuality/Rector/ClassMethod/DataProviderArrayItemsNewLinedRector.php index 4d2186ff..1f6cfa44 100644 --- a/rules/CodeQuality/Rector/ClassMethod/DataProviderArrayItemsNewLinedRector.php +++ b/rules/CodeQuality/Rector/ClassMethod/DataProviderArrayItemsNewLinedRector.php @@ -5,7 +5,6 @@ namespace Rector\PHPUnit\CodeQuality\Rector\ClassMethod; use PhpParser\Node; -use PhpParser\Node\ArrayItem; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Return_; @@ -136,10 +135,6 @@ public function refactor(Node $node): ?Node private function shouldRePrint(Array_ $array): bool { foreach ($array->items as $key => $item) { - if (! $item instanceof ArrayItem) { - continue; - } - if (! isset($array->items[$key + 1])) { continue; } diff --git a/rules/PHPUnit100/Rector/Class_/RemoveNamedArgsInDataProviderRector.php b/rules/PHPUnit100/Rector/Class_/RemoveNamedArgsInDataProviderRector.php index 9b8794d7..d9036cb5 100644 --- a/rules/PHPUnit100/Rector/Class_/RemoveNamedArgsInDataProviderRector.php +++ b/rules/PHPUnit100/Rector/Class_/RemoveNamedArgsInDataProviderRector.php @@ -5,11 +5,9 @@ namespace Rector\PHPUnit\PHPUnit100\Rector\Class_; use PhpParser\Node; -use PhpParser\Node\ArrayItem; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\Yield_; -use PhpParser\Node\Scalar\Int_; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\Expression; use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer; @@ -127,18 +125,12 @@ private function handleArray(Array_ $array): bool { $hasChanged = false; foreach ($array->items as $item) { - if (! $item instanceof ArrayItem) { - continue; - } - if (! $item->key instanceof Expr) { continue; } - if (! $item->key instanceof Int_ && $item->key instanceof Expr) { - $item->key = null; - $hasChanged = true; - } + $item->key = null; + $hasChanged = true; } return $hasChanged; diff --git a/src/NodeFactory/ConsecutiveIfsFactory.php b/src/NodeFactory/ConsecutiveIfsFactory.php index f7be2e67..388649d6 100644 --- a/src/NodeFactory/ConsecutiveIfsFactory.php +++ b/src/NodeFactory/ConsecutiveIfsFactory.php @@ -5,7 +5,6 @@ namespace Rector\PHPUnit\NodeFactory; use PhpParser\Node\Arg; -use PhpParser\Node\ArrayItem; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\ArrowFunction; @@ -44,10 +43,6 @@ public function createIfs(MethodCall $withConsecutiveMethodCall, MethodCall $num if ($withConsecutiveArg->value instanceof Array_) { $array = $withConsecutiveArg->value; foreach ($array->items as $assertKey => $assertArrayItem) { - if (! $assertArrayItem instanceof ArrayItem) { - continue; - } - if (! $assertArrayItem->value instanceof MethodCall) { $parametersDimFetch = new ArrayDimFetch(new Variable('parameters'), new Int_($assertKey)); $args = [new Arg($assertArrayItem->value), new Arg($parametersDimFetch)];