Verified Commit 0be35cac authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3427388 by godotislate, Berdir: Update...

Issue #3427388 by godotislate, Berdir: Update Drupal\Component\Annotation\Doctrine\StaticReflectionParser::hasClassAttribute() to allow attribute subclasses

(cherry picked from commit 0356ea59)
parent 1c279bde
Loading
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ protected function parse()
                    break;
                case T_CLASS:
                    // Convert the attributes to fully qualified names.
                    $this->classAttributes = array_map(fn($name) => strtolower($this->fullySpecifyName($name)), $attributeNames);
                    $this->classAttributes = array_map(fn($name) => $this->fullySpecifyName($name), $attributeNames);
                    if ($last_token !== T_PAAMAYIM_NEKUDOTAYIM && $last_token !== T_NEW) {
                        $this->docComment['class'] = $docComment;
                        $docComment                = '';
@@ -346,7 +346,13 @@ public function getStaticReflectionParserForDeclaringClass($type, $name)
    public function hasClassAttribute(string $attribute): bool
    {
        $this->parse();
        return in_array('\\' . ltrim(strtolower($attribute), '\\'), $this->classAttributes, TRUE);
        foreach ($this->classAttributes as $classAttribute) {
            if (is_a($classAttribute, $attribute, TRUE)) {
                return TRUE;
            }
        }

        return FALSE;
    }

    /**
+9 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\Component\Annotation\Doctrine\Fixtures\Attribute;

// @phpstan-ignore-next-line
#[NonexistentAttribute]
final class Nonexistent
{
}
+1 −1
Original line number Diff line number Diff line
@@ -3,6 +3,6 @@
namespace Drupal\Tests\Component\Annotation\Doctrine\Fixtures\ExtraAttributes;

#[\Attribute]
final class ExampleAttribute
final class ExampleAttribute extends ExampleParentAttribute
{
}
+8 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\Component\Annotation\Doctrine\Fixtures\ExtraAttributes;

#[\Attribute]
class ExampleParentAttribute {

}
+8 −5
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@ class StaticReflectionParserTest extends TestCase {

  /**
   * @testWith ["AttributeClass", "\\Attribute", true]
   *           ["AttributeClass", "attribute", true]
   *           ["AttributeClass", "Attribute", true]
   *           ["AttributeClass", "\\DoesNotExist", false]
   *           ["Nonexistent", "NonexistentAttribute", false]
   *           ["MultipleAttributes", "Attribute", true]
   *           ["MultipleAttributes", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\Attribute\\AttributeClass", true]
   *           ["MultipleAttributes", "DoesNotExist", false]
@@ -26,15 +28,16 @@ class StaticReflectionParserTest extends TestCase {
   *           ["UsedAsQualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleAttribute", true]
   *           ["Qualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleAttribute", true]
   *           ["Relative", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\Attribute\\SubDir\\SubDirAttribute", true]
   *           ["FullyQualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
   *           ["Used", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
   *           ["UsedAs", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
   *           ["UsedAsQualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
   *           ["Qualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
   */
  public function testAttribute(string $class, string $attribute_class, bool $expected) {
    $finder = MockFileFinder::create(__DIR__ . '/Fixtures/Attribute/' . $class . '.php');
    $parser = new StaticReflectionParser('\\Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\Attribute\\' . $class, $finder);
    $this->assertSame($expected, $parser->hasClassAttribute($attribute_class), "'$class' has '$attribute_class'");
    // Attribute names and namespaces are case-insensitive in PHP. Practically
    // Composer autoloading makes this untrue but builtins like \Attribute are
    // case-insensitive so we should support that.
    $this->assertSame($expected, $parser->hasClassAttribute(strtoupper($attribute_class)), "'$class' has '$attribute_class'");
    $this->assertSame($expected, $parser->hasClassAttribute($attribute_class), "'$class' has attribute that is a '$attribute_class'");
  }

}