Skip to content

Commit 224e316

Browse files
authored
add object support to DocblockReturnArrayFromDirectArrayInstanceRector (#7795)
1 parent 566b3be commit 224e316

File tree

4 files changed

+78
-8
lines changed

4 files changed

+78
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Fixture;
4+
5+
final class CoverObjectReturn
6+
{
7+
private ?\Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Sourde\SomeObjectInDirectArray $item = null;
8+
9+
public function toArray(): array
10+
{
11+
return [
12+
'key1' => 100,
13+
'key2' => $this->item
14+
];
15+
}
16+
}
17+
18+
?>
19+
-----
20+
<?php
21+
22+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Fixture;
23+
24+
final class CoverObjectReturn
25+
{
26+
private ?\Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Sourde\SomeObjectInDirectArray $item = null;
27+
28+
/**
29+
* @return array<string, \Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Sourde\SomeObjectInDirectArray|int|null>
30+
*/
31+
public function toArray(): array
32+
{
33+
return [
34+
'key1' => 100,
35+
'key2' => $this->item
36+
];
37+
}
38+
}
39+
40+
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Sourde;
6+
7+
final class SomeObjectInDirectArray
8+
{
9+
}

rules/Privatization/TypeManipulator/TypeNormalizer.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Rector\Privatization\TypeManipulator;
66

7+
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
78
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
89
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
910
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
@@ -18,13 +19,15 @@
1819
use PHPStan\Type\IntegerType;
1920
use PHPStan\Type\MixedType;
2021
use PHPStan\Type\NeverType;
22+
use PHPStan\Type\ObjectType;
2123
use PHPStan\Type\StringType;
2224
use PHPStan\Type\Type;
2325
use PHPStan\Type\TypeTraverser;
2426
use PHPStan\Type\UnionType;
2527
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
2628
use Rector\NodeTypeResolver\PHPStan\TypeHasher;
2729
use Rector\StaticTypeMapper\StaticTypeMapper;
30+
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
2831

2932
final readonly class TypeNormalizer
3033
{
@@ -138,14 +141,10 @@ public function generalizeConstantTypes(Type $type): Type
138141
if (count($uniqueGeneralizedUnionTypes) > 1) {
139142
$generalizedUnionType = new UnionType($uniqueGeneralizedUnionTypes);
140143

141-
// avoid too huge print in docblock
142-
$unionedDocType = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode(
143-
$generalizedUnionType
144-
);
144+
$shortUnionedDocType = $this->resolveNameShortDocTypeNode($generalizedUnionType);
145145

146-
// too long
147146
if (strlen(
148-
(string) $unionedDocType
147+
(string) $shortUnionedDocType
149148
) > self::MAX_PRINTED_UNION_DOC_LENGTH && $this->avoidPrintedDocblockTrimming(
150149
$generalizedUnionType
151150
) === false) {
@@ -221,4 +220,24 @@ private function avoidPrintedDocblockTrimming(UnionType $unionType): bool
221220

222221
return $unionType->getObjectClassNames() !== [];
223222
}
223+
224+
private function resolveNameShortDocTypeNode(UnionType $unionType): TypeNode
225+
{
226+
// we have to converet name to short here, to make sure the not FQN, but short name is counted to the full length
227+
$objectShortGeneralizedUnionType = TypeTraverser::map($unionType, function (
228+
Type $type,
229+
callable $traverseCallback
230+
): Type {
231+
if ($type instanceof ObjectType && str_contains($type->getClassName(), '\\')) {
232+
// after last "\\"
233+
$shortClassName = substr($type->getClassName(), strrpos($type->getClassName(), '\\') + 1);
234+
235+
return new ShortenedObjectType($shortClassName, $type->getClassName());
236+
}
237+
238+
return $traverseCallback($type, $traverseCallback);
239+
});
240+
241+
return $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($objectShortGeneralizedUnionType);
242+
}
224243
}

rules/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ public function refactor(Node $node): ?Node
113113
return null;
114114
}
115115

116-
if ($returnedType->getReferencedClasses() !== []) {
117-
// better handled by shared-interface/class rule, to avoid turning objects to mixed
116+
// better handled by shared-interface/class rule, to avoid turning objects to mixed
117+
if ($returnedType->getReferencedClasses() !== [] && count($returnedType->getReferencedClasses()) === count(
118+
$returnedType->getValueTypes()
119+
)) {
118120
return null;
119121
}
120122

0 commit comments

Comments
 (0)