Commit a05bd5e2 authored by beberlei's avatar beberlei

[2.0] DDC-78 - Added support for context specific information in Annotation...

[2.0] DDC-78 - Added support for context specific information in Annotation Parser Syntax Error Exceptions.
parent a0c9e9db
...@@ -99,7 +99,7 @@ class AnnotationReader ...@@ -99,7 +99,7 @@ class AnnotationReader
return $this->_cache->fetch($cacheKey); return $this->_cache->fetch($cacheKey);
} }
$annotations = $this->_parser->parse($class->getDocComment()); $annotations = $this->_parser->parse($class->getDocComment(), "class ".$class->getName());
$this->_cache->save($cacheKey, $annotations, null); $this->_cache->save($cacheKey, $annotations, null);
return $annotations; return $annotations;
...@@ -134,7 +134,8 @@ class AnnotationReader ...@@ -134,7 +134,8 @@ class AnnotationReader
return $this->_cache->fetch($cacheKey); return $this->_cache->fetch($cacheKey);
} }
$annotations = $this->_parser->parse($property->getDocComment()); $context = "property ".$property->getDeclaringClass()->getName()."::\$".$property->getName();
$annotations = $this->_parser->parse($property->getDocComment(), $context);
$this->_cache->save($cacheKey, $annotations, null); $this->_cache->save($cacheKey, $annotations, null);
return $annotations; return $annotations;
...@@ -169,7 +170,8 @@ class AnnotationReader ...@@ -169,7 +170,8 @@ class AnnotationReader
return $this->_cache->fetch($cacheKey); return $this->_cache->fetch($cacheKey);
} }
$annotations = $this->_parser->parse($method->getDocComment()); $context = "method ".$method->getDeclaringClass()->getName()."::".$method->getName()."()";
$annotations = $this->_parser->parse($method->getDocComment(), $context);
$this->_cache->save($cacheKey, $annotations, null); $this->_cache->save($cacheKey, $annotations, null);
return $annotations; return $annotations;
......
...@@ -73,6 +73,11 @@ class Parser ...@@ -73,6 +73,11 @@ class Parser
*/ */
private $_namespaceAliases = array(); private $_namespaceAliases = array();
/**
* @var string
*/
private $_context = '';
/** /**
* Constructs a new AnnotationParser. * Constructs a new AnnotationParser.
* *
...@@ -107,11 +112,14 @@ class Parser ...@@ -107,11 +112,14 @@ class Parser
/** /**
* Parses the given docblock string for annotations. * Parses the given docblock string for annotations.
* *
* @param $docBlockString * @param string $docBlockString
* @param string $context
* @return array Array of Annotations. If no annotations are found, an empty array is returned. * @return array Array of Annotations. If no annotations are found, an empty array is returned.
*/ */
public function parse($docBlockString) public function parse($docBlockString, $context='')
{ {
$this->_context = $context;
// Strip out some known inline tags. // Strip out some known inline tags.
$input = str_replace(self::$_strippedInlineTags, '', $docBlockString); $input = str_replace(self::$_strippedInlineTags, '', $docBlockString);
...@@ -164,10 +172,15 @@ class Parser ...@@ -164,10 +172,15 @@ class Parser
$message = "Expected '{$expected}', got "; $message = "Expected '{$expected}', got ";
if ($this->_lexer->lookahead === null) { if ($this->_lexer->lookahead === null) {
$message .= 'end of string.'; $message .= 'end of string';
} else { } else {
$message .= "'{$token['value']}' at position {$token['position']}."; $message .= "'{$token['value']}' at position {$token['position']}";
}
if(strlen($this->_context)) {
$message .= ' in '.$this->_context;
} }
$message .= '.';
throw AnnotationException::syntaxError($message); throw AnnotationException::syntaxError($message);
} }
......
...@@ -57,6 +57,57 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase ...@@ -57,6 +57,57 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase
$classAnnot = $reader->getClassAnnotation($class, 'Doctrine\Tests\Common\Annotations\DummyAnnotation'); $classAnnot = $reader->getClassAnnotation($class, 'Doctrine\Tests\Common\Annotations\DummyAnnotation');
$this->assertEquals('hello', $classAnnot->dummyValue); $this->assertEquals('hello', $classAnnot->dummyValue);
} }
public function testClassSyntaxErrorContext()
{
$this->setExpectedException(
"Doctrine\Common\Annotations\AnnotationException",
"[Syntax Error] Expected '', got ')' at position 18 in class ".
"Doctrine\Tests\Common\Annotations\DummyClassSyntaxError."
);
$class = new \ReflectionClass('\Doctrine\Tests\Common\Annotations\DummyClassSyntaxError');
$reader = $this->createAnnotationReader();
$reader->getClassAnnotations($class);
}
public function testMethodSyntaxErrorContext()
{
$this->setExpectedException(
"Doctrine\Common\Annotations\AnnotationException",
"[Syntax Error] Expected '', got ')' at position 18 in ".
"method Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError::foo()."
);
$class = new \ReflectionClass('\Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError');
$method = $class->getMethod('foo');
$reader = $this->createAnnotationReader();
$reader->getMethodAnnotations($method);
}
public function testPropertySyntaxErrorContext()
{
$this->setExpectedException(
"Doctrine\Common\Annotations\AnnotationException",
"[Syntax Error] Expected '', got ')' at position 18 in ".
"property Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError::\$foo."
);
$class = new \ReflectionClass('\Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError');
$property = $class->getProperty('foo');
$reader = $this->createAnnotationReader();
$reader->getPropertyAnnotations($property);
}
public function createAnnotationReader()
{
$reader = new AnnotationReader(new \Doctrine\Common\Cache\ArrayCache);
$reader->setDefaultAnnotationNamespace('Doctrine\Tests\Common\Annotations\\');
return $reader;
}
} }
/** /**
...@@ -108,3 +159,30 @@ class DummyJoinTable extends \Doctrine\Common\Annotations\Annotation { ...@@ -108,3 +159,30 @@ class DummyJoinTable extends \Doctrine\Common\Annotations\Annotation {
public $joinColumns; public $joinColumns;
public $inverseJoinColumns; public $inverseJoinColumns;
} }
/**
* @DummyAnnotation(@)
*/
class DummyClassSyntaxError
{
}
class DummyClassMethodSyntaxError
{
/**
* @DummyAnnotation(@)
*/
public function foo()
{
}
}
class DummyClassPropertySyntaxError
{
/**
* @DummyAnnotation(@)
*/
public $foo;
}
\ No newline at end of file
...@@ -10,8 +10,7 @@ class ParserTest extends \Doctrine\Tests\DoctrineTestCase ...@@ -10,8 +10,7 @@ class ParserTest extends \Doctrine\Tests\DoctrineTestCase
{ {
public function testBasicAnnotations() public function testBasicAnnotations()
{ {
$parser = new Parser; $parser = $this->createTestParser();
$parser->setDefaultAnnotationNamespace('Doctrine\Tests\Common\Annotations\\');
// Marker annotation // Marker annotation
$result = $parser->parse("@Name"); $result = $parser->parse("@Name");
...@@ -108,6 +107,21 @@ DOCBLOCK; ...@@ -108,6 +107,21 @@ DOCBLOCK;
$parser->setDefaultAnnotationNamespace('Doctrine\Tests\Common\Annotations\\'); $parser->setDefaultAnnotationNamespace('Doctrine\Tests\Common\Annotations\\');
return $parser; return $parser;
} }
/**
* @group DDC-78
*/
public function testSyntaxErrorWithContextDescription()
{
$this->setExpectedException(
'Doctrine\Common\Annotations\AnnotationException',
"[Syntax Error] Expected 'PlainValue', got ''' at position 10 ".
"in class \Doctrine\Tests\Common\Annotations\Name"
);
$parser = $this->createTestParser();
$parser->parse("@Name(foo='bar')", "class \Doctrine\Tests\Common\Annotations\Name");
}
} }
class Name extends \Doctrine\Common\Annotations\Annotation { class Name extends \Doctrine\Common\Annotations\Annotation {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment