From 2c373fad120eb9bb11c57d82aee63a8f26349ea8 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 14 Oct 2025 08:25:34 +0700 Subject: [PATCH 1/3] [TypeDeclarationDocblocks] Handle array union type on DocblockVarArrayFromPropertyDefaultsRector --- .../Fixture/array_union_type.php.inc | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_type.php.inc diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_type.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_type.php.inc new file mode 100644 index 00000000000..f3e8c742c11 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_type.php.inc @@ -0,0 +1,36 @@ + +----- +|class-string<\DateTime>> + */ + protected array $dependencies = [ + stdClass::class, + DateTime::class, + ]; +} + +?> From 7eda1b140d0324b14a7506567b9380e7865375c8 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 14 Oct 2025 08:37:29 +0700 Subject: [PATCH 2/3] fix --- ... => array_union_generic_same_type.php.inc} | 4 +-- .../Type/SpacingAwareArrayTypeNode.php | 30 +++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) rename rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/{array_union_type.php.inc => array_union_generic_same_type.php.inc} (90%) diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_type.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_generic_same_type.php.inc similarity index 90% rename from rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_type.php.inc rename to rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_generic_same_type.php.inc index f3e8c742c11..6eb037a11d9 100644 --- a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_type.php.inc +++ b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromPropertyDefaultsRector/Fixture/array_union_generic_same_type.php.inc @@ -5,7 +5,7 @@ namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\DocblockVarArrayFr use DateTime; use stdClass; -class ArrayUnionType +class ArrayUnionGenericSameType { protected array $dependencies = [ stdClass::class, @@ -22,7 +22,7 @@ namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\DocblockVarArrayFr use DateTime; use stdClass; -class ArrayUnionType +class ArrayUnionGenericSameType { /** * @var array|class-string<\DateTime>> diff --git a/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php b/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php index 6a8349d2e2c..a3bd13b2a2a 100644 --- a/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php +++ b/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php @@ -6,6 +6,7 @@ use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode; use PHPStan\PhpDocParser\Ast\Type\CallableTypeNode; +use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode; use PHPStan\PhpDocParser\Ast\Type\TypeNode; use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode; use Rector\PHPStanStaticTypeMapper\TypeMapper\ArrayTypeMapper; @@ -60,12 +61,37 @@ private function printArrayType(ArrayTypeNode $arrayTypeNode): string private function printUnionType(BracketsAwareUnionTypeNode $bracketsAwareUnionTypeNode): string { - $unionedTypes = []; - if ($bracketsAwareUnionTypeNode->isWrappedInBrackets()) { return $bracketsAwareUnionTypeNode . '[]'; } + // If all types in the union are GenericTypeNode, use array syntax + $allGeneric = true; + $firstGenericTypeName = null; + + foreach ($bracketsAwareUnionTypeNode->types as $unionedType) { + if (! $unionedType instanceof GenericTypeNode) { + $allGeneric = false; + break; + } + + // ensure all generic types has the same base type + $currentTypeName = $unionedType->type->name; + + if ($firstGenericTypeName === null) { + $firstGenericTypeName = $currentTypeName; + } elseif ($firstGenericTypeName !== $currentTypeName) { + // Different generic base types (e.g., class-string vs array) + $allGeneric = false; + break; + } + } + + if ($allGeneric) { + return sprintf('array', (string) $bracketsAwareUnionTypeNode); + } + + $unionedTypes = []; foreach ($bracketsAwareUnionTypeNode->types as $unionedType) { $unionedTypes[] = $unionedType . '[]'; } From 957ca993674fb9724d8397a636b9afa3f9ec0652 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 14 Oct 2025 08:40:15 +0700 Subject: [PATCH 3/3] fix --- .../ValueObject/Type/SpacingAwareArrayTypeNode.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php b/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php index a3bd13b2a2a..4e33184ab26 100644 --- a/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php +++ b/src/BetterPhpDocParser/ValueObject/Type/SpacingAwareArrayTypeNode.php @@ -75,6 +75,13 @@ private function printUnionType(BracketsAwareUnionTypeNode $bracketsAwareUnionTy break; } + // ensure only check on base level + // avoid mix usage without [] added + if (count($unionedType->genericTypes) !== 1) { + $allGeneric = false; + break; + } + // ensure all generic types has the same base type $currentTypeName = $unionedType->type->name;