Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. DocParser.php

function DocParser::collectAnnotationMetadata

Same name in this branch
  1. 11.1.x core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php \Drupal\Component\Annotation\Doctrine\DocParser::collectAnnotationMetadata()

Collects parsing metadata for a given annotation class

Parameters

class-string $name The annotation name:

Throws

AnnotationException

ReflectionException

1 call to DocParser::collectAnnotationMetadata()
DocParser::Annotation in vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
Annotation ::= "@" AnnotationName MethodCall AnnotationName ::= QualifiedName | SimpleName QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName NameSpacePart ::= identifier | null | false |…

File

vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php, line 488

Class

DocParser
A parser for docblock annotations.

Namespace

Doctrine\Common\Annotations

Code

private function collectAnnotationMetadata(string $name) : void {
    if (self::$metadataParser === null) {
        self::$metadataParser = new self();
        self::$metadataParser->setIgnoreNotImportedAnnotations(true);
        self::$metadataParser->setIgnoredAnnotationNames($this->ignoredAnnotationNames);
        self::$metadataParser->setImports([
            'enum' => Enum::class,
            'target' => Target::class,
            'attribute' => Attribute::class,
            'attributes' => Attributes::class,
            'namedargumentconstructor' => NamedArgumentConstructor::class,
        ]);
        // Make sure that annotations from metadata are loaded
        class_exists(Enum::class);
        class_exists(Target::class);
        class_exists(Attribute::class);
        class_exists(Attributes::class);
        class_exists(NamedArgumentConstructor::class);
    }
    $class = new ReflectionClass($name);
    $docComment = $class->getDocComment();
    // Sets default values for annotation metadata
    $constructor = $class->getConstructor();
    $metadata = [
        'default_property' => null,
        'has_constructor' => $constructor !== null && $constructor->getNumberOfParameters() > 0,
        'constructor_args' => [],
        'properties' => [],
        'property_types' => [],
        'attribute_types' => [],
        'targets_literal' => null,
        'targets' => Target::TARGET_ALL,
        'is_annotation' => strpos($docComment, '@Annotation') !== false,
    ];
    $metadata['has_named_argument_constructor'] = false;
    // verify that the class is really meant to be an annotation
    if ($metadata['is_annotation']) {
        self::$metadataParser->setTarget(Target::TARGET_CLASS);
        foreach (self::$metadataParser->parse($docComment, 'class @' . $name) as $annotation) {
            if ($annotation instanceof Target) {
                $metadata['targets'] = $annotation->targets;
                $metadata['targets_literal'] = $annotation->literal;
                continue;
            }
            if ($annotation instanceof NamedArgumentConstructor) {
                $metadata['has_named_argument_constructor'] = $metadata['has_constructor'];
                if ($metadata['has_named_argument_constructor']) {
                    // choose the first argument as the default property
                    $metadata['default_property'] = $constructor->getParameters()[0]
                        ->getName();
                }
            }
            if (!$annotation instanceof Attributes) {
                continue;
            }
            foreach ($annotation->value as $attribute) {
                $this->collectAttributeTypeMetadata($metadata, $attribute);
            }
        }
        // if not has a constructor will inject values into public properties
        if ($metadata['has_constructor'] === false) {
            // collect all public properties
            foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
                $metadata['properties'][$property->name] = $property->name;
                $propertyComment = $property->getDocComment();
                if ($propertyComment === false) {
                    continue;
                }
                $attribute = new Attribute();
                $attribute->required = strpos($propertyComment, '@Required') !== false;
                $attribute->name = $property->name;
                $attribute->type = strpos($propertyComment, '@var') !== false && preg_match('/@var\\s+([^\\s]+)/', $propertyComment, $matches) ? $matches[1] : 'mixed';
                $this->collectAttributeTypeMetadata($metadata, $attribute);
                // checks if the property has @Enum
                if (strpos($propertyComment, '@Enum') === false) {
                    continue;
                }
                $context = 'property ' . $class->name . '::$' . $property->name;
                self::$metadataParser->setTarget(Target::TARGET_PROPERTY);
                foreach (self::$metadataParser->parse($propertyComment, $context) as $annotation) {
                    if (!$annotation instanceof Enum) {
                        continue;
                    }
                    $metadata['enum'][$property->name]['value'] = $annotation->value;
                    $metadata['enum'][$property->name]['literal'] = !empty($annotation->literal) ? $annotation->literal : $annotation->value;
                }
            }
            // choose the first property as default property
            $metadata['default_property'] = reset($metadata['properties']);
        }
        elseif ($metadata['has_named_argument_constructor']) {
            foreach ($constructor->getParameters() as $parameter) {
                if ($parameter->isVariadic()) {
                    break;
                }
                $metadata['constructor_args'][$parameter->getName()] = [
                    'position' => $parameter->getPosition(),
                    'default' => $parameter->isOptional() ? $parameter->getDefaultValue() : null,
                ];
            }
        }
    }
    self::$annotationMetadata[$name] = $metadata;
}
RSS feed
Powered by Drupal