Skip to content

Commit 8a3b54e

Browse files
authored
Fix #337: Log invalid tags
1 parent 35612f8 commit 8a3b54e

File tree

7 files changed

+160
-2
lines changed

7 files changed

+160
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Yii Framework 2 apidoc extension Change Log
44
3.0.9 under development
55
-----------------------
66

7-
- no changes in this release.
7+
- Enh #337: Log invalid tags (mspirkov)
88

99

1010
3.0.8 November 24, 2025

models/BaseDoc.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* @link https://www.yiiframework.com/
45
* @copyright Copyright (c) 2008 Yii Software LLC
@@ -10,6 +11,7 @@
1011
use phpDocumentor\Reflection\DocBlock\Tag;
1112
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
1213
use phpDocumentor\Reflection\DocBlock\Tags\Generic;
14+
use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
1315
use phpDocumentor\Reflection\DocBlock\Tags\Since;
1416
use phpDocumentor\Reflection\Php\Class_;
1517
use phpDocumentor\Reflection\Php\Constant;
@@ -193,6 +195,19 @@ public function __construct($reflector = null, $context = null, $config = [])
193195
} elseif ($tag instanceof Generic && $tag->getName() === self::TODO_TAG_NAME) {
194196
$this->todos[] = $tag;
195197
unset($this->tags[$i]);
198+
} elseif ($tag instanceof InvalidTag && $context !== null) {
199+
$exception = $tag->getException();
200+
$message = 'Invalid tag: ' . $tag->render() . '.';
201+
202+
if ($exception !== null) {
203+
$message .= ' Exception message: ' . $exception->getMessage();
204+
}
205+
206+
$context->errors[] = [
207+
'line' => $this->startLine,
208+
'file' => $this->sourceFile,
209+
'message' => $message,
210+
];
196211
}
197212
}
198213

@@ -242,7 +257,8 @@ public static function extractFirstSentence($text, $prevText = '')
242257
if ($length >= $pos + 2) {
243258
$abbrev = mb_substr($text, $pos - 3, 4, 'utf-8');
244259
// do not break sentence after abbreviation
245-
if ($abbrev === 'e.g.' ||
260+
if (
261+
$abbrev === 'e.g.' ||
246262
$abbrev === 'i.e.' ||
247263
mb_substr_count($prevText, '`', 'utf-8') % 2 === 1
248264
) {

tests/commands/ApiControllerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,15 @@ public function testGenerateBootstrap()
9999
$sourceFilesCount = count(FileHelper::findFiles($sourceFilesDir, ['recursive' => true]));
100100

101101
$this->assertSame($sourceFilesCount, $filesCount);
102+
103+
$warningsContent = file_get_contents("{$outputPath}/warnings.txt");
104+
// Remove the dynamic parts of the file paths
105+
$warningsContent = preg_replace('/(\s*\[file\] => ).*(\/tests\/.*\.php)/', '$1$2', $warningsContent);
106+
$this->assertMatchesTextSnapshot($warningsContent);
107+
108+
$errorsContent = file_get_contents("{$outputPath}/errors.txt");
109+
// Remove the dynamic parts of the file paths
110+
$errorsContent = preg_replace('/(\s*\[file\] => ).*(\/tests\/.*\.php)/', '$1$2', $errorsContent);
111+
$this->assertMatchesTextSnapshot($errorsContent);
102112
}
103113
}

tests/commands/__snapshots__/ApiControllerTest__testGenerateBootstrap__3.html

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ <h2>Public Methods</h2>
166166
<td><a href="yiiunit-apidoc-data-api-animal-dog.html#isOlder()-detail">isOlder()</a></td>
167167
<td>Checks whether the animal is older than the specified time.</td>
168168
<td><a href="yiiunit-apidoc-data-api-animal-animal.html">yiiunit\apidoc\data\api\animal\Animal</a></td>
169+
</tr>
170+
<tr class="">
171+
<td><a href="yiiunit-apidoc-data-api-animal-dog.html#methodWithInvalidReturnTag()-detail">methodWithInvalidReturnTag()</a></td>
172+
<td></td>
173+
<td><a href="yiiunit-apidoc-data-api-animal-dog.html">yiiunit\apidoc\data\api\animal\Dog</a></td>
169174
</tr>
170175
<tr class="">
171176
<td><a href="yiiunit-apidoc-data-api-animal-dog.html#render()-detail">render()</a></td>
@@ -406,6 +411,50 @@ <h2>Method Details</h2>
406411
</span>{
407412
<span class="hljs-keyword">return</span><span class="hljs-keyword">$this</span>-&gt;getAge() &gt; $date;
408413
}
414+
</code>
415+
</pre>
416+
</div>
417+
</div>
418+
419+
</div>
420+
<div class="">
421+
<div class="detail-header h3">
422+
<a class="tool-link" title="go to top"><span class="glyphicon glyphicon-arrow-up"></span></a>
423+
<a class="tool-link hash" href="yiiunit-apidoc-data-api-animal-dog.html#methodWithInvalidReturnTag()-detail" title="direct link to this method"><span class="glyphicon icon-hash"></span></a>
424+
425+
methodWithInvalidReturnTag()
426+
427+
<span class="detail-header-tag small">
428+
public method
429+
</span>
430+
</div>
431+
432+
433+
<div class="doc-description">
434+
435+
<p><strong></strong></p>
436+
</div>
437+
438+
<table class="detail-table table table-striped table-bordered table-hover">
439+
<tr><td colspan="3" class="signature">
440+
<span class="signature-defs">public</span><span class="signature-type"><a href="https://www.php.net/language.types.mixed">mixed</a></span><strong><a href="yiiunit-apidoc-data-api-animal-dog.html#methodWithInvalidReturnTag()-detail">methodWithInvalidReturnTag</a></strong> ( )</td></tr>
441+
442+
</table>
443+
444+
445+
446+
447+
<p>
448+
<a class="btn btn-link" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="collapseMethodWithInvalidReturnTag">
449+
Source code
450+
</a>
451+
</p>
452+
<div class="collapse">
453+
<div class="card card-body">
454+
<pre>
455+
<code class="hljs php language-php"><span class="hljs-keyword">public</span><span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-title">methodWithInvalidReturnTag</span><span class="hljs-params">()</span>
456+
</span>{
457+
}
409458
</code>
410459
</pre>
411460
</div>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
Array
2+
(
3+
[0] => Array
4+
(
5+
[line] => 41
6+
[file] => /tests/data/api/animal/Animal.php
7+
[message] => No docblock for element '$propertyWithoutDoc'
8+
)
9+
10+
[1] => Array
11+
(
12+
[line] => 41
13+
[file] => /tests/data/api/animal/Animal.php
14+
[message] => No short description for element '$propertyWithoutDoc'
15+
)
16+
17+
[2] => Array
18+
(
19+
[line] => 43
20+
[file] => /tests/data/api/animal/Animal.php
21+
[message] => No docblock for element '$propertyWithoutDocAndTypeHint'
22+
)
23+
24+
[3] => Array
25+
(
26+
[line] => 43
27+
[file] => /tests/data/api/animal/Animal.php
28+
[message] => No short description for element '$propertyWithoutDocAndTypeHint'
29+
)
30+
31+
[4] => Array
32+
(
33+
[line] => 70
34+
[file] => /tests/data/api/animal/Animal.php
35+
[message] => No docblock for element 'setBirthDate'
36+
)
37+
38+
[5] => Array
39+
(
40+
[line] => 32
41+
[file] => /tests/data/api/animal/Cat.php
42+
[message] => No docblock for element 'methodWithoutDocAndTypeHints'
43+
)
44+
45+
[6] => Array
46+
(
47+
[line] => 40
48+
[file] => /tests/data/api/animal/Cat.php
49+
[message] => No short description for Method 'methodWithTodoTag'
50+
)
51+
52+
[7] => Array
53+
(
54+
[line] => 30
55+
[file] => /tests/data/api/animal/Dog.php
56+
[message] => No short description for Method 'methodWithInvalidReturnTag'
57+
)
58+
59+
[8] => Array
60+
(
61+
[line] => 11
62+
[file] => /tests/data/api/base/Component.php
63+
[message] => No docblock for element 'yiiunit\apidoc\data\api\base\Component'
64+
)
65+
66+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Array
2+
(
3+
[0] => Array
4+
(
5+
[line] => 30
6+
[file] => /tests/data/api/animal/Dog.php
7+
[message] => Invalid tag: @return invalid-type. Exception message: "\yiiunit\apidoc\data\api\animal\invalid-type" is not a valid Fqsen.
8+
)
9+
10+
)

tests/data/api/animal/Dog.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,11 @@ public function render()
2323
// this method has `inheritdoc` tag without brackets
2424
return 'This is a dog';
2525
}
26+
27+
/**
28+
* @return invalid-type
29+
*/
30+
public function methodWithInvalidReturnTag()
31+
{
32+
}
2633
}

0 commit comments

Comments
 (0)