Updating vendors

skala
Julio Montoya 12 years ago
parent 75ef83696e
commit 28ea16582a
  1. 3
      vendor/doctrine/annotations/.gitignore
  2. 9
      vendor/doctrine/annotations/.travis.yml
  3. 11
      vendor/doctrine/annotations/README.md
  4. 30
      vendor/doctrine/annotations/composer.json
  5. 79
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php
  6. 47
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php
  7. 37
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php
  8. 85
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php
  9. 54
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php
  10. 33
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Required.php
  11. 107
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php
  12. 158
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php
  13. 318
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php
  14. 139
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php
  15. 250
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php
  16. 132
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php
  17. 1049
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
  18. 269
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php
  19. 141
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php
  20. 89
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PhpParser.php
  21. 67
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php
  22. 157
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php
  23. 175
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php
  24. 31
      vendor/doctrine/annotations/phpunit.xml.dist
  25. 571
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AbstractReaderTest.php
  26. 13
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php
  27. 56
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php
  28. 137
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DocLexerTest.php
  29. 1276
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DocParserTest.php
  30. 48
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DummyClass.php
  31. 40
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/FileCacheReaderTest.php
  32. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/AnnotWithDefaultValue.php
  33. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/Autoload.php
  34. 11
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/Route.php
  35. 18
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/Secure.php
  36. 14
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/Template.php
  37. 11
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/Version.php
  38. 21
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationEnum.php
  39. 17
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationEnumInvalid.php
  40. 34
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationEnumLiteral.php
  41. 31
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationEnumLiteralInvalid.php
  42. 14
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationTargetAll.php
  43. 14
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationTargetAnnotation.php
  44. 15
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationTargetClass.php
  45. 15
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationTargetMethod.php
  46. 14
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationTargetPropertyMethod.php
  47. 119
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithAttributes.php
  48. 20
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithConstants.php
  49. 50
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithRequiredAttributes.php
  50. 24
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithRequiredAttributesWithoutContructor.php
  51. 11
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithTargetSyntaxError.php
  52. 62
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithVarType.php
  53. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Api.php
  54. 30
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassDDC1660.php
  55. 29
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithAnnotationEnum.php
  56. 21
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithAnnotationWithTargetSyntaxError.php
  57. 31
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithAnnotationWithVarType.php
  58. 52
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithClosure.php
  59. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithConstants.php
  60. 11
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithFullyQualifiedUseStatements.php
  61. 17
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithInvalidAnnotationTargetAtClass.php
  62. 20
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithInvalidAnnotationTargetAtMethod.php
  63. 24
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithInvalidAnnotationTargetAtProperty.php
  64. 15
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithRequire.php
  65. 41
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithValidAnnotationTarget.php
  66. 300
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Controller.php
  67. 15
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/DifferentNamespacesPerFileWithClassAsFirst.php
  68. 15
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/DifferentNamespacesPerFileWithClassAsLast.php
  69. 13
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/EqualNamespacesPerFileWithClassAsFirst.php
  70. 12
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/EqualNamespacesPerFileWithClassAsLast.php
  71. 12
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/GlobalNamespacesPerFileWithClassAsFirst.php
  72. 12
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/GlobalNamespacesPerFileWithClassAsLast.php
  73. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/IntefaceWithConstants.php
  74. 14
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/InvalidAnnotationUsageButIgnoredClass.php
  75. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/InvalidAnnotationUsageClass.php
  76. 9
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/MultipleClassesInFile.php
  77. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/MultipleImportsInUseStatement.php
  78. 20
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/NamespaceAndClassCommentedOut.php
  79. 12
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/NamespaceWithClosureDeclaration.php
  80. 1009
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/NamespacedSingleClassLOC1000.php
  81. 5
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/NoAnnotation.php
  82. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/NonNamespacedClass.php
  83. 1006
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/SingleClassLOC1000.php
  84. 13
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/TestInterface.php
  85. 194
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/PerformanceTest.php
  86. 207
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/PhpParserTest.php
  87. 97
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/SimpleAnnotationReaderTest.php
  88. 65
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM55Test.php
  89. 8
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Entity.php
  90. 112
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Test.php
  91. 8
      vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/TopLevelAnnotation.php
  92. 10
      vendor/doctrine/annotations/tests/Doctrine/Tests/DoctrineTestCase.php
  93. 26
      vendor/doctrine/annotations/tests/Doctrine/Tests/TestInit.php
  94. 2
      vendor/doctrine/cache/.gitignore
  95. 9
      vendor/doctrine/cache/.travis.yml
  96. 19
      vendor/doctrine/cache/LICENSE
  97. 10
      vendor/doctrine/cache/README.md
  98. 3
      vendor/doctrine/cache/build.properties
  99. 101
      vendor/doctrine/cache/build.xml
  100. 29
      vendor/doctrine/cache/composer.json
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,3 @@
vendor/
composer.lock
composer.phar

@ -0,0 +1,9 @@
language: php
php:
- 5.3
- 5.4
before_script:
- composer --prefer-source --dev install
- phpunit

@ -0,0 +1,11 @@
# Doctrine Annotations
[![Build Status](https://travis-ci.org/doctrine/annotations.png?branch=master)](https://travis-ci.org/doctrine/annotations)
Docblock Annotations Parser library (extracted from Doctrine Common).
## Changelog
### v1.1
* Add Exception when ZendOptimizer+ or Opcache is configured to drop comments

@ -0,0 +1,30 @@
{
"name": "doctrine/annotations",
"type": "library",
"description": "Docblock Annotations Parser",
"keywords": ["annotations", "docblock", "parser"],
"homepage": "http://www.doctrine-project.org",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": ">=5.3.2",
"doctrine/lexer": "1.*"
},
"require-dev": {
"doctrine/cache": "1.*"
},
"autoload": {
"psr-0": { "Doctrine\\Common\\Annotations\\": "lib/" }
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

@ -0,0 +1,79 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* Annotations class
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class Annotation
{
/**
* Value property. Common among all derived classes.
*
* @var string
*/
public $value;
/**
* Constructor
*
* @param array $data Key-value for properties to be defined in this class
*/
public final function __construct(array $data)
{
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
/**
* Error handler for unknown property accessor in Annotation class.
*
* @param string $name Unknown property name
*
* @throws \BadMethodCallException
*/
public function __get($name)
{
throw new \BadMethodCallException(
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
);
}
/**
* Error handler for unknown property mutator in Annotation class.
*
* @param string $name Unkown property name
* @param mixed $value Property value
*
* @throws \BadMethodCallException
*/
public function __set($name, $value)
{
throw new \BadMethodCallException(
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
);
}
}

@ -0,0 +1,47 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the attribute type during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Attribute
{
/**
* @var string
*/
public $name;
/**
* @var string
*/
public $type;
/**
* @var boolean
*/
public $required = false;
}

@ -0,0 +1,37 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the types of all declared attributes during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Attributes
{
/**
* @var array<Doctrine\Common\Annotations\Annotation\Attribute>
*/
public $value;
}

@ -0,0 +1,85 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the available values during the parsing process.
*
* @since 2.4
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
* @Attributes({
* @Attribute("value", required = true, type = "array"),
* @Attribute("literal", required = false, type = "array")
* })
*/
final class Enum
{
/**
* @var array
*/
public $value;
/**
* Literal target declaration.
*
* @var array
*/
public $literal;
/**
* Annotation construct
*
* @param array $values
*
* @throws \InvalidArgumentException
*/
public function __construct(array $values)
{
if ( ! isset($values['literal'])) {
$values['literal'] = array();
}
foreach ($values['value'] as $var) {
if( ! is_scalar($var)) {
throw new \InvalidArgumentException(sprintf(
'@Enum supports only scalar values "%s" given.',
is_object($var) ? get_class($var) : gettype($var)
));
}
}
foreach ($values['literal'] as $key => $var) {
if( ! in_array($key, $values['value'])) {
throw new \InvalidArgumentException(sprintf(
'Undefined enumerator value "%s" for literal "%s".',
$key , $var
));
}
}
$this->value = $values['value'];
$this->literal = $values['literal'];
}
}

@ -0,0 +1,54 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser to ignore specific
* annotations during the parsing process.
*
* @Annotation
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
final class IgnoreAnnotation
{
/**
* @var array
*/
public $names;
/**
* Constructor
*
* @param array $values
*
* @throws \RuntimeException
*/
public function __construct(array $values)
{
if (is_string($values['value'])) {
$values['value'] = array($values['value']);
}
if (!is_array($values['value'])) {
throw new \RuntimeException(sprintf('@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', json_encode($values['value'])));
}
$this->names = $values['value'];
}
}

@ -0,0 +1,33 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check if that attribute is required during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Required
{
}

@ -0,0 +1,107 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations\Annotation;
/**
* Annotation that can be used to signal to the parser
* to check the annotation target during the parsing process.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*
* @Annotation
*/
final class Target
{
const TARGET_CLASS = 1;
const TARGET_METHOD = 2;
const TARGET_PROPERTY = 4;
const TARGET_ANNOTATION = 8;
const TARGET_ALL = 15;
/**
* @var array
*/
private static $map = array(
'ALL' => self::TARGET_ALL,
'CLASS' => self::TARGET_CLASS,
'METHOD' => self::TARGET_METHOD,
'PROPERTY' => self::TARGET_PROPERTY,
'ANNOTATION' => self::TARGET_ANNOTATION,
);
/**
* @var array
*/
public $value;
/**
* Targets as bitmask.
*
* @var integer
*/
public $targets;
/**
* Literal target declaration.
*
* @var integer
*/
public $literal;
/**
* Annotation construct
*
* @param array $values
*
* @throws \InvalidArgumentException
*/
public function __construct(array $values)
{
if (!isset($values['value'])){
$values['value'] = null;
}
if (is_string($values['value'])){
$values['value'] = array($values['value']);
}
if (!is_array($values['value'])){
throw new \InvalidArgumentException(
sprintf('@Target expects either a string value, or an array of strings, "%s" given.',
is_object($values['value']) ? get_class($values['value']) : gettype($values['value'])
)
);
}
$bitmask = 0;
foreach ($values['value'] as $literal) {
if(!isset(self::$map[$literal])){
throw new \InvalidArgumentException(
sprintf('Invalid Target "%s". Available targets: [%s]',
$literal, implode(', ', array_keys(self::$map)))
);
}
$bitmask += self::$map[$literal];
}
$this->targets = $bitmask;
$this->value = $values['value'];
$this->literal = implode(', ', $this->value);
}
}

@ -0,0 +1,158 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* Description of AnnotationException
*
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class AnnotationException extends \Exception
{
/**
* Creates a new AnnotationException describing a Syntax error.
*
* @param string $message Exception message
* @return AnnotationException
*/
public static function syntaxError($message)
{
return new self('[Syntax Error] ' . $message);
}
/**
* Creates a new AnnotationException describing a Semantical error.
*
* @param string $message Exception message
* @return AnnotationException
*/
public static function semanticalError($message)
{
return new self('[Semantical Error] ' . $message);
}
/**
* Creates a new AnnotationException describing a constant semantical error.
*
* @since 2.3
* @param string $identifier
* @param string $context
* @return AnnotationException
*/
public static function semanticalErrorConstants($identifier, $context = null)
{
return self::semanticalError(sprintf(
"Couldn't find constant %s%s", $identifier,
$context ? ", $context." : "."
));
}
/**
* Creates a new AnnotationException describing an error which occurred during
* the creation of the annotation.
*
* @since 2.2
* @param string $message
* @return AnnotationException
*/
public static function creationError($message)
{
return new self('[Creation Error] ' . $message);
}
/**
* Creates a new AnnotationException describing an type error of an attribute.
*
* @since 2.2
* @param string $attributeName
* @param string $annotationName
* @param string $context
* @param string $expected
* @param mixed $actual
* @return AnnotationException
*/
public static function typeError($attributeName, $annotationName, $context, $expected, $actual)
{
return new self(sprintf(
'[Type Error] Attribute "%s" of @%s declared on %s expects %s, but got %s.',
$attributeName,
$annotationName,
$context,
$expected,
is_object($actual) ? 'an instance of '.get_class($actual) : gettype($actual)
));
}
/**
* Creates a new AnnotationException describing an required error of an attribute.
*
* @since 2.2
* @param string $attributeName
* @param string $annotationName
* @param string $context
* @param string $expected
* @return AnnotationException
*/
public static function requiredError($attributeName, $annotationName, $context, $expected)
{
return new self(sprintf(
'[Type Error] Attribute "%s" of @%s declared on %s expects %s. This value should not be null.',
$attributeName,
$annotationName,
$context,
$expected
));
}
/**
* Creates a new AnnotationException describing a invalid enummerator.
*
* @since 2.4
* @param string $attributeName
* @param string $annotationName
* @param string $context
* @param array $available
* @param mixed $given
* @return AnnotationException
*/
public static function enumeratorError($attributeName, $annotationName, $context, $available, $given)
{
throw new self(sprintf(
'[Enum Error] Attribute "%s" of @%s declared on %s accept only [%s], but got %s.',
$attributeName,
$annotationName,
$context,
implode(', ', $available),
is_object($given) ? get_class($given) : $given
));
}
/**
* @return AnnotationException
*/
public static function optimizerPlusSaveComments()
{
throw new self("You have to enable opcache.save_comments=1 or zend_optimizerplus.save_comments=1.");
}
}

@ -0,0 +1,318 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
use Doctrine\Common\Annotations\Annotation\Target;
use Closure;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
/**
* A reader for docblock annotations.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class AnnotationReader implements Reader
{
/**
* Global map for imports.
*
* @var array
*/
private static $globalImports = array(
'ignoreannotation' => 'Doctrine\Common\Annotations\Annotation\IgnoreAnnotation',
);
/**
* A list with annotations that are not causing exceptions when not resolved to an annotation class.
*
* The names are case sensitive.
*
* @var array
*/
private static $globalIgnoredNames = array(
'access'=> true, 'author'=> true, 'copyright'=> true, 'deprecated'=> true,
'example'=> true, 'ignore'=> true, 'internal'=> true, 'link'=> true, 'see'=> true,
'since'=> true, 'tutorial'=> true, 'version'=> true, 'package'=> true,
'subpackage'=> true, 'name'=> true, 'global'=> true, 'param'=> true,
'return'=> true, 'staticvar'=> true, 'category'=> true, 'staticVar'=> true,
'static'=> true, 'var'=> true, 'throws'=> true, 'inheritdoc'=> true,
'inheritDoc'=> true, 'license'=> true, 'todo'=> true, 'TODO'=> true,
'deprec'=> true, 'property' => true, 'method' => true,
'abstract'=> true, 'exception'=> true, 'magic' => true, 'api' => true,
'final'=> true, 'filesource'=> true, 'throw' => true, 'uses' => true,
'usedby'=> true, 'private' => true, 'Annotation' => true, 'override' => true,
'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true,
'Required' => true, 'Attribute' => true, 'Attributes' => true,
'Target' => true, 'SuppressWarnings' => true,
'ingroup' => true, 'code' => true, 'endcode' => true,
'package_version' => true, 'fixme' => true
);
/**
* Add a new annotation to the globally ignored annotation names with regard to exception handling.
*
* @param string $name
*/
static public function addGlobalIgnoredName($name)
{
self::$globalIgnoredNames[$name] = true;
}
/**
* Annotations Parser
*
* @var \Doctrine\Common\Annotations\DocParser
*/
private $parser;
/**
* Annotations Parser used to collect parsing metadata
*
* @var \Doctrine\Common\Annotations\DocParser
*/
private $preParser;
/**
* PHP Parser used to collect imports.
*
* @var \Doctrine\Common\Annotations\PhpParser
*/
private $phpParser;
/**
* In-memory cache mechanism to store imported annotations per class.
*
* @var array
*/
private $imports = array();
/**
* In-memory cache mechanism to store ignored annotations per class.
*
* @var array
*/
private $ignoredAnnotationNames = array();
/**
* Constructor.
*
* Initializes a new AnnotationReader.
*/
public function __construct()
{
if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === "0" || ini_get('opcache.save_comments') === "0")) {
throw AnnotationException::optimizerPlusSaveComments();
}
if (extension_loaded('opcache') && ini_get('opcache.save_comments') == 0) {
throw AnnotationException::optimizerPlusSaveComments();
}
AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php');
$this->parser = new DocParser;
$this->preParser = new DocParser;
$this->preParser->setImports(self::$globalImports);
$this->preParser->setIgnoreNotImportedAnnotations(true);
$this->phpParser = new PhpParser;
}
/**
* Gets the annotations applied to a class.
*
* @param ReflectionClass $class The ReflectionClass of the class from which
* the class annotations should be read.
* @return array An array of Annotations.
*/
public function getClassAnnotations(ReflectionClass $class)
{
$this->parser->setTarget(Target::TARGET_CLASS);
$this->parser->setImports($this->getImports($class));
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
}
/**
* Gets a class annotation.
*
* @param ReflectionClass $class The ReflectionClass of the class from which
* the class annotations should be read.
* @param string $annotationName The name of the annotation.
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getClassAnnotation(ReflectionClass $class, $annotationName)
{
$annotations = $this->getClassAnnotations($class);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* 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)
{
$class = $property->getDeclaringClass();
$context = 'property ' . $class->getName() . "::\$" . $property->getName();
$this->parser->setTarget(Target::TARGET_PROPERTY);
$this->parser->setImports($this->getImports($class));
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
return $this->parser->parse($property->getDocComment(), $context);
}
/**
* Gets a property annotation.
*
* @param ReflectionProperty $property
* @param string $annotationName The name of the annotation.
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
{
$annotations = $this->getPropertyAnnotations($property);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* Gets the annotations applied to a method.
*
* @param \ReflectionMethod $method The ReflectionMethod of the method from which
* the annotations should be read.
*
* @return array An array of Annotations.
*/
public function getMethodAnnotations(ReflectionMethod $method)
{
$class = $method->getDeclaringClass();
$context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
$this->parser->setTarget(Target::TARGET_METHOD);
$this->parser->setImports($this->getImports($class));
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
return $this->parser->parse($method->getDocComment(), $context);
}
/**
* Gets a method annotation.
*
* @param ReflectionMethod $method
* @param string $annotationName The name of the annotation.
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
{
$annotations = $this->getMethodAnnotations($method);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* Returns the ignored annotations for the given class.
*
* @param ReflectionClass $class
* @return array
*/
private function getIgnoredAnnotationNames(ReflectionClass $class)
{
if (isset($this->ignoredAnnotationNames[$name = $class->getName()])) {
return $this->ignoredAnnotationNames[$name];
}
$this->collectParsingMetadata($class);
return $this->ignoredAnnotationNames[$name];
}
/**
* Retrieve imports
*
* @param \ReflectionClass $class
* @return array
*/
private function getImports(ReflectionClass $class)
{
if (isset($this->imports[$name = $class->getName()])) {
return $this->imports[$name];
}
$this->collectParsingMetadata($class);
return $this->imports[$name];
}
/**
* 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;
}
}

@ -0,0 +1,139 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* AnnotationRegistry
*/
final class AnnotationRegistry
{
/**
* A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
*
* Contains the namespace as key and an array of directories as value. If the value is NULL
* the include path is used for checking for the corresponding file.
*
* This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
*
* @var array
*/
static private $autoloadNamespaces = array();
/**
* A map of autoloader callables.
*
* @var array
*/
static private $loaders = array();
static public function reset()
{
self::$autoloadNamespaces = array();
self::$loaders = array();
}
/**
* Register file
*
* @param string $file
*/
static public function registerFile($file)
{
require_once $file;
}
/**
* Add a namespace with one or many directories to look for files or null for the include path.
*
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
*
* @param string $namespace
* @param string|array|null $dirs
*/
static public function registerAutoloadNamespace($namespace, $dirs = null)
{
self::$autoloadNamespaces[$namespace] = $dirs;
}
/**
* Register multiple namespaces
*
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
*
* @param array $namespaces
*/
static public function registerAutoloadNamespaces(array $namespaces)
{
self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces);
}
/**
* Register an autoloading callable for annotations, much like spl_autoload_register().
*
* NOTE: These class loaders HAVE to be silent when a class was not found!
* IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
*
* @param callable $callable
*
* @throws \InvalidArgumentException
*/
static public function registerLoader($callable)
{
if (!is_callable($callable)) {
throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader().");
}
self::$loaders[] = $callable;
}
/**
* Autoload an annotation class silently.
*
* @param string $class
* @return boolean
*/
static public function loadAnnotationClass($class)
{
foreach (self::$autoloadNamespaces AS $namespace => $dirs) {
if (strpos($class, $namespace) === 0) {
$file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php";
if ($dirs === null) {
if ($path = stream_resolve_include_path($file)) {
require $path;
return true;
}
} else {
foreach((array)$dirs AS $dir) {
if (is_file($dir . DIRECTORY_SEPARATOR . $file)) {
require $dir . DIRECTORY_SEPARATOR . $file;
return true;
}
}
}
}
}
foreach (self::$loaders AS $loader) {
if (call_user_func($loader, $class) === true) {
return true;
}
}
return false;
}
}

@ -0,0 +1,250 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Cache\Cache;
/**
* A cache aware annotation reader.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
final class CachedReader implements Reader
{
/**
* @var string
*/
private static $CACHE_SALT = '@[Annot]';
/**
* @var Reader
*/
private $delegate;
/**
* @var Cache
*/
private $cache;
/**
* @var boolean
*/
private $debug;
/**
* @var array
*/
private $loadedAnnotations;
/**
* Constructor
*
* @param Reader $reader
* @param Cache $cache
* @param bool $debug
*/
public function __construct(Reader $reader, Cache $cache, $debug = false)
{
$this->delegate = $reader;
$this->cache = $cache;
$this->debug = (Boolean) $debug;
}
/**
* Get annotations for class
*
* @param \ReflectionClass $class
* @return array
*/
public function getClassAnnotations(\ReflectionClass $class)
{
$cacheKey = $class->getName();
if (isset($this->loadedAnnotations[$cacheKey])) {
return $this->loadedAnnotations[$cacheKey];
}
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) {
$annots = $this->delegate->getClassAnnotations($class);
$this->saveToCache($cacheKey, $annots);
}
return $this->loadedAnnotations[$cacheKey] = $annots;
}
/**
* Get selected annotation for class
*
* @param \ReflectionClass $class
* @param string $annotationName
* @return null
*/
public function getClassAnnotation(\ReflectionClass $class, $annotationName)
{
foreach ($this->getClassAnnotations($class) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* Get annotations for property
*
* @param \ReflectionProperty $property
* @return array
*/
public function getPropertyAnnotations(\ReflectionProperty $property)
{
$class = $property->getDeclaringClass();
$cacheKey = $class->getName().'$'.$property->getName();
if (isset($this->loadedAnnotations[$cacheKey])) {
return $this->loadedAnnotations[$cacheKey];
}
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) {
$annots = $this->delegate->getPropertyAnnotations($property);
$this->saveToCache($cacheKey, $annots);
}
return $this->loadedAnnotations[$cacheKey] = $annots;
}
/**
* Get selected annotation for property
*
* @param \ReflectionProperty $property
* @param string $annotationName
* @return null
*/
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
{
foreach ($this->getPropertyAnnotations($property) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* Get method annotations
*
* @param \ReflectionMethod $method
* @return array
*/
public function getMethodAnnotations(\ReflectionMethod $method)
{
$class = $method->getDeclaringClass();
$cacheKey = $class->getName().'#'.$method->getName();
if (isset($this->loadedAnnotations[$cacheKey])) {
return $this->loadedAnnotations[$cacheKey];
}
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) {
$annots = $this->delegate->getMethodAnnotations($method);
$this->saveToCache($cacheKey, $annots);
}
return $this->loadedAnnotations[$cacheKey] = $annots;
}
/**
* Get selected method annotation
*
* @param \ReflectionMethod $method
* @param string $annotationName
* @return null
*/
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
{
foreach ($this->getMethodAnnotations($method) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* Clear loaded annotations
*/
public function clearLoadedAnnotations()
{
$this->loadedAnnotations = array();
}
/**
* Fetches a value from the cache.
*
* @param string $rawCacheKey The cache key.
* @param \ReflectionClass $class The related class.
* @return mixed|boolean The cached value or false when the value is not in cache.
*/
private function fetchFromCache($rawCacheKey, \ReflectionClass $class)
{
$cacheKey = $rawCacheKey . self::$CACHE_SALT;
if (($data = $this->cache->fetch($cacheKey)) !== false) {
if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
return $data;
}
}
return false;
}
/**
* Saves a value to the cache
*
* @param string $rawCacheKey The cache key.
* @param mixed $value The value.
*/
private function saveToCache($rawCacheKey, $value)
{
$cacheKey = $rawCacheKey . self::$CACHE_SALT;
$this->cache->save($cacheKey, $value);
if ($this->debug) {
$this->cache->save('[C]'.$cacheKey, time());
}
}
/**
* Check if cache is fresh
*
* @param string $cacheKey
* @param \ReflectionClass $class
* @return bool
*/
private function isCacheFresh($cacheKey, \ReflectionClass $class)
{
if (false === $filename = $class->getFilename()) {
return true;
}
return $this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename);
}
}

@ -0,0 +1,132 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Lexer\AbstractLexer;
/**
* Simple lexer for docblock annotations.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
final class DocLexer extends AbstractLexer
{
const T_NONE = 1;
const T_INTEGER = 2;
const T_STRING = 3;
const T_FLOAT = 4;
// All tokens that are also identifiers should be >= 100
const T_IDENTIFIER = 100;
const T_AT = 101;
const T_CLOSE_CURLY_BRACES = 102;
const T_CLOSE_PARENTHESIS = 103;
const T_COMMA = 104;
const T_EQUALS = 105;
const T_FALSE = 106;
const T_NAMESPACE_SEPARATOR = 107;
const T_OPEN_CURLY_BRACES = 108;
const T_OPEN_PARENTHESIS = 109;
const T_TRUE = 110;
const T_NULL = 111;
const T_COLON = 112;
protected $noCase = array(
'@' => self::T_AT,
',' => self::T_COMMA,
'(' => self::T_OPEN_PARENTHESIS,
')' => self::T_CLOSE_PARENTHESIS,
'{' => self::T_OPEN_CURLY_BRACES,
'}' => self::T_CLOSE_CURLY_BRACES,
'=' => self::T_EQUALS,
':' => self::T_COLON,
'\\' => self::T_NAMESPACE_SEPARATOR
);
protected $withCase = array(
'true' => self::T_TRUE,
'false' => self::T_FALSE,
'null' => self::T_NULL
);
/**
* {@inheritdoc}
*/
protected function getCatchablePatterns()
{
return array(
'[a-z_\\\][a-z0-9_\:\\\]*[a-z]{1}',
'(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?',
'"(?:[^"]|"")*"',
);
}
/**
* {@inheritdoc}
*/
protected function getNonCatchablePatterns()
{
return array('\s+', '\*+', '(.)');
}
/**
* {@inheritdoc}
*
* @param string $value
*
* @return int
*/
protected function getType(&$value)
{
$type = self::T_NONE;
if ($value[0] === '"') {
$value = str_replace('""', '"', substr($value, 1, strlen($value) - 2));
return self::T_STRING;
}
if (isset($this->noCase[$value])) {
return $this->noCase[$value];
}
if ($value[0] === '_' || $value[0] === '\\' || ctype_alpha($value[0])) {
return self::T_IDENTIFIER;
}
$lowerValue = strtolower($value);
if (isset($this->withCase[$lowerValue])) {
return $this->withCase[$lowerValue];
}
// Checking numeric value
if (is_numeric($value)) {
return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
? self::T_FLOAT : self::T_INTEGER;
}
return $type;
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,269 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* File cache reader for annotations.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class FileCacheReader implements Reader
{
/**
* @var Reader
*/
private $reader;
/**
* @var string
*/
private $dir;
/**
* @var bool
*/
private $debug;
/**
* @var array
*/
private $loadedAnnotations = array();
private $classNameHashes = array();
/**
* Constructor
*
* @param Reader $reader
* @param string $cacheDir
* @param bool $debug
*
* @throws \InvalidArgumentException
*/
public function __construct(Reader $reader, $cacheDir, $debug = false)
{
$this->reader = $reader;
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir));
}
if (!is_writable($cacheDir)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $cacheDir));
}
$this->dir = rtrim($cacheDir, '\\/');
$this->debug = $debug;
}
/**
* Retrieve annotations for class
*
* @param \ReflectionClass $class
* @return array
*/
public function getClassAnnotations(\ReflectionClass $class)
{
if ( ! isset($this->classNameHashes[$class->name])) {
$this->classNameHashes[$class->name] = sha1($class->name);
}
$key = $this->classNameHashes[$class->name];
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
if (!is_file($path)) {
$annot = $this->reader->getClassAnnotations($class);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug
&& (false !== $filename = $class->getFilename())
&& filemtime($path) < filemtime($filename)) {
@unlink($path);
$annot = $this->reader->getClassAnnotations($class);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = include $path;
}
/**
* Get annotations for property
*
* @param \ReflectionProperty $property
* @return array
*/
public function getPropertyAnnotations(\ReflectionProperty $property)
{
$class = $property->getDeclaringClass();
if ( ! isset($this->classNameHashes[$class->name])) {
$this->classNameHashes[$class->name] = sha1($class->name);
}
$key = $this->classNameHashes[$class->name].'$'.$property->getName();
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
if (!is_file($path)) {
$annot = $this->reader->getPropertyAnnotations($property);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug
&& (false !== $filename = $class->getFilename())
&& filemtime($path) < filemtime($filename)) {
@unlink($path);
$annot = $this->reader->getPropertyAnnotations($property);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = include $path;
}
/**
* Retrieve annotations for method
*
* @param \ReflectionMethod $method
* @return array
*/
public function getMethodAnnotations(\ReflectionMethod $method)
{
$class = $method->getDeclaringClass();
if ( ! isset($this->classNameHashes[$class->name])) {
$this->classNameHashes[$class->name] = sha1($class->name);
}
$key = $this->classNameHashes[$class->name].'#'.$method->getName();
if (isset($this->loadedAnnotations[$key])) {
return $this->loadedAnnotations[$key];
}
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
if (!is_file($path)) {
$annot = $this->reader->getMethodAnnotations($method);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
if ($this->debug
&& (false !== $filename = $class->getFilename())
&& filemtime($path) < filemtime($filename)) {
@unlink($path);
$annot = $this->reader->getMethodAnnotations($method);
$this->saveCacheFile($path, $annot);
return $this->loadedAnnotations[$key] = $annot;
}
return $this->loadedAnnotations[$key] = include $path;
}
/**
* Save cache file
*
* @param string $path
* @param mixed $data
*/
private function saveCacheFile($path, $data)
{
file_put_contents($path, '<?php return unserialize('.var_export(serialize($data), true).');');
}
/**
* Gets a class annotation.
*
* @param \ReflectionClass $class The ReflectionClass of the class from which
* the class annotations should be read.
* @param string $annotationName The name of the annotation.
*
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getClassAnnotation(\ReflectionClass $class, $annotationName)
{
$annotations = $this->getClassAnnotations($class);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* Gets a method annotation.
*
* @param \ReflectionMethod $method
* @param string $annotationName The name of the annotation.
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
{
$annotations = $this->getMethodAnnotations($method);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* Gets a property annotation.
*
* @param \ReflectionProperty $property
* @param string $annotationName The name of the annotation.
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
{
$annotations = $this->getPropertyAnnotations($property);
foreach ($annotations as $annotation) {
if ($annotation instanceof $annotationName) {
return $annotation;
}
}
return null;
}
/**
* Clear stores annotations
*/
public function clearLoadedAnnotations()
{
$this->loadedAnnotations = array();
}
}

@ -0,0 +1,141 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Annotations\Reader;
/**
* Allows the reader to be used in-place of Doctrine's reader.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class IndexedReader implements Reader
{
/**
* @var Reader
*/
private $delegate;
/**
* Constructor
*
* @param Reader $reader
*/
public function __construct(Reader $reader)
{
$this->delegate = $reader;
}
/**
* Get Annotations for class
*
* @param \ReflectionClass $class
* @return array
*/
public function getClassAnnotations(\ReflectionClass $class)
{
$annotations = array();
foreach ($this->delegate->getClassAnnotations($class) as $annot) {
$annotations[get_class($annot)] = $annot;
}
return $annotations;
}
/**
* Get selected annotation for class
*
* @param \ReflectionClass $class
* @param string $annotation
* @return mixed
*/
public function getClassAnnotation(\ReflectionClass $class, $annotation)
{
return $this->delegate->getClassAnnotation($class, $annotation);
}
/**
* Get Annotations for method
*
* @param \ReflectionMethod $method
* @return array
*/
public function getMethodAnnotations(\ReflectionMethod $method)
{
$annotations = array();
foreach ($this->delegate->getMethodAnnotations($method) as $annot) {
$annotations[get_class($annot)] = $annot;
}
return $annotations;
}
/**
* Get selected annotation for method
*
* @param \ReflectionMethod $method
* @param string $annotation
* @return mixed
*/
public function getMethodAnnotation(\ReflectionMethod $method, $annotation)
{
return $this->delegate->getMethodAnnotation($method, $annotation);
}
/**
* Get annotations for property
*
* @param \ReflectionProperty $property
* @return array
*/
public function getPropertyAnnotations(\ReflectionProperty $property)
{
$annotations = array();
foreach ($this->delegate->getPropertyAnnotations($property) as $annot) {
$annotations[get_class($annot)] = $annot;
}
return $annotations;
}
/**
* Get selected annotation for property
*
* @param \ReflectionProperty $property
* @param string $annotation
* @return mixed
*/
public function getPropertyAnnotation(\ReflectionProperty $property, $annotation)
{
return $this->delegate->getPropertyAnnotation($property, $annotation);
}
/**
* Proxy all methods to the delegate.
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call($method, $args)
{
return call_user_func_array(array($this->delegate, $method), $args);
}
}

@ -0,0 +1,89 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use SplFileObject;
/**
* Parses a file for namespaces/use/class declarations.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Christian Kaps <christian.kaps@mohiva.com>
*/
final class PhpParser
{
/**
* Parses a class.
*
* @param \ReflectionClass $class A <code>ReflectionClass</code> object.
* @return array A list with use statements in the form (Alias => FQN).
*/
public function parseClass(\ReflectionClass $class)
{
if (method_exists($class, 'getUseStatements')) {
return $class->getUseStatements();
}
if (false === $filename = $class->getFilename()) {
return array();
}
$content = $this->getFileContent($filename, $class->getStartLine());
if (null === $content) {
return array();
}
$namespace = preg_quote($class->getNamespaceName());
$content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
$tokenizer = new TokenParser('<?php ' . $content);
$statements = $tokenizer->parseUseStatements($class->getNamespaceName());
return $statements;
}
/**
* Get the content of the file right up to the given line number.
*
* @param string $filename The name of the file to load.
* @param int $lineNumber The number of lines to read from file.
* @return string The content of the file.
*/
private function getFileContent($filename, $lineNumber)
{
if ( ! is_file($filename)) {
return null;
}
$content = '';
$lineCnt = 0;
$file = new SplFileObject($filename);
while (!$file->eof()) {
if ($lineCnt++ == $lineNumber) {
break;
}
$content .= $file->fgets();
}
return $content;
}
}

@ -0,0 +1,67 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* Interface for annotation readers.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface Reader
{
/**
* @param \ReflectionClass $class
* @return mixed
*/
function getClassAnnotations(\ReflectionClass $class);
/**
* @param \ReflectionClass $class
* @param string $annotationName
* @return mixed
*/
function getClassAnnotation(\ReflectionClass $class, $annotationName);
/**
* @param \ReflectionMethod $method
* @return mixed
*/
function getMethodAnnotations(\ReflectionMethod $method);
/**
* @param \ReflectionMethod $method
* @param string $annotationName
* @return mixed
*/
function getMethodAnnotation(\ReflectionMethod $method, $annotationName);
/**
* @param \ReflectionProperty $property
* @return mixed
*/
function getPropertyAnnotations(\ReflectionProperty $property);
/**
* @param \ReflectionProperty $property
* @param string $annotationName
* @return mixed
*/
function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);
}

@ -0,0 +1,157 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
use Doctrine\Common\Annotations\Annotation\Target;
/**
* Simple Annotation Reader.
*
* This annotation reader is intended to be used in projects where you have
* full-control over all annotations that are available.
*
* @since 2.2
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class SimpleAnnotationReader implements Reader
{
/**
* @var DocParser
*/
private $parser;
/**
* Constructor.
*
* Initializes a new SimpleAnnotationReader.
*/
public function __construct()
{
$this->parser = new DocParser();
$this->parser->setIgnoreNotImportedAnnotations(true);
}
/**
* Adds a namespace in which we will look for annotations.
*
* @param string $namespace
*/
public function addNamespace($namespace)
{
$this->parser->addNamespace($namespace);
}
/**
* Gets the annotations applied to a class.
*
* @param \ReflectionClass $class The ReflectionClass of the class from which
* the class annotations should be read.
*
* @return array An array of Annotations.
*/
public function getClassAnnotations(\ReflectionClass $class)
{
return $this->parser->parse($class->getDocComment(), 'class '.$class->getName());
}
/**
* Gets the annotations applied to a method.
*
* @param \ReflectionMethod $method The ReflectionMethod of the method from which
* the annotations should be read.
*
* @return array An array of Annotations.
*/
public function getMethodAnnotations(\ReflectionMethod $method)
{
return $this->parser->parse($method->getDocComment(), 'method '.$method->getDeclaringClass()->name.'::'.$method->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)
{
return $this->parser->parse($property->getDocComment(), 'property '.$property->getDeclaringClass()->name.'::$'.$property->getName());
}
/**
* Gets a class annotation.
*
* @param \ReflectionClass $class The ReflectionClass of the class from which
* the class annotations should be read.
* @param string $annotationName The name of the annotation.
*
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getClassAnnotation(\ReflectionClass $class, $annotationName)
{
foreach ($this->getClassAnnotations($class) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* Gets a method annotation.
*
* @param \ReflectionMethod $method
* @param string $annotationName The name of the annotation.
*
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
{
foreach ($this->getMethodAnnotations($method) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
/**
* Gets a property annotation.
*
* @param \ReflectionProperty $property
* @param string $annotationName The name of the annotation.
* @return mixed The Annotation or NULL, if the requested annotation does not exist.
*/
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
{
foreach ($this->getPropertyAnnotations($property) as $annot) {
if ($annot instanceof $annotationName) {
return $annot;
}
}
return null;
}
}

@ -0,0 +1,175 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
/**
* Parses a file for namespaces/use/class declarations.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Christian Kaps <christian.kaps@mohiva.com>
*/
class TokenParser
{
/**
* The token list.
*
* @var array
*/
private $tokens;
/**
* The number of tokens.
*
* @var int
*/
private $numTokens = 0;
/**
* The current array pointer.
*
* @var int
*/
private $pointer = 0;
public function __construct($contents)
{
$this->tokens = token_get_all($contents);
$this->numTokens = count($this->tokens);
$this->pointer = 0;
}
/**
* Gets the next non whitespace and non comment token.
*
* @param $docCommentIsComment
* If TRUE then a doc comment is considered a comment and skipped.
* If FALSE then only whitespace and normal comments are skipped.
*
* @return array The token if exists, null otherwise.
*/
public function next($docCommentIsComment = TRUE)
{
for ($i = $this->pointer; $i < $this->numTokens; $i++) {
$this->pointer++;
if ($this->tokens[$i][0] === T_WHITESPACE ||
$this->tokens[$i][0] === T_COMMENT ||
($docCommentIsComment && $this->tokens[$i][0] === T_DOC_COMMENT)) {
continue;
}
return $this->tokens[$i];
}
return null;
}
/**
* Parse a single use statement.
*
* @return array A list with all found class names for a use statement.
*/
public function parseUseStatement()
{
$class = '';
$alias = '';
$statements = array();
$explicitAlias = false;
while (($token = $this->next())) {
$isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR;
if (!$explicitAlias && $isNameToken) {
$class .= $token[1];
$alias = $token[1];
} else if ($explicitAlias && $isNameToken) {
$alias .= $token[1];
} else if ($token[0] === T_AS) {
$explicitAlias = true;
$alias = '';
} else if ($token === ',') {
$statements[strtolower($alias)] = $class;
$class = '';
$alias = '';
$explicitAlias = false;
} else if ($token === ';') {
$statements[strtolower($alias)] = $class;
break;
} else {
break;
}
}
return $statements;
}
/**
* Get all use statements.
*
* @param string $namespaceName The namespace name of the reflected class.
* @return array A list with all found use statements.
*/
public function parseUseStatements($namespaceName)
{
$statements = array();
while (($token = $this->next())) {
if ($token[0] === T_USE) {
$statements = array_merge($statements, $this->parseUseStatement());
continue;
}
if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) {
continue;
}
// Get fresh array for new namespace. This is to prevent the parser to collect the use statements
// for a previous namespace with the same name. This is the case if a namespace is defined twice
// or if a namespace with the same name is commented out.
$statements = array();
}
return $statements;
}
/**
* Get the namespace.
*
* @return string The found namespace.
*/
public function parseNamespace()
{
$name = '';
while (($token = $this->next()) && ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR)) {
$name .= $token[1];
}
return $name;
}
/**
* Get the class name.
*
* @return string The foundclass name.
*/
public function parseClass()
{
// Namespaces and class names are tokenized the same: T_STRINGs
// separated by T_NS_SEPARATOR so we can use one function to provide
// both.
return $this->parseNamespace();
}
}

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./tests/Doctrine/Tests/TestInit.php"
>
<testsuites>
<testsuite name="Doctrine Annotations Test Suite">
<directory>./tests/Doctrine/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./lib/Doctrine/</directory>
</whitelist>
</filter>
<groups>
<exclude>
<group>performance</group>
</exclude>
</groups>
</phpunit>

@ -0,0 +1,571 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Common\Annotations\DoctrineReader;
use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
use Doctrine\Common\Annotations\Annotation\IgnorePhpDoc;
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
{
public function getReflectionClass()
{
$className = 'Doctrine\Tests\Common\Annotations\DummyClass';
return new ReflectionClass($className);
}
public function testAnnotations()
{
$class = $this->getReflectionClass();
$reader = $this->getReader();
$this->assertEquals(1, count($reader->getClassAnnotations($class)));
$this->assertInstanceOf($annotName = 'Doctrine\Tests\Common\Annotations\DummyAnnotation', $annot = $reader->getClassAnnotation($class, $annotName));
$this->assertEquals("hello", $annot->dummyValue);
$field1Prop = $class->getProperty('field1');
$propAnnots = $reader->getPropertyAnnotations($field1Prop);
$this->assertEquals(1, count($propAnnots));
$this->assertInstanceOf($annotName, $annot = $reader->getPropertyAnnotation($field1Prop, $annotName));
$this->assertEquals("fieldHello", $annot->dummyValue);
$getField1Method = $class->getMethod('getField1');
$methodAnnots = $reader->getMethodAnnotations($getField1Method);
$this->assertEquals(1, count($methodAnnots));
$this->assertInstanceOf($annotName, $annot = $reader->getMethodAnnotation($getField1Method, $annotName));
$this->assertEquals(array(1, 2, "three"), $annot->value);
$field2Prop = $class->getProperty('field2');
$propAnnots = $reader->getPropertyAnnotations($field2Prop);
$this->assertEquals(1, count($propAnnots));
$this->assertInstanceOf($annotName = 'Doctrine\Tests\Common\Annotations\DummyJoinTable', $joinTableAnnot = $reader->getPropertyAnnotation($field2Prop, $annotName));
$this->assertEquals(1, count($joinTableAnnot->joinColumns));
$this->assertEquals(1, count($joinTableAnnot->inverseJoinColumns));
$this->assertTrue($joinTableAnnot->joinColumns[0] instanceof DummyJoinColumn);
$this->assertTrue($joinTableAnnot->inverseJoinColumns[0] instanceof DummyJoinColumn);
$this->assertEquals('col1', $joinTableAnnot->joinColumns[0]->name);
$this->assertEquals('col2', $joinTableAnnot->joinColumns[0]->referencedColumnName);
$this->assertEquals('col3', $joinTableAnnot->inverseJoinColumns[0]->name);
$this->assertEquals('col4', $joinTableAnnot->inverseJoinColumns[0]->referencedColumnName);
$dummyAnnot = $reader->getMethodAnnotation($class->getMethod('getField1'), 'Doctrine\Tests\Common\Annotations\DummyAnnotation');
$this->assertEquals('', $dummyAnnot->dummyValue);
$this->assertEquals(array(1, 2, 'three'), $dummyAnnot->value);
$dummyAnnot = $reader->getPropertyAnnotation($class->getProperty('field1'), 'Doctrine\Tests\Common\Annotations\DummyAnnotation');
$this->assertEquals('fieldHello', $dummyAnnot->dummyValue);
$classAnnot = $reader->getClassAnnotation($class, 'Doctrine\Tests\Common\Annotations\DummyAnnotation');
$this->assertEquals('hello', $classAnnot->dummyValue);
}
public function testAnnotationsWithValidTargets()
{
$reader = $this->getReader();
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithValidAnnotationTarget');
$this->assertEquals(1,count($reader->getClassAnnotations($class)));
$this->assertEquals(1,count($reader->getPropertyAnnotations($class->getProperty('foo'))));
$this->assertEquals(1,count($reader->getMethodAnnotations($class->getMethod('someFunction'))));
$this->assertEquals(1,count($reader->getPropertyAnnotations($class->getProperty('nested'))));
}
public function testAnnotationsWithVarType()
{
$reader = $this->getReader();
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType');
$this->assertEquals(1,count($fooAnnot = $reader->getPropertyAnnotations($class->getProperty('foo'))));
$this->assertEquals(1,count($barAnnot = $reader->getMethodAnnotations($class->getMethod('bar'))));
$this->assertInternalType('string', $fooAnnot[0]->string);
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', $barAnnot[0]->annotation);
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtClass'));
}
public function testClassWithWithInclude()
{
$reader = $this->getReader();
$annots = $reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithRequire'));
$this->assertCount(1, $annots);
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty', 'foo'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty', 'bar'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getMethodAnnotations(new \ReflectionMethod('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtMethod', 'functionName'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithTargetSyntaxError'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithTargetSyntaxError','foo'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getMethodAnnotations(new \ReflectionMethod('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithTargetSyntaxError','bar'));
}
/**
* @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()
{
$reader = $this->getReader();
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType');
$reader->getPropertyAnnotations($class->getProperty('invalidProperty'));
}
/**
* @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()
{
$reader = $this->getReader();
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType');
$reader->getMethodAnnotations($class->getMethod('invalidMethod'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\DummyClassSyntaxError'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getMethodAnnotations(new \ReflectionMethod('Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError', 'foo'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError', 'foo'));
}
/**
* @group regression
*/
public function testMultipleAnnotationsOnSameLine()
{
$reader = $this->getReader();
$annots = $reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\DummyClass2', 'id'));
$this->assertEquals(3, count($annots));
}
public function testNonAnnotationProblem()
{
$reader = $this->getReader();
$this->assertNotNull($annot = $reader->getPropertyAnnotation(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\DummyClassNonAnnotationProblem', 'foo'), $name = 'Doctrine\Tests\Common\Annotations\DummyAnnotation'));
$this->assertInstanceOf($name, $annot);
}
public function testImportWithConcreteAnnotation()
{
$reader = $this->getReader();
$property = new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestImportWithConcreteAnnotation', 'field');
$annotations = $reader->getPropertyAnnotations($property);
$this->assertEquals(1, count($annotations));
$this->assertNotNull($reader->getPropertyAnnotation($property, 'Doctrine\Tests\Common\Annotations\DummyAnnotation'));
}
public function testImportWithInheritance()
{
$reader = $this->getReader();
$class = new TestParentClass();
$ref = new \ReflectionClass($class);
$childAnnotations = $reader->getPropertyAnnotations($ref->getProperty('child'));
$this->assertEquals(1, count($childAnnotations));
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Foo\Name', reset($childAnnotations));
$parentAnnotations = $reader->getPropertyAnnotations($ref->getProperty('parent'));
$this->assertEquals(1, count($parentAnnotations));
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Bar\Name', reset($parentAnnotations));
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage The annotation "@NameFoo" in property Doctrine\Tests\Common\Annotations\TestAnnotationNotImportedClass::$field was never imported.
*/
public function testImportDetectsNotImportedAnnotation()
{
$reader = $this->getReader();
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestAnnotationNotImportedClass', 'field'));
}
/**
* @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()
{
$reader = $this->getReader();
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestNonExistentAnnotationClass', 'field'));
}
public function testTopLevelAnnotation()
{
$reader = $this->getReader();
$annotations = $reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestTopLevelAnnotationClass', 'field'));
$this->assertEquals(1, count($annotations));
$this->assertInstanceOf('\TopLevelAnnotation', reset($annotations));
}
public function testIgnoresAnnotationsNotPrefixedWithWhitespace()
{
$reader = $this->getReader();
$annotation = $reader->getClassAnnotation(new \ReflectionClass(new TestIgnoresNonAnnotationsClass()), 'Doctrine\Tests\Common\Annotations\Name');
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Name', $annotation);
}
/**
* @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()
{
$reader = $this->getReader();
$ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\InvalidAnnotationUsageClass');
$reader->getClassAnnotations($ref);
}
public function testInvalidAnnotationUsageButIgnoredClass()
{
$reader = $this->getReader();
$ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\InvalidAnnotationUsageButIgnoredClass');
$annots = $reader->getClassAnnotations($ref);
$this->assertEquals(2, count($annots));
}
/**
* @group DDC-1660
* @group regression
*/
public function testInvalidAnnotationButIgnored()
{
$reader = $this->getReader();
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassDDC1660');
$this->assertTrue(class_exists('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Version'));
$this->assertCount(0, $reader->getClassAnnotations($class));
$this->assertCount(0, $reader->getMethodAnnotations($class->getMethod('bar')));
$this->assertCount(0, $reader->getPropertyAnnotations($class->getProperty('foo')));
}
public function testAnnotationEnumeratorException()
{
$reader = $this->getReader();
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum');
$this->assertCount(1, $bar = $reader->getMethodAnnotations($class->getMethod('bar')));
$this->assertCount(1, $foo = $reader->getPropertyAnnotations($class->getProperty('foo')));
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum', $bar[0]);
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum', $foo[0]);
try {
$reader->getPropertyAnnotations($class->getProperty('invalidProperty'));
$this->fail();
} catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
$this->assertEquals('[Enum Error] Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum::$invalidProperty accept only [ONE, TWO, THREE], but got FOUR.', $exc->getMessage());
}
try {
$reader->getMethodAnnotations($class->getMethod('invalidMethod'));
$this->fail();
} catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
$this->assertEquals('[Enum Error] Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum declared on method Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum::invalidMethod() accept only [ONE, TWO, THREE], but got 5.', $exc->getMessage());
}
}
/**
* @group DCOM-106
*/
public function testIgnoreFixMeAndUpperCaseToDo()
{
$reader = $this->getReader();
$ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\DCOM106');
$reader->getClassAnnotations($ref);
}
/**
* @return AnnotationReader
*/
abstract protected function getReader();
}
/**
* @parseAnnotation("var")
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*
*/
class TestParseAnnotationClass
{
/**
* @var
*/
private $field;
}
/**
* @Name
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class TestIgnoresNonAnnotationsClass
{
}
class TestTopLevelAnnotationClass
{
/**
* @\TopLevelAnnotation
*/
private $field;
}
class TestNonExistentAnnotationClass
{
/**
* @Foo\Bar\Name
*/
private $field;
}
class TestAnnotationNotImportedClass
{
/**
* @NameFoo
*/
private $field;
}
class TestChildClass
{
/**
* @\Doctrine\Tests\Common\Annotations\Foo\Name(name = "foo")
*/
protected $child;
}
class TestParentClass extends TestChildClass
{
/**
* @\Doctrine\Tests\Common\Annotations\Bar\Name(name = "bar")
*/
private $parent;
}
class TestImportWithConcreteAnnotation
{
/**
* @DummyAnnotation(dummyValue = "bar")
*/
private $field;
}
/**
* @ignoreAnnotation("var")
*/
class DummyClass2 {
/**
* @DummyId @DummyColumn(type="integer") @DummyGeneratedValue
* @var integer
*/
private $id;
}
/** @Annotation */
class DummyId extends \Doctrine\Common\Annotations\Annotation {}
/** @Annotation */
class DummyColumn extends \Doctrine\Common\Annotations\Annotation {
public $type;
}
/** @Annotation */
class DummyGeneratedValue extends \Doctrine\Common\Annotations\Annotation {}
/** @Annotation */
class DummyAnnotation extends \Doctrine\Common\Annotations\Annotation {
public $dummyValue;
}
/**
* @api
* @Annotation
*/
class DummyAnnotationWithIgnoredAnnotation extends \Doctrine\Common\Annotations\Annotation {
public $dummyValue;
}
/** @Annotation */
class DummyJoinColumn extends \Doctrine\Common\Annotations\Annotation {
public $name;
public $referencedColumnName;
}
/** @Annotation */
class DummyJoinTable extends \Doctrine\Common\Annotations\Annotation {
public $name;
public $joinColumns;
public $inverseJoinColumns;
}
/**
* @DummyAnnotation(@)
*/
class DummyClassSyntaxError
{
}
class DummyClassMethodSyntaxError
{
/**
* @DummyAnnotation(@)
*/
public function foo()
{
}
}
class DummyClassPropertySyntaxError
{
/**
* @DummyAnnotation(@)
*/
public $foo;
}
/**
* @ignoreAnnotation({"since", "var"})
*/
class DummyClassNonAnnotationProblem
{
/**
* @DummyAnnotation
*
* @var \Test
* @since 0.1
*/
public $foo;
}
/**
* @DummyAnnotation Foo bar <foobar@1domain.com>
*/
class DummyClassWithEmail
{
}
/**
* @fixme public
* @TODO
*/
class DCOM106
{
}
namespace Doctrine\Tests\Common\Annotations\Foo;
/** @Annotation */
class Name extends \Doctrine\Common\Annotations\Annotation
{
public $name;
}
namespace Doctrine\Tests\Common\Annotations\Bar;
/** @Annotation */
class Name extends \Doctrine\Common\Annotations\Annotation
{
public $name;
}

@ -0,0 +1,13 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Common\Annotations\AnnotationReader;
class AnnotationReaderTest extends AbstractReaderTest
{
protected function getReader()
{
return new AnnotationReader();
}
}

@ -0,0 +1,56 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\CachedReader;
use Doctrine\Common\Cache\ArrayCache;
class CachedReaderTest extends AbstractReaderTest
{
private $cache;
public function testIgnoresStaleCache()
{
$file = __DIR__.'/Fixtures/Controller.php';
touch($file);
$name = 'Doctrine\Tests\Common\Annotations\Fixtures\Controller';
$cacheKey = $name.'@[Annot]';
$cache = $this->getMock('Doctrine\Common\Cache\Cache');
$cache
->expects($this->at(0))
->method('fetch')
->with($this->equalTo($cacheKey))
->will($this->returnValue(array()))
;
$cache
->expects($this->at(1))
->method('fetch')
->with($this->equalTo('[C]'.$cacheKey))
->will($this->returnValue(time() - 10))
;
$cache
->expects($this->at(2))
->method('save')
->with($this->equalTo($cacheKey))
;
$cache
->expects($this->at(3))
->method('save')
->with($this->equalTo('[C]'.$cacheKey))
;
$reader = new CachedReader(new AnnotationReader(), $cache, true);
$route = new Route();
$route->pattern = '/someprefix';
$this->assertEquals(array($route), $reader->getClassAnnotations(new \ReflectionClass($name)));
}
protected function getReader()
{
$this->cache = new ArrayCache();
return new CachedReader(new AnnotationReader(), $this->cache);
}
}

@ -0,0 +1,137 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Common\Annotations\DocLexer;
class DocLexerTest extends \PHPUnit_Framework_TestCase
{
public function testMarkerAnnotation()
{
$lexer = new DocLexer;
$lexer->setInput("@Name");
$this->assertNull($lexer->token);
$this->assertNull($lexer->lookahead);
$this->assertTrue($lexer->moveNext());
$this->assertNull($lexer->token);
$this->assertEquals('@', $lexer->lookahead['value']);
$this->assertTrue($lexer->moveNext());
$this->assertEquals('@', $lexer->token['value']);
$this->assertEquals('Name', $lexer->lookahead['value']);
$this->assertFalse($lexer->moveNext());
}
public function testScannerTokenizesDocBlockWhitConstants()
{
$lexer = new DocLexer();
$docblock = '@AnnotationWithConstants(PHP_EOL, ClassWithConstants::SOME_VALUE, \Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_VALUE)';
$tokens = array (
array(
'value' => '@',
'position' => 0,
'type' => DocLexer::T_AT,
),
array(
'value' => 'AnnotationWithConstants',
'position' => 1,
'type' => DocLexer::T_IDENTIFIER,
),
array(
'value' => '(',
'position' => 24,
'type' => DocLexer::T_OPEN_PARENTHESIS,
),
array(
'value' => 'PHP_EOL',
'position' => 25,
'type' => DocLexer::T_IDENTIFIER,
),
array(
'value' => ',',
'position' => 32,
'type' => DocLexer::T_COMMA,
),
array(
'value' => 'ClassWithConstants::SOME_VALUE',
'position' => 34,
'type' => DocLexer::T_IDENTIFIER,
),
array(
'value' => ',',
'position' => 64,
'type' => DocLexer::T_COMMA,
),
array(
'value' => '\\Doctrine\\Tests\\Common\\Annotations\\Fixtures\\IntefaceWithConstants::SOME_VALUE',
'position' => 66,
'type' => DocLexer::T_IDENTIFIER,
),
array(
'value' => ')',
'position' => 143,
'type' => DocLexer::T_CLOSE_PARENTHESIS,
)
);
$lexer->setInput($docblock);
foreach ($tokens as $expected) {
$lexer->moveNext();
$lookahead = $lexer->lookahead;
$this->assertEquals($expected['value'], $lookahead['value']);
$this->assertEquals($expected['type'], $lookahead['type']);
$this->assertEquals($expected['position'], $lookahead['position']);
}
$this->assertFalse($lexer->moveNext());
}
public function testScannerTokenizesDocBlockWhitInvalidIdentifier()
{
$lexer = new DocLexer();
$docblock = '@Foo\3.42';
$tokens = array (
array(
'value' => '@',
'position' => 0,
'type' => DocLexer::T_AT,
),
array(
'value' => 'Foo',
'position' => 1,
'type' => DocLexer::T_IDENTIFIER,
),
array(
'value' => '\\',
'position' => 4,
'type' => DocLexer::T_NAMESPACE_SEPARATOR,
),
array(
'value' => 3.42,
'position' => 5,
'type' => DocLexer::T_FLOAT,
)
);
$lexer->setInput($docblock);
foreach ($tokens as $expected) {
$lexer->moveNext();
$lookahead = $lexer->lookahead;
$this->assertEquals($expected['value'], $lookahead['value']);
$this->assertEquals($expected['type'], $lookahead['type']);
$this->assertEquals($expected['position'], $lookahead['position']);
}
$this->assertFalse($lexer->moveNext());
}
}

@ -0,0 +1,48 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Tests\Common\Annotations\DummyAnnotation;
use Doctrine\Tests\Common\Annotations\Name;
use Doctrine\Tests\Common\Annotations\DummyJoinTable;
use Doctrine\Tests\Common\Annotations\DummyJoinColumn;
/**
* A description of this class.
*
* Let's see if the parser recognizes that this @ is not really referring to an
* annotation. Also make sure that @var \ is not concated to "@var\is".
*
* @author robo
* @since 2.0
* @DummyAnnotation(dummyValue="hello")
*/
class DummyClass
{
/**
* A nice property.
*
* @var mixed
* @DummyAnnotation(dummyValue="fieldHello")
*/
private $field1;
/**
* @DummyJoinTable(name="join_table",
* joinColumns={@DummyJoinColumn(name="col1", referencedColumnName="col2")},
* inverseJoinColumns={
* @DummyJoinColumn(name="col3", referencedColumnName="col4")
* })
*/
private $field2;
/**
* Gets the value of field1.
*
* @return mixed
* @DummyAnnotation({1,2,"three"})
*/
public function getField1()
{
}
}

@ -0,0 +1,40 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\FileCacheReader;
class FileCacheReaderTest extends AbstractReaderTest
{
private $cacheDir;
protected function getReader()
{
$this->cacheDir = sys_get_temp_dir() . "/annotations_". uniqid();
@mkdir($this->cacheDir);
return new FileCacheReader(new AnnotationReader(), $this->cacheDir);
}
public function tearDown()
{
foreach (glob($this->cacheDir.'/*.php') AS $file) {
unlink($file);
}
rmdir($this->cacheDir);
}
/**
* @group DCOM-81
*/
public function testAttemptToCreateAnnotationCacheDir()
{
$this->cacheDir = sys_get_temp_dir() . "/not_existed_dir_". uniqid();
$this->assertFalse(is_dir($this->cacheDir));
$cache = new FileCacheReader(new AnnotationReader(), $this->cacheDir);
$this->assertTrue(is_dir($this->cacheDir));
}
}

@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
/** @Annotation */
class AnnotWithDefaultValue
{
/** @var string */
public $foo = 'bar';
}

@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
/**
* @Annotation
*/
class Autoload
{
}

@ -0,0 +1,11 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
/** @Annotation */
class Route
{
/** @var string @Required */
public $pattern;
public $name;
}

@ -0,0 +1,18 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
/** @Annotation */
class Secure
{
private $roles;
public function __construct(array $values)
{
if (is_string($values['value'])) {
$values['value'] = array($values['value']);
}
$this->roles = $values['value'];
}
}

@ -0,0 +1,14 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
/** @Annotation */
class Template
{
private $name;
public function __construct(array $values)
{
$this->name = isset($values['value']) ? $values['value'] : null;
}
}

@ -0,0 +1,11 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class Version
{
}

@ -0,0 +1,21 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
*/
final class AnnotationEnum
{
const ONE = 'ONE';
const TWO = 'TWO';
const THREE = 'THREE';
/**
* @var mixed
*
* @Enum({"ONE","TWO","THREE"})
*/
public $value;
}

@ -0,0 +1,17 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
*/
final class AnnotationEnumInvalid
{
/**
* @var mixed
*
* @Enum({1, 2, "foo", "bar", {"foo":"bar"}})
*/
public $value;
}

@ -0,0 +1,34 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnumLiteral as SelfEnum;
/**
* @Annotation
* @Target("ALL")
*/
final class AnnotationEnumLiteral
{
const ONE = 1;
const TWO = 2;
const THREE = 3;
/**
* @var mixed
*
* @Enum(
* value = {
* 1,
* 2,
* 3,
* },
* literal = {
* 1 : "AnnotationEnumLiteral::ONE",
* 2 : "AnnotationEnumLiteral::TWO",
* 3 : "AnnotationEnumLiteral::THREE",
* }
* )
*/
public $value;
}

@ -0,0 +1,31 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
*/
final class AnnotationEnumLiteralInvalid
{
const ONE = 1;
const TWO = 2;
const THREE = 3;
/**
* @var mixed
*
* @Enum(
* value = {
* 1,
* 2
* },
* literal = {
* 1 : "AnnotationEnumLiteral::ONE",
* 2 : "AnnotationEnumLiteral::TWO",
* 3 : "AnnotationEnumLiteral::THREE"
* }
* )
*/
public $value;
}

@ -0,0 +1,14 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
*/
class AnnotationTargetAll
{
public $data;
public $name;
public $target;
}

@ -0,0 +1,14 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target({ "ANNOTATION" })
*/
final class AnnotationTargetAnnotation
{
public $data;
public $name;
public $target;
}

@ -0,0 +1,15 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("CLASS")
*/
final class AnnotationTargetClass
{
public $data;
public $name;
public $target;
}

@ -0,0 +1,15 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("METHOD")
*/
final class AnnotationTargetMethod
{
public $data;
public $name;
public $target;
}

@ -0,0 +1,14 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target({ "METHOD", "PROPERTY" })
*/
final class AnnotationTargetPropertyMethod
{
public $data;
public $name;
public $target;
}

@ -0,0 +1,119 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
* @Attributes({
@Attribute("mixed", type = "mixed"),
@Attribute("boolean", type = "boolean"),
@Attribute("bool", type = "bool"),
@Attribute("float", type = "float"),
@Attribute("string", type = "string"),
@Attribute("integer", type = "integer"),
@Attribute("array", type = "array"),
@Attribute("arrayOfIntegers", type = "array<integer>"),
@Attribute("annotation", type = "Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll"),
@Attribute("arrayOfAnnotations", type = "array<Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll>"),
})
*/
final class AnnotationWithAttributes
{
public final function __construct(array $data)
{
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
private $mixed;
private $boolean;
private $bool;
private $float;
private $string;
private $integer;
private $array;
private $annotation;
private $arrayOfIntegers;
private $arrayOfAnnotations;
/**
* @return mixed
*/
public function getMixed()
{
return $this->mixed;
}
/**
* @return boolean
*/
public function getBoolean()
{
return $this->boolean;
}
/**
* @return bool
*/
public function getBool()
{
return $this->bool;
}
/**
* @return float
*/
public function getFloat()
{
return $this->float;
}
/**
* @return string
*/
public function getString()
{
return $this->string;
}
public function getInteger()
{
return $this->integer;
}
/**
* @return array
*/
public function getArray()
{
return $this->array;
}
/**
* @return Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll
*/
public function getAnnotation()
{
return $this->annotation;
}
/**
* @return array<integer>
*/
public function getArrayOfIntegers()
{
return $this->arrayOfIntegers;
}
/**
* @return array<Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll>
*/
public function getArrayOfAnnotations()
{
return $this->arrayOfAnnotations;
}
}

@ -0,0 +1,20 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
*/
final class AnnotationWithConstants
{
const INTEGER = 1;
const FLOAT = 1.2;
const STRING = '1.2.3';
/**
* @var mixed
*/
public $value;
}

@ -0,0 +1,50 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
* @Attributes({
@Attribute("value", required = true , type = "string"),
@Attribute("annot", required = true , type = "Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation"),
})
*/
final class AnnotationWithRequiredAttributes
{
public final function __construct(array $data)
{
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
/**
* @var string
*/
private $value;
/**
*
* @var Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation
*/
private $annot;
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* @return Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation
*/
public function getAnnot()
{
return $this->annot;
}
}

@ -0,0 +1,24 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
*/
final class AnnotationWithRequiredAttributesWithoutContructor
{
/**
* @Required
* @var string
*/
public $value;
/**
* @Required
* @var Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation
*/
public $annot;
}

@ -0,0 +1,11 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target(@)
*/
final class AnnotationWithTargetSyntaxError
{
}

@ -0,0 +1,62 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @Annotation
* @Target("ALL")
*/
final class AnnotationWithVarType
{
/**
* @var mixed
*/
public $mixed;
/**
* @var boolean
*/
public $boolean;
/**
* @var bool
*/
public $bool;
/**
* @var float
*/
public $float;
/**
* @var string
*/
public $string;
/**
* @var integer
*/
public $integer;
/**
* @var array
*/
public $array;
/**
* @var Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll
*/
public $annotation;
/**
* @var array<integer>
*/
public $arrayOfIntegers;
/**
* @var array<Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll>
*/
public $arrayOfAnnotations;
}

@ -0,0 +1,10 @@
<?php
/**
* This class is not an annotation
* It's a class build to test ClassWithInclude
*/
class Api
{
}

@ -0,0 +1,30 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @since 2.0
* @version $Id: SomeEntityClass.php 509 2012-02-03 09:38:48Z mf $
*/
class ClassDDC1660
{
/**
* @var string
* @since 2.0
* @version 1
*/
public $foo;
/**
* @param string
* @return string
* @since 2.0
* @version 1
*/
public function bar($param)
{
return null;
}
}

@ -0,0 +1,29 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum;
class ClassWithAnnotationEnum
{
/**
* @AnnotationEnum(AnnotationEnum::ONE)
*/
public $foo;
/**
* @AnnotationEnum("TWO")
*/
public function bar(){}
/**
* @AnnotationEnum("FOUR")
*/
public $invalidProperty;
/**
* @AnnotationEnum(5)
*/
public function invalidMethod(){}
}

@ -0,0 +1,21 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError;
/**
* @AnnotationWithTargetSyntaxError()
*/
class ClassWithAnnotationWithTargetSyntaxError
{
/**
* @AnnotationWithTargetSyntaxError()
*/
public $foo;
/**
* @AnnotationWithTargetSyntaxError()
*/
public function bar(){}
}

@ -0,0 +1,31 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation;
class ClassWithAnnotationWithVarType
{
/**
* @AnnotationWithVarType(string = "String Value")
*/
public $foo;
/**
* @AnnotationWithVarType(annotation = @AnnotationTargetAll)
*/
public function bar(){}
/**
* @AnnotationWithVarType(string = 123)
*/
public $invalidProperty;
/**
* @AnnotationWithVarType(annotation = @AnnotationTargetAnnotation)
*/
public function invalidMethod(){}
}

@ -0,0 +1,52 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation;
/**
* @AnnotationTargetAll("Foo")
*/
final class ClassWithClosure
{
/**
* @AnnotationTargetAll(@AnnotationTargetAnnotation)
* @var string
*/
public $value;
/**
* @AnnotationTargetAll(@AnnotationTargetAnnotation)
*
* @param \Closure $callback
* @return \Closure
*/
public function methodName(\Closure $callback)
{
$self = $this;
return function() use ($self, $callback) {
return $callback;
};
}
/**
* @param integer $year
* @param integer $month
* @param integer $day
* @return \Doctrine\Common\Collections\ArrayCollection
*/
public function getEventsForDate($year, $month, $day){
$extractEvents = null; // check if date of item is inside day given
$extractEvents = $this->events->filter(function ($item) use ($year, $month, $day) {
$leftDate = new \DateTime($year.'-'.$month.'-'.$day.' 00:00');
$rigthDate = new \DateTime($year.'-'.$month.'-'.$day.' +1 day 00:00');
return ( ( $leftDate <= $item->getDateStart() ) && ( $item->getDateStart() < $rigthDate ) );
}
);
return $extractEvents;
}
}

@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
class ClassWithConstants
{
const SOME_VALUE = 'ClassWithConstants.SOME_VALUE';
const SOME_KEY = 'ClassWithConstants.SOME_KEY';
}

@ -0,0 +1,11 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use
\Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure,
\Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route
;
use \Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
class ClassWithFullyQualifiedUseStatements {}

@ -0,0 +1,17 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetPropertyMethod;
/**
* @AnnotationTargetPropertyMethod("Some data")
*/
class ClassWithInvalidAnnotationTargetAtClass
{
/**
* @AnnotationTargetPropertyMethod("Bar")
*/
public $foo;
}

@ -0,0 +1,20 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass;
/**
* @AnnotationTargetClass("Some data")
*/
class ClassWithInvalidAnnotationTargetAtMethod
{
/**
* @AnnotationTargetClass("functionName")
*/
public function functionName($param)
{
}
}

@ -0,0 +1,24 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation;
/**
* @AnnotationTargetClass("Some data")
*/
class ClassWithInvalidAnnotationTargetAtProperty
{
/**
* @AnnotationTargetClass("Bar")
*/
public $foo;
/**
* @AnnotationTargetAnnotation("Foo")
*/
public $bar;
}

@ -0,0 +1,15 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
// Include a class named Api
require_once(__DIR__ . '/Api.php');
use Doctrine\Tests\Common\Annotations\DummyAnnotationWithIgnoredAnnotation;
/**
* @DummyAnnotationWithIgnoredAnnotation(dummyValue="hello")
*/
class ClassWithRequire
{
}

@ -0,0 +1,41 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetPropertyMethod;
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetNestedAnnotation;
/**
* @AnnotationTargetClass("Some data")
*/
class ClassWithValidAnnotationTarget
{
/**
* @AnnotationTargetPropertyMethod("Some data")
*/
public $foo;
/**
* @AnnotationTargetAll("Some data",name="Some name")
*/
public $name;
/**
* @AnnotationTargetPropertyMethod("Some data",name="Some name")
*/
public function someFunction()
{
}
/**
* @AnnotationTargetAll(@AnnotationTargetAnnotation)
*/
public $nested;
}

@ -0,0 +1,300 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
/**
* @Route("/someprefix")
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class Controller
{
/**
* @Route("/", name="_demo")
* @Template()
*/
public function indexAction()
{
return array();
}
/**
* @Route("/hello/{name}", name="_demo_hello")
* @Template()
*/
public function helloAction($name)
{
return array('name' => $name);
}
/**
* @Route("/contact", name="_demo_contact")
* @Template()
*/
public function contactAction()
{
$form = ContactForm::create($this->get('form.context'), 'contact');
$form->bind($this->container->get('request'), $form);
if ($form->isValid()) {
$form->send($this->get('mailer'));
$this->get('session')->setFlash('notice', 'Message sent!');
return new RedirectResponse($this->generateUrl('_demo'));
}
return array('form' => $form);
}
/**
* Creates the ACL for the passed object identity
*
* @param ObjectIdentityInterface $oid
* @return void
*/
private function createObjectIdentity(ObjectIdentityInterface $oid)
{
$classId = $this->createOrRetrieveClassId($oid->getType());
$this->connection->executeQuery($this->getInsertObjectIdentitySql($oid->getIdentifier(), $classId, true));
}
/**
* Returns the primary key for the passed class type.
*
* If the type does not yet exist in the database, it will be created.
*
* @param string $classType
* @return integer
*/
private function createOrRetrieveClassId($classType)
{
if (false !== $id = $this->connection->executeQuery($this->getSelectClassIdSql($classType))->fetchColumn()) {
return $id;
}
$this->connection->executeQuery($this->getInsertClassSql($classType));
return $this->connection->executeQuery($this->getSelectClassIdSql($classType))->fetchColumn();
}
/**
* Returns the primary key for the passed security identity.
*
* If the security identity does not yet exist in the database, it will be
* created.
*
* @param SecurityIdentityInterface $sid
* @return integer
*/
private function createOrRetrieveSecurityIdentityId(SecurityIdentityInterface $sid)
{
if (false !== $id = $this->connection->executeQuery($this->getSelectSecurityIdentityIdSql($sid))->fetchColumn()) {
return $id;
}
$this->connection->executeQuery($this->getInsertSecurityIdentitySql($sid));
return $this->connection->executeQuery($this->getSelectSecurityIdentityIdSql($sid))->fetchColumn();
}
/**
* Deletes all ACEs for the given object identity primary key.
*
* @param integer $oidPK
* @return void
*/
private function deleteAccessControlEntries($oidPK)
{
$this->connection->executeQuery($this->getDeleteAccessControlEntriesSql($oidPK));
}
/**
* Deletes the object identity from the database.
*
* @param integer $pk
* @return void
*/
private function deleteObjectIdentity($pk)
{
$this->connection->executeQuery($this->getDeleteObjectIdentitySql($pk));
}
/**
* Deletes all entries from the relations table from the database.
*
* @param integer $pk
* @return void
*/
private function deleteObjectIdentityRelations($pk)
{
$this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk));
}
/**
* This regenerates the ancestor table which is used for fast read access.
*
* @param AclInterface $acl
* @return void
*/
private function regenerateAncestorRelations(AclInterface $acl)
{
$pk = $acl->getId();
$this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk));
$this->connection->executeQuery($this->getInsertObjectIdentityRelationSql($pk, $pk));
$parentAcl = $acl->getParentAcl();
while (null !== $parentAcl) {
$this->connection->executeQuery($this->getInsertObjectIdentityRelationSql($pk, $parentAcl->getId()));
$parentAcl = $parentAcl->getParentAcl();
}
}
/**
* This processes changes on an ACE related property (classFieldAces, or objectFieldAces).
*
* @param string $name
* @param array $changes
* @return void
*/
private function updateFieldAceProperty($name, array $changes)
{
$sids = new \SplObjectStorage();
$classIds = new \SplObjectStorage();
$currentIds = array();
foreach ($changes[1] as $field => $new) {
for ($i=0,$c=count($new); $i<$c; $i++) {
$ace = $new[$i];
if (null === $ace->getId()) {
if ($sids->contains($ace->getSecurityIdentity())) {
$sid = $sids->offsetGet($ace->getSecurityIdentity());
} else {
$sid = $this->createOrRetrieveSecurityIdentityId($ace->getSecurityIdentity());
}
$oid = $ace->getAcl()->getObjectIdentity();
if ($classIds->contains($oid)) {
$classId = $classIds->offsetGet($oid);
} else {
$classId = $this->createOrRetrieveClassId($oid->getType());
}
$objectIdentityId = $name === 'classFieldAces' ? null : $ace->getAcl()->getId();
$this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, $field, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure()));
$aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, $field, $i))->fetchColumn();
$this->loadedAces[$aceId] = $ace;
$aceIdProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Entry', 'id');
$aceIdProperty->setAccessible(true);
$aceIdProperty->setValue($ace, intval($aceId));
} else {
$currentIds[$ace->getId()] = true;
}
}
}
foreach ($changes[0] as $old) {
for ($i=0,$c=count($old); $i<$c; $i++) {
$ace = $old[$i];
if (!isset($currentIds[$ace->getId()])) {
$this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId()));
unset($this->loadedAces[$ace->getId()]);
}
}
}
}
/**
* This processes changes on an ACE related property (classAces, or objectAces).
*
* @param string $name
* @param array $changes
* @return void
*/
private function updateAceProperty($name, array $changes)
{
list($old, $new) = $changes;
$sids = new \SplObjectStorage();
$classIds = new \SplObjectStorage();
$currentIds = array();
for ($i=0,$c=count($new); $i<$c; $i++) {
$ace = $new[$i];
if (null === $ace->getId()) {
if ($sids->contains($ace->getSecurityIdentity())) {
$sid = $sids->offsetGet($ace->getSecurityIdentity());
} else {
$sid = $this->createOrRetrieveSecurityIdentityId($ace->getSecurityIdentity());
}
$oid = $ace->getAcl()->getObjectIdentity();
if ($classIds->contains($oid)) {
$classId = $classIds->offsetGet($oid);
} else {
$classId = $this->createOrRetrieveClassId($oid->getType());
}
$objectIdentityId = $name === 'classAces' ? null : $ace->getAcl()->getId();
$this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, null, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure()));
$aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, null, $i))->fetchColumn();
$this->loadedAces[$aceId] = $ace;
$aceIdProperty = new \ReflectionProperty($ace, 'id');
$aceIdProperty->setAccessible(true);
$aceIdProperty->setValue($ace, intval($aceId));
} else {
$currentIds[$ace->getId()] = true;
}
}
for ($i=0,$c=count($old); $i<$c; $i++) {
$ace = $old[$i];
if (!isset($currentIds[$ace->getId()])) {
$this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId()));
unset($this->loadedAces[$ace->getId()]);
}
}
}
/**
* Persists the changes which were made to ACEs to the database.
*
* @param \SplObjectStorage $aces
* @return void
*/
private function updateAces(\SplObjectStorage $aces)
{
foreach ($aces as $ace) {
$propertyChanges = $aces->offsetGet($ace);
$sets = array();
if (isset($propertyChanges['mask'])) {
$sets[] = sprintf('mask = %d', $propertyChanges['mask'][1]);
}
if (isset($propertyChanges['strategy'])) {
$sets[] = sprintf('granting_strategy = %s', $this->connection->quote($propertyChanges['strategy']));
}
if (isset($propertyChanges['aceOrder'])) {
$sets[] = sprintf('ace_order = %d', $propertyChanges['aceOrder'][1]);
}
if (isset($propertyChanges['auditSuccess'])) {
$sets[] = sprintf('audit_success = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditSuccess'][1]));
}
if (isset($propertyChanges['auditFailure'])) {
$sets[] = sprintf('audit_failure = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditFailure'][1]));
}
$this->connection->executeQuery($this->getUpdateAccessControlEntrySql($ace->getId(), $sets));
}
}
}

@ -0,0 +1,15 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
class DifferentNamespacesPerFileWithClassAsFirst {}
}
namespace {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
}
namespace Doctrine\Tests\Common\Annotations\Fixtures\Foo {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
}

@ -0,0 +1,15 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures\Foo {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
}
namespace {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
}
namespace Doctrine\Tests\Common\Annotations\Fixtures {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
class DifferentNamespacesPerFileWithClassAsLast {}
}

@ -0,0 +1,13 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
class EqualNamespacesPerFileWithClassAsFirst {}
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;

@ -0,0 +1,12 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
class EqualNamespacesPerFileWithClassAsLast {}

@ -0,0 +1,12 @@
<?php
namespace {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
class GlobalNamespacesPerFileWithClassAsFirst {}
}
namespace {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
}

@ -0,0 +1,12 @@
<?php
namespace {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
}
namespace {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
class GlobalNamespacesPerFileWithClassAsLast {}
}

@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
interface IntefaceWithConstants
{
const SOME_VALUE = 'IntefaceWithConstants.SOME_VALUE';
const SOME_KEY = 'IntefaceWithConstants.SOME_KEY';
}

@ -0,0 +1,14 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
/**
* @NoAnnotation
* @IgnoreAnnotation("NoAnnotation")
* @Route("foo")
*/
class InvalidAnnotationUsageButIgnoredClass
{
}

@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
/**
* @NoAnnotation
*/
class InvalidAnnotationUsageClass
{
}

@ -0,0 +1,9 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
class AnotherClass { }
class MultipleClassesInFile { }

@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use
Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route,
Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure
;
class MultipleImportsInUseStatement {}

@ -0,0 +1,20 @@
<?php
// namespace Doctrine\Tests\Common\Annotations\Fixtures;
namespace Doctrine\Tests\Common\Annotations\Fixtures\Foo {
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
// class NamespaceAndClassCommentedOut {}
}
namespace Doctrine\Tests\Common\Annotations\Fixtures {
// class NamespaceAndClassCommentedOut {}
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
// namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
class NamespaceAndClassCommentedOut {}
}

@ -0,0 +1,12 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
$var = 1;
function () use ($var) {};
class NamespaceWithClosureDeclaration {}

@ -0,0 +1,5 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
class NoAnnotation {}

@ -0,0 +1,10 @@
<?php
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
/**
* @Route("foo")
* @Template
*/
class AnnotationsTestsFixturesNonNamespacedClass { }

@ -0,0 +1,13 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Fixtures;
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure;
interface TestInterface
{
/**
* @Secure
*/
function foo();
}

@ -0,0 +1,194 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Common\Annotations\FileCacheReader;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Annotations\CachedReader;
use Doctrine\Common\Annotations\DocLexer;
use Doctrine\Common\Annotations\DocParser;
use Doctrine\Common\Annotations\PhpParser;
use Doctrine\Common\Annotations\AnnotationReader;
require_once __DIR__ . '/Fixtures/Annotation/Route.php';
require_once __DIR__ . '/Fixtures/Annotation/Template.php';
require_once __DIR__ . '/Fixtures/Annotation/Secure.php';
require_once __DIR__ . '/Fixtures/SingleClassLOC1000.php';
class PerformanceTest extends \PHPUnit_Framework_TestCase
{
/**
* @group performance
*/
public function testCachedReadPerformanceWithInMemory()
{
$reader = new CachedReader(new AnnotationReader(), new ArrayCache());
$method = $this->getMethod();
$time = microtime(true);
for ($i=0,$c=500; $i<$c; $i++) {
$reader->getMethodAnnotations($method);
}
$time = microtime(true) - $time;
$this->printResults('cached reader (in-memory)', $time, $c);
}
/**
* @group performance
*/
public function testCachedReadPerformanceWithFileCache()
{
$method = $this->getMethod();
// prime cache
$reader = new FileCacheReader(new AnnotationReader(), sys_get_temp_dir());
$reader->getMethodAnnotations($method);
$time = microtime(true);
for ($i=0,$c=500; $i<$c; $i++) {
$reader = new FileCacheReader(new AnnotationReader(), sys_get_temp_dir());
$reader->getMethodAnnotations($method);
clearstatcache();
}
$time = microtime(true) - $time;
$this->printResults('cached reader (file)', $time, $c);
}
/**
* @group performance
*/
public function testReadPerformance()
{
$method = $this->getMethod();
$time = microtime(true);
for ($i=0,$c=150; $i<$c; $i++) {
$reader = new AnnotationReader();
$reader->getMethodAnnotations($method);
}
$time = microtime(true) - $time;
$this->printResults('reader', $time, $c);
}
/**
* @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);
}
/**
* @group performance
*/
public function testDocLexerPerformance()
{
$method = $this->getMethod();
$methodComment = $method->getDocComment();
$classComment = $method->getDeclaringClass()->getDocComment();
$time = microtime(true);
for ($i=0,$c=500; $i<$c; $i++) {
$lexer = new DocLexer();
$lexer->setInput($methodComment);
$lexer->setInput($classComment);
}
$time = microtime(true) - $time;
$this->printResults('doc-lexer', $time, $c);
}
/**
* @group performance
*/
public function testPhpParserPerformanceWithShortCut()
{
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\NamespacedSingleClassLOC1000');
$time = microtime(true);
for ($i=0,$c=500; $i<$c; $i++) {
$parser = new PhpParser();
$parser->parseClass($class);
}
$time = microtime(true) - $time;
$this->printResults('doc-parser-with-short-cut', $time, $c);
}
/**
* @group performance
*/
public function testPhpParserPerformanceWithoutShortCut()
{
$class = new \ReflectionClass('SingleClassLOC1000');
$time = microtime(true);
for ($i=0,$c=500; $i<$c; $i++) {
$parser = new PhpParser();
$parser->parseClass($class);
}
$time = microtime(true) - $time;
$this->printResults('doc-parser-without-short-cut', $time, $c);
}
private function getMethod()
{
return new \ReflectionMethod('Doctrine\Tests\Common\Annotations\Fixtures\Controller', 'helloAction');
}
private function printResults($test, $time, $iterations)
{
if (0 == $iterations) {
throw new \InvalidArgumentException('$iterations cannot be zero.');
}
$title = $test." results:\n";
$iterationsText = sprintf("Iterations: %d\n", $iterations);
$totalTime = sprintf("Total Time: %.3f s\n", $time);
$iterationTime = sprintf("Time per iteration: %.3f ms\n", $time/$iterations * 1000);
$max = max(strlen($title), strlen($iterationTime)) - 1;
echo "\n".str_repeat('-', $max)."\n";
echo $title;
echo str_repeat('=', $max)."\n";
echo $iterationsText;
echo $totalTime;
echo $iterationTime;
echo str_repeat('-', $max)."\n";
}
}

@ -0,0 +1,207 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use ReflectionClass;
use Doctrine\Common\Annotations\PhpParser;
require_once __DIR__.'/Fixtures/NonNamespacedClass.php';
require_once __DIR__.'/Fixtures/GlobalNamespacesPerFileWithClassAsFirst.php';
require_once __DIR__.'/Fixtures/GlobalNamespacesPerFileWithClassAsLast.php';
class PhpParserTest extends \PHPUnit_Framework_TestCase
{
public function testParseClassWithMultipleClassesInFile()
{
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\MultipleClassesInFile');
$parser = new PhpParser();
$this->assertEquals(array(
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
), $parser->parseClass($class));
}
public function testParseClassWithMultipleImportsInUseStatement()
{
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\MultipleImportsInUseStatement');
$parser = new PhpParser();
$this->assertEquals(array(
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
), $parser->parseClass($class));
}
public function testParseClassWhenNotUserDefined()
{
$parser = new PhpParser();
$this->assertEquals(array(), $parser->parseClass(new \ReflectionClass('\stdClass')));
}
public function testClassFileDoesNotExist()
{
$class = $this->getMockBuilder('\ReflectionClass')
->disableOriginalConstructor()
->getMock();
$class->expects($this->once())
->method('getFilename')
->will($this->returnValue('/valid/class/Fake.php(35) : eval()d code'));
$parser = new PhpParser();
$this->assertEquals(array(), $parser->parseClass($class));
}
public function testParseClassWhenClassIsNotNamespaced()
{
$parser = new PhpParser();
$class = new ReflectionClass('\AnnotationsTestsFixturesNonNamespacedClass');
$this->assertEquals(array(
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
public function testParseClassWhenClassIsInterface()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\TestInterface');
$this->assertEquals(array(
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
), $parser->parseClass($class));
}
public function testClassWithFullyQualifiedUseStatements()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\ClassWithFullyQualifiedUseStatements');
$this->assertEquals(array(
'secure' => '\\' . __NAMESPACE__ . '\Fixtures\Annotation\Secure',
'route' => '\\' . __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => '\\' . __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
public function testNamespaceAndClassCommentedOut()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\NamespaceAndClassCommentedOut');
$this->assertEquals(array(
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
public function testEqualNamespacesPerFileWithClassAsFirst()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\EqualNamespacesPerFileWithClassAsFirst');
$this->assertEquals(array(
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
), $parser->parseClass($class));
}
public function testEqualNamespacesPerFileWithClassAsLast()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\EqualNamespacesPerFileWithClassAsLast');
$this->assertEquals(array(
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
public function testDifferentNamespacesPerFileWithClassAsFirst()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\DifferentNamespacesPerFileWithClassAsFirst');
$this->assertEquals(array(
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
), $parser->parseClass($class));
}
public function testDifferentNamespacesPerFileWithClassAsLast()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\DifferentNamespacesPerFileWithClassAsLast');
$this->assertEquals(array(
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
public function testGlobalNamespacesPerFileWithClassAsFirst()
{
$parser = new PhpParser();
$class = new \ReflectionClass('\GlobalNamespacesPerFileWithClassAsFirst');
$this->assertEquals(array(
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
), $parser->parseClass($class));
}
public function testGlobalNamespacesPerFileWithClassAsLast()
{
$parser = new PhpParser();
$class = new ReflectionClass('\GlobalNamespacesPerFileWithClassAsLast');
$this->assertEquals(array(
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
public function testNamespaceWithClosureDeclaration()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\NamespaceWithClosureDeclaration');
$this->assertEquals(array(
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
public function testIfPointerResetsOnMultipleParsingTries()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\NamespaceWithClosureDeclaration');
$this->assertEquals(array(
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
$this->assertEquals(array(
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure',
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route',
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template',
), $parser->parseClass($class));
}
/**
* @group DCOM-97
* @group regression
*/
public function testClassWithClosure()
{
$parser = new PhpParser();
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\ClassWithClosure');
$this->assertEquals(array(
'annotationtargetall' => __NAMESPACE__ . '\Fixtures\AnnotationTargetAll',
'annotationtargetannotation' => __NAMESPACE__ . '\Fixtures\AnnotationTargetAnnotation',
), $parser->parseClass($class));
}
}

@ -0,0 +1,97 @@
<?php
namespace Doctrine\Tests\Common\Annotations;
use Doctrine\Common\Annotations\SimpleAnnotationReader;
class SimpleAnnotationReaderTest extends AbstractReaderTest
{
/**
* Contrary to the behavior of the default annotation reader, we do just ignore
* these in the simple annotation reader (so, no expected exception here).
*/
public function testImportDetectsNotImportedAnnotation()
{
parent::testImportDetectsNotImportedAnnotation();
}
/**
* Contrary to the behavior of the default annotation reader, we do just ignore
* these in the simple annotation reader (so, no expected exception here).
*/
public function testImportDetectsNonExistentAnnotation()
{
parent::testImportDetectsNonExistentAnnotation();
}
/**
* Contrary to the behavior of the default annotation reader, we do just ignore
* these in the simple annotation reader (so, no expected exception here).
*/
public function testClassWithInvalidAnnotationTargetAtClassDocBlock()
{
parent::testClassWithInvalidAnnotationTargetAtClassDocBlock();
}
/**
* Contrary to the behavior of the default annotation reader, we do just ignore
* these in the simple annotation reader (so, no expected exception here).
*/
public function testClassWithInvalidAnnotationTargetAtPropertyDocBlock()
{
parent::testClassWithInvalidAnnotationTargetAtPropertyDocBlock();
}
/**
* Contrary to the behavior of the default annotation reader, we do just ignore
* these in the simple annotation reader (so, no expected exception here).
*/
public function testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock()
{
parent::testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock();
}
/**
* Contrary to the behavior of the default annotation reader, we do just ignore
* these in the simple annotation reader (so, no expected exception here).
*/
public function testClassWithInvalidAnnotationTargetAtMethodDocBlock()
{
parent::testClassWithInvalidAnnotationTargetAtMethodDocBlock();
}
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
*/
public function testInvalidAnnotationUsageButIgnoredClass()
{
parent::testInvalidAnnotationUsageButIgnoredClass();
}
/**
* @group DDC-1660
* @group regression
*
* Contrary to the behavior of the default annotation reader, @version is not ignored
*/
public function testInvalidAnnotationButIgnored()
{
$reader = $this->getReader();
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassDDC1660');
$this->assertTrue(class_exists('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Version'));
$this->assertCount(1, $reader->getClassAnnotations($class));
$this->assertCount(1, $reader->getMethodAnnotations($class->getMethod('bar')));
$this->assertCount(1, $reader->getPropertyAnnotations($class->getProperty('foo')));
}
protected function getReader()
{
$reader = new SimpleAnnotationReader();
$reader->addNamespace(__NAMESPACE__);
$reader->addNamespace(__NAMESPACE__ . '\Fixtures');
$reader->addNamespace(__NAMESPACE__ . '\Fixtures\Annotation');
return $reader;
}
}

@ -0,0 +1,65 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Ticket;
use Doctrine\Tests\Common\Annotations\Fixtures\Controller;
/**
* @group
*/
class DCOM55Test extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException Doctrine\Common\Annotations\AnnotationException
* @expectedExceptionMessage [Semantical Error] The class "Doctrine\Tests\Common\Annotations\Fixtures\Controller" 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\Controller". If it is indeed no annotation, then you need to add @IgnoreAnnotation("Controller") to the _class_ doc comment of class Doctrine\Tests\Common\Annotations\Ticket\Dummy.
*/
public function testIssue()
{
$class = new \ReflectionClass(__NAMESPACE__ . '\\Dummy');
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader->getClassAnnotations($class);
}
public function testAnnotation()
{
$class = new \ReflectionClass(__NAMESPACE__ . '\\DCOM55Consumer');
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$annots = $reader->getClassAnnotations($class);
$this->assertEquals(1, count($annots));
$this->assertInstanceOf(__NAMESPACE__.'\\DCOM55Annotation', $annots[0]);
}
public function testParseAnnotationDocblocks()
{
$class = new \ReflectionClass(__NAMESPACE__ . '\\DCOM55Annotation');
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$annots = $reader->getClassAnnotations($class);
$this->assertEquals(0, count($annots));
}
}
/**
* @Controller
*/
class Dummy
{
}
/**
* @Annotation
*/
class DCOM55Annotation
{
}
/**
* @DCOM55Annotation
*/
class DCOM55Consumer
{
}

@ -0,0 +1,8 @@
<?php
// Some class named Entity in the global namespace
/**
* @Annotation
*/
class Entity
{
}

@ -0,0 +1,112 @@
<?php
namespace Doctrine\Tests\Common\Annotations\Ticket;
//Some class named Entity in the global namespace
include __DIR__ .'/DCOM58Entity.php';
/**
* @group DCOM58
*/
class DCOM58Test extends \PHPUnit_Framework_TestCase
{
public function testIssue()
{
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$result = $reader->getClassAnnotations(new \ReflectionClass(__NAMESPACE__."\MappedClass"));
foreach ($result as $annot) {
$classAnnotations[get_class($annot)] = $annot;
}
$this->assertTrue(!isset($classAnnotations['']), 'Class "xxx" is not a valid entity or mapped super class.');
}
public function testIssueGlobalNamespace()
{
$docblock = "@Entity";
$parser = new \Doctrine\Common\Annotations\DocParser();
$parser->setImports(array(
"__NAMESPACE__" =>"Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping"
));
$annots = $parser->parse($docblock);
$this->assertEquals(1, count($annots));
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping\Entity", $annots[0]);
}
public function testIssueNamespaces()
{
$docblock = "@Entity";
$parser = new \Doctrine\Common\Annotations\DocParser();
$parser->addNamespace("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM");
$annots = $parser->parse($docblock);
$this->assertEquals(1, count($annots));
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Entity", $annots[0]);
}
public function testIssueMultipleNamespaces()
{
$docblock = "@Entity";
$parser = new \Doctrine\Common\Annotations\DocParser();
$parser->addNamespace("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping");
$parser->addNamespace("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM");
$annots = $parser->parse($docblock);
$this->assertEquals(1, count($annots));
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping\Entity", $annots[0]);
}
public function testIssueWithNamespacesOrImports()
{
$docblock = "@Entity";
$parser = new \Doctrine\Common\Annotations\DocParser();
$annots = $parser->parse($docblock);
$this->assertEquals(1, count($annots));
$this->assertInstanceOf("Entity", $annots[0]);
$this->assertEquals(1, count($annots));
}
public function testIssueSimpleAnnotationReader()
{
$reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader();
$reader->addNamespace('Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping');
$annots = $reader->getClassAnnotations(new \ReflectionClass(__NAMESPACE__."\MappedClass"));
$this->assertEquals(1, count($annots));
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping\Entity", $annots[0]);
}
}
/**
* @Entity
*/
class MappedClass
{
}
namespace Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping;
/**
* @Annotation
*/
class Entity
{
}
namespace Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM;
/**
* @Annotation
*/
class Entity
{
}

@ -0,0 +1,8 @@
<?php
use Doctrine\Common\Annotations\Annotation;
/** @Annotation */
class TopLevelAnnotation extends Annotation
{
}

@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests;
/**
* Base testcase class for all Doctrine testcases.
*/
abstract class DoctrineTestCase extends \PHPUnit_Framework_TestCase
{
}

@ -0,0 +1,26 @@
<?php
/*
* This file bootstraps the test environment.
*/
namespace Doctrine\Tests;
error_reporting(E_ALL | E_STRICT);
// register silently failing autoloader
spl_autoload_register(function($class)
{
if (0 === strpos($class, 'Doctrine\Tests\\')) {
$path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php';
if (is_file($path) && is_readable($path)) {
require_once $path;
return true;
}
}
});
require_once __DIR__ . "/../../../vendor/autoload.php";
\Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(
'Doctrine\Tests\Common\Annotations\Fixtures', __DIR__ . '/../../'
);

@ -0,0 +1,2 @@
vendor/
phpunit.xml

@ -0,0 +1,9 @@
language: php
php:
- 5.3
- 5.4
- 5.5
before_script:
- composer --prefer-source --dev install

@ -0,0 +1,19 @@
Copyright (c) 2006-2012 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,10 @@
# Doctrine Cache
Cache component extracted from the Doctrine Common project.
## Changelog
### v1.2
* Added support for MongoDB as Cache Provider
* Fix namespace version reset

@ -0,0 +1,3 @@
# Version class and file
project.version_class = Doctrine\\Common\\Cache\\Version
project.version_file = lib/Doctrine/Common/Cache/Version.php

@ -0,0 +1,101 @@
<?xml version="1.0"?>
<project name="DoctrineCommonCache" default="build" basedir=".">
<property file="build.properties" />
<target name="php">
<exec executable="which" outputproperty="php_executable">
<arg value="php" />
</exec>
</target>
<target name="prepare">
<mkdir dir="build" />
</target>
<target name="build" depends="check-git-checkout-clean,prepare,php,composer">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="archive" />
<arg value="--dir=build" />
</exec>
</target>
<target name="composer" depends="php,composer-check,composer-download">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="install" />
</exec>
</target>
<target name="composer-check" depends="prepare">
<available file="build/composer.phar" property="composer.present"/>
</target>
<target name="composer-download" unless="composer.present">
<exec executable="wget">
<arg value="-Obuild/composer.phar" />
<arg value="http://getcomposer.org/composer.phar" />
</exec>
</target>
<target name="make-release" depends="check-git-checkout-clean,prepare,php">
<replace file="${project.version_file}" token="-DEV" value="" failOnNoReplacements="true" />
<exec executable="${php_executable}" outputproperty="doctrine.current_version" failonerror="true">
<arg value="-r" />
<arg value="require_once '${project.version_file}';echo ${project.version_class}::VERSION;" />
</exec>
<exec executable="${php_executable}" outputproperty="doctrine.next_version" failonerror="true">
<arg value="-r" />
<arg value="$parts = explode('.', str_ireplace(array('-DEV', '-ALPHA', '-BETA'), '', '${doctrine.current_version}'));
if (count($parts) != 3) {
throw new \InvalidArgumentException('Version is assumed in format x.y.z, ${doctrine.current_version} given');
}
$parts[2]++;
echo implode('.', $parts);
" />
</exec>
<git-commit file="${project.version_file}" message="Release ${doctrine.current_version}" />
<git-tag version="${doctrine.current_version}" />
<replace file="${project.version_file}" token="${doctrine.current_version}" value="${doctrine.next_version}-DEV" />
<git-commit file="${project.version_file}" message="Bump version to ${doctrine.next_version}" />
</target>
<target name="check-git-checkout-clean">
<exec executable="git" failonerror="true">
<arg value="diff-index" />
<arg value="--quiet" />
<arg value="HEAD" />
</exec>
</target>
<macrodef name="git-commit">
<attribute name="file" default="NOT SET"/>
<attribute name="message" default="NOT SET"/>
<sequential>
<exec executable="git">
<arg value="add" />
<arg value="@{file}" />
</exec>
<exec executable="git">
<arg value="commit" />
<arg value="-m" />
<arg value="@{message}" />
</exec>
</sequential>
</macrodef>
<macrodef name="git-tag">
<attribute name="version" default="NOT SET" />
<sequential>
<exec executable="git">
<arg value="tag" />
<arg value="-m" />
<arg value="v@{version}" />
<arg value="v@{version}" />
</exec>
</sequential>
</macrodef>
</project>

@ -0,0 +1,29 @@
{
"name": "doctrine/cache",
"type": "library",
"description": "Caching library offering an object-oriented API for many cache backends",
"keywords": ["cache", "caching"],
"homepage": "http://www.doctrine-project.org",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": ">=5.3.2"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"autoload": {
"psr-0": { "Doctrine\\Common\\Cache\\": "lib/" }
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save