diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/union_objects.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/union_objects.php.inc new file mode 100644 index 00000000000..b2f8dd0b917 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/union_objects.php.inc @@ -0,0 +1,60 @@ +run($this->getUnion()); + } + + private function run(array $items) + { + } + + /** + * @return SomeReturnedObject[]|AnotherReturnedObject[] + */ + private function getUnion(): array + { + return []; + } +} + +?> +----- +run($this->getUnion()); + } + + /** + * @param \Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\ClassMethodArrayDocblockParamFromLocalCallsRector\Source\AnotherReturnedObject[]|\Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\ClassMethodArrayDocblockParamFromLocalCallsRector\Source\SomeReturnedObject[] $items + */ + private function run(array $items) + { + } + + /** + * @return SomeReturnedObject[]|AnotherReturnedObject[] + */ + private function getUnion(): array + { + return []; + } +} + +?> diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Source/AnotherReturnedObject.php b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Source/AnotherReturnedObject.php new file mode 100644 index 00000000000..2ada9dccb16 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Source/AnotherReturnedObject.php @@ -0,0 +1,8 @@ + 1) { $generalizedUnionType = new UnionType($uniqueGeneralizedUnionTypes); + // avoid too huge print in docblock $unionedDocType = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode( $generalizedUnionType ); // too long - if (strlen((string) $unionedDocType) > self::MAX_PRINTED_UNION_DOC_LENGHT) { + if (strlen( + (string) $unionedDocType + ) > self::MAX_PRINTED_UNION_DOC_LENGHT && $this->avoidPrintedDocblockTrimming( + $generalizedUnionType + ) === false) { $alwaysKnownArrayType = $this->narrowToAlwaysKnownArrayType($generalizedUnionType); if ($alwaysKnownArrayType instanceof ArrayType) { return $alwaysKnownArrayType; @@ -164,4 +169,20 @@ private function narrowToAlwaysKnownArrayType(UnionType $unionType): ?ArrayType ); return new ArrayType($arrayUniqueKeyType, new MixedType()); } + + /** + * Is object only? avoid trimming, as auto import handles it better + */ + private function avoidPrintedDocblockTrimming(UnionType $unionType): bool + { + if ($unionType->getConstantScalarTypes() !== []) { + return false; + } + + if ($unionType->getConstantArrays() !== []) { + return false; + } + + return $unionType->getObjectClassNames() !== []; + } } diff --git a/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php b/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php index bf031547a55..301ebdbf5f9 100644 --- a/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php +++ b/rules/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector.php @@ -5,8 +5,10 @@ namespace Rector\TypeDeclarationDocblocks\Rector\Class_; use PhpParser\Node; +use PhpParser\Node\Param; use PhpParser\Node\Stmt\Class_; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; +use PHPStan\Type\ArrayType; use PHPStan\Type\MixedType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; @@ -93,11 +95,7 @@ public function refactor(Node $node): ?Node $classMethodParameterTypes = $this->callTypesResolver->resolveTypesFromCalls($methodCalls); foreach ($classMethod->getParams() as $parameterPosition => $param) { - if ($param->type === null) { - continue; - } - - if (! $this->isName($param->type, 'array')) { + if (! $this->hasParamArrayType($param)) { continue; } @@ -118,6 +116,10 @@ public function refactor(Node $node): ?Node continue; } + if ($resolvedParameterType instanceof ArrayType && $resolvedParameterType->getItemType() instanceof MixedType && $resolvedParameterType->getKeyType() instanceof MixedType) { + continue; + } + // in case of array type declaration, null cannot be passed or is already casted $resolvedParameterType = TypeCombinator::removeNull($resolvedParameterType); @@ -140,4 +142,13 @@ public function refactor(Node $node): ?Node return $node; } + + private function hasParamArrayType(Param $param): bool + { + if (! $param->type instanceof Node) { + return false; + } + + return $this->isName($param->type, 'array'); + } }