mirror of
https://github.com/barryvdh/ReflectionDocBlock.git
synced 2026-08-18 01:57:13 +00:00
Introduce Types
phpDocumentor is capable of representing a whole series of types, more than PHP supports in fact, and this commit represents those types and a Resolver that is capable of taking a type Expression and resolving that to a series of Value Objects representing those types.
This commit is contained in:
committed by
Mike van Riel
parent
fab7169255
commit
b54671f51f
+26
-2
@@ -10,12 +10,21 @@
|
|||||||
* @link http://phpdoc.org
|
* @link http://phpdoc.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace phpDocumentor\Reflection\Types;
|
namespace phpDocumentor\Reflection\Types;
|
||||||
|
|
||||||
|
use phpDocumentor\Reflection\Fqsen;
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
class Array_ implements Type
|
/**
|
||||||
|
* Represents an array type as described in the PSR-5, the PHPDoc Standard.
|
||||||
|
*
|
||||||
|
* An array can be represented in two forms:
|
||||||
|
*
|
||||||
|
* 1. Untyped (`array`), where the key and value type is unknown and hence classified as 'Mixed'.
|
||||||
|
* 2. Types (`string[]`), where the value type is provided by preceding an opening and closing square bracket with a
|
||||||
|
* type name.
|
||||||
|
*/
|
||||||
|
final class Array_ implements Type
|
||||||
{
|
{
|
||||||
/** @var Type */
|
/** @var Type */
|
||||||
private $valueType;
|
private $valueType;
|
||||||
@@ -23,6 +32,12 @@ class Array_ implements Type
|
|||||||
/** @var Type */
|
/** @var Type */
|
||||||
private $keyType;
|
private $keyType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this representation of an array with the given Type or Fqsen.
|
||||||
|
*
|
||||||
|
* @param Type $valueType
|
||||||
|
* @param Type $keyType
|
||||||
|
*/
|
||||||
public function __construct(Type $valueType = null, Type $keyType = null)
|
public function __construct(Type $valueType = null, Type $keyType = null)
|
||||||
{
|
{
|
||||||
if ($keyType === null) {
|
if ($keyType === null) {
|
||||||
@@ -37,6 +52,8 @@ class Array_ implements Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the type for the keys of this array.
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
*/
|
*/
|
||||||
public function getKeyType()
|
public function getKeyType()
|
||||||
@@ -45,6 +62,8 @@ class Array_ implements Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the value for the keys of this array.
|
||||||
|
*
|
||||||
* @return Type
|
* @return Type
|
||||||
*/
|
*/
|
||||||
public function getValueType()
|
public function getValueType()
|
||||||
@@ -52,6 +71,11 @@ class Array_ implements Type
|
|||||||
return $this->valueType;
|
return $this->valueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
if ($this->valueType instanceof Mixed) {
|
if ($this->valueType instanceof Mixed) {
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing a Boolean type.
|
||||||
|
*/
|
||||||
final class Boolean implements Type
|
final class Boolean implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'bool';
|
return 'bool';
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing a Callable type.
|
||||||
|
*/
|
||||||
final class Callable_ implements Type
|
final class Callable_ implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'callable';
|
return 'callable';
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
<?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<[email protected]>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link http://phpdoc.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace phpDocumentor\Reflection\Types;
|
|
||||||
|
|
||||||
use phpDocumentor\Reflection\Types\Resolver;
|
|
||||||
use phpDocumentor\Reflection\DocBlock\Context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection
|
|
||||||
*/
|
|
||||||
class Collection extends \ArrayObject
|
|
||||||
{
|
|
||||||
/** @var string Definition of the OR operator for types */
|
|
||||||
const OPERATOR_OR = '|';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Current invoking location.
|
|
||||||
*
|
|
||||||
* This is used to prepend to type with a relative location.
|
|
||||||
* May also be 'default' or 'global', in which case they are ignored.
|
|
||||||
*
|
|
||||||
* @var Context
|
|
||||||
*/
|
|
||||||
protected $context = null;
|
|
||||||
/**
|
|
||||||
* @var Resolver
|
|
||||||
*/
|
|
||||||
private $resolver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the namespace and aliases; uses that to add and expand the given types.
|
|
||||||
*
|
|
||||||
* @param string[] $types Array containing a list of types to add to this container.
|
|
||||||
* @param Context $context
|
|
||||||
* @param Resolver $resolver
|
|
||||||
*/
|
|
||||||
public function __construct(array $types = array(), Context $context = null, Resolver $resolver = null)
|
|
||||||
{
|
|
||||||
$this->context = $context ?: new Context('');
|
|
||||||
$this->resolver = $resolver ?: new Resolver();
|
|
||||||
|
|
||||||
foreach ($types as $type) {
|
|
||||||
$this->add($type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current invoking location.
|
|
||||||
*
|
|
||||||
* @return Context
|
|
||||||
*/
|
|
||||||
public function getContext()
|
|
||||||
{
|
|
||||||
return $this->context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new type to the collection and expands it if it contains a
|
|
||||||
* relative namespace.
|
|
||||||
*
|
|
||||||
* If a class in the type contains a relative namespace than this collection
|
|
||||||
* will try to expand that into a FQCN.
|
|
||||||
*
|
|
||||||
* @param string $type A 'Type' as defined in the phpDocumentor
|
|
||||||
* documentation.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException if a non-string argument is passed.
|
|
||||||
*
|
|
||||||
* @see http://phpdoc.org/docs/latest/for-users/types.html for the
|
|
||||||
* definition of a type.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function add($type)
|
|
||||||
{
|
|
||||||
if (!is_string($type)) {
|
|
||||||
throw new \InvalidArgumentException(
|
|
||||||
'A type should be represented by a string, received: '
|
|
||||||
. var_export($type, true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// separate the type by the OR operator
|
|
||||||
$type_parts = explode(self::OPERATOR_OR, $type);
|
|
||||||
foreach ($type_parts as $part) {
|
|
||||||
$expanded_type = $this->resolver->resolve($part, $this->context);
|
|
||||||
if ($expanded_type) {
|
|
||||||
$this[] = $expanded_type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string representation of the collection.
|
|
||||||
*
|
|
||||||
* @return string The resolved types across the collection, separated with
|
|
||||||
* {@link self::OPERATOR_OR}.
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return implode(self::OPERATOR_OR, $this->getArrayCopy());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+26
-4
@@ -10,29 +10,44 @@
|
|||||||
* @link http://phpdoc.org
|
* @link http://phpdoc.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace phpDocumentor\Reflection\Types;
|
namespace phpDocumentor\Reflection\Types;
|
||||||
|
|
||||||
use phpDocumentor\Reflection\Fqsen;
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing a Compound Type.
|
||||||
|
*
|
||||||
|
* A Compound Type is not so much a special keyword or object reference but is a series of Types that are separated
|
||||||
|
* using an OR operator (`|`). This combination of types signifies that whatever is associated with this compound type
|
||||||
|
* may contain a value with any of the given types.
|
||||||
|
*/
|
||||||
final class Compound implements Type
|
final class Compound implements Type
|
||||||
{
|
{
|
||||||
/** @var Type[] */
|
/** @var Type[] */
|
||||||
private $types = [];
|
private $types = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Type[]|Fqsen[] $types
|
* Initializes a compound type (i.e. `string|int`) and tests if the provided types all implement the Type interface.
|
||||||
|
*
|
||||||
|
* @param Type[] $types
|
||||||
*/
|
*/
|
||||||
public function __construct($types)
|
public function __construct($types)
|
||||||
{
|
{
|
||||||
|
foreach ($types as $type) {
|
||||||
|
if (!$type instanceof Type) {
|
||||||
|
throw new \InvalidArgumentException('A compound type can only have other types as elements');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->types = $types;
|
$this->types = $types;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the type at the given index.
|
||||||
|
*
|
||||||
* @param integer $index
|
* @param integer $index
|
||||||
*
|
*
|
||||||
* @return null|Type|Fqsen
|
* @return Type|null
|
||||||
*/
|
*/
|
||||||
public function get($index)
|
public function get($index)
|
||||||
{
|
{
|
||||||
@@ -44,6 +59,8 @@ final class Compound implements Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Tests if this compound type has a type with the given index.
|
||||||
|
*
|
||||||
* @param integer $index
|
* @param integer $index
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
@@ -53,6 +70,11 @@ final class Compound implements Type
|
|||||||
return isset($this->types[$index]);
|
return isset($this->types[$index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return implode('|', $this->types);
|
return implode('|', $this->types);
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing a Float.
|
||||||
|
*/
|
||||||
final class Float implements Type
|
final class Float implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'float';
|
return 'float';
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ use phpDocumentor\Reflection\Type;
|
|||||||
|
|
||||||
final class Integer implements Type
|
final class Integer implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'int';
|
return 'int';
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing an unknown, or mixed, type.
|
||||||
|
*/
|
||||||
final class Mixed implements Type
|
final class Mixed implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'mixed';
|
return 'mixed';
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing a null value or type.
|
||||||
|
*/
|
||||||
final class Null_ implements Type
|
final class Null_ implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'null';
|
return 'null';
|
||||||
|
|||||||
@@ -12,12 +12,59 @@
|
|||||||
|
|
||||||
namespace phpDocumentor\Reflection\Types;
|
namespace phpDocumentor\Reflection\Types;
|
||||||
|
|
||||||
|
use phpDocumentor\Reflection\Fqsen;
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing an object.
|
||||||
|
*
|
||||||
|
* An object can be either typed or untyped. When an object is typed it means that it has an identifier, the FQSEN,
|
||||||
|
* pointing to an element in PHP. Object types that are untyped do not refer to a specific class but represent objects
|
||||||
|
* in general.
|
||||||
|
*/
|
||||||
final class Object_ implements Type
|
final class Object_ implements Type
|
||||||
{
|
{
|
||||||
|
/** @var Fqsen|null */
|
||||||
|
private $fqsen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this object with an optional FQSEN, if not provided this object is considered 'untyped'.
|
||||||
|
*
|
||||||
|
* @param Fqsen $fqsen
|
||||||
|
*/
|
||||||
|
public function __construct(Fqsen $fqsen = null)
|
||||||
|
{
|
||||||
|
if (strpos((string)$fqsen, '::') !== false || strpos((string)$fqsen, '()') !== false) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'Object types can only refer to a class, interface or trait but a method, function, constant or '
|
||||||
|
. 'property was received: ' . (string)$fqsen
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->fqsen = $fqsen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the FQSEN associated with this object.
|
||||||
|
*
|
||||||
|
* @return Fqsen|null
|
||||||
|
*/
|
||||||
|
public function getFqsen()
|
||||||
|
{
|
||||||
|
return $this->fqsen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
|
if ($this->fqsen) {
|
||||||
|
return (string)$this->fqsen;
|
||||||
|
}
|
||||||
|
|
||||||
return 'object';
|
return 'object';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-6
@@ -65,7 +65,7 @@ class Resolver
|
|||||||
* @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be
|
* @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be
|
||||||
* replaced with another namespace.
|
* replaced with another namespace.
|
||||||
*
|
*
|
||||||
* @return Fqsen|Type|null
|
* @return Type|null
|
||||||
*/
|
*/
|
||||||
public function resolve($type, Context $context)
|
public function resolve($type, Context $context)
|
||||||
{
|
{
|
||||||
@@ -101,6 +101,32 @@ class Resolver
|
|||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a keyword to the list of Keywords and associates it with a specific Value Object.
|
||||||
|
*
|
||||||
|
* @param string $keyword
|
||||||
|
* @param string $typeClassName
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addKeyword($keyword, $typeClassName)
|
||||||
|
{
|
||||||
|
if (!class_exists($typeClassName)) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class'
|
||||||
|
. ' but we could not find the class ' . $typeClassName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array(Type::class, class_implements($typeClassName))) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'The class "' . $typeClassName . '" must implement the interface "phpDocumentor\Reflection\Type"'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->keywords[$keyword] = $typeClassName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detects whether the given type represents an array.
|
* Detects whether the given type represents an array.
|
||||||
*
|
*
|
||||||
@@ -193,11 +219,11 @@ class Resolver
|
|||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
*
|
*
|
||||||
* @return Fqsen
|
* @return Object_
|
||||||
*/
|
*/
|
||||||
private function resolveFqsen($type)
|
private function resolveFqsen($type)
|
||||||
{
|
{
|
||||||
return new Fqsen($type);
|
return new Object_(new Fqsen($type));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,7 +233,7 @@ class Resolver
|
|||||||
* @param string $type
|
* @param string $type
|
||||||
* @param Context $context
|
* @param Context $context
|
||||||
*
|
*
|
||||||
* @return Fqsen
|
* @return Object_
|
||||||
*/
|
*/
|
||||||
private function resolvePartialStructuralElementName($type, Context $context)
|
private function resolvePartialStructuralElementName($type, Context $context)
|
||||||
{
|
{
|
||||||
@@ -222,12 +248,12 @@ class Resolver
|
|||||||
$namespace .= self::OPERATOR_NAMESPACE;
|
$namespace .= self::OPERATOR_NAMESPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type);
|
return new Object_(new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type));
|
||||||
}
|
}
|
||||||
|
|
||||||
$typeParts[0] = $namespaceAliases[$typeParts[0]];
|
$typeParts[0] = $namespaceAliases[$typeParts[0]];
|
||||||
|
|
||||||
return new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts));
|
return new Object_(new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing the 'resource' Type.
|
||||||
|
*/
|
||||||
final class Resource implements Type
|
final class Resource implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'resource';
|
return 'resource';
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
class Scalar implements Type
|
/**
|
||||||
|
* Value Object representing the 'scalar' pseudo-type, which is either a string, integer, float or boolean.
|
||||||
|
*/
|
||||||
|
final class Scalar implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'scalar';
|
return 'scalar';
|
||||||
|
|||||||
@@ -14,8 +14,18 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing the 'self' type.
|
||||||
|
*
|
||||||
|
* Self, as a Type, represents the class in which the associated element was defined.
|
||||||
|
*/
|
||||||
final class Self_ implements Type
|
final class Self_ implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'self';
|
return 'self';
|
||||||
|
|||||||
@@ -14,8 +14,23 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing the 'static' type.
|
||||||
|
*
|
||||||
|
* Self, as a Type, represents the class in which the associated element was called. This differs from self as self does
|
||||||
|
* not take inheritance into account but static means that the return type is always that of the class of the called
|
||||||
|
* element.
|
||||||
|
*
|
||||||
|
* See the documentation on late static binding in the PHP Documentation for more information on the difference between
|
||||||
|
* static and self.
|
||||||
|
*/
|
||||||
final class Static_ implements Type
|
final class Static_ implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'static';
|
return 'static';
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing the type 'string'.
|
||||||
|
*/
|
||||||
final class String implements Type
|
final class String implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'string';
|
return 'string';
|
||||||
|
|||||||
@@ -14,8 +14,19 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing the '$this' pseudo-type.
|
||||||
|
*
|
||||||
|
* $this, as a Type, represents the instance of the class associated with the element as it was called. $this is
|
||||||
|
* commonly used when documenting fluent interfaces since it represents that the same object is returned.
|
||||||
|
*/
|
||||||
final class This implements Type
|
final class This implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return '$this';
|
return '$this';
|
||||||
|
|||||||
@@ -14,8 +14,19 @@ namespace phpDocumentor\Reflection\Types;
|
|||||||
|
|
||||||
use phpDocumentor\Reflection\Type;
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value Object representing the pseudo-type 'void'.
|
||||||
|
*
|
||||||
|
* Void is generally only used when working with return types as it signifies that the method intentionally does not
|
||||||
|
* return any value.
|
||||||
|
*/
|
||||||
final class Void implements Type
|
final class Void implements Type
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return 'void';
|
return 'void';
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* phpDocumentor
|
|
||||||
*
|
|
||||||
* PHP Version 5.3
|
|
||||||
*
|
|
||||||
* @author Mike van Riel <[email protected]>
|
|
||||||
* @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link http://phpdoc.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace phpDocumentor\Reflection\DocBlock\Type;
|
|
||||||
|
|
||||||
use phpDocumentor\Reflection\DocBlock\Context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection
|
|
||||||
*
|
|
||||||
* @author Mike van Riel <[email protected]>
|
|
||||||
* @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
||||||
* @link http://phpdoc.org
|
|
||||||
*/
|
|
||||||
class Collection extends \ArrayObject
|
|
||||||
{
|
|
||||||
/** @var string Definition of the OR operator for types */
|
|
||||||
const OPERATOR_OR = '|';
|
|
||||||
|
|
||||||
/** @var string Definition of the ARRAY operator for types */
|
|
||||||
const OPERATOR_ARRAY = '[]';
|
|
||||||
|
|
||||||
/** @var string Definition of the NAMESPACE operator in PHP */
|
|
||||||
const OPERATOR_NAMESPACE = '\\';
|
|
||||||
|
|
||||||
/** @var string[] List of recognized keywords */
|
|
||||||
protected static $keywords = array(
|
|
||||||
'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double',
|
|
||||||
'object', 'mixed', 'array', 'resource', 'void', 'null', 'scalar',
|
|
||||||
'callback', 'callable', 'false', 'true', 'self', '$this', 'static'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Current invoking location.
|
|
||||||
*
|
|
||||||
* This is used to prepend to type with a relative location.
|
|
||||||
* May also be 'default' or 'global', in which case they are ignored.
|
|
||||||
*
|
|
||||||
* @var Context
|
|
||||||
*/
|
|
||||||
protected $context = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the namespace and aliases; uses that to add and expand the
|
|
||||||
* given types.
|
|
||||||
*
|
|
||||||
* @param string[] $types Array containing a list of types to add to this
|
|
||||||
* container.
|
|
||||||
* @param Context $location The current invoking location.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
array $types = array(),
|
|
||||||
Context $context = null
|
|
||||||
) {
|
|
||||||
$this->context = null === $context ? new Context() : $context;
|
|
||||||
|
|
||||||
foreach ($types as $type) {
|
|
||||||
$this->add($type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current invoking location.
|
|
||||||
*
|
|
||||||
* @return Context
|
|
||||||
*/
|
|
||||||
public function getContext()
|
|
||||||
{
|
|
||||||
return $this->context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new type to the collection and expands it if it contains a
|
|
||||||
* relative namespace.
|
|
||||||
*
|
|
||||||
* If a class in the type contains a relative namespace than this collection
|
|
||||||
* will try to expand that into a FQCN.
|
|
||||||
*
|
|
||||||
* @param string $type A 'Type' as defined in the phpDocumentor
|
|
||||||
* documentation.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException if a non-string argument is passed.
|
|
||||||
*
|
|
||||||
* @see http://phpdoc.org/docs/latest/for-users/types.html for the
|
|
||||||
* definition of a type.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function add($type)
|
|
||||||
{
|
|
||||||
if (!is_string($type)) {
|
|
||||||
throw new \InvalidArgumentException(
|
|
||||||
'A type should be represented by a string, received: '
|
|
||||||
.var_export($type, true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// separate the type by the OR operator
|
|
||||||
$type_parts = explode(self::OPERATOR_OR, $type);
|
|
||||||
foreach ($type_parts as $part) {
|
|
||||||
$expanded_type = $this->expand($part);
|
|
||||||
if ($expanded_type) {
|
|
||||||
$this[] = $expanded_type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string representation of the collection.
|
|
||||||
*
|
|
||||||
* @return string The resolved types across the collection, separated with
|
|
||||||
* {@link self::OPERATOR_OR}.
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return implode(self::OPERATOR_OR, $this->getArrayCopy());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Analyzes the given type and returns the FQCN variant.
|
|
||||||
*
|
|
||||||
* When a type is provided this method checks whether it is not a keyword or
|
|
||||||
* Fully Qualified Class Name. If so it will use the given namespace and
|
|
||||||
* aliases to expand the type to a FQCN representation.
|
|
||||||
*
|
|
||||||
* This method only works as expected if the namespace and aliases are set;
|
|
||||||
* no dynamic reflection is being performed here.
|
|
||||||
*
|
|
||||||
* @param string $type The relative or absolute type.
|
|
||||||
*
|
|
||||||
* @uses getNamespace to determine with what to prefix the type name.
|
|
||||||
* @uses getNamespaceAliases to check whether the first part of the relative
|
|
||||||
* type name should not be replaced with another namespace.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function expand($type)
|
|
||||||
{
|
|
||||||
$type = trim($type);
|
|
||||||
if (!$type) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->isTypeAnArray($type)) {
|
|
||||||
return $this->expand(substr($type, 0, -2)) . self::OPERATOR_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->isRelativeType($type) && !$this->isTypeAKeyword($type)) {
|
|
||||||
$type_parts = explode(self::OPERATOR_NAMESPACE, $type, 2);
|
|
||||||
|
|
||||||
$namespace_aliases = $this->context->getNamespaceAliases();
|
|
||||||
// if the first segment is not an alias; prepend namespace name and
|
|
||||||
// return
|
|
||||||
if (!isset($namespace_aliases[$type_parts[0]])) {
|
|
||||||
$namespace = $this->context->getNamespace();
|
|
||||||
if ('' !== $namespace) {
|
|
||||||
$namespace .= self::OPERATOR_NAMESPACE;
|
|
||||||
}
|
|
||||||
return self::OPERATOR_NAMESPACE . $namespace . $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
$type_parts[0] = $namespace_aliases[$type_parts[0]];
|
|
||||||
$type = implode(self::OPERATOR_NAMESPACE, $type_parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects whether the given type represents an array.
|
|
||||||
*
|
|
||||||
* @param string $type A relative or absolute type as defined in the
|
|
||||||
* phpDocumentor documentation.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function isTypeAnArray($type)
|
|
||||||
{
|
|
||||||
return substr($type, -2) === self::OPERATOR_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects whether the given type represents a PHPDoc keyword.
|
|
||||||
*
|
|
||||||
* @param string $type A relative or absolute type as defined in the
|
|
||||||
* phpDocumentor documentation.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function isTypeAKeyword($type)
|
|
||||||
{
|
|
||||||
return in_array(strtolower($type), static::$keywords, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects whether the given type represents a relative or absolute path.
|
|
||||||
*
|
|
||||||
* This method will detect keywords as being absolute; even though they are
|
|
||||||
* not preceeded by a namespace separator.
|
|
||||||
*
|
|
||||||
* @param string $type A relative or absolute type as defined in the
|
|
||||||
* phpDocumentor documentation.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function isRelativeType($type)
|
|
||||||
{
|
|
||||||
return ($type[0] !== self::OPERATOR_NAMESPACE)
|
|
||||||
|| $this->isTypeAKeyword($type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
namespace phpDocumentor\Reflection\Types;
|
namespace phpDocumentor\Reflection\Types;
|
||||||
|
|
||||||
|
use Mockery as m;
|
||||||
use phpDocumentor\Reflection\DocBlock\Context;
|
use phpDocumentor\Reflection\DocBlock\Context;
|
||||||
|
use phpDocumentor\Reflection\Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @coversDefaultClass phpDocumentor\Reflection\Types\Resolver
|
* @coversDefaultClass phpDocumentor\Reflection\Types\Resolver
|
||||||
@@ -26,8 +28,9 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @covers ::resolve
|
* @covers ::resolve
|
||||||
* @covers ::<private>
|
* @covers ::<private>
|
||||||
*
|
*
|
||||||
* @uses phpDocumentor\Reflection\DocBlock\Context
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
* @uses phpDocumentor\Reflection\Types\Array_
|
* @uses phpDocumentor\Reflection\Types\Array_
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Object_
|
||||||
*
|
*
|
||||||
* @dataProvider provideKeywords
|
* @dataProvider provideKeywords
|
||||||
*/
|
*/
|
||||||
@@ -46,8 +49,9 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @covers ::resolve
|
* @covers ::resolve
|
||||||
* @covers ::<private>
|
* @covers ::<private>
|
||||||
*
|
*
|
||||||
* @uses phpDocumentor\Reflection\DocBlock\Context
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
* @uses phpDocumentor\Reflection\Fqsen
|
* @uses phpDocumentor\Reflection\Types\Object_
|
||||||
|
* @uses phpDocumentor\Reflection\Fqsen
|
||||||
*
|
*
|
||||||
* @dataProvider provideFqsen
|
* @dataProvider provideFqsen
|
||||||
*/
|
*/
|
||||||
@@ -55,9 +59,11 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$fixture = new Resolver();
|
$fixture = new Resolver();
|
||||||
|
|
||||||
|
/** @var Object_ $resolvedType */
|
||||||
$resolvedType = $fixture->resolve($fqsen, new Context(''));
|
$resolvedType = $fixture->resolve($fqsen, new Context(''));
|
||||||
|
|
||||||
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType);
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $resolvedType);
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType->getFqsen());
|
||||||
$this->assertSame($fqsen, (string)$resolvedType);
|
$this->assertSame($fqsen, (string)$resolvedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,15 +73,18 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @covers ::<private>
|
* @covers ::<private>
|
||||||
*
|
*
|
||||||
* @uses phpDocumentor\Reflection\DocBlock\Context
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Object_
|
||||||
* @uses phpDocumentor\Reflection\Fqsen
|
* @uses phpDocumentor\Reflection\Fqsen
|
||||||
*/
|
*/
|
||||||
public function testResolvingRelativeQSENsBasedOnNamespace()
|
public function testResolvingRelativeQSENsBasedOnNamespace()
|
||||||
{
|
{
|
||||||
$fixture = new Resolver();
|
$fixture = new Resolver();
|
||||||
|
|
||||||
|
/** @var Object_ $resolvedType */
|
||||||
$resolvedType = $fixture->resolve('DocBlock', new Context('phpDocumentor\Reflection'));
|
$resolvedType = $fixture->resolve('DocBlock', new Context('phpDocumentor\Reflection'));
|
||||||
|
|
||||||
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType);
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $resolvedType);
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType->getFqsen());
|
||||||
$this->assertSame('\phpDocumentor\Reflection\DocBlock', (string)$resolvedType);
|
$this->assertSame('\phpDocumentor\Reflection\DocBlock', (string)$resolvedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,18 +93,21 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @covers ::<private>
|
* @covers ::<private>
|
||||||
*
|
*
|
||||||
* @uses phpDocumentor\Reflection\DocBlock\Context
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Object_
|
||||||
* @uses phpDocumentor\Reflection\Fqsen
|
* @uses phpDocumentor\Reflection\Fqsen
|
||||||
*/
|
*/
|
||||||
public function testResolvingRelativeQSENsBasedOnNamespaceAlias()
|
public function testResolvingRelativeQSENsBasedOnNamespaceAlias()
|
||||||
{
|
{
|
||||||
$fixture = new Resolver();
|
$fixture = new Resolver();
|
||||||
|
|
||||||
|
/** @var Object_ $resolvedType */
|
||||||
$resolvedType = $fixture->resolve(
|
$resolvedType = $fixture->resolve(
|
||||||
'm\MockInterface',
|
'm\MockInterface',
|
||||||
new Context('phpDocumentor\Reflection', ['m' => '\Mockery'])
|
new Context('phpDocumentor\Reflection', ['m' => '\Mockery'])
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType);
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $resolvedType);
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType->getFqsen());
|
||||||
$this->assertSame('\Mockery\MockInterface', (string)$resolvedType);
|
$this->assertSame('\Mockery\MockInterface', (string)$resolvedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +168,7 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
* @uses phpDocumentor\Reflection\DocBlock\Context
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
* @uses phpDocumentor\Reflection\Types\Compound
|
* @uses phpDocumentor\Reflection\Types\Compound
|
||||||
* @uses phpDocumentor\Reflection\Types\String
|
* @uses phpDocumentor\Reflection\Types\String
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Object_
|
||||||
* @uses phpDocumentor\Reflection\Fqsen
|
* @uses phpDocumentor\Reflection\Fqsen
|
||||||
*/
|
*/
|
||||||
public function testResolvingCompoundTypes()
|
public function testResolvingCompoundTypes()
|
||||||
@@ -167,8 +180,98 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType);
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType);
|
||||||
$this->assertSame('string|\phpDocumentor\Reflection\DocBlock', (string)$resolvedType);
|
$this->assertSame('string|\phpDocumentor\Reflection\DocBlock', (string)$resolvedType);
|
||||||
$this->assertInstanceOf('phpDocumentor\Reflection\Types\String', $resolvedType->get(0));
|
|
||||||
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $resolvedType->get(1));
|
/** @var String $secondType */
|
||||||
|
$firstType = $resolvedType->get(0);
|
||||||
|
|
||||||
|
/** @var Object_ $secondType */
|
||||||
|
$secondType = $resolvedType->get(1);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\String', $firstType);
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Object_', $secondType);
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Fqsen', $secondType->getFqsen());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test asserts that the parameter order is correct.
|
||||||
|
*
|
||||||
|
* When you pass two arrays separated by the compound operator (i.e. 'integer[]|string[]') then we always split the
|
||||||
|
* expression in its compound parts and then we parse the types with the array operators. If we were to switch the
|
||||||
|
* order around then 'integer[]|string[]' would read as an array of string or integer array; which is something
|
||||||
|
* other than what we intend.
|
||||||
|
*
|
||||||
|
* @covers ::resolve
|
||||||
|
* @covers ::<private>
|
||||||
|
*
|
||||||
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Compound
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Array_
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Integer
|
||||||
|
* @uses phpDocumentor\Reflection\Types\String
|
||||||
|
*/
|
||||||
|
public function testResolvingCompoundTypesWithTwoArrays()
|
||||||
|
{
|
||||||
|
$fixture = new Resolver();
|
||||||
|
|
||||||
|
/** @var Compound $resolvedType */
|
||||||
|
$resolvedType = $fixture->resolve('integer[]|string[]', new Context(''));
|
||||||
|
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Compound', $resolvedType);
|
||||||
|
$this->assertSame('int[]|string[]', (string)$resolvedType);
|
||||||
|
|
||||||
|
/** @var Array_ $firstType */
|
||||||
|
$firstType = $resolvedType->get(0);
|
||||||
|
|
||||||
|
/** @var Array_ $secondType */
|
||||||
|
$secondType = $resolvedType->get(1);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $firstType);
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Integer', $firstType->getValueType());
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\Array_', $secondType);
|
||||||
|
$this->assertInstanceOf('phpDocumentor\Reflection\Types\String', $secondType->getValueType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::addKeyword
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Resolver::resolve
|
||||||
|
* @uses phpDocumentor\Reflection\Types\Resolver::<private>
|
||||||
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
|
*/
|
||||||
|
public function testAddingAKeyword()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
$typeMock = m::mock(Type::class);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$fixture = new Resolver();
|
||||||
|
$fixture->addKeyword('mock', get_class($typeMock));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$result = $fixture->resolve('mock', new Context(''));
|
||||||
|
$this->assertInstanceOf(get_class($typeMock), $result);
|
||||||
|
$this->assertNotSame($typeMock, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::addKeyword
|
||||||
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testAddingAKeywordFailsIfTypeClassDoesNotExist()
|
||||||
|
{
|
||||||
|
$fixture = new Resolver();
|
||||||
|
$fixture->addKeyword('mock', 'IDoNotExist');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::addKeyword
|
||||||
|
* @uses phpDocumentor\Reflection\DocBlock\Context
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testAddingAKeywordFailsIfTypeClassDoesNotImplementTypeInterface()
|
||||||
|
{
|
||||||
|
$fixture = new Resolver();
|
||||||
|
$fixture->addKeyword('mock', 'stdClass');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,6 +298,11 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
$fixture->resolve(['a'], new Context(''));
|
$fixture->resolve(['a'], new Context(''));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of keywords and expected classes that are created from them.
|
||||||
|
*
|
||||||
|
* @return string[][]
|
||||||
|
*/
|
||||||
public function provideKeywords()
|
public function provideKeywords()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@@ -220,6 +328,11 @@ class ResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of FQSENs to test the resolution patterns with.
|
||||||
|
*
|
||||||
|
* @return string[][]
|
||||||
|
*/
|
||||||
public function provideFqsen()
|
public function provideFqsen()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|||||||
Reference in New Issue
Block a user