/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName | AliasedName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * AliasedName ::= Alias ":" SimpleName * NameSpacePart ::= identifier * SimpleName ::= identifier * Alias ::= identifier * * @return mixed False if it is not a valid annotation. */ public function Annotation() { $values = array(); $nameParts = array(); $this->match(Lexer::T_AT); if ($this->isNestedAnnotation === false) { if ($this->lexer->lookahead['type'] !== Lexer::T_IDENTIFIER) { return false; } $this->lexer->moveNext(); } else { $this->match(Lexer::T_IDENTIFIER); } $nameParts[] = $this->lexer->token['value']; while ($this->lexer->isNextToken(Lexer::T_NAMESPACE_SEPARATOR)) { $this->match(Lexer::T_NAMESPACE_SEPARATOR); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->lexer->token['value']; } // Effectively pick the name of the class (append default NS if none, grab from NS alias, etc) if (strpos($nameParts[0], ':')) { list($alias, $nameParts[0]) = explode(':', $nameParts[0]); // If the namespace alias doesnt exist, skip until next annotation if (!isset($this->namespaceAliases[$alias])) { $this->lexer->skipUntil(Lexer::T_AT); return false; } $name = $this->namespaceAliases[$alias] . implode('\\', $nameParts); } else { if (count($nameParts) == 1) { $name = $this->defaultAnnotationNamespace . $nameParts[0]; } else { $name = implode('\\', $nameParts); } } // Does the annotation class exist? if (!class_exists($name, $this->autoloadAnnotations)) { $this->lexer->skipUntil(Lexer::T_AT); return false; } // Next will be nested $this->isNestedAnnotation = true; if ($this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { $this->match(Lexer::T_OPEN_PARENTHESIS); if (!$this->lexer->isNextToken(Lexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(Lexer::T_CLOSE_PARENTHESIS); } if ($this->annotationCreationFunction !== null) { $func = $this->annotationCreationFunction; $annot = $func($name, $values); } return isset($annot) ? $annot : $this->newAnnotation($name, $values); }
/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName | AliasedName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * AliasedName ::= Alias ":" SimpleName * NameSpacePart ::= identifier * SimpleName ::= identifier * Alias ::= identifier * * @return mixed False if it is not a valid Annotation; instance of Annotation subclass otherwise. */ public function Annotation() { $values = array(); $nameParts = array(); $this->match(Lexer::T_AT); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->_lexer->token['value']; while ($this->_lexer->isNextToken(Lexer::T_NAMESPACE_SEPARATOR)) { $this->match(Lexer::T_NAMESPACE_SEPARATOR); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->_lexer->token['value']; } // Effectively pick the name of class (append default NS if none, grab from NS alias, etc) if (count($nameParts) == 1) { if (strpos($nameParts[0], ':')) { list($alias, $simpleName) = explode(':', $nameParts[0]); $name = $this->_namespaceAliases[$alias] . $simpleName; } else { $name = $this->_defaultAnnotationNamespace . $nameParts[0]; } } else { $name = implode('\\', $nameParts); } // Is it really an annotation class? if (!$this->_isNestedAnnotation && $this->_lexer->lookahead != null && !$this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS) && !$this->_lexer->isNextToken(Lexer::T_AT) || !class_exists($name, false)) { $this->_lexer->skipUntil(Lexer::T_AT); return false; } // Next will be nested $this->_isNestedAnnotation = true; if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { $this->match(Lexer::T_OPEN_PARENTHESIS); if (!$this->_lexer->isNextToken(Lexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(Lexer::T_CLOSE_PARENTHESIS); } return new $name($values); }