Skip to content

Commit ca661c2

Browse files
authored
Merge branch 'master' into feature/code-style-improvements
2 parents 1e36395 + 88bdcb5 commit ca661c2

File tree

5 files changed

+183
-1
lines changed

5 files changed

+183
-1
lines changed

src/TypeResolver.php

+29
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use phpDocumentor\Reflection\Types\Compound;
1717
use phpDocumentor\Reflection\Types\Context;
1818
use phpDocumentor\Reflection\Types\Iterable_;
19+
use phpDocumentor\Reflection\Types\Nullable;
1920
use phpDocumentor\Reflection\Types\Object_;
2021

2122
final class TypeResolver
@@ -49,6 +50,7 @@ final class TypeResolver
4950
'self' => Types\Self_::class,
5051
'$this' => Types\This::class,
5152
'static' => Types\Static_::class,
53+
'parent' => Types\Parent_::class,
5254
'iterable' => Iterable_::class,
5355
);
5456

@@ -102,6 +104,8 @@ public function resolve($type, Context $context = null)
102104
}
103105

104106
switch (true) {
107+
case $this->isNullableType($type):
108+
return $this->resolveNullableType($type, $context);
105109
case $this->isKeyword($type):
106110
return $this->resolveKeyword($type);
107111
case ($this->isCompoundType($type)):
@@ -208,6 +212,18 @@ private function isCompoundType($type)
208212
return strpos($type, '|') !== false;
209213
}
210214

215+
/**
216+
* Test whether the given type is a nullable type (i.e. `?string`)
217+
*
218+
* @param string $type
219+
*
220+
* @return bool
221+
*/
222+
private function isNullableType($type)
223+
{
224+
return $type[0] === '?';
225+
}
226+
211227
/**
212228
* Resolves the given typed array string (i.e. `string[]`) into an Array object with the right types set.
213229
*
@@ -266,4 +282,17 @@ private function resolveCompoundType($type, Context $context)
266282

267283
return new Compound($types);
268284
}
285+
286+
/**
287+
* Resolve nullable types (i.e. `?string`) into a Nullable type wrapper
288+
*
289+
* @param string $type
290+
* @param Context $context
291+
*
292+
* @return Nullable
293+
*/
294+
private function resolveNullableType($type, Context $context)
295+
{
296+
return new Nullable($this->resolve(ltrim($type, '?'), $context));
297+
}
269298
}

src/Types/Nullable.php

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
/**
3+
* This file is part of phpDocumentor.
4+
*
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @copyright 2010-2017 Mike van Riel<[email protected]>
9+
* @license http://www.opensource.org/licenses/mit-license.php MIT
10+
* @link http://phpdoc.org
11+
*/
12+
13+
namespace phpDocumentor\Reflection\Types;
14+
15+
use phpDocumentor\Reflection\Type;
16+
17+
/**
18+
* Value Object representing a nullable type. The real type is wrapped.
19+
*/
20+
final class Nullable implements Type
21+
{
22+
/**
23+
* @var Type
24+
*/
25+
private $realType;
26+
27+
/**
28+
* Initialises this nullable type using the real type embedded
29+
*
30+
* @param Type $realType
31+
*/
32+
public function __construct(Type $realType)
33+
{
34+
$this->realType = $realType;
35+
}
36+
37+
/**
38+
* Provide access to the actual type directly, if needed.
39+
*
40+
* @return Type
41+
*/
42+
public function getActualType()
43+
{
44+
return $this->realType;
45+
}
46+
47+
/**
48+
* Returns a rendered output of the Type as it would be used in a DocBlock.
49+
*
50+
* @return string
51+
*/
52+
public function __toString()
53+
{
54+
return '?' . $this->realType->__toString();
55+
}
56+
}

src/Types/Parent_.php

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
/**
3+
* This file is part of phpDocumentor.
4+
*
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @copyright 2010-2015 Mike van Riel<[email protected]>
9+
* @license http://www.opensource.org/licenses/mit-license.php MIT
10+
* @link http://phpdoc.org
11+
*/
12+
13+
namespace phpDocumentor\Reflection\Types;
14+
15+
use phpDocumentor\Reflection\Type;
16+
17+
/**
18+
* Value Object representing the 'parent' type.
19+
*
20+
* Parent, as a Type, represents the parent class of class in which the associated element was defined.
21+
*/
22+
final class Parent_ implements Type
23+
{
24+
/**
25+
* Returns a rendered output of the Type as it would be used in a DocBlock.
26+
*
27+
* @return string
28+
*/
29+
public function __toString()
30+
{
31+
return 'parent';
32+
}
33+
}

tests/unit/TypeResolverTest.php

+25-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
use phpDocumentor\Reflection\Types\Compound;
1818
use phpDocumentor\Reflection\Types\Context;
1919
use phpDocumentor\Reflection\Types\Iterable_;
20+
use phpDocumentor\Reflection\Types\Nullable;
2021
use phpDocumentor\Reflection\Types\Object_;
2122
use Mockery\MockInterface;
23+
use phpDocumentor\Reflection\Types\String_;
2224

2325
/**
2426
* @coversDefaultClass phpDocumentor\Reflection\TypeResolver
@@ -149,9 +151,30 @@ public function testResolvingTypedArrays()
149151
* @covers ::<private>
150152
*
151153
* @uses \phpDocumentor\Reflection\Types\Context
152-
* @uses \phpDocumentor\Reflection\Types\Array_
154+
* @uses \phpDocumentor\Reflection\Types\Nullable
153155
* @uses \phpDocumentor\Reflection\Types\String_
154156
*/
157+
public function testResolvingNullableTypes()
158+
{
159+
$fixture = new TypeResolver();
160+
161+
/** @var Nullable $resolvedType */
162+
$resolvedType = $fixture->resolve('?string', new Context(''));
163+
164+
$this->assertInstanceOf(Nullable::class, $resolvedType);
165+
$this->assertInstanceOf(String_::class, $resolvedType->getActualType());
166+
$this->assertSame('?string', (string)$resolvedType);
167+
}
168+
169+
/**
170+
* @covers ::__construct
171+
* @covers ::resolve
172+
* @covers ::<private>
173+
*
174+
* @uses phpDocumentor\Reflection\Types\Context
175+
* @uses phpDocumentor\Reflection\Types\Array_
176+
* @uses phpDocumentor\Reflection\Types\String_
177+
*/
155178
public function testResolvingNestedTypedArrays()
156179
{
157180
$fixture = new TypeResolver();
@@ -379,6 +402,7 @@ public function provideKeywords()
379402
['$this', Types\This::class],
380403
['static', Types\Static_::class],
381404
['self', Types\Self_::class],
405+
['parent', Types\Parent_::class],
382406
['iterable', Iterable_::class],
383407
];
384408
}

tests/unit/Types/NullableTest.php

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* This file is part of phpDocumentor.
4+
*
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @copyright 2010-2017 Mike van Riel<[email protected]>
9+
* @license http://www.opensource.org/licenses/mit-license.php MIT
10+
* @link http://phpdoc.org
11+
*/
12+
13+
namespace phpDocumentor\Reflection\Types;
14+
15+
/**
16+
* @coversDefaultClass \phpDocumentor\Reflection\Types\Nullable
17+
*/
18+
class NullableTest extends \PHPUnit_Framework_TestCase
19+
{
20+
/**
21+
* @covers ::__construct
22+
* @covers ::getActualType
23+
*/
24+
public function testNullableTypeWrapsCorrectly()
25+
{
26+
$realType = new String_();
27+
28+
$nullableString = new Nullable($realType);
29+
30+
$this->assertSame($realType, $nullableString->getActualType());
31+
}
32+
33+
/**
34+
* @covers ::__toString
35+
*/
36+
public function testNullableStringifyCorrectly()
37+
{
38+
$this->assertSame('?string', (string)(new Nullable(new String_())));
39+
}
40+
}

0 commit comments

Comments
 (0)