Skip to content

Commit 04298b7

Browse files
authored
Merge pull request #274 from mspirkov/improve-array-to-string-conversion
Improve the conversion of arrays to strings
2 parents 1336512 + 5a284e8 commit 04298b7

File tree

5 files changed

+54
-25
lines changed

5 files changed

+54
-25
lines changed

src/Types/AbstractList.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,4 @@ public function getValueType(): Type
7070
{
7171
return $this->valueType ?? $this->defaultValueType;
7272
}
73-
74-
/**
75-
* Returns a rendered output of the Type as it would be used in a DocBlock.
76-
*/
77-
public function __toString(): string
78-
{
79-
if ($this->valueType === null) {
80-
return 'array';
81-
}
82-
83-
if ($this->keyType) {
84-
return 'array<' . $this->keyType . ', ' . $this->valueType . '>';
85-
}
86-
87-
if ($this->valueType instanceof Compound) {
88-
return '(' . $this->valueType . ')[]';
89-
}
90-
91-
return $this->valueType . '[]';
92-
}
9373
}

src/Types/Array_.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
namespace phpDocumentor\Reflection\Types;
1515

16+
use function preg_match;
17+
use function substr;
18+
1619
/**
1720
* Represents an array type as described in the PSR-5, the PHPDoc Standard.
1821
*
@@ -26,4 +29,22 @@
2629
*/
2730
class Array_ extends AbstractList
2831
{
32+
public function __toString(): string
33+
{
34+
if ($this->valueType === null) {
35+
return 'array';
36+
}
37+
38+
$valueTypeString = (string) $this->valueType;
39+
40+
if ($this->keyType) {
41+
return 'array<' . $this->keyType . ', ' . $valueTypeString . '>';
42+
}
43+
44+
if (!preg_match('/[^\w\\\\]/', $valueTypeString) || substr($valueTypeString, -2, 2) === '[]') {
45+
return $valueTypeString . '[]';
46+
}
47+
48+
return 'array<' . $valueTypeString . '>';
49+
}
2950
}

tests/unit/TypeResolverTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ public function testResolvingArrayExpressionObjectsTypes(): void
382382
$resolvedType = $fixture->resolve('(\stdClass|Reflection\DocBlock)[]', new Context('phpDocumentor'));
383383

384384
$this->assertInstanceOf(Array_::class, $resolvedType);
385-
$this->assertSame('(\stdClass|\phpDocumentor\Reflection\DocBlock)[]', (string) $resolvedType);
385+
$this->assertSame('array<\stdClass|\phpDocumentor\Reflection\DocBlock>', (string) $resolvedType);
386386

387387
$valueType = $resolvedType->getValueType();
388388

@@ -411,7 +411,7 @@ public function testResolvingArrayExpressionSimpleTypes(): void
411411
$resolvedType = $fixture->resolve('(string|\stdClass|boolean)[]', new Context(''));
412412

413413
$this->assertInstanceOf(Array_::class, $resolvedType);
414-
$this->assertSame('(string|\stdClass|bool)[]', (string) $resolvedType);
414+
$this->assertSame('array<string|\stdClass|bool>', (string) $resolvedType);
415415

416416
$valueType = $resolvedType->getValueType();
417417

@@ -443,7 +443,7 @@ public function testResolvingArrayOfArrayExpressionTypes(): void
443443
$resolvedType = $fixture->resolve('(string|\stdClass)[][]', new Context(''));
444444

445445
$this->assertInstanceOf(Array_::class, $resolvedType);
446-
$this->assertSame('(string|\stdClass)[][]', (string) $resolvedType);
446+
$this->assertSame('array<array<string|\stdClass>>', (string) $resolvedType);
447447

448448
$parentArrayType = $resolvedType->getValueType();
449449
$this->assertInstanceOf(Array_::class, $parentArrayType);
@@ -489,7 +489,7 @@ public function testResolvingArrayExpressionOrCompoundTypes(): void
489489
$resolvedType = $fixture->resolve('\stdClass|(string|\stdClass)[]|bool', new Context(''));
490490

491491
$this->assertInstanceOf(Compound::class, $resolvedType);
492-
$this->assertSame('\stdClass|(string|\stdClass)[]|bool', (string) $resolvedType);
492+
$this->assertSame('\stdClass|array<string|\stdClass>|bool', (string) $resolvedType);
493493

494494
$firstType = $resolvedType->get(0);
495495
$this->assertInstanceOf(Object_::class, $firstType);

tests/unit/Types/ArrayTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
namespace phpDocumentor\Reflection\Types;
1515

1616
use phpDocumentor\Reflection\Fqsen;
17+
use phpDocumentor\Reflection\PseudoTypes\ArrayShape;
18+
use phpDocumentor\Reflection\PseudoTypes\ArrayShapeItem;
19+
use phpDocumentor\Reflection\PseudoTypes\ObjectShape;
20+
use phpDocumentor\Reflection\PseudoTypes\ObjectShapeItem;
1721
use PHPUnit\Framework\TestCase;
1822

1923
final class ArrayTest extends TestCase
@@ -63,8 +67,27 @@ public function provideToStringData(): array
6367
'simple array' => [new Array_(), 'array'],
6468
'array of mixed' => [new Array_(new Mixed_()), 'mixed[]'],
6569
'array of single type' => [new Array_(new String_()), 'string[]'],
66-
'array of compound type' => [new Array_(new Compound([new Integer(), new String_()])), '(int|string)[]'],
70+
'multidimensional array' => [new Array_(new Array_(new String_())), 'string[][]'],
71+
'array of compound type' => [new Array_(new Compound([new Integer(), new String_()])), 'array<int|string>'],
6772
'array with key type' => [new Array_(new String_(), new Integer()), 'array<int, string>'],
73+
'array of array shapes' => [
74+
new Array_(
75+
new ArrayShape(
76+
new ArrayShapeItem('foo', new String_(), false),
77+
new ArrayShapeItem('bar', new Integer(), false)
78+
)
79+
),
80+
'array<array{foo: string, bar: int}>',
81+
],
82+
'array of object shapes' => [
83+
new Array_(
84+
new ObjectShape(
85+
new ObjectShapeItem('foo', new String_(), false),
86+
new ObjectShapeItem('bar', new Integer(), false)
87+
)
88+
),
89+
'array<object{foo: string, bar: int}>',
90+
],
6891
];
6992
}
7093
}

tests/unit/Types/ContextFactoryTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,5 +262,10 @@ public function assertNamespaceAliasesFrom(Context $context): void
262262
class Foo extends AbstractList
263263
{
264264
// dummy class
265+
266+
public function __toString(): string
267+
{
268+
return '';
269+
}
265270
}
266271
}

0 commit comments

Comments
 (0)