Commit 402a3cae authored by webchick's avatar webchick

Issue #2138867 by chx: Allow dangling commas in annotations.

parent 6deedddb
......@@ -3,20 +3,20 @@
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "4c727150110aeae10efe10a92ff256f5",
"hash": "414745173d1e926721e1d7511a65dcec",
"packages": [
{
"name": "doctrine/annotations",
"version": "v1.1.2",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "v1.1.2"
"reference": "463d926a8dcc49271cb7db5a08364a70ed6e3cd3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/v1.1.2",
"reference": "v1.1.2",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/463d926a8dcc49271cb7db5a08364a70ed6e3cd3",
"reference": "463d926a8dcc49271cb7db5a08364a70ed6e3cd3",
"shasum": ""
},
"require": {
......@@ -45,7 +45,8 @@
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com",
"homepage": "http://www.jwage.com/"
"homepage": "http://www.jwage.com/",
"role": "Creator"
},
{
"name": "Guilherme Blanco",
......@@ -63,7 +64,7 @@
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh",
"homepage": "http://jmsyst.com",
"role": "Developer of wrapped JMSSerializerBundle"
}
],
......@@ -74,7 +75,7 @@
"docblock",
"parser"
],
"time": "2013-06-16 21:33:03"
"time": "2013-11-19 05:59:59"
},
{
"name": "doctrine/cache",
......@@ -2056,6 +2057,7 @@
"minimum-stability": "stable",
"stability-flags": {
"doctrine/common": 10,
"doctrine/annotations": 20,
"kriswallsmith/assetic": 15,
"symfony-cmf/routing": 15,
"easyrdf/easyrdf": 10
......
......@@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitdcdeef3a2347836a4b3309cb54064cf9::getLoader();
return ComposerAutoloaderInite23e221879b77f56988466576fc63488::getLoader();
......@@ -8,4 +8,4 @@
return array(
$vendorDir . '/kriswallsmith/assetic/src/functions.php',
$baseDir . '/core/lib/Drupal.php',
);
\ No newline at end of file
);
......@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitdcdeef3a2347836a4b3309cb54064cf9
class ComposerAutoloaderInite23e221879b77f56988466576fc63488
{
private static $loader;
......@@ -19,9 +19,9 @@ public static function getLoader()
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitdcdeef3a2347836a4b3309cb54064cf9', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInite23e221879b77f56988466576fc63488', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitdcdeef3a2347836a4b3309cb54064cf9', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInite23e221879b77f56988466576fc63488', 'loadClassLoader'));
$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname($vendorDir));
......
......@@ -735,79 +735,6 @@
"parser"
]
},
{
"name": "doctrine/annotations",
"version": "v1.1.2",
"version_normalized": "1.1.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "v1.1.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/v1.1.2",
"reference": "v1.1.2",
"shasum": ""
},
"require": {
"doctrine/lexer": "1.*",
"php": ">=5.3.2"
},
"require-dev": {
"doctrine/cache": "1.*"
},
"time": "2013-06-16 21:33:03",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Doctrine\\Common\\Annotations\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com",
"homepage": "http://www.jwage.com/"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com",
"homepage": "http://www.instaclick.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh",
"role": "Developer of wrapped JMSSerializerBundle"
}
],
"description": "Docblock Annotations Parser",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"annotations",
"docblock",
"parser"
]
},
{
"name": "doctrine/collections",
"version": "v1.1",
......@@ -2115,5 +2042,79 @@
"filesystem",
"iterator"
]
},
{
"name": "doctrine/annotations",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "463d926a8dcc49271cb7db5a08364a70ed6e3cd3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/463d926a8dcc49271cb7db5a08364a70ed6e3cd3",
"reference": "463d926a8dcc49271cb7db5a08364a70ed6e3cd3",
"shasum": ""
},
"require": {
"doctrine/lexer": "1.*",
"php": ">=5.3.2"
},
"require-dev": {
"doctrine/cache": "1.*"
},
"time": "2013-11-19 05:59:59",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Doctrine\\Common\\Annotations\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com",
"homepage": "http://www.jwage.com/",
"role": "Creator"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com",
"homepage": "http://www.instaclick.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "http://jmsyst.com",
"role": "Developer of wrapped JMSSerializerBundle"
}
],
"description": "Docblock Annotations Parser",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"annotations",
"docblock",
"parser"
]
}
]
......@@ -3,6 +3,7 @@ language: php
php:
- 5.3
- 5.4
- 5.5
before_script:
- composer --prefer-source --dev install
......
......@@ -69,7 +69,7 @@ class AnnotationReader implements Reader
'Required' => true, 'Attribute' => true, 'Attributes' => true,
'Target' => true, 'SuppressWarnings' => true,
'ingroup' => true, 'code' => true, 'endcode' => true,
'package_version' => true, 'fixme' => true
'package_version' => true, 'fixme' => true, 'noinspection' => true
);
/**
......
......@@ -19,11 +19,9 @@
namespace Doctrine\Common\Annotations;
use Closure;
use ReflectionClass;
use Doctrine\Common\Annotations\Annotation\Enum;
use Doctrine\Common\Annotations\Annotation\Target;
use Doctrine\Common\Annotations\Annotation\Attribute;
use Doctrine\Common\Annotations\Annotation\Attributes;
/**
......@@ -582,7 +580,7 @@ private function Annotations()
}
/**
* Annotation ::= "@" AnnotationName ["(" [Values] ")"]
* Annotation ::= "@" AnnotationName MethodCall
* AnnotationName ::= QualifiedName | SimpleName
* QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName
* NameSpacePart ::= identifier | null | false | true
......@@ -673,16 +671,7 @@ private function Annotation()
);
}
$values = array();
if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) {
$this->match(DocLexer::T_OPEN_PARENTHESIS);
if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) {
$values = $this->Values();
}
$this->match(DocLexer::T_CLOSE_PARENTHESIS);
}
$values = $this->MethodCall();
if (isset(self::$annotationMetadata[$name]['enum'])) {
// checks all declared attributes
......@@ -736,6 +725,7 @@ private function Annotation()
}
$instance = new $name();
foreach ($values as $property => $value) {
if (!isset(self::$annotationMetadata[$name]['properties'][$property])) {
if ('value' !== $property) {
......@@ -755,7 +745,31 @@ private function Annotation()
}
/**
* Values ::= Array | Value {"," Value}*
* MethodCall ::= ["(" [Values] ")"]
*
* @return array
*/
private function MethodCall()
{
$values = array();
if ( ! $this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) {
return $values;
}
$this->match(DocLexer::T_OPEN_PARENTHESIS);
if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) {
$values = $this->Values();
}
$this->match(DocLexer::T_CLOSE_PARENTHESIS);
return $values;
}
/**
* Values ::= Array | Value {"," Value}* [","]
*
* @return array
*/
......@@ -766,6 +780,7 @@ private function Values()
// Handle the case of a single array as value, i.e. @Foo({....})
if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) {
$values['value'] = $this->Value();
return $values;
}
......@@ -773,6 +788,11 @@ private function Values()
while ($this->lexer->isNextToken(DocLexer::T_COMMA)) {
$this->match(DocLexer::T_COMMA);
if ($this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) {
break;
}
$token = $this->lexer->lookahead;
$value = $this->Value();
......@@ -812,12 +832,12 @@ private function Constant()
{
$identifier = $this->Identifier();
if (!defined($identifier) && false !== strpos($identifier, '::') && '\\' !== $identifier[0]) {
if ( ! defined($identifier) && false !== strpos($identifier, '::') && '\\' !== $identifier[0]) {
list($className, $const) = explode('::', $identifier);
$alias = (false === $pos = strpos($className, '\\'))? $className : substr($className, 0, $pos);
$alias = (false === $pos = strpos($className, '\\')) ? $className : substr($className, 0, $pos);
$found = false;
switch (true) {
case !empty ($this->namespaces):
foreach ($this->namespaces as $ns) {
......
......@@ -2,19 +2,10 @@
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Common\Annotations\DoctrineReader;
use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
use Doctrine\Common\Annotations\Annotation\IgnorePhpDoc;
use Doctrine\Common\Annotations\Annotation;
use ReflectionClass, Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Tests\Common\Annotations\DummyAnnotation;
use Doctrine\Tests\Common\Annotations\Name;
use Doctrine\Tests\Common\Annotations\DummyId;
use Doctrine\Tests\Common\Annotations\DummyJoinTable;
use Doctrine\Tests\Common\Annotations\DummyJoinColumn;
use Doctrine\Tests\Common\Annotations\DummyColumn;
use Doctrine\Tests\Common\Annotations\DummyGeneratedValue;
require_once __DIR__ . '/TopLevelAnnotation.php';
abstract class AbstractReaderTest extends \PHPUnit_Framework_TestCase
......@@ -93,8 +84,16 @@ public function testAnnotationsWithVarType()
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', $barAnnot[0]->annotation);
}
public function testClassWithWithDanglingComma()
{
$reader = $this->getReader();
$annots = $reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\DummyClassWithDanglingComma'));
$this->assertCount(1, $annots);
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetPropertyMethod is not allowed to be declared on class Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtClass. You may only use this annotation on these code elements: METHOD, PROPERTY
*/
public function testClassWithInvalidAnnotationTargetAtClassDocBlock()
......@@ -111,7 +110,7 @@ public function testClassWithWithInclude()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetClass is not allowed to be declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty::$foo. You may only use this annotation on these code elements: CLASS
*/
public function testClassWithInvalidAnnotationTargetAtPropertyDocBlock()
......@@ -121,7 +120,7 @@ public function testClassWithInvalidAnnotationTargetAtPropertyDocBlock()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetAnnotation is not allowed to be declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty::$bar. You may only use this annotation on these code elements: ANNOTATION
*/
public function testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock()
......@@ -131,7 +130,7 @@ public function testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetClass is not allowed to be declared on method Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtMethod::functionName(). You may only use this annotation on these code elements: CLASS
*/
public function testClassWithInvalidAnnotationTargetAtMethodDocBlock()
......@@ -141,7 +140,7 @@ public function testClassWithInvalidAnnotationTargetAtMethodDocBlock()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError.
*/
public function testClassWithAnnotationWithTargetSyntaxErrorAtClassDocBlock()
......@@ -151,7 +150,7 @@ public function testClassWithAnnotationWithTargetSyntaxErrorAtClassDocBlock()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError.
*/
public function testClassWithAnnotationWithTargetSyntaxErrorAtPropertyDocBlock()
......@@ -161,7 +160,7 @@ public function testClassWithAnnotationWithTargetSyntaxErrorAtPropertyDocBlock()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError.
*/
public function testClassWithAnnotationWithTargetSyntaxErrorAtMethodDocBlock()
......@@ -171,7 +170,7 @@ public function testClassWithAnnotationWithTargetSyntaxErrorAtMethodDocBlock()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage [Type Error] Attribute "string" of @AnnotationWithVarType declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType::$invalidProperty expects a(n) string, but got integer.
*/
public function testClassWithPropertyInvalidVarTypeError()
......@@ -183,7 +182,7 @@ public function testClassWithPropertyInvalidVarTypeError()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage [Type Error] Attribute "annotation" of @AnnotationWithVarType declared on method Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType::invalidMethod() expects a(n) Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll, but got an instance of Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation.
*/
public function testClassWithMethodInvalidVarTypeError()
......@@ -195,7 +194,7 @@ public function testClassWithMethodInvalidVarTypeError()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 18 in class Doctrine\Tests\Common\Annotations\DummyClassSyntaxError.
*/
public function testClassSyntaxErrorContext()
......@@ -205,7 +204,7 @@ public function testClassSyntaxErrorContext()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 18 in method Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError::foo().
*/
public function testMethodSyntaxErrorContext()
......@@ -215,7 +214,7 @@ public function testMethodSyntaxErrorContext()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 18 in property Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError::$foo.
*/
public function testPropertySyntaxErrorContext()
......@@ -268,7 +267,7 @@ public function testImportWithInheritance()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage The annotation "@NameFoo" in property Doctrine\Tests\Common\Annotations\TestAnnotationNotImportedClass::$field was never imported.
*/
public function testImportDetectsNotImportedAnnotation()
......@@ -278,7 +277,7 @@ public function testImportDetectsNotImportedAnnotation()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage The annotation "@Foo\Bar\Name" in property Doctrine\Tests\Common\Annotations\TestNonExistentAnnotationClass::$field was never imported.
*/
public function testImportDetectsNonExistentAnnotation()
......@@ -305,7 +304,7 @@ public function testIgnoresAnnotationsNotPrefixedWithWhitespace()
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedException \Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage The class "Doctrine\Tests\Common\Annotations\Fixtures\NoAnnotation" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "Doctrine\Tests\Common\Annotations\Fixtures\NoAnnotation". If it is indeed no annotation, then you need to add @IgnoreAnnotation("NoAnnotation") to the _class_ doc comment of class Doctrine\Tests\Common\Annotations\Fixtures\InvalidAnnotationUsageClass.
*/
public function testErrorWhenInvalidAnnotationIsUsed()
......@@ -462,15 +461,15 @@ class DummyClass2 {
}
/** @Annotation */
class DummyId extends \Doctrine\Common\Annotations\Annotation {}
class DummyId extends Annotation {}
/** @Annotation */
class DummyColumn extends \Doctrine\Common\Annotations\Annotation {
class DummyColumn extends Annotation {
public $type;
}
/** @Annotation */
class DummyGeneratedValue extends \Doctrine\Common\Annotations\Annotation {}
class DummyGeneratedValue extends Annotation {}
/** @Annotation */
class DummyAnnotation extends \Doctrine\Common\Annotations\Annotation {
class DummyAnnotation extends Annotation {
public $dummyValue;
}
......@@ -478,22 +477,29 @@ class DummyAnnotation extends \Doctrine\Common\Annotations\Annotation {
* @api
* @Annotation
*/
class DummyAnnotationWithIgnoredAnnotation extends \Doctrine\Common\Annotations\Annotation {
class DummyAnnotationWithIgnoredAnnotation extends Annotation {
public $dummyValue;
}
/** @Annotation */
class DummyJoinColumn extends \Doctrine\Common\Annotations\Annotation {
class DummyJoinColumn extends Annotation {
public $name;
public $referencedColumnName;
}
/** @Annotation */
class DummyJoinTable extends \Doctrine\Common\Annotations\Annotation {
class DummyJoinTable extends Annotation {
public $name;
public $joinColumns;
public $inverseJoinColumns;
}
/**
* @DummyAnnotation(dummyValue = "bar",)
*/
class DummyClassWithDanglingComma
{
}
/**
* @DummyAnnotation(@)