Skip to content

Commit dde5d42

Browse files
authored
[type-declaration-docblocks] add nesting support to DocblockReturnArrayFromDirectArrayInstanceRector (#7255)
1 parent 9e93740 commit dde5d42

2 files changed

Lines changed: 60 additions & 6 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Fixture;
4+
5+
final class SingleNestedLevel
6+
{
7+
public function getNames($value): array
8+
{
9+
return [
10+
'key' => [
11+
'subkey' => $value
12+
],
13+
];
14+
}
15+
}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\DocblockReturnArrayFromDirectArrayInstanceRector\Fixture;
22+
23+
final class SingleNestedLevel
24+
{
25+
/**
26+
* @return array<string, array<string, mixed>>
27+
*/
28+
public function getNames($value): array
29+
{
30+
return [
31+
'key' => [
32+
'subkey' => $value
33+
],
34+
];
35+
}
36+
}
37+
38+
?>

rules/TypeDeclarationDocblocks/Rector/ClassMethod/DocblockReturnArrayFromDirectArrayInstanceRector.php

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

116-
$genericKeyType = $this->constantToGenericType($returnedType->getKeyType());
117-
$genericItemType = $this->constantToGenericType($returnedType->getItemType());
118-
119-
$genericTypeNode = $this->createArrayGenericTypeNode($genericKeyType, $genericItemType);
116+
$genericTypeNode = $this->createGenericArrayTypeFromConstantArrayType($returnedType);
120117

121118
$returnTagValueNode = new ReturnTagValueNode($genericTypeNode, '');
122119
$phpDocInfo->addTagValueNode($returnTagValueNode);
@@ -151,10 +148,29 @@ private function constantToGenericType(Type $type): Type
151148
return new MixedType();
152149
}
153150

154-
private function createArrayGenericTypeNode(Type $keyType, Type $itemType): GenericTypeNode
151+
private function createGenericArrayTypeFromConstantArrayType(ConstantArrayType $constantArrayType): GenericTypeNode
152+
{
153+
$genericKeyType = $this->constantToGenericType($constantArrayType->getKeyType());
154+
155+
$itemType = $constantArrayType->getItemType();
156+
if ($itemType instanceof ConstantArrayType) {
157+
$genericItemType = $this->createGenericArrayTypeFromConstantArrayType($itemType);
158+
} else {
159+
$genericItemType = $this->constantToGenericType($itemType);
160+
}
161+
162+
return $this->createArrayGenericTypeNode($genericKeyType, $genericItemType);
163+
}
164+
165+
private function createArrayGenericTypeNode(Type $keyType, Type|GenericTypeNode $itemType): GenericTypeNode
155166
{
156167
$keyDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($keyType);
157-
$itemDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($itemType);
168+
169+
if ($itemType instanceof Type) {
170+
$itemDocTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($itemType);
171+
} else {
172+
$itemDocTypeNode = $itemType;
173+
}
158174

159175
return new GenericTypeNode(new IdentifierTypeNode('array'), [$keyDocTypeNode, $itemDocTypeNode]);
160176
}

0 commit comments

Comments
 (0)