From 2fb208a2a8d439092a5a7ee5df2edcf5089466ea Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 28 Sep 2025 10:22:51 +0700 Subject: [PATCH 1/4] [TypeDeclarationDocblocks] Handle with duplicated nested type[] array docblock on DocblockReturnArrayFromDirectArrayInstanceRector --- .../with_duplicated_nested_array.php.inc | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc new file mode 100644 index 00000000000..2d3def88a33 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc @@ -0,0 +1,48 @@ + [false, 1, $testingUrls], + '$cacheQueryString=true' => [true, 5, $testingUrls], + '$cacheQueryString=array' => [['important_parameter'], 3, $testingUrls], + ]; + } +} + +?> +----- + + */ + public static function run(): iterable + { + $testingUrls = [ + 'test', + 'test?important_parameter=1', + ]; + + return [ + '$cacheQueryString=false' => [false, 1, $testingUrls], + '$cacheQueryString=true' => [true, 5, $testingUrls], + '$cacheQueryString=array' => [['important_parameter'], 3, $testingUrls], + ]; + } +} + +?> From 8a9aaa821776b243e84579a922ae5caf0a80e68e Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 28 Sep 2025 10:35:45 +0700 Subject: [PATCH 2/4] note to debug --- src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php b/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php index e900d9e01eb..9f9d4ae59e9 100644 --- a/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php +++ b/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php @@ -62,6 +62,7 @@ public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode $unionedType = new ArrayType($unionedType->getKeyType(), new MixedType()); } + // here to debug ... $unionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType); } From 331149d94e75e4c4ab40c97234faf78bddd6180f Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 28 Sep 2025 11:00:54 +0700 Subject: [PATCH 3/4] Fix --- .../TypeMapper/UnionTypeMapper.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php b/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php index 9f9d4ae59e9..fd162b7cfc0 100644 --- a/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php +++ b/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php @@ -19,6 +19,7 @@ use PHPStan\Type\Type; use PHPStan\Type\UnionType; use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode; +use Rector\BetterPhpDocParser\ValueObject\Type\SpacingAwareArrayTypeNode; use Rector\NodeAnalyzer\PropertyAnalyzer; use Rector\Php\PhpVersionProvider; use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface; @@ -57,13 +58,32 @@ public function getNodeClass(): string public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode { $unionTypesNodes = []; + $existingTypes = []; + foreach ($type->getTypes() as $unionedType) { if ($unionedType instanceof ArrayType && $unionedType->getItemType() instanceof NeverType) { $unionedType = new ArrayType($unionedType->getKeyType(), new MixedType()); } - // here to debug ... - $unionTypesNodes[] = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType); + $unionedType = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($unionedType); + + if ($unionedType instanceof SpacingAwareArrayTypeNode && $unionedType->type instanceof BracketsAwareUnionTypeNode) { + foreach ($unionedType->type->types as $key => $innerTypeNode) { + $printedInnerType = (string) $innerTypeNode; + if (in_array($printedInnerType, $existingTypes, true)) { + unset($unionedType->type->types[$key]); + continue; + } + + $existingTypes[] = $printedInnerType; + } + + if ($unionedType->type->types === []) { + continue; + } + } + + $unionTypesNodes[] = $unionedType; } return new BracketsAwareUnionTypeNode($unionTypesNodes); From 6b924abcadd9691d2769e69438bcf0a2e3d66753 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 28 Sep 2025 11:02:26 +0700 Subject: [PATCH 4/4] reference --- .../Fixture/with_duplicated_nested_array.php.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc index 2d3def88a33..63242d692e1 100644 --- a/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc +++ b/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc @@ -2,6 +2,9 @@ namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Fixture; +/** + * @see https://github.com/codeigniter4/CodeIgniter4/blob/89fee62b666c07550197203a94fb7dd94303d7ca/tests/system/CodeIgniterTest.php#L893 + */ final class WithDuplicatedNestedArray { public static function run(): iterable @@ -25,6 +28,9 @@ final class WithDuplicatedNestedArray namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Fixture; +/** + * @see https://github.com/codeigniter4/CodeIgniter4/blob/89fee62b666c07550197203a94fb7dd94303d7ca/tests/system/CodeIgniterTest.php#L893 + */ final class WithDuplicatedNestedArray { /**