Skip to content
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

Parser does not see docComments between attributes and class declaration #762

Open
ondrejmirtes opened this issue Mar 1, 2021 · 4 comments

Comments

@ondrejmirtes
Copy link
Contributor

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: phpstan/phpstan#4633

@nikic nikic changed the title Emulative lexer does not see docComments between attributes and class declaration Parser does not see docComments between attributes and class declaration Apr 25, 2021
@nikic
Copy link
Owner

nikic commented Apr 25, 2021

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.

@ondrejmirtes
Copy link
Contributor Author

Alright, thanks! This is probably the same issue:

class HelloWorld
{
    #[Groups]
    #[Valid]
    /** @var \stdClass[]|null */
    public ?array $damages = null;
}

@bwl21
Copy link

bwl21 commented Oct 24, 2021

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.

@vudaltsov
Copy link

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 {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants