Parser does not see docComments between attributes and class declaration
Given this PHP code:
<?php
#[AttributeStub()]
/**
* @template T
*/
class ClassStub
{
/**
* @param T $var
*/
public function __construct(public $var) {}
}
PHP itself sees both attribute and doc comment: https://3v4l.org/Pe17n
But PHP-Parser doesn't (bin/php-parse output on PHP 7.4):
array(
0: Stmt_Class(
attrGroups: array(
0: AttributeGroup(
attrs: array(
0: Attribute(
name: Name(
parts: array(
0: AttributeStub
)
)
args: array(
)
)
)
)
)
flags: 0
name: Identifier(
name: ClassStub
)
extends: null
implements: array(
)
stmts: array(
0: Stmt_ClassMethod(
attrGroups: array(
)
flags: MODIFIER_PUBLIC (1)
byRef: false
name: Identifier(
name: __construct
)
params: array(
0: Param(
attrGroups: array(
)
flags: MODIFIER_PUBLIC (1)
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: var
)
default: null
)
)
returnType: null
stmts: array(
)
comments: array(
0: /**
* @param T $var
*/
)
)
)
)
)
Original report: https://github.com/phpstan/phpstan/issues/4633
The parser only collects comments before a node -- as the attributes are considered part of the class, the doc comment ends up being "inside" the class, and thus lost. It's not really possible to fix this with the current architecture.
Alright, thanks! This is probably the same issue:
class HelloWorld
{
#[Groups]
#[Valid]
/** @var \stdClass[]|null */
public ?array $damages = null;
}
given this php code
if (
/** @authdoc-c (i18n="foobar") */
!check("view", "foobar") &&
/** @authdoc-c (i18n="barfoo") */
(empty($myGroups[$groupId]) || !check($myGroups[$groupId], "barfoo"))
)
the second docblock is not seen as well. I guess it is a similar problem.
It seems to me, using $node->name->getStartLine() is the most reliable option right now. It's not always correct, because we can have
#[Attr]
final
class
A {}
But it's less likely than
#[Attr]
final class A {}