Skip to content

Commit c2f6921

Browse files
committed
Merge branch 'master' of github.com:boenrobot/ReflectionDocBlock into author
Conflicts: src/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.php
2 parents f19dac1 + 1ac9106 commit c2f6921

24 files changed

+863
-432
lines changed

src/phpDocumentor/Reflection/DocBlock.php

Lines changed: 9 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class DocBlock implements \Reflector
3939
/** @var string the current namespace */
4040
protected $namespace = '\\';
4141

42-
/** @var string[] List of namespace aliases => Fully Qualified Namespace */
42+
/** @var array List of namespace aliases => Fully Qualified Namespace */
4343
protected $namespace_aliases = array();
4444

4545
/**
@@ -56,7 +56,7 @@ class DocBlock implements \Reflector
5656
* asterisks) or reflector supporting the getDocComment method.
5757
* @param string $namespace The namespace where this
5858
* DocBlock resides in; defaults to `\`.
59-
* @param string[] $namespace_aliases A list of namespace aliases
59+
* @param array $namespace_aliases A list of namespace aliases
6060
* as provided by the `use` keyword; the key of the array is the alias
6161
* name or last part of the alias array if no alias name is provided.
6262
*
@@ -66,7 +66,7 @@ class DocBlock implements \Reflector
6666
public function __construct(
6767
$docblock,
6868
$namespace = '\\',
69-
$namespace_aliases = array()
69+
array $namespace_aliases = array()
7070
) {
7171
if (is_object($docblock)) {
7272
if (!method_exists($docblock, 'getDocComment')) {
@@ -83,7 +83,7 @@ public function __construct(
8383

8484
list($short, $long, $tags) = $this->splitDocBlock($docblock);
8585
$this->short_description = $short;
86-
$this->long_description = new DocBlock\LongDescription($long);
86+
$this->long_description = new DocBlock\Description($long);
8787
$this->parseTags($tags);
8888

8989
$this->namespace = $namespace;
@@ -222,9 +222,7 @@ protected function parseTags($tags)
222222

223223
// create proper Tag objects
224224
foreach ($result as $key => $tag_line) {
225-
$tag = DocBlock\Tag::createInstance($tag_line);
226-
$tag->setDocBlock($this);
227-
$result[$key] = $tag;
225+
$result[$key] = DocBlock\Tag::createInstance($tag_line, $this);
228226
}
229227
}
230228

@@ -304,85 +302,6 @@ public function hasTag($name)
304302
return false;
305303
}
306304

307-
/**
308-
* Tries to expand a type to it's full namespaced equivalent (FQCN).
309-
*
310-
* This method will take the given type and examine the current namespace
311-
* and namespace aliases to see whether it should expand it into a FQCN
312-
* as defined by the rules in PHP.
313-
*
314-
* @param string $type Type to expand into full namespaced
315-
* equivalent.
316-
* @param string[] $ignore_keywords Whether to ignore given keywords, when
317-
* null it will use the default keywords:
318-
* 'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double',
319-
* 'object', 'mixed', 'array', 'resource', 'void', 'null', 'callback',
320-
* 'false', 'true', 'self', '$this', 'callable'.
321-
* Default value for this parameter is null.
322-
*
323-
* @return string
324-
*/
325-
public function expandType($type, $ignore_keywords = null)
326-
{
327-
if ($type === null) {
328-
return null;
329-
}
330-
331-
if ($ignore_keywords === null) {
332-
$ignore_keywords = array(
333-
'string', 'int', 'integer', 'bool', 'boolean', 'float',
334-
'double', 'object', 'mixed', 'array', 'resource', 'void',
335-
'null', 'callback', 'false', 'true', 'self', '$this', 'callable'
336-
);
337-
}
338-
339-
$namespace = '\\';
340-
if ($this->namespace != 'default' && $this->namespace != 'global') {
341-
$namespace = rtrim($this->namespace, '\\') . '\\';
342-
}
343-
344-
$type = explode('|', $type);
345-
foreach ($type as &$item) {
346-
$item = trim($item);
347-
348-
// add support for array notation
349-
$is_array = false;
350-
if (substr($item, -2) == '[]') {
351-
$item = substr($item, 0, -2);
352-
$is_array = true;
353-
}
354-
355-
if ((substr($item, 0, 1) != '\\')
356-
&& (!in_array(strtolower($item), $ignore_keywords))
357-
) {
358-
$type_parts = explode('\\', $item);
359-
360-
// if the first segment is an alias; replace with full name
361-
if (isset($this->namespace_aliases[$type_parts[0]])) {
362-
$type_parts[0] = $this->namespace_aliases[$type_parts[0]];
363-
$item = implode('\\', $type_parts);
364-
} else {
365-
// otherwise prepend the current namespace
366-
$item = $namespace . $item;
367-
}
368-
}
369-
370-
// full paths always start with a slash
371-
if (isset($item[0]) && ($item[0] !== '\\')
372-
&& (!in_array(strtolower($item), $ignore_keywords))
373-
) {
374-
$item = '\\' . $item;
375-
}
376-
377-
// re-add the array notation markers
378-
if ($is_array) {
379-
$item .= '[]';
380-
}
381-
}
382-
383-
return implode('|', $type);
384-
}
385-
386305
/**
387306
* Builds a string representation of this object.
388307
*
@@ -410,13 +329,16 @@ public function __toString()
410329
}
411330

412331
/**
413-
* @return string
332+
* @return string The namespace where this DocBlock resides in.
414333
*/
415334
public function getNamespace()
416335
{
417336
return $this->namespace;
418337
}
419338

339+
/**
340+
* @return array List of namespace aliases => Fully Qualified Namespace.
341+
*/
420342
public function getNamespaceAliases()
421343
{
422344
return $this->namespace_aliases;

src/phpDocumentor/Reflection/DocBlock/LongDescription.php renamed to src/phpDocumentor/Reflection/DocBlock/Description.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
namespace phpDocumentor\Reflection\DocBlock;
1414

1515
/**
16-
* Parses a Long Description of a DocBlock.
16+
* Parses a Description of a DocBlock or tag.
1717
*
1818
* @author Mike van Riel <[email protected]>
1919
* @license http://www.opensource.org/licenses/mit-license.php MIT
2020
* @link http://phpdoc.org
2121
*/
22-
class LongDescription implements \Reflector
22+
class Description implements \Reflector
2323
{
2424
/** @var string */
2525
protected $contents = '';
@@ -30,15 +30,20 @@ class LongDescription implements \Reflector
3030
/** @var \phpDocumentor\Reflection\DocBlock\Tags[] */
3131
protected $tags = array();
3232

33+
/** @var DocBlock The DocBlock which this description belongs to. */
34+
protected $docblock = null;
35+
3336
/**
3437
* Parses the string for inline tags and if the Markdown class is included;
3538
* format the found text.
3639
*
37-
* @param string $content the DocBlock contents without asterisks.
40+
* @param string $content The DocBlock contents without asterisks.
41+
* @param DocBlock $docblock The DocBlock which this description belongs to.
3842
*/
39-
public function __construct($content)
43+
public function __construct($content, DocBlock $docblock = null)
4044
{
4145
$this->contents = trim($content);
46+
$this->docblock = $docblock;
4247
}
4348

4449
/**
@@ -97,7 +102,8 @@ public function getParsedContents()
97102
);
98103
for ($i=1, $l = count($this->parsedContents); $i<$l; $i += 2) {
99104
$this->parsedContents[$i] = Tag::createInstance(
100-
$this->parsedContents[$i]
105+
$this->parsedContents[$i],
106+
$this->docblock
101107
);
102108
}
103109

@@ -120,6 +126,9 @@ public function getParsedContents()
120126
*
121127
* @todo this should become a more intelligent piece of code where the
122128
* configuration contains a setting what format long descriptions are.
129+
*
130+
* @codeCoverageIgnore Will be removed soon, in favor of adapters at
131+
* PhpDocumentor itself that will process text in various formats.
123132
*
124133
* @return string
125134
*/

src/phpDocumentor/Reflection/DocBlock/Tag.php

Lines changed: 99 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
namespace phpDocumentor\Reflection\DocBlock;
1414

15+
use phpDocumentor\Reflection\DocBlock;
16+
1517
/**
1618
* Parses a tag definition for a DocBlock.
1719
*
@@ -36,20 +38,59 @@ class Tag implements \Reflector
3638
/** @var int Line number of the tag */
3739
protected $line_number = 0;
3840

39-
/** @var \phpDocumentor\Reflection\DocBlock docblock class */
40-
protected $docblock;
41+
/** @var DocBlock The DocBlock which this tag belongs to. */
42+
protected $docblock = null;
43+
44+
/**
45+
* @var array An array with a tag as a key, and an FQCN to a class that
46+
* handles it as an array value. The class is expected to inherit this
47+
* class.
48+
*/
49+
private static $tagHandlerMappings = array(
50+
'author'
51+
=> '\phpDocumentor\Reflection\DocBlock\Tag\AuthorTag',
52+
'covers'
53+
=> '\phpDocumentor\Reflection\DocBlock\Tag\CoversTag',
54+
'link'
55+
=> '\phpDocumentor\Reflection\DocBlock\Tag\LinkTag',
56+
'method'
57+
=> '\phpDocumentor\Reflection\DocBlock\Tag\MethodTag',
58+
'param'
59+
=> '\phpDocumentor\Reflection\DocBlock\Tag\ParamTag',
60+
'property-read'
61+
=> '\phpDocumentor\Reflection\DocBlock\Tag\PropertyReadTag',
62+
'property'
63+
=> '\phpDocumentor\Reflection\DocBlock\Tag\PropertyTag',
64+
'property-write'
65+
=> '\phpDocumentor\Reflection\DocBlock\Tag\PropertyWriteTag',
66+
'return'
67+
=> '\phpDocumentor\Reflection\DocBlock\Tag\ReturnTag',
68+
'see'
69+
=> '\phpDocumentor\Reflection\DocBlock\Tag\SeeTag',
70+
'throw'
71+
=> '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag',
72+
'throws'
73+
=> '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag',
74+
'uses'
75+
=> '\phpDocumentor\Reflection\DocBlock\Tag\UsesTag',
76+
'var'
77+
=> '\phpDocumentor\Reflection\DocBlock\Tag\VarTag'
78+
);
4179

4280
/**
4381
* Factory method responsible for instantiating the correct sub type.
4482
*
45-
* @param string $tag_line The text for this tag, including description.
83+
* @param string $tag_line The text for this tag, including description.
84+
* @param DocBlock $docblock The DocBlock which this tag belongs to.
4685
*
4786
* @throws \InvalidArgumentException if an invalid tag line was presented.
4887
*
49-
* @return \phpDocumentor\Reflection\DocBlock\Tag
88+
* @return static A new tag object.
5089
*/
51-
public static function createInstance($tag_line)
52-
{
90+
final public static function createInstance(
91+
$tag_line,
92+
DocBlock $docblock = null
93+
) {
5394
if (!preg_match(
5495
'/^@([\w\-\_\\\\]+)(?:\s*([^\s].*)|$)?/us',
5596
$tag_line,
@@ -60,31 +101,66 @@ public static function createInstance($tag_line)
60101
);
61102
}
62103

63-
// support hypphen separated tag names
64-
$tag_name = str_replace(
65-
' ',
66-
'',
67-
ucwords(str_replace('-', ' ', $matches[1]))
68-
).'Tag';
69-
$class_name = 'phpDocumentor\\Reflection\\DocBlock\\Tag\\' . $tag_name;
70-
71-
return ($matches[1] === strtolower($matches[1])
72-
&& @class_exists($class_name))
73-
? new $class_name($matches[1], isset($matches[2]) ? $matches[2] : '')
74-
: new self($matches[1], isset($matches[2]) ? $matches[2] : '');
104+
if (isset(self::$tagHandlerMappings[$matches[1]])) {
105+
$handler = self::$tagHandlerMappings[$matches[1]];
106+
return new $handler(
107+
$matches[1],
108+
isset($matches[2]) ? $matches[2] : '',
109+
$docblock
110+
);
111+
}
112+
return new self(
113+
$matches[1],
114+
isset($matches[2]) ? $matches[2] : '',
115+
$docblock
116+
);
117+
}
118+
119+
/**
120+
* Registers a handler for tags.
121+
*
122+
* Registers a handler for tags. The class specified is autoloaded if it's
123+
* not available. It must inherit from this class.
124+
*
125+
* @param string $tag Name of tag to regiser a handler for.
126+
* @param string|null $handler FQCN of handler. Specifing NULL removes the
127+
* handler for the specified tag, if any.
128+
*
129+
* @return bool TRUE on success, FALSE on failure.
130+
*/
131+
final public static function registerTagHandler($tag, $handler)
132+
{
133+
$tag = trim((string)$tag);
134+
135+
if (null === $handler) {
136+
unset(self::$tagHandlerMappings[$tag]);
137+
return true;
138+
}
139+
140+
if ('' !== $tag
141+
&& class_exists($handler, true)
142+
&& is_subclass_of($handler, __CLASS__)
143+
) {
144+
self::$tagHandlerMappings[$tag] = $handler;
145+
return true;
146+
}
147+
148+
return false;
75149
}
76150

77151
/**
78152
* Parses a tag and populates the member variables.
79153
*
80-
* @param string $type Name of the tag.
81-
* @param string $content The contents of the given tag.
154+
* @param string $type Name of the tag.
155+
* @param string $content The contents of the given tag.
156+
* @param DocBlock $docblock The DocBlock which this tag belongs to.
82157
*/
83-
public function __construct($type, $content)
158+
public function __construct($type, $content, DocBlock $docblock = null)
84159
{
85160
$this->tag = $type;
86161
$this->content = $content;
87-
$this->description = $content;
162+
$this->description = trim($content);
163+
$this->docblock = $docblock;
88164
}
89165

90166
/**
@@ -126,7 +202,7 @@ public function getDescription()
126202
public function getParsedDescription()
127203
{
128204
if (null === $this->parsedDescription) {
129-
$description = new LongDescription($this->description);
205+
$description = new Description($this->description, $this->docblock);
130206
$this->parsedDescription = $description->getParsedContents();
131207
}
132208
return $this->parsedDescription;
@@ -154,20 +230,6 @@ public function getLineNumber()
154230
return $this->line_number;
155231
}
156232

157-
/**
158-
* Inject the docblock class
159-
*
160-
* This exposes some common functionality contained in the docblock abstract.
161-
*
162-
* @param object $docblock Object containing the DocBlock.
163-
*
164-
* @return void
165-
*/
166-
public function setDocBlock($docblock)
167-
{
168-
$this->docblock = $docblock;
169-
}
170-
171233
/**
172234
* Builds a string representation of this object.
173235
*

0 commit comments

Comments
 (0)