private function DocParser::collectAnnotationMetadata

Collects parsing metadata for a given annotation class

Parameters

string $name The annotation name:

1 call to DocParser::collectAnnotationMetadata()
DocParser::Annotation in drupal/core/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocParser.php
Annotation ::= "@" AnnotationName ["(" [Values] ")"] AnnotationName ::= QualifiedName | SimpleName QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName NameSpacePart ::= identifier…

File

drupal/core/vendor/doctrine/common/lib/Doctrine/Common/Annotations/DocParser.php, line 392

Class

DocParser
A parser for docblock annotations.

Namespace

Doctrine\Common\Annotations

Code

private function collectAnnotationMetadata($name) {
  if (self::$metadataParser == null) {
    self::$metadataParser = new self();
    self::$metadataParser
      ->setTarget(Target::TARGET_CLASS);
    self::$metadataParser
      ->setIgnoreNotImportedAnnotations(true);
    self::$metadataParser
      ->setImports(array(
      'target' => 'Doctrine\\Common\\Annotations\\Annotation\\Target',
      'attribute' => 'Doctrine\\Common\\Annotations\\Annotation\\Attribute',
      'attributes' => 'Doctrine\\Common\\Annotations\\Annotation\\Attributes',
    ));
    AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Target.php');
    AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attribute.php');
    AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attributes.php');
  }
  $class = new \ReflectionClass($name);
  $docComment = $class
    ->getDocComment();

  // Sets default values for annotation metadata
  $metadata = array(
    'default_property' => null,
    'has_constructor' => null !== ($constructor = $class
      ->getConstructor()) && $constructor
      ->getNumberOfParameters() > 0,
    'properties' => array(),
    'property_types' => array(),
    'attribute_types' => array(),
    'targets_literal' => null,
    'targets' => Target::TARGET_ALL,
    'is_annotation' => false !== strpos($docComment, '@Annotation'),
  );

  // verify that the class is really meant to be an annotation
  if ($metadata['is_annotation']) {
    foreach (self::$metadataParser
      ->parse($docComment, 'class @' . $name) as $annotation) {
      if ($annotation instanceof Target) {
        $metadata['targets'] = $annotation->targets;
        $metadata['targets_literal'] = $annotation->literal;
      }
      elseif ($annotation instanceof Attributes) {
        foreach ($annotation->value as $attrib) {

          // handle internal type declaration
          $type = isset(self::$typeMap[$attrib->type]) ? self::$typeMap[$attrib->type] : $attrib->type;

          // handle the case if the property type is mixed
          if ('mixed' !== $type) {

            // Checks if the property has array<type>
            if (false !== ($pos = strpos($type, '<'))) {
              $arrayType = substr($type, $pos + 1, -1);
              $type = 'array';
              if (isset(self::$typeMap[$arrayType])) {
                $arrayType = self::$typeMap[$arrayType];
              }
              $metadata['attribute_types'][$attrib->name]['array_type'] = $arrayType;
            }
            $metadata['attribute_types'][$attrib->name]['type'] = $type;
            $metadata['attribute_types'][$attrib->name]['value'] = $attrib->type;
            $metadata['attribute_types'][$attrib->name]['required'] = $attrib->required;
          }
        }
      }
    }

    // if not has a constructor will inject values into public properties
    if (false === $metadata['has_constructor']) {

      // collect all public properties
      foreach ($class
        ->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
        $metadata['properties'][$property->name] = $property->name;

        // checks if the property has @var annotation
        if (false !== ($propertyComment = $property
          ->getDocComment()) && false !== strpos($propertyComment, '@var') && preg_match('/@var\\s+([^\\s]+)/', $propertyComment, $matches)) {

          // literal type declaration
          $value = $matches[1];

          // handle internal type declaration
          $type = isset(self::$typeMap[$value]) ? self::$typeMap[$value] : $value;

          // handle the case if the property type is mixed
          if ('mixed' !== $type) {

            // Checks if the property has @var array<type> annotation
            if (false !== ($pos = strpos($type, '<'))) {
              $arrayType = substr($type, $pos + 1, -1);
              $type = 'array';
              if (isset(self::$typeMap[$arrayType])) {
                $arrayType = self::$typeMap[$arrayType];
              }
              $metadata['attribute_types'][$property->name]['array_type'] = $arrayType;
            }
            $metadata['attribute_types'][$property->name]['type'] = $type;
            $metadata['attribute_types'][$property->name]['value'] = $value;
            $metadata['attribute_types'][$property->name]['required'] = false !== strpos($propertyComment, '@Required');
          }
        }
      }

      // choose the first property as default property
      $metadata['default_property'] = reset($metadata['properties']);
    }
  }
  self::$annotationMetadata[$name] = $metadata;
}