mirror of
https://github.com/barryvdh/ReflectionDocBlock.git
synced 2026-08-17 17:47:13 +00:00
Parse template tag for generics (#21)
* Parse template tag for generics * Fixed templatetag docblock * Fixed PHP 7 issue * Fixed PHP 7.2 issue * Fixed another 7.2 issue
This commit is contained in:
@@ -15,6 +15,7 @@ namespace Barryvdh\Reflection;
|
||||
use Barryvdh\Reflection\DocBlock\Tag;
|
||||
use Barryvdh\Reflection\DocBlock\Context;
|
||||
use Barryvdh\Reflection\DocBlock\Location;
|
||||
use Barryvdh\Reflection\DocBlock\Tag\TemplateTag;
|
||||
|
||||
/**
|
||||
* Parses the DocBlock for any structure.
|
||||
@@ -40,6 +41,9 @@ class DocBlock implements \Reflector
|
||||
*/
|
||||
protected $tags = array();
|
||||
|
||||
/** @var string[] An array containing all the generics in this docblock. */
|
||||
protected $generics = array();
|
||||
|
||||
/** @var Context Information about the context of this DocBlock. */
|
||||
protected $context = null;
|
||||
|
||||
@@ -238,7 +242,11 @@ class DocBlock implements \Reflector
|
||||
|
||||
// create proper Tag objects
|
||||
foreach ($result as $key => $tag_line) {
|
||||
$result[$key] = Tag::createInstance(trim($tag_line), $this);
|
||||
$tag = Tag::createInstance(trim($tag_line), $this);
|
||||
if ($tag instanceof TemplateTag) {
|
||||
$this->generics[] = $tag->getTemplateName();
|
||||
}
|
||||
$result[$key] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +465,16 @@ class DocBlock implements \Reflector
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the generics for this DocBlock.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getGenerics()
|
||||
{
|
||||
return $this->generics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a string representation of this object.
|
||||
*
|
||||
|
||||
@@ -97,7 +97,9 @@ class Tag implements \Reflector
|
||||
'version'
|
||||
=> '\Barryvdh\Reflection\DocBlock\Tag\VersionTag',
|
||||
'SuppressWarnings'
|
||||
=> '\Barryvdh\Reflection\DocBlock\Tag\SuppressWarningsTag'
|
||||
=> '\Barryvdh\Reflection\DocBlock\Tag\SuppressWarningsTag',
|
||||
'template'
|
||||
=> '\Barryvdh\Reflection\DocBlock\Tag\TemplateTag'
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -120,7 +120,8 @@ class ReturnTag extends Tag
|
||||
if (null === $this->types) {
|
||||
$this->types = new Collection(
|
||||
array($this->type),
|
||||
$this->docblock ? $this->docblock->getContext() : null
|
||||
$this->docblock ? $this->docblock->getContext() : null,
|
||||
$this->docblock ? $this->docblock->getGenerics() : array()
|
||||
);
|
||||
}
|
||||
return $this->types;
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?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 Barryvdh\Reflection\DocBlock\Tag;
|
||||
|
||||
/**
|
||||
* Reflection class for a @template tag in a Docblock.
|
||||
*
|
||||
* @author chack1172 <[email protected]>
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
||||
* @link http://phpdoc.org
|
||||
*/
|
||||
class TemplateTag extends ParamTag
|
||||
{
|
||||
/** @var string */
|
||||
protected $templateName = null;
|
||||
|
||||
/** @var string|null */
|
||||
protected $bound = null;
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
if (null === $this->content) {
|
||||
$this->content = $this->templateName;
|
||||
if (null !== $this->bound) {
|
||||
$this->content .= ' of ' . $this->bound;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setContent($content)
|
||||
{
|
||||
$parts = explode(' of ', $content);
|
||||
$this->templateName = $parts[0];
|
||||
if (isset($parts[1])) {
|
||||
$this->bound = $parts[1];
|
||||
}
|
||||
|
||||
$this->setDescription('');
|
||||
$this->content = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the template name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplateName()
|
||||
{
|
||||
return $this->templateName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the template name
|
||||
*
|
||||
* @param string $templateName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTemplateName($templateName)
|
||||
{
|
||||
$this->templateName = $templateName;
|
||||
$this->content = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bound type
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getBound()
|
||||
{
|
||||
return $this->bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bound type
|
||||
* @param string|null $bound
|
||||
* @return $this
|
||||
*/
|
||||
public function setBound($bound)
|
||||
{
|
||||
$this->bound = $bound;
|
||||
$this->content = null;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,13 @@ class Collection extends \ArrayObject
|
||||
*/
|
||||
protected $context = null;
|
||||
|
||||
/**
|
||||
* List of generics types
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $generics = array();
|
||||
|
||||
/**
|
||||
* Registers the namespace and aliases; uses that to add and expand the
|
||||
* given types.
|
||||
@@ -60,9 +67,11 @@ class Collection extends \ArrayObject
|
||||
*/
|
||||
public function __construct(
|
||||
array $types = array(),
|
||||
?Context $context = null
|
||||
?Context $context = null,
|
||||
array $generics = array()
|
||||
) {
|
||||
$this->context = null === $context ? new Context() : $context;
|
||||
$this->generics = $generics;
|
||||
|
||||
foreach ($types as $type) {
|
||||
$this->add($type);
|
||||
@@ -197,7 +206,7 @@ class Collection extends \ArrayObject
|
||||
return $this->expand(substr($type, 0, -2)) . self::OPERATOR_ARRAY;
|
||||
}
|
||||
|
||||
if ($this->isRelativeType($type) && !$this->isTypeAKeyword($type)) {
|
||||
if ($this->isRelativeType($type) && !$this->isTypeAKeyword($type) && !$this->isTypeAGeneric($type)) {
|
||||
|
||||
if($this->shouldBeAbsolute($type)){
|
||||
return self::OPERATOR_NAMESPACE . $type;
|
||||
@@ -273,6 +282,19 @@ class Collection extends \ArrayObject
|
||||
|| $this->isTypeAKeyword($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects whether the given type represents a generic.
|
||||
*
|
||||
* @param string $type A relative or absolute type as defined in the
|
||||
* phpDocumentor documentation.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isTypeAGeneric($type)
|
||||
{
|
||||
return in_array($type, $this->generics, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if the type should actually be absolute, by checking if it exists.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* phpDocumentor Template Tag Test
|
||||
*
|
||||
* PHP version 5.3
|
||||
*
|
||||
* @author Daniel O'Connor <[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 Barryvdh\Reflection\DocBlock\Tag;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Test class for \Barryvdh\Reflection\DocBlock\Tag\TemplateTag
|
||||
*
|
||||
* @author Daniel O'Connor <[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 TemplateTagTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Test that the phpDocumentor_Reflection_DocBlock_Tag_See can create a link
|
||||
* for the @see doc block.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $content
|
||||
* @param string $exContent
|
||||
* @param string $exReference
|
||||
*
|
||||
* @covers \Barryvdh\Reflection\DocBlock\Tag\SeeTag
|
||||
* @dataProvider provideDataForConstuctor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConstructorParesInputsIntoCorrectFields(
|
||||
$type,
|
||||
$content,
|
||||
$exContent,
|
||||
$exDescription,
|
||||
$exTemplateName,
|
||||
$exBound
|
||||
) {
|
||||
$tag = new TemplateTag($type, $content);
|
||||
|
||||
$this->assertEquals($type, $tag->getName());
|
||||
$this->assertEquals($exContent, $tag->getContent());
|
||||
$this->assertEquals($exDescription, $tag->getDescription());
|
||||
$this->assertEquals($exTemplateName, $tag->getTemplateName());
|
||||
$this->assertEquals($exBound, $tag->getBound());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testConstructorParesInputsIntoCorrectFields
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provideDataForConstuctor()
|
||||
{
|
||||
// $type, $content, $exContent, $exDescription, $exTemplateName, $exBound
|
||||
return array(
|
||||
array(
|
||||
'template',
|
||||
'TValue',
|
||||
'TValue',
|
||||
'',
|
||||
'TValue',
|
||||
null,
|
||||
),
|
||||
array(
|
||||
'template',
|
||||
'TValue of string',
|
||||
'TValue of string',
|
||||
'',
|
||||
'TValue',
|
||||
'string',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -144,6 +144,27 @@ class CollectionTest extends TestCase
|
||||
$this->assertSame($expected, $collection->getArrayCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fixture
|
||||
* @param array $expected
|
||||
*
|
||||
* @dataProvider provideTypesToExpandWithGenerics
|
||||
* @covers Barryvdh\Reflection\DocBlock\Type\Collection::add
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAddWithGenerics($fixture, $expected)
|
||||
{
|
||||
$collection = new Collection(
|
||||
array(),
|
||||
new Context('\My\Space', array('Alias' => '\My\Space\Aliasing')),
|
||||
array('TValue')
|
||||
);
|
||||
$collection->add($fixture);
|
||||
|
||||
$this->assertSame($expected, $collection->getArrayCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Barryvdh\Reflection\DocBlock\Type\Collection::add
|
||||
*
|
||||
@@ -267,4 +288,22 @@ class CollectionTest extends TestCase
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the types and their expected values to test the retrieval of
|
||||
* types including generics.
|
||||
*
|
||||
* @param string $method Name of the method consuming this data provider.
|
||||
* @param string $namespace Name of the namespace to user as basis.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function provideTypesToExpandWithGenerics($method, $namespace = '\My\Space\\')
|
||||
{
|
||||
return array(
|
||||
array('TValue', array('TValue')),
|
||||
array('TValue[]', array('TValue[]')),
|
||||
array('TValue|DocBlock', array('TValue', $namespace . 'DocBlock')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,4 +336,22 @@ DOCBLOCK;
|
||||
$this->assertCount(1, $object->getTagsByName('return'));
|
||||
$this->assertCount(2, $object->getTagsByName('param'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Barryvdh\Reflection\DocBlock::parseTags
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGenericsAreParsed()
|
||||
{
|
||||
$fixture = <<<DOCBLOCK
|
||||
/**
|
||||
* @template TValue
|
||||
* @param TValue
|
||||
* @return TValue
|
||||
*/
|
||||
DOCBLOCK;
|
||||
$object = new DocBlock($fixture);
|
||||
$this->assertSame(array('TValue'), $object->getGenerics());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user