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..63242d692e1 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector/Fixture/with_duplicated_nested_array.php.inc @@ -0,0 +1,54 @@ + [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], + ]; + } +} + +?> diff --git a/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php b/src/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php index e900d9e01eb..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,12 +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()); } - $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);