Skip to content

Commit 0d5382e

Browse files
committed
Add GenericTemplate
1 parent 9f4525f commit 0d5382e

5 files changed

Lines changed: 96 additions & 7 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link http://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Reflection\PseudoTypes;
15+
16+
use phpDocumentor\Reflection\Type;
17+
use phpDocumentor\Reflection\Types\Object_;
18+
19+
/**
20+
* Value Object representing the wrapper over the generic.
21+
*
22+
* @psalm-immutable
23+
*/
24+
final class GenericTemplate implements Type
25+
{
26+
/** @var Object_ */
27+
private $resolvedType;
28+
29+
public function __construct(Object_ $resolvedType)
30+
{
31+
$this->resolvedType = $resolvedType;
32+
}
33+
34+
public function getResolvedType(): Object_
35+
{
36+
return $this->resolvedType;
37+
}
38+
39+
public function __toString(): string
40+
{
41+
return (string) $this->resolvedType;
42+
}
43+
}

src/TypeResolver.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use phpDocumentor\Reflection\PseudoTypes\False_;
2525
use phpDocumentor\Reflection\PseudoTypes\FloatValue;
2626
use phpDocumentor\Reflection\PseudoTypes\Generic;
27+
use phpDocumentor\Reflection\PseudoTypes\GenericTemplate;
2728
use phpDocumentor\Reflection\PseudoTypes\HtmlEscapedString;
2829
use phpDocumentor\Reflection\PseudoTypes\IntegerRange;
2930
use phpDocumentor\Reflection\PseudoTypes\IntegerValue;
@@ -465,7 +466,17 @@ private function createFromGeneric(GenericTypeNode $type, Context $context): Typ
465466
throw new RuntimeException(sprintf('%s is an unsupported generic', (string) $mainType));
466467
}
467468

468-
$types = $this->createTypesByTypeNodes($type->genericTypes, $context);
469+
$types = array_map(
470+
function (TypeNode $node) use ($context): Type {
471+
$innerType = $this->createType($node, $context);
472+
if ($innerType instanceof Object_ && $innerType instanceof Generic === false) {
473+
return new GenericTemplate($innerType);
474+
}
475+
476+
return $innerType;
477+
},
478+
$type->genericTypes
479+
);
469480

470481
return new Generic($mainType->getFqsen(), $types);
471482
}

tests/unit/CollectionResolverTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace phpDocumentor\Reflection;
1515

1616
use phpDocumentor\Reflection\PseudoTypes\Generic;
17+
use phpDocumentor\Reflection\PseudoTypes\GenericTemplate;
1718
use phpDocumentor\Reflection\PseudoTypes\List_;
1819
use phpDocumentor\Reflection\PseudoTypes\NonEmptyList;
1920
use phpDocumentor\Reflection\Types\Array_;
@@ -80,8 +81,7 @@ public function testResolvingCollectionWithKeyType(): void
8081
$this->assertArrayHasKey(0, $types);
8182
$this->assertEquals(new Array_(new String_()), $types[0]);
8283
$this->assertArrayHasKey(1, $types);
83-
$this->assertInstanceOf(Object_::class, $types[1]);
84-
$this->assertSame('\\Iterator', (string) $types[1]->getFqsen());
84+
$this->assertEquals(new GenericTemplate(new Object_(new Fqsen('\\Iterator'))), $types[1]);
8585
}
8686

8787
/**
@@ -193,7 +193,7 @@ public function testResolvingCollectionOfCollection(): void
193193

194194
$nestedGenericTypes = $types[1]->getTypes();
195195
$this->assertArrayHasKey(0, $nestedGenericTypes);
196-
$this->assertEquals(new Object_(new Fqsen('\\DateTime')), $nestedGenericTypes[0]);
196+
$this->assertEquals(new GenericTemplate(new Object_(new Fqsen('\\DateTime'))), $nestedGenericTypes[0]);
197197
}
198198

199199
/**
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Reflection\PseudoTypes;
6+
7+
use phpDocumentor\Reflection\Fqsen;
8+
use phpDocumentor\Reflection\Types\Object_;
9+
use PHPUnit\Framework\TestCase;
10+
11+
/**
12+
* @coversDefaultClass \phpDocumentor\Reflection\PseudoTypes\GenericTemplate
13+
*/
14+
class GenericTemplateTest extends TestCase
15+
{
16+
/**
17+
* @covers ::getResolvedType
18+
*/
19+
public function testCreate(): void
20+
{
21+
$resolvedType = new Object_(new Fqsen('\\Foo\\SomeClass'));
22+
$type = new GenericTemplate($resolvedType);
23+
24+
$this->assertSame($resolvedType, $type->getResolvedType());
25+
}
26+
27+
/**
28+
* @covers ::__toString
29+
*/
30+
public function testToString(): void
31+
{
32+
$type = new GenericTemplate(new Object_(new Fqsen('\\Foo\\SomeClass')));
33+
$this->assertSame('\\Foo\\SomeClass', (string) $type);
34+
}
35+
}

tests/unit/PseudoTypes/GenericTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use PHPUnit\Framework\TestCase;
1313

1414
/**
15-
* @coversDefaultClass \phpDocumentor\Reflection\Types\Generic
15+
* @coversDefaultClass \phpDocumentor\Reflection\PseudoTypes\Generic
1616
*/
1717
class GenericTest extends TestCase
1818
{
@@ -66,11 +66,11 @@ public static function provideToStringData(): array
6666
),
6767
],
6868
'more than two generics' => [
69-
'\\MyClass<\\SomeClassFirst, \\SomeClassSecond, \\SomeClassThird>',
69+
'\\MyClass<\\T, \\SomeClassSecond, \\SomeClassThird>',
7070
new Generic(
7171
new Fqsen('\\MyClass'),
7272
[
73-
new Object_(new Fqsen('\\SomeClassFirst')),
73+
new GenericTemplate(new Object_(new Fqsen('\\T'))),
7474
new Object_(new Fqsen('\\SomeClassSecond')),
7575
new Object_(new Fqsen('\\SomeClassThird')),
7676
]

0 commit comments

Comments
 (0)