Problem/Motivation

When authoring a class using PHP 8, it is now possible to attach attributes to classes. When attributes are used on classes, though, PHPCS/Coder complain that the docblock for the class is missing unless the docblock appears between the attribute and the class name.

This does not affect attributes on methods, for which it would appear that a change was made back in February 2023.

Steps to reproduce

  1. Within a Drupal module, create a source file called src/TestAttributes.php.
  2. Paste the following code into the new file:
    <?php
    
    namespace Drupal\MY_MODULE;
    
    /**
     * My class comment.
     */
    #[\Attribute]
    class AllGood {
    }
    
  3. Run PHPCS with the Drupal coding style on the module.
  4. Move the attribute above the docblock, as follows:
    <?php
    
    namespace Drupal\MY_MODULE;
    
    #[\Attribute]
    /**
     * My class comment.
     */
    class AllGood {
    }
    
  5. Re-run PHPCS.

When the attribute is right above the class, this is the error:

FOUND 1 ERROR AFFECTING 1 LINE
--------------------------------------------------------------------------------
 9 | ERROR | [x] Missing class doc comment (Drupal.Commenting.ClassComment.Missing)
--------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
--------------------------------------------------------------------------------

The error does not appear if the attribute is above the comment, but that doesn't look right.

Proposed resolution

Tweak the sniff so it allows annotations above classes the same way it allows them on methods; below is what's allowed for methods:

/**
 * Test PHP attributes.
 */
class TestPhpAttributes {

  /**
   * Tests method with PHP attribute and docblock.
   */
  #[\ReturnTypeWillChange]
  public function attributes(): void {
  }

}

Remaining tasks

User interface changes

API changes

Data model changes

Comments

GuyPaddock created an issue. See original summary.

guypaddock’s picture

As a workaround, this appears to work:


namespace Drupal\MY_MODULE\Plugin\search_api\processor;

// phpcs:disable Drupal.Commenting.ClassComment.Missing
/**
 * My class comment.
 */
#[\Attribute]
class AllGood {
}
// phpcs:enable Drupal.Commenting.ClassComment.Missing

class OtherClass {
}

In the code above, OtherClass will get the warning (as intended) but AllGood will not.

guypaddock’s picture

Issue summary: View changes
guypaddock’s picture

Issue summary: View changes
guypaddock’s picture

Issue summary: View changes
klausi’s picture

Thanks for reporting!

I started a fix at https://github.com/pfrenssen/coder/pull/179 , but the fixer does not work correctly yet.

  • klausi authored 1c466233 on 8.3.x
    fix(ClassComment): Support PHP 8 class attributes (#3322615)
    
    
klausi’s picture

Status: Active » Fixed

Improved the fixer and merged it!

claudiu.cristea’s picture

Status: Fixed » Needs work

This is only fixing the case when there's one attribute. But a method might expose multiple attributes. The following will fail with: Missing class doc comment (Drupal.Commenting.ClassComment.Missing)


/**
 * Method docblock.
 */
#[Some\Attribute(foo: 'bar')]
#[Other\Attribute(baz: 'qux')]
public function method() {
}
klausi’s picture

Thanks for reporting, I'll put that in as test case and will check.

  • klausi committed 1609318d on 8.3.x
    test(ClassComment): Add test case for double attribute lines on classes...
klausi’s picture

Status: Needs work » Fixed

Added a test case for class comments, there it works as expected.

It looks like you are talking about method attributes, which are not checked in the class comment sniff. Will open a new issue to check for that.

klausi’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.