Skip to content

Commit

Permalink
Address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentj authored and jaapio committed Aug 17, 2017
1 parent 13ebf89 commit e555aca
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 98 deletions.
2 changes: 1 addition & 1 deletion src/TypeResolver.php
Expand Up @@ -5,7 +5,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
* @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://phpdoc.org
*/
Expand Down
94 changes: 94 additions & 0 deletions src/Types/AbstractList.php
@@ -0,0 +1,94 @@
<?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-2015 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;

/**
* Represents a list of values. This is an abstract class for Array_ and Collection.
*
*/
abstract class AbstractList implements Type
{
/** @var Type */
protected $valueType;

/** @var Type|null */
protected $keyType;

/** @var Type */
protected $defaultKeyType;

/**
* Initializes this representation of an array with the given Type.
*
* @param Type $valueType
* @param Type $keyType
*/
public function __construct(Type $valueType = null, Type $keyType = null)
{
if ($valueType === null) {
$valueType = new Mixed_();
}

$this->valueType = $valueType;
$this->defaultKeyType = new Compound([ new String_(), new Integer() ]);
$this->keyType = $keyType;

}

/**
* Returns the type for the keys of this array.
*
* @return Type
*/
public function getKeyType()
{
if ($this->keyType === null) {
return $this->defaultKeyType;
}
return $this->keyType;
}

/**
* Returns the value for the keys of this array.
*
* @return Type
*/
public function getValueType()
{
return $this->valueType;
}

/**
* Returns a rendered output of the Type as it would be used in a DocBlock.
*
* @return string
*/
public function __toString()
{
if ($this->keyType) {
return 'array<'.$this->keyType.','.$this->valueType.'>';
}

if ($this->valueType instanceof Mixed_) {
return 'array';
}

if ($this->valueType instanceof Compound) {
return '(' . $this->valueType . ')[]';
}

return $this->valueType . '[]';
}
}
75 changes: 1 addition & 74 deletions src/Types/Array_.php
Expand Up @@ -12,8 +12,6 @@

namespace phpDocumentor\Reflection\Types;

use phpDocumentor\Reflection\Type;

/**
* Represents an array type as described in the PSR-5, the PHPDoc Standard.
*
Expand All @@ -23,77 +21,6 @@
* 2. Types (`string[]`), where the value type is provided by preceding an opening and closing square bracket with a
* type name.
*/
class Array_ implements Type
final class Array_ extends AbstractList
{
/** @var Type */
protected $valueType;

/** @var Type|null */
protected $keyType;

/** @var Type */
protected $defaultKeyType;

/**
* Initializes this representation of an array with the given Type.
*
* @param Type $valueType
* @param Type $keyType
*/
public function __construct(Type $valueType = null, Type $keyType = null)
{
if ($valueType === null) {
$valueType = new Mixed_();
}

$this->valueType = $valueType;
$this->defaultKeyType = new Compound([ new String_(), new Integer() ]);
$this->keyType = $keyType;

}

/**
* Returns the type for the keys of this array.
*
* @return Type
*/
public function getKeyType()
{
if ($this->keyType === null) {
return $this->defaultKeyType;
}
return $this->keyType;
}

/**
* Returns the value for the keys of this array.
*
* @return Type
*/
public function getValueType()
{
return $this->valueType;
}

/**
* Returns a rendered output of the Type as it would be used in a DocBlock.
*
* @return string
*/
public function __toString()
{
if ($this->keyType) {
return 'array<'.$this->keyType.','.$this->valueType.'>';
}

if ($this->valueType instanceof Mixed_) {
return 'array';
}

if ($this->valueType instanceof Compound) {
return '(' . $this->valueType . ')[]';
}

return $this->valueType . '[]';
}
}
4 changes: 2 additions & 2 deletions src/Types/Collection.php
Expand Up @@ -26,7 +26,7 @@
* - ACollectionObject can be 'array' or an object that can act as an array
* - aValueType and aKeyType can be any type expression
*/
class Collection extends Array_
final class Collection extends AbstractList
{

/** @var Fqsen */
Expand All @@ -43,7 +43,6 @@ public function __construct(Fqsen $fqsen, Type $valueType, Type $keyType = null)
parent::__construct($valueType, $keyType);

$this->fqsen = $fqsen;

}

/**
Expand All @@ -66,6 +65,7 @@ public function __toString()
if ($this->keyType === null) {
return $this->fqsen.'<'.$this->valueType . '>';
}

return $this->fqsen.'<'.$this->keyType . ',' . $this->valueType . '>';
}
}
51 changes: 30 additions & 21 deletions tests/unit/CollectionResolverTest.php
Expand Up @@ -12,19 +12,14 @@

namespace phpDocumentor\Reflection;

use Mockery as m;
use phpDocumentor\Reflection\Types\Array_;
use phpDocumentor\Reflection\Types\Collection;
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\Boolean;
use Mockery\MockInterface;
use phpDocumentor\Reflection\Types\String_;

/**
* @covers ::<private>
* @coversDefaultClass phpDocumentor\Reflection\TypeResolver
*/
class CollectionResolverTest extends \PHPUnit_Framework_TestCase
Expand All @@ -33,7 +28,6 @@ class CollectionResolverTest extends \PHPUnit_Framework_TestCase
*
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Compound
Expand Down Expand Up @@ -65,7 +59,6 @@ public function testResolvingCollection() {
*
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Compound
Expand Down Expand Up @@ -99,7 +92,6 @@ public function testResolvingCollectionWithKeyType() {
*
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Compound
Expand Down Expand Up @@ -129,7 +121,6 @@ public function testResolvingArrayCollection() {
*
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Compound
Expand Down Expand Up @@ -159,7 +150,6 @@ public function testResolvingArrayCollectionWithKey() {
*
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Compound
Expand Down Expand Up @@ -192,61 +182,80 @@ public function testResolvingCollectionOfCollection() {
$this->assertInstanceOf(Types\Float_::class, $keyType->get(2));
}


/**
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
* @expectedException \RuntimeException
* @expectedExceptionMessage An array can have only integers or strings as keys
*/
public function testBadArrayCollectionKey()
{
$fixture = new TypeResolver();
$fixture->resolve('array<object,string>', new Context(''));

}

/**
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
* @expectedException \RuntimeException
* @expectedExceptionMessage Unexpected collection operator "<", class name is missing
*/
public function testMissingStartCollection()
{
$fixture = new TypeResolver();
$fixture->resolve('<string>', new Context(''));

}

/**
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
* @expectedException \RuntimeException
* @expectedExceptionMessage Collection: ">" is missing
*/
public function testMissingEndCollection()
{
$fixture = new TypeResolver();
$fixture->resolve('ArrayObject<object|string', new Context(''));

}


/**
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
* @expectedException \RuntimeException
* @expectedExceptionMessage string is not a collection
*/
public function testBadCollectionClass()
{
$fixture = new TypeResolver();
$fixture->resolve('string<integer>', new Context(''));
}

/**
*
* @covers ::__construct
* @covers ::resolve
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Compound
* @uses \phpDocumentor\Reflection\Types\Collection
* @uses \phpDocumentor\Reflection\Types\String_
*/
public function testResolvingCollectionAsArray() {
$fixture = new TypeResolver();

/** @var Collection $resolvedType */
$resolvedType = $fixture->resolve('array<string,float>', new Context(''));

$this->assertInstanceOf(Array_::class, $resolvedType);
$this->assertSame('array<string,float>', (string)$resolvedType);

/** @var Array_ $valueType */
$valueType = $resolvedType->getValueType();

/** @var Compound $keyType */
$keyType = $resolvedType->getKeyType();

$this->assertInstanceOf(Types\Float_::class, $valueType);
$this->assertInstanceOf(Types\String_::class, $keyType);
}
}
}

0 comments on commit e555aca

Please sign in to comment.