parse() public method

Parses the given docblock string for annotations.
public parse ( string $input, string $context = '' ) : array
$input string The docblock string to parse.
$context string The parsing context.
return array Array of annotations. If no annotations are found, an empty array is returned.
Beispiel #1
0
 /**
  * Dispatch annotations found in phpDoc with context given in second argument.
  *
  * @param string     $phpDoc     phpDoc
  * @param mixed      $context    context
  */
 private function processDocComment($phpDoc, $context = null)
 {
     $annotations = $this->docParser->parse($phpDoc);
     foreach ($annotations as $annotation) {
         $this->collection->dispatch(Events::TOKEN_PHP_ANNOTATION, new Context\PHP\Annotation($annotation, $context), $this->result);
     }
 }
 /**
  * {@inheritDoc}
  */
 public function getMethodAnnotations(ReflectionMethod $method)
 {
     $class = $method->getDeclaringClass();
     $context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
     $this->parser->setTarget(Target::TARGET_METHOD);
     $this->parser->setImports($this->getMethodImports($method));
     $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
     return $this->parser->parse($method->getDocComment(), $context);
 }
 /**
  * @param Node $node
  * @return void
  */
 public function enterNode(Node $node)
 {
     if (!$node instanceof Node\Expr\MethodCall || !is_string($node->name) || !in_array(strtolower($node->name), array_map('strtolower', array_keys($this->methodsToExtractFrom)))) {
         $this->previousNode = $node;
         return;
     }
     $ignore = false;
     $desc = $meaning = null;
     if (null !== ($docComment = $this->getDocCommentForNode($node))) {
         if ($docComment instanceof Doc) {
             $docComment = $docComment->getText();
         }
         foreach ($this->docParser->parse($docComment, 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } elseif ($annot instanceof Desc) {
                 $desc = $annot->text;
             } elseif ($annot instanceof Meaning) {
                 $meaning = $annot->text;
             }
         }
     }
     if (!$node->args[0]->value instanceof String_) {
         if ($ignore) {
             return;
         }
         $message = sprintf('Can only extract the translation id from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
         if ($this->logger) {
             $this->logger->error($message);
             return;
         }
         throw new RuntimeException($message);
     }
     $id = $node->args[0]->value->value;
     $index = $this->methodsToExtractFrom[strtolower($node->name)];
     if (isset($node->args[$index])) {
         if (!$node->args[$index]->value instanceof String_) {
             if ($ignore) {
                 return;
             }
             $message = sprintf('Can only extract the translation domain from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
             if ($this->logger) {
                 $this->logger->error($message);
                 return;
             }
             throw new RuntimeException($message);
         }
         $domain = $node->args[$index]->value->value;
     } else {
         $domain = 'messages';
     }
     $message = new Message($id, $domain);
     $message->setDesc($desc);
     $message->setMeaning($meaning);
     $message->addSource($this->fileSourceFactory->create($this->file, $node->getLine()));
     $this->catalogue->add($message);
 }
Beispiel #4
0
 public function testIssueWithNamespacesOrImports()
 {
     $docblock = "@Entity";
     $parser = new DocParser();
     $annots = $parser->parse($docblock);
     $this->assertEquals(1, count($annots));
     $this->assertInstanceOf("Entity", $annots[0]);
     $this->assertEquals(1, count($annots));
 }
Beispiel #5
0
 /**
  * @group performance
  */
 public function testDocParsePerformance()
 {
     $imports = array('ignorephpdoc' => 'Annotations\\Annotation\\IgnorePhpDoc', 'ignoreannotation' => 'Annotations\\Annotation\\IgnoreAnnotation', 'route' => 'Doctrine\\Tests\\Common\\Annotations\\Fixtures\\Annotation\\Route', 'template' => 'Doctrine\\Tests\\Common\\Annotations\\Fixtures\\Annotation\\Template', '__NAMESPACE__' => 'Doctrine\\Tests\\Common\\Annotations\\Fixtures');
     $ignored = array('access', 'author', 'copyright', 'deprecated', 'example', 'ignore', 'internal', 'link', 'see', 'since', 'tutorial', 'version', 'package', 'subpackage', 'name', 'global', 'param', 'return', 'staticvar', 'static', 'var', 'throws', 'inheritdoc');
     $method = $this->getMethod();
     $methodComment = $method->getDocComment();
     $classComment = $method->getDeclaringClass()->getDocComment();
     $time = microtime(true);
     for ($i = 0, $c = 200; $i < $c; $i++) {
         $parser = new DocParser();
         $parser->setImports($imports);
         $parser->setIgnoredAnnotationNames($ignored);
         $parser->setIgnoreNotImportedAnnotations(true);
         $parser->parse($methodComment);
         $parser->parse($classComment);
     }
     $time = microtime(true) - $time;
     $this->printResults('doc-parser', $time, $c);
 }
 /**
  * @param $item
  * @param null $domain
  */
 private function parseItem($item, $domain = null)
 {
     // get doc comment
     $ignore = false;
     $desc = $meaning = $docComment = null;
     if ($item->key) {
         $docComment = $item->key->getDocComment();
     }
     if (!$docComment) {
         $docComment = $item->value->getDocComment();
     }
     $docComment = is_object($docComment) ? $docComment->getText() : null;
     if ($docComment) {
         if ($docComment instanceof Doc) {
             $docComment = $docComment->getText();
         }
         foreach ($this->docParser->parse($docComment, 'file ' . $this->file . ' near line ' . $item->value->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } elseif ($annot instanceof Desc) {
                 $desc = $annot->text;
             } elseif ($annot instanceof Meaning) {
                 $meaning = $annot->text;
             }
         }
     }
     // check if the value is explicitly set to false => e.g. for FormField that should be rendered without label
     $ignore = $ignore || !$item->value instanceof Node\Scalar\String_ || $item->value->value == false;
     if (!$item->value instanceof Node\Scalar\String_ && !$item->value instanceof Node\Scalar\LNumber) {
         if ($ignore) {
             return;
         }
         $message = sprintf('Unable to extract translation id for form label/title/placeholder from non-string values, but got "%s" in %s on line %d. Please refactor your code to pass a string, or add "/** @Ignore */".', get_class($item->value), $this->file, $item->value->getLine());
         if ($this->logger) {
             $this->logger->error($message);
             return;
         }
         throw new RuntimeException($message);
     }
     if ($domain === false) {
         // Don't translate when domain is `false`
         return;
     }
     $source = $this->fileSourceFactory->create($this->file, $item->value->getLine());
     $id = $item->value->value;
     if (null === $domain) {
         $this->defaultDomainMessages[] = array('id' => $id, 'source' => $source, 'desc' => $desc, 'meaning' => $meaning);
     } else {
         $this->addToCatalogue($id, $source, $domain, $desc, $meaning);
     }
 }
 public function scanForAnnotations(string $docBlock, $context, array $imports) : Annotations
 {
     // Hack to ensure an attempt to autoload an annotation class is made
     AnnotationRegistry::registerLoader(function ($class) {
         return (bool) class_exists($class);
     });
     $imports = array_combine(array_map(function ($string) {
         return strtolower($string);
     }, array_keys($imports)), array_values($imports));
     $parser = new DocParser();
     $parser->setIgnoreNotImportedAnnotations(true);
     $parser->setImports($imports);
     return new Annotations($parser->parse($docBlock, $context));
 }
Beispiel #8
0
 /**
  * Use doctrine to parse the comment block and return the detected annotations.
  *
  * @param string $comment a T_DOC_COMMENT.
  * @param Context $context
  * @return array Annotations
  */
 public function fromComment($comment, $context = null)
 {
     if ($context === null) {
         $context = new Context(['comment' => $comment]);
     } else {
         $context->comment = $comment;
     }
     try {
         self::$context = $context;
         if ($context->is('annotations') === false) {
             $context->annotations = [];
         }
         $comment = preg_replace_callback('/^[\\t ]*\\*[\\t ]+/m', function ($match) {
             // Replace leading tabs with spaces.
             // Workaround for http://www.doctrine-project.org/jira/browse/DCOM-255
             return str_replace("\t", ' ', $match[0]);
         }, $comment);
         $annotations = $this->docParser->parse($comment, $context);
         self::$context = null;
         return $annotations;
     } catch (Exception $e) {
         self::$context = null;
         if (preg_match('/^(.+) at position ([0-9]+) in ' . preg_quote($context, '/') . '\\.$/', $e->getMessage(), $matches)) {
             $errorMessage = $matches[1];
             $errorPos = $matches[2];
             $atPos = strpos($comment, '@');
             $context->line += substr_count($comment, "\n", 0, $atPos + $errorPos);
             $lines = explode("\n", substr($comment, $atPos, $errorPos));
             $context->character = strlen(array_pop($lines)) + 1;
             // position starts at 0 character starts at 1
             Logger::warning(new Exception($errorMessage . ' in ' . $context, $e->getCode(), $e));
         } else {
             Logger::warning($e);
         }
         return [];
     }
 }
 /**
  * Collects parsing metadata for a given class.
  *
  * @param \ReflectionClass $class
  */
 private function collectParsingMetadata(ReflectionClass $class)
 {
     $ignoredAnnotationNames = self::$globalIgnoredNames;
     $annotations = $this->preParser->parse($class->getDocComment(), 'class ' . $class->name);
     foreach ($annotations as $annotation) {
         if ($annotation instanceof IgnoreAnnotation) {
             foreach ($annotation->names as $annot) {
                 $ignoredAnnotationNames[$annot] = true;
             }
         }
     }
     $name = $class->getName();
     $this->imports[$name] = array_merge(self::$globalImports, $this->phpParser->parseClass($class), array('__NAMESPACE__' => $class->getNamespaceName()));
     $this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames;
 }
 /**
  * @param Node $node
  */
 public function enterNode(Node $node)
 {
     if (!$node instanceof Node\Expr\New_ || !is_string($node->class) || strtolower($node->class) !== 'validationerror') {
         $this->previousNode = $node;
         return;
     }
     $ignore = false;
     $desc = $meaning = null;
     if (null !== ($docComment = $this->getDocCommentForNode($node))) {
         if ($docComment instanceof Doc) {
             $docComment = $docComment->getText();
         }
         foreach ($this->docParser->parse($docComment, 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } elseif ($annot instanceof Desc) {
                 $desc = $annot->text;
             } elseif ($annot instanceof Meaning) {
                 $meaning = $annot->text;
             }
         }
     }
     if (!$node->args[0]->value instanceof String_) {
         if ($ignore) {
             return;
         }
         $message = sprintf('Can only extract the translation id from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
         if ($this->logger) {
             $this->logger->error($message);
             return;
         }
         throw new RuntimeException($message);
     }
     $message = new Message($node->args[0]->value->value, $this->defaultDomain);
     $message->setDesc($desc);
     $message->setMeaning($meaning);
     $message->addSource($this->fileSourceFactory->create($this->file, $node->getLine()));
     $this->catalogue->add($message);
     // plural
     if ($node->args[1]->value instanceof String_) {
         $message = new Message($node->args[1]->value->value, $this->defaultDomain);
         $message->setDesc($desc);
         $message->setMeaning($meaning);
         $message->addSource($this->fileSourceFactory->create($this->file, $node->getLine()));
         $this->catalogue->add($message);
     }
 }
 /**
  * @param RefComment $comment
  *
  * @return Annotation[]
  */
 private function parseComment(RefComment $comment = null)
 {
     if ($comment === null) {
         return [];
     }
     $annotations = $this->docParser->parse($comment->text);
     foreach ($annotations as $key => $annotation) {
         if (!$annotation instanceof Annotation) {
             unset($annotations[$key]);
             continue;
         }
         if ($annotation instanceof ContentInterface) {
             $content = $this->extractContent($comment->text, get_class($annotation));
             $annotation->setContent($content);
         }
     }
     return $annotations;
 }
Beispiel #12
0
 /**
  *
  * @param Context $context
  * @return AbstractAnnotation[]
  */
 protected function parseContext($context)
 {
     try {
         self::$context = $context;
         $annotations = $this->docParser->parse($context->comment, $context);
         self::$context = null;
     } catch (\Exception $e) {
         self::$context = null;
         if (preg_match('/^(.+) at position ([0-9]+) in ' . preg_quote($context, '/') . '\\.$/', $e->getMessage(), $matches)) {
             $errorMessage = $matches[1];
             $errorPos = $matches[2];
             $atPos = strpos($context->comment, '@');
             $context->line += substr_count($context->comment, "\n", 0, $atPos + $errorPos);
             $lines = explode("\n", substr($context->comment, $atPos, $errorPos));
             $context->character = strlen(array_pop($lines)) + 1;
             // position starts at 0 character starts at 1
             Logger::warning(new \Exception($errorMessage . ' in ' . $context, $e->getCode(), $e));
         } else {
             Logger::warning($e);
         }
         return array();
     }
     foreach ($annotations as $annotation) {
         foreach ($this->processors as $processor) {
             $processor->process($annotation, $context);
         }
         if ($annotation instanceof AbstractAnnotation) {
             if ($annotation->hasPartialId()) {
                 if ($this->hasPartial($annotation->_partialId)) {
                     Logger::notice('partial="' . $annotation->_partialId . '" is not unique. another was found in ' . $annotation->_context);
                 }
                 $this->setPartial($annotation->_partialId, $annotation);
             } elseif ($annotation instanceof Resource) {
                 $this->resources[] = $annotation;
             } elseif ($annotation instanceof Model) {
                 $this->models[] = $annotation;
             }
         }
     }
     return $annotations;
 }
Beispiel #13
0
 /**
  * Collects parsing metadata for a given annotation class
  *
  * @param string $name The annotation name
  */
 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;
 }
Beispiel #14
0
 /**
  * @group DCOM-56
  */
 public function testAutoloadAnnotation()
 {
     $this->assertFalse(class_exists('Doctrine\\Tests\\Common\\Annotations\\Fixture\\Annotation\\Autoload', false), 'Pre-condition: Doctrine\\Tests\\Common\\Annotations\\Fixture\\Annotation\\Autoload not allowed to be loaded.');
     $parser = new DocParser();
     AnnotationRegistry::registerAutoloadNamespace('Doctrine\\Tests\\Common\\Annotations\\Fixtures\\Annotation', __DIR__ . '/../../../../');
     $parser->setImports(array('autoload' => 'Doctrine\\Tests\\Common\\Annotations\\Fixtures\\Annotation\\Autoload'));
     $annotations = $parser->parse('@Autoload');
     $this->assertEquals(1, count($annotations));
     $this->assertInstanceOf('Doctrine\\Tests\\Common\\Annotations\\Fixtures\\Annotation\\Autoload', $annotations[0]);
 }
 /**
  * Collects parsing metadata for a given annotation class
  *
  * @param string $name The annotation name
  *
  * @return void
  */
 private function collectAnnotationMetadata($name)
 {
     if (self::$metadataParser === null) {
         self::$metadataParser = new self();
         self::$metadataParser->setIgnoreNotImportedAnnotations(true);
         self::$metadataParser->setIgnoredAnnotationNames($this->ignoredAnnotationNames);
         self::$metadataParser->setImports(array('enum' => 'Doctrine\\Common\\Annotations\\Annotation\\Enum', 'target' => 'Doctrine\\Common\\Annotations\\Annotation\\Target', 'attribute' => 'Doctrine\\Common\\Annotations\\Annotation\\Attribute', 'attributes' => 'Doctrine\\Common\\Annotations\\Annotation\\Attributes'));
         AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Enum.php');
         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']) {
         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 Attributes) {
                 foreach ($annotation->value as $attribute) {
                     $this->collectAttributeTypeMetadata($metadata, $attribute);
                 }
             }
         }
         // 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;
                 if (false === ($propertyComment = $property->getDocComment())) {
                     continue;
                 }
                 $attribute = new Attribute();
                 $attribute->required = false !== strpos($propertyComment, '@Required');
                 $attribute->name = $property->name;
                 $attribute->type = false !== strpos($propertyComment, '@var') && preg_match('/@var\\s+([^\\s]+)/', $propertyComment, $matches) ? $matches[1] : 'mixed';
                 $this->collectAttributeTypeMetadata($metadata, $attribute);
                 // checks if the property has @Enum
                 if (false !== strpos($propertyComment, '@Enum')) {
                     $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']);
         }
     }
     self::$annotationMetadata[$name] = $metadata;
 }
 /**
  * Gets the annotations applied to a property.
  *
  * @param \ReflectionProperty $property The ReflectionProperty of the property
  *                                     from which the annotations should be read.
  *
  * @return array An array of Annotations.
  */
 public function getPropertyAnnotations(\ReflectionProperty $property)
 {
     return $this->parser->parse($property->getDocComment(), 'property ' . $property->getDeclaringClass()->name . '::$' . $property->getName());
 }
 /**
  * Gets the annotations applied to a property.
  *
  * @param ReflectionProperty $property The ReflectionProperty of the property
  *                                     from which the annotations should be read.
  * @return array An array of Annotations.
  */
 public function getPropertyAnnotations(\ReflectionProperty $property)
 {
     $this->parser->setTarget(Target::TARGET_PROPERTY);
     return $this->parser->parse($property->getDocComment(), 'property ' . $property->getDeclaringClass()->name . '::$' . $property->getName());
 }
 /**
  * @group DCOM-41
  * @expectedException Doctrine\Common\Annotations\AnnotationException
  */
 public function testAnnotationThrowsExceptionWhenAtSignIsNotFollowedByIdentifierInNestedAnnotation()
 {
     $parser = new DocParser();
     $result = $parser->parse("@Doctrine\\Tests\\Common\\Annotations\\Name(@')");
 }
 public function enterNode(\PHPParser_Node $node)
 {
     /**
      * determine domain from namespace of files.
      * Finder appears to start with root level files so Namespace is correct for remaining files
      */
     if ($node instanceof \PHPParser_Node_Stmt_Namespace) {
         if (isset($node->name)) {
             if (array_key_exists($node->name->toString(), $this->bundles)) {
                 $this->domain = strtolower($this->bundles[$node->name->toString()]);
             }
             return;
         } else {
             foreach ($node->stmts as $node) {
                 $this->enterNode($node);
             }
             return;
         }
     }
     if (!$node instanceof \PHPParser_Node_Expr_MethodCall || !is_string($node->name) || !in_array(strtolower($node->name), $this->methodNames)) {
         $this->previousNode = $node;
         return;
     }
     $ignore = false;
     $desc = $meaning = null;
     if (null !== ($docComment = $this->getDocCommentForNode($node))) {
         foreach ($this->docParser->parse($docComment, 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } else {
                 if ($annot instanceof Desc) {
                     $desc = $annot->text;
                 } else {
                     if ($annot instanceof Meaning) {
                         $meaning = $annot->text;
                     }
                 }
             }
         }
     }
     if (!$node->args[0]->value instanceof \PHPParser_Node_Scalar_String) {
         if ($ignore) {
             return;
         }
         $message = sprintf('Can only extract the translation id from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
         if ($this->logger) {
             $this->logger->err($message);
             return;
         }
         throw new RuntimeException($message);
     }
     $id = $node->args[0]->value->value;
     if (in_array(strtolower($node->name), array('_n', '_fn'), true)) {
         // concatenate pluralized strings from zikula functions
         $id = $node->args[0]->value->value . '|' . $node->args[1]->value->value;
     }
     // determine location of domain
     $domainIndex = array_search(strtolower($node->name), $this->methodNames);
     if (isset($node->args[$domainIndex])) {
         if (!$node->args[$domainIndex]->value instanceof \PHPParser_Node_Scalar_String) {
             if ($ignore) {
                 return;
             }
             $message = sprintf('Can only extract the translation domain from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
             if ($this->logger) {
                 $this->logger->err($message);
                 return;
             }
             throw new RuntimeException($message);
         }
         $domain = $node->args[$domainIndex]->value->value;
     } else {
         $domain = !empty($this->domain) ? $this->domain : 'messages';
     }
     $message = new Message($id, $domain);
     $message->setDesc($desc);
     $message->setMeaning($meaning);
     $message->addSource(new FileSource((string) $this->file, $node->getLine()));
     $this->catalogue->add($message);
 }
 /**
  * @param Node $node
  * @return void
  */
 public function enterNode(Node $node)
 {
     if ($node instanceof Node\Stmt\Namespace_) {
         if (isset($node->name)) {
             $this->namespace = implode('\\', $node->name->parts);
         }
         return;
     }
     if ($node instanceof Node\Stmt\Class_) {
         $name = '' === $this->namespace ? $node->name : $this->namespace . '\\' . $node->name;
         if (!class_exists($name)) {
             return;
         }
         $ref = new \ReflectionClass($name);
         if (!$ref->isSubclassOf('Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException') && $ref->name !== 'Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException') {
             return;
         }
         if (!$ref->hasMethod('getMessageKey')) {
             return;
         }
         $this->inAuthException = true;
         return;
     }
     if (!$this->inAuthException) {
         return;
     }
     if ($node instanceof Node\Stmt\ClassMethod) {
         if ('getmessagekey' === strtolower($node->name)) {
             $this->inGetMessageKey = true;
         }
         return;
     }
     if (!$this->inGetMessageKey) {
         return;
     }
     if (!$node instanceof Node\Stmt\Return_) {
         return;
     }
     $ignore = false;
     $desc = $meaning = null;
     if ($docComment = $node->getDocComment()) {
         foreach ($this->docParser->parse($docComment->getText(), 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } elseif ($annot instanceof Desc) {
                 $desc = $annot->text;
             } elseif ($annot instanceof Meaning) {
                 $meaning = $annot->text;
             }
         }
     }
     if (!$node->expr instanceof Node\Scalar\String_) {
         if ($ignore) {
             return;
         }
         $message = sprintf('Could not extract id from return value, expected scalar string but got %s (in %s on line %d).', get_class($node->expr), $this->file, $node->expr->getLine());
         if ($this->logger) {
             $this->logger->error($message);
             return;
         }
         throw new RuntimeException($message);
     }
     $message = Message::create($node->expr->value, $this->domain)->setDesc($desc)->setMeaning($meaning)->addSource(new FileSource((string) $this->file, $node->expr->getLine()));
     $this->catalogue->add($message);
 }