From 0515d9abb7f7dd5776e6ed9f789aa6fb4b0d3748 Mon Sep 17 00:00:00 2001 From: romanb Date: Tue, 7 Jul 2009 11:25:58 +0000 Subject: [PATCH] [2.0] New Annotation API work: Simplifications, changed namespace separator to match the one of PHP, adjusted Lexer to swallow any * characters outside of a string value to be more forgiving when it comes to formatting. --- .../Common/Annotations/AnnotationReader.php | 101 +++++++++++------- lib/Doctrine/Common/Annotations/Lexer.php | 2 +- lib/Doctrine/Common/Annotations/Parser.php | 13 ++- .../Annotations/AnnotationReaderTest.php | 21 ++-- .../Tests/Common/Annotations/ParserTest.php | 2 +- 5 files changed, 88 insertions(+), 51 deletions(-) diff --git a/lib/Doctrine/Common/Annotations/AnnotationReader.php b/lib/Doctrine/Common/Annotations/AnnotationReader.php index 8b780a521..ef406b405 100644 --- a/lib/Doctrine/Common/Annotations/AnnotationReader.php +++ b/lib/Doctrine/Common/Annotations/AnnotationReader.php @@ -1,10 +1,35 @@ . + */ namespace Doctrine\Common\Annotations; use \ReflectionClass, \ReflectionMethod, \ReflectionProperty; use Doctrine\Common\Cache\Cache; +/** + * A reader for docblock annotations. + * + * @author Roman Borschel + * @since 2.0 + */ class AnnotationReader { private static $CACHE_SALT = "@"; @@ -12,12 +37,22 @@ class AnnotationReader private $_cache; private $_annotations = array(); + /** + * Initiaizes a new AnnotationReader that uses the given Cache provider to cache annotations. + * + * @param Cache $cache The cache provider to use. + */ public function __construct(Cache $cache) { $this->_parser = new Parser; $this->_cache = $cache; } + /** + * + * @param $defaultNamespace + * @return unknown_type + */ public function setDefaultAnnotationNamespace($defaultNamespace) { $this->_parser->setDefaultAnnotationNamespace($defaultNamespace); @@ -30,13 +65,9 @@ class AnnotationReader * the class annotations should be read. * @return array An array of Annotations. */ - public function getClassAnnotations($class) + public function getClassAnnotations(ReflectionClass $class) { - if (is_string($class)) { - $className = $class; - } else { - $className = $class->getName(); - } + $className = $class->getName(); if (isset($this->_annotations[$className])) { return $this->_annotations[$className]; @@ -45,16 +76,18 @@ class AnnotationReader return $this->_annotations[$className]; } - if (is_string($class)) { - $class = new ReflectionClass($className); - } - $this->_annotations[$className] = $this->_parser->parse($class->getDocComment()); return $this->_annotations[$className]; } - public function getClassAnnotation($class, $annotation) + /** + * + * @param $class + * @param $annotation + * @return unknown_type + */ + public function getClassAnnotation(ReflectionClass $class, $annotation) { $annotations = $this->getClassAnnotations($class); return isset($annotations[$annotation]) ? $annotations[$annotation] : null; @@ -68,14 +101,9 @@ class AnnotationReader * from which the annotations should be read. * @return array An array of Annotations. */ - public function getPropertyAnnotations($class, $property) + public function getPropertyAnnotations(ReflectionProperty $property) { - $className = is_string($class) ? $class : $class->getName(); - if (is_string($property)) { - $propertyName = $className . '$' . $property; - } else { - $propertyName = $className . '$' . $property->getName(); - } + $propertyName = $property->getDeclaringClass()->getName() . '$' . $property->getName(); if (isset($this->_annotations[$propertyName])) { return $this->_annotations[$propertyName]; @@ -84,18 +112,20 @@ class AnnotationReader return $this->_annotations[$propertyName]; } - if (is_string($property)) { - $property = new ReflectionProperty($className, $property); - } - $this->_annotations[$propertyName] = $this->_parser->parse($property->getDocComment()); return $this->_annotations[$propertyName]; } - public function getPropertyAnnotation($class, $property, $annotation) + /** + * + * @param $property + * @param $annotation + * @return unknown_type + */ + public function getPropertyAnnotation(ReflectionProperty $property, $annotation) { - $annotations = $this->getPropertyAnnotations($class, $property); + $annotations = $this->getPropertyAnnotations($property); return isset($annotations[$annotation]) ? $annotations[$annotation] : null; } @@ -107,14 +137,9 @@ class AnnotationReader * the annotations should be read. * @return array An array of Annotations. */ - public function getMethodAnnotations($class, $method) + public function getMethodAnnotations(ReflectionMethod $method) { - $className = is_string($class) ? $class : $class->getName(); - if (is_string($method)) { - $methodName = $className . '#' . $method; - } else { - $methodName = $className . '#' . $method->getName(); - } + $methodName = $method->getDeclaringClass()->getName() . '#' . $method->getName(); if (isset($this->_annotations[$methodName])) { return $this->_annotations[$methodName]; @@ -123,18 +148,20 @@ class AnnotationReader return $this->_annotations[$methodName]; } - if (is_string($method)) { - $method = new ReflectionMethod($className, $method); - } - $this->_annotations[$methodName] = $this->_parser->parse($method->getDocComment()); return $this->_annotations[$methodName]; } - public function getMethodAnnotation($class, $method, $annotation) + /** + * + * @param $method + * @param $annotation + * @return unknown_type + */ + public function getMethodAnnotation(ReflectionMethod $method, $annotation) { - $annotations = $this->getMethodAnnotations($class, $method); + $annotations = $this->getMethodAnnotations($method); return isset($annotations[$annotation]) ? $annotations[$annotation] : null; } } \ No newline at end of file diff --git a/lib/Doctrine/Common/Annotations/Lexer.php b/lib/Doctrine/Common/Annotations/Lexer.php index 78360e65a..dd94a943b 100644 --- a/lib/Doctrine/Common/Annotations/Lexer.php +++ b/lib/Doctrine/Common/Annotations/Lexer.php @@ -151,7 +151,7 @@ class Lexer '(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?', '"(?:[^"]|"")*"' ); - $regex = '/(' . implode(')|(', $patterns) . ')|\s+|(.)/i'; + $regex = '/(' . implode(')|(', $patterns) . ')|\s+|\*+|(.)/i'; } $matches = preg_split($regex, $input, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); diff --git a/lib/Doctrine/Common/Annotations/Parser.php b/lib/Doctrine/Common/Annotations/Parser.php index 4f903933c..c0ae414c4 100644 --- a/lib/Doctrine/Common/Annotations/Parser.php +++ b/lib/Doctrine/Common/Annotations/Parser.php @@ -39,6 +39,13 @@ class Parser $this->_defaultAnnotationNamespace = $defaultNamespace; } + /** + * Sets an alias for an annotation namespace. + * + * @param $namespace + * @param $alias + * @return unknown_type + */ public function setAnnotationNamespaceAlias($namespace, $alias) { $this->_namespaceAliases[$alias] = $namespace; @@ -139,7 +146,7 @@ class Parser * Annotation ::= "@" AnnotationName [ "(" [Values] ")" ] * AnnotationName ::= SimpleName | QualifiedName * SimpleName ::= identifier - * QualifiedName ::= NameSpacePart "." (NameSpacePart ".")* SimpleName + * QualifiedName ::= NameSpacePart "\" (NameSpacePart "\")* SimpleName * NameSpacePart ::= identifier */ public function Annotation() @@ -150,8 +157,8 @@ class Parser $this->match('@'); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->_lexer->token['value']; - while ($this->_lexer->isNextToken('.')) { - $this->match('.'); + while ($this->_lexer->isNextToken('\\')) { + $this->match('\\'); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->_lexer->token['value']; } diff --git a/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php b/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php index 8613a6183..1c96bbb0d 100644 --- a/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php +++ b/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php @@ -21,18 +21,21 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase $this->assertTrue($classAnnots[$annotName] instanceof DummyAnnotation); $this->assertEquals("hello", $classAnnots[$annotName]->dummyValue); - $propAnnots = $reader->getPropertyAnnotations($class, 'field1'); + $field1Prop = $class->getProperty('field1'); + $propAnnots = $reader->getPropertyAnnotations($field1Prop); $this->assertEquals(1, count($propAnnots)); $this->assertTrue($propAnnots[$annotName] instanceof DummyAnnotation); $this->assertEquals("fieldHello", $propAnnots[$annotName]->dummyValue); - $methodAnnots = $reader->getMethodAnnotations($class, 'getField1'); + $getField1Method = $class->getMethod('getField1'); + $methodAnnots = $reader->getMethodAnnotations($getField1Method); $this->assertEquals(1, count($methodAnnots)); $this->assertTrue($methodAnnots[$annotName] instanceof DummyAnnotation); $this->assertEquals("methodHello", $methodAnnots[$annotName]->dummyValue); $this->assertEquals(array(array(1, 2, "three")), $methodAnnots[$annotName]->value); - $propAnnots = $reader->getPropertyAnnotations($class, 'field2'); + $field2Prop = $class->getProperty('field2'); + $propAnnots = $reader->getPropertyAnnotations($field2Prop); $this->assertEquals(1, count($propAnnots)); $this->assertTrue(isset($propAnnots['Doctrine\Tests\Common\Annotations\DummyJoinTable'])); $joinTableAnnot = $propAnnots['Doctrine\Tests\Common\Annotations\DummyJoinTable']; @@ -65,12 +68,12 @@ class DummyClass { /** * @DummyJoinTable(name="join_table", - joinColumns={ - @DummyJoinColumn(name="col1", referencedColumnName="col2") - }, - inverseJoinColumns={ - @DummyJoinColumn(name="col3", referencedColumnName="col4") - }) + * joinColumns={ + * @DummyJoinColumn(name="col1", referencedColumnName="col2") + * }, + * inverseJoinColumns={ + * @DummyJoinColumn(name="col3", referencedColumnName="col4") + * }) */ private $field2; diff --git a/tests/Doctrine/Tests/Common/Annotations/ParserTest.php b/tests/Doctrine/Tests/Common/Annotations/ParserTest.php index db300fa32..25eb68aee 100644 --- a/tests/Doctrine/Tests/Common/Annotations/ParserTest.php +++ b/tests/Doctrine/Tests/Common/Annotations/ParserTest.php @@ -75,7 +75,7 @@ DOCBLOCK; * Some nifty class. * * @author Mr.X - * @Doctrine.Tests.Common.Annotations.Name(foo="bar") + * @Doctrine\Tests\Common\Annotations\Name(foo="bar") */ DOCBLOCK;