Don't require doc comment to be last comment

Fixes #652.
This commit is contained in:
Nikita Popov 2020-02-15 10:52:34 +01:00
parent a2443aaefa
commit 3ec87ef757
3 changed files with 26 additions and 24 deletions

View File

@ -95,8 +95,6 @@ interface Node
/**
* Gets the doc comment of the node.
*
* The doc comment has to be the last comment associated with the node.
*
* @return null|Comment\Doc Doc comment object or null
*/
public function getDocComment();

View File

@ -108,22 +108,18 @@ abstract class NodeAbstract implements Node, \JsonSerializable
/**
* Gets the doc comment of the node.
*
* The doc comment has to be the last comment associated with the node.
*
* @return null|Comment\Doc Doc comment object or null
*/
public function getDocComment() {
$comments = $this->getComments();
if (!$comments) {
return null;
for ($i = count($comments) - 1; $i >= 0; $i--) {
$comment = $comments[$i];
if ($comment instanceof Comment\Doc) {
return $comment;
}
}
$lastComment = $comments[count($comments) - 1];
if (!$lastComment instanceof Comment\Doc) {
return null;
}
return $lastComment;
return null;
}
/**
@ -135,16 +131,17 @@ abstract class NodeAbstract implements Node, \JsonSerializable
*/
public function setDocComment(Comment\Doc $docComment) {
$comments = $this->getComments();
$numComments = count($comments);
if ($numComments > 0 && $comments[$numComments - 1] instanceof Comment\Doc) {
// Replace existing doc comment
$comments[$numComments - 1] = $docComment;
} else {
// Append new comment
$comments[] = $docComment;
for ($i = count($comments) - 1; $i >= 0; $i--) {
if ($comments[$i] instanceof Comment\Doc) {
// Replace existing doc comment.
$comments[$i] = $docComment;
$this->setAttribute('comments', $comments);
return;
}
}
// Append new doc comment.
$comments[] = $docComment;
$this->setAttribute('comments', $comments);
}

View File

@ -34,8 +34,9 @@ class NodeAbstractTest extends \PHPUnit\Framework\TestCase
'startFilePos' => 14,
'endFilePos' => 15,
'comments' => [
new Comment('// Comment' . "\n"),
new Comment('// Comment 1' . "\n"),
new Comment\Doc('/** doc comment */'),
new Comment('// Comment 2' . "\n"),
],
];
@ -79,12 +80,12 @@ class NodeAbstractTest extends \PHPUnit\Framework\TestCase
$this->assertSame('/** doc comment */', $node->getDocComment()->getText());
$comments = $node->getComments();
array_pop($comments); // remove doc comment
array_splice($comments, 1, 1, []); // remove doc comment
$node->setAttribute('comments', $comments);
$this->assertNull($node->getDocComment());
array_pop($comments); // remove comment
$node->setAttribute('comments', $comments);
// Remove all comments.
$node->setAttribute('comments', []);
$this->assertNull($node->getDocComment());
}
@ -108,6 +109,12 @@ class NodeAbstractTest extends \PHPUnit\Framework\TestCase
$node->setAttribute('comments', [$c1, $c2]);
$node->setDocComment($docComment);
$this->assertSame([$c1, $c2, $docComment], $node->getAttribute('comments'));
// Replace doc comment that is not at the end.
$newDocComment = new Comment\Doc('/** new baz */');
$node->setAttribute('comments', [$c1, $docComment, $c2]);
$node->setDocComment($newDocComment);
$this->assertSame([$c1, $newDocComment, $c2], $node->getAttribute('comments'));
}
/**