phpstan-drupal: Reflection error: Drupal\Tests\PhpunitCompatibilityTrait not found

How is drupal-check installed?

drupal-check is installed as a dependency to my project

Environment:

  • OS: macOS
  • PHP Version: 7.3
  • Drupal core: 9.0.x

Describe the bug Reflection error occurs when using multiple arguments to test different files. $ vendor/bin/drupal-check --deprecations --no-progress --drupal-root=…/drupal --exclude-dir=vendor cookiebot_consent.module src/Event/LibrariesEvent.php

This issue was partially fixed in https://github.com/phpstan/phpstan/issues/3522 but still occurs when using different files as arguments.

cookiebot_consent.module

  $event = new LibrariesEvent($extension);

src/Event/LibrariesEvent.php

use Symfony\Contracts\EventDispatcher\Event;

class LibrariesEvent extends Event {

Symfony\Contracts\EventDispatcher\Event

namespace Symfony\Contracts\EventDispatcher;

use Psr\EventDispatcher\StoppableEventInterface;

if (interface_exists(StoppableEventInterface::class)) {
    class Event implements StoppableEventInterface
    {
    }
} else {
    class Event
    {
    }
}

Console output

 ------ -------------------------------------------------------------------- 
  Line   cookiebot_consent.module                                            
 ------ -------------------------------------------------------------------- 
         Reflection error: Psr\EventDispatcher\StoppableEventInterface not   
         found.                                                              
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols  
 ------ -------------------------------------------------------------------- 

 ------ -------------------------------------------------------------------- 
  Line   src/Event/LibrariesEvent.php                                        
 ------ -------------------------------------------------------------------- 
         Reflection error: Psr\EventDispatcher\StoppableEventInterface not   
         found.                                                              
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols  
  52     Reflection error: Psr\EventDispatcher\StoppableEventInterface not   
         found.                                                              
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols  
 ------ -------------------------------------------------------------------- 

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 31 (21 by maintainers)

Commits related to this issue

Most upvoted comments

Since we updated phpstan/phpstan to 0.12.43 we’re seeing a lot of these Reflection errors when running drupal-check, here’s another one:

 ------ --------------------------------------------------------------------- 
         Reflection error: Drupal\Tests\PhpunitCompatibilityTrait not found.  
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols   
 ------ --------------------------------------------------------------------- 

Looks like something changed in ondrejmirtes/better-reflection that’s triggering this.

I found the error! It’s due to an alias defined for PHPUnit compatibility between PHPUnit 6 and 7. I also double checked, it’s not due to it being defined dynamically.

See: https://git.drupalcode.org/project/drupal/-/blob/8.8.x/core/tests/Drupal/Tests/PhpunitCompatibilityTrait.php#L10

```php
// In order to manage different method signatures between PHPUnit versions, we
// dynamically load a compatibility trait dependent on the PHPUnit runner
// version.
if (!trait_exists(PhpunitVersionDependentTestCompatibilityTrait::class, FALSE)) {
  class_alias("Drupal\TestTools\PhpUnitCompatibility\PhpUnit" . RunnerVersion::getMajor() . "\TestCompatibilityTrait", PhpunitVersionDependentTestCompatibilityTrait::class);
}

When I comment out that line of code and target the trait directly, non-aliased, everything works fine: ie use \Drupal\TestTools\PhpUnitCompatibility\PhpUnit7\TestCompatibilityTrait;.

When I modify the statement to be hardcoded and not rely on RunnerVersion::getMajor() it still breaks. So there is something about defining the trait alias that makes reflection break.

#144 fixes the tests here and uncovers this bug