-
Notifications
You must be signed in to change notification settings - Fork 515
Playground: Implement PhpdocCommentRule #4074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
25827d4
5a932e3
c503d73
356eccd
686f83c
aa70750
6775b34
36d28d7
f62b6a9
7a96062
923c1f8
4eaf002
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Playground; | ||
|
||
use Nette\Utils\Strings; | ||
use PhpParser\Node; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Node\VirtualNode; | ||
use PHPStan\Rules\Rule; | ||
use PHPStan\Rules\RuleErrorBuilder; | ||
use function str_starts_with; | ||
|
||
/** | ||
* @implements Rule<Node> | ||
*/ | ||
final class PhpdocCommentRule implements Rule | ||
{ | ||
|
||
public function getNodeType(): string | ||
{ | ||
return Node::class; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd do it only for Node\Stmt. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tbh there are so many different node types, that I don't know what the differences are in this case. adjusted it per request :) |
||
} | ||
|
||
public function processNode(Node $node, Scope $scope): array | ||
{ | ||
if ($node instanceof VirtualNode) { | ||
return []; | ||
} | ||
|
||
$comments = $node->getComments(); | ||
|
||
$errors = []; | ||
foreach ($comments as $comment) { | ||
foreach (['/**', '//', '#'] as $startTag) { | ||
if (str_starts_with($comment->getText(), $startTag)) { | ||
continue 2; | ||
} | ||
} | ||
|
||
if (Strings::match($comment->getText(), '{(\s|^)@\w+(\s|$)}') === null) { | ||
continue; | ||
} | ||
|
||
$errors[] = RuleErrorBuilder::message('Comment contains PHPDoc tag but does not start with /** prefix.') | ||
->identifier('phpstanPlayground.phpDoc') | ||
->build(); | ||
} | ||
|
||
return $errors; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Playground; | ||
|
||
use PHPStan\Rules\Rule; | ||
use PHPStan\Testing\RuleTestCase; | ||
|
||
/** | ||
* @extends RuleTestCase<PhpdocCommentRule> | ||
*/ | ||
class PhpdocCommentRuleTest extends RuleTestCase | ||
{ | ||
|
||
protected function getRule(): Rule | ||
{ | ||
return new PhpdocCommentRule(); | ||
} | ||
|
||
public function testRule(): void | ||
{ | ||
$this->analyse([__DIR__ . '/data/comments.php'], [ | ||
[ | ||
'Comment contains PHPDoc tag but does not start with /** prefix.', | ||
13, | ||
], | ||
[ | ||
'Comment contains PHPDoc tag but does not start with /** prefix.', | ||
23, | ||
], | ||
]); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
namespace CommentTypes; | ||
|
||
/** | ||
* @template T of FooInterface | ||
*/ | ||
class Bar | ||
{ | ||
/* | ||
* @var T $foo | ||
*/ | ||
protected FooInterface $foo; | ||
|
||
/** | ||
* @param T $foo | ||
*/ | ||
public function __construct(FooInterface $foo) { $this->foo = $foo; } | ||
|
||
/* | ||
* @return T | ||
*/ | ||
public function getFoo(): FooInterface | ||
{ | ||
return $this->foo; | ||
} | ||
|
||
/* | ||
* some method | ||
*/ | ||
public function getBar(): FooInterface | ||
{ | ||
return $this->foo; | ||
} | ||
|
||
// this should not error: @var | ||
# this should not error: @var | ||
|
||
/* | ||
* comments which look like phpdoc should be ignored | ||
* | ||
* x@x.cz | ||
* 10 amps @ 1 volt | ||
*/ | ||
public function ignoreComments(): FooInterface | ||
{ | ||
return $this->foo; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not synced with getNodeType