Skip to content

Commit

Permalink
Resolve nullable types using a Nullable type wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
asgrim authored and jaapio committed Apr 30, 2017
1 parent 9cf5c16 commit 719e816
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/TypeResolver.php
Expand Up @@ -16,6 +16,7 @@
use phpDocumentor\Reflection\Types\Compound;
use phpDocumentor\Reflection\Types\Context;
use phpDocumentor\Reflection\Types\Iterable_;
use phpDocumentor\Reflection\Types\Nullable;
use phpDocumentor\Reflection\Types\Object_;

final class TypeResolver
Expand Down Expand Up @@ -102,6 +103,8 @@ public function resolve($type, Context $context = null)
}

switch (true) {
case $this->isNullableType($type):
return $this->resolveNullableType($type, $context);
case $this->isKeyword($type):
return $this->resolveKeyword($type);
case ($this->isCompoundType($type)):
Expand Down Expand Up @@ -208,6 +211,18 @@ private function isCompoundType($type)
return strpos($type, '|') !== false;
}

/**
* Test whether the given type is a nullable type (i.e. `?string`)
*
* @param string $type
*
* @return bool
*/
private function isNullableType($type)
{
return $type[0] === '?';
}

/**
* Resolves the given typed array string (i.e. `string[]`) into an Array object with the right types set.
*
Expand Down Expand Up @@ -265,4 +280,17 @@ private function resolveCompoundType($type, Context $context)

return new Compound($types);
}

/**
* Resolve nullable types (i.e. `?string`) into a Nullable type wrapper
*
* @param string $type
* @param Context $context
*
* @return Nullable
*/
private function resolveNullableType($type, Context $context)
{
return new Nullable($this->resolve(ltrim($type, '?'), $context));
}
}
56 changes: 56 additions & 0 deletions src/Types/Nullable.php
@@ -0,0 +1,56 @@
<?php
/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://phpdoc.org
*/

namespace phpDocumentor\Reflection\Types;

use phpDocumentor\Reflection\Type;

/**
* Value Object representing a nullable type. The real type is wrapped.
*/
final class Nullable implements Type
{
/**
* @var Type
*/
private $realType;

/**
* Initialises this nullable type using the real type embedded
*
* @param Type $realType
*/
public function __construct(Type $realType)
{
$this->realType = $realType;
}

/**
* Provide access to the actual type directly, if needed.
*
* @return Type
*/
public function getActualType()
{
return $this->realType;
}

/**
* Returns a rendered output of the Type as it would be used in a DocBlock.
*
* @return string
*/
public function __toString()
{
return '?' . $this->realType->__toString();
}
}
23 changes: 23 additions & 0 deletions tests/unit/TypeResolverTest.php
Expand Up @@ -17,7 +17,9 @@
use phpDocumentor\Reflection\Types\Compound;
use phpDocumentor\Reflection\Types\Context;
use phpDocumentor\Reflection\Types\Iterable_;
use phpDocumentor\Reflection\Types\Nullable;
use phpDocumentor\Reflection\Types\Object_;
use phpDocumentor\Reflection\Types\String_;

/**
* @coversDefaultClass phpDocumentor\Reflection\TypeResolver
Expand Down Expand Up @@ -142,6 +144,27 @@ public function testResolvingTypedArrays()
$this->assertInstanceOf('phpDocumentor\Reflection\Types\String_', $resolvedType->getValueType());
}

/**
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Nullable
* @uses \phpDocumentor\Reflection\Types\String_
*/
public function testResolvingNullableTypes()
{
$fixture = new TypeResolver();

/** @var Nullable $resolvedType */
$resolvedType = $fixture->resolve('?string', new Context(''));

$this->assertInstanceOf(Nullable::class, $resolvedType);
$this->assertInstanceOf(String_::class, $resolvedType->getActualType());
$this->assertSame('?string', (string)$resolvedType);
}

/**
* @covers ::__construct
* @covers ::resolve
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/Types/NullableTest.php
@@ -0,0 +1,40 @@
<?php
/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://phpdoc.org
*/

namespace phpDocumentor\Reflection\Types;

/**
* @coversDefaultClass \phpDocumentor\Reflection\Types\Nullable
*/
class NullableTest extends \PHPUnit_Framework_TestCase
{
/**
* @covers ::__construct
* @covers ::getActualType
*/
public function testNullableTypeWrapsCorrectly()
{
$realType = new String_();

$nullableString = new Nullable($realType);

$this->assertSame($realType, $nullableString->getActualType());
}

/**
* @covers ::__toString
*/
public function testNullableStringifyCorrectly()
{
$this->assertSame('?string', (string)(new Nullable(new String_())));
}
}

0 comments on commit 719e816

Please sign in to comment.