Skip to content

Commit 7a03741

Browse files
committed
Added support for namespaced tags;
Simplified @see and @link parsing; Added comments to the regexes of @method, @example and @source; Added a test case for what 2812eac intended to fix.
1 parent b20c7da commit 7a03741

File tree

8 files changed

+77
-23
lines changed

8 files changed

+77
-23
lines changed

src/phpDocumentor/Reflection/DocBlock/Tag.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,21 @@ final public static function createInstance(
113113
);
114114
}
115115

116+
$handler = __CLASS__;
116117
if (isset(self::$tagHandlerMappings[$matches[1]])) {
117118
$handler = self::$tagHandlerMappings[$matches[1]];
118-
return new $handler(
119-
$matches[1],
120-
isset($matches[2]) ? $matches[2] : '',
121-
$docblock,
122-
$location
119+
} elseif (isset($docblock)) {
120+
$tagName = (string)new Type\Collection(
121+
array($matches[1]),
122+
$docblock->getContext()
123123
);
124+
125+
if (isset(self::$tagHandlerMappings[$tagName])) {
126+
$handler = self::$tagHandlerMappings[$tagName];
127+
}
124128
}
125-
return new self(
129+
130+
return new $handler(
126131
$matches[1],
127132
isset($matches[2]) ? $matches[2] : '',
128133
$docblock,
@@ -136,7 +141,9 @@ final public static function createInstance(
136141
* Registers a handler for tags. The class specified is autoloaded if it's
137142
* not available. It must inherit from this class.
138143
*
139-
* @param string $tag Name of tag to regiser a handler for.
144+
* @param string $tag Name of tag to regiser a handler for. When
145+
* registering a namespaced tag, the full name, along with a prefixing
146+
* slash MUST be provided.
140147
* @param string|null $handler FQCN of handler. Specifing NULL removes the
141148
* handler for the specified tag, if any.
142149
*
@@ -154,6 +161,7 @@ final public static function registerTagHandler($tag, $handler)
154161
if ('' !== $tag
155162
&& class_exists($handler, true)
156163
&& is_subclass_of($handler, __CLASS__)
164+
&& !strpos($tag, '\\') //Accept no slash, and 1st slash at offset 0.
157165
) {
158166
self::$tagHandlerMappings[$tag] = $handler;
159167
return true;

src/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,17 @@ public function __construct(
4343
) {
4444
Tag::__construct($type, $content, $docblock, $location);
4545
if (preg_match(
46-
'/^(?:\"([^\"]+)\"|(\S+))(?:\s+(.*))?$/su',
46+
'/^
47+
(?:
48+
# File path in quotes
49+
\"([^\"]+)\"
50+
|
51+
# File URI
52+
(\S+)
53+
)
54+
# Remaining content (parsed by SourceTag)
55+
(?:\s+(.*))?
56+
$/sux',
4757
$this->description,
4858
$matches
4959
)) {

src/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,12 @@ public function __construct(
4242
Location $location = null
4343
) {
4444
parent::__construct($type, $content, $docblock, $location);
45-
$pieces = explode(' ', $this->description);
45+
$content = preg_split('/\s+/u', $this->description, 2);
4646

47-
if (count($pieces) > 1) {
48-
$this->link = array_shift($pieces);
49-
$this->description = implode(' ', $pieces);
50-
} else {
51-
$this->link = $content;
52-
$this->description = $content;
53-
}
47+
// any output is considered a type
48+
$this->link = $content[0];
5449

55-
$this->content = $content;
50+
$this->description = isset($content[1]) ? $content[1] : $content[0];
5651
}
5752

5853
/**

src/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,24 @@ public function __construct(
5757
// until a ) and whitespace : as method name with signature
5858
// 5. any remaining text : as description
5959
if (preg_match(
60-
'/^[\s]*(?:([\w\|_\\\\]+)[\s]+)?(?:[\w_]+\(\)[\s]+)?([\w\|_\\\\]+)'
61-
.'\(([^\)]*)\)[\s]*(.*)/u',
60+
'/^
61+
# Return type
62+
(?:
63+
([\w\|_\\\\]+)
64+
\s+
65+
)?
66+
# Legacy method name (not captured)
67+
(?:
68+
[\w_]+\(\)\s+
69+
)?
70+
# Method name
71+
([\w\|_\\\\]+)
72+
# Arguments
73+
\(([^\)]*)\)
74+
\s*
75+
# Description
76+
(.*)
77+
$/sux',
6278
$this->description,
6379
$matches
6480
)) {

src/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ public function __construct(
4242
Location $location = null
4343
) {
4444
parent::__construct($type, $content, $docblock, $location);
45-
$content = preg_split('/\s+/u', $content);
45+
$content = preg_split('/\s+/u', $this->description, 2);
4646

4747
// any output is considered a type
48-
$this->refers = array_shift($content);
48+
$this->refers = $content[0];
4949

50-
$this->description = implode(' ', $content);
50+
$this->description = isset($content[1]) ? $content[1] : '';
5151
}
5252

5353
/**

src/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,18 @@ public function __construct(
5151
) {
5252
parent::__construct($type, $content, $docblock, $location);
5353
if (preg_match(
54-
'/^([1-9]\d*)\s*(?:([1-9]\d*)\s+)?(.*)$/su',
54+
'/^
55+
# Starting line
56+
([1-9]\d*)
57+
\s*
58+
# Number of lines
59+
(?:
60+
((?1))
61+
\s+
62+
)?
63+
# Description
64+
(.*)
65+
$/sux',
5566
$this->description,
5667
$matches
5768
)) {

tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ public function provideDataForConstructor()
9292
'int',
9393
array('int'),
9494
"Number of Bobs"
95+
),
96+
array(
97+
'return',
98+
"int\nNumber of Bobs",
99+
'int',
100+
array('int'),
101+
"Number of Bobs"
95102
)
96103
);
97104
}

tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ public function provideDataForConstructor()
9090
'int',
9191
array('int'),
9292
"Number of Bobs"
93+
),
94+
array(
95+
'throws',
96+
"int\nNumber of Bobs",
97+
'int',
98+
array('int'),
99+
"Number of Bobs"
93100
)
94101
);
95102
}

0 commit comments

Comments
 (0)