.gitignore000064400000000044144760114530006537 0ustar00vendor/ composer.lock composer.phar .travis.yml000064400000000172144760114530006662 0ustar00language: php php: - 5.3 - 5.4 - 5.5 - 5.6 - hhvm before_script: - composer --prefer-source --dev install LICENSE000064400000002051144760114530005554 0ustar00Copyright (c) 2006-2013 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. README.md000064400000001125144760114530006027 0ustar00# 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](https://github.com/doctrine/common)). ## Changelog ### v1.2.0 * HHVM support * Allowing dangling comma in annotations * Excluded annotations are no longer autoloaded * Importing namespaces also in traits * Added support for `::class` 5.5-style constant, works also in 5.3 and 5.4 ### v1.1 * Add Exception when ZendOptimizer+ or Opcache is configured to drop comments composer.json000064400000001720144760114530007273 0ustar00{ "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.*", "phpunit/phpunit": "4.*" }, "autoload": { "psr-0": { "Doctrine\\Common\\Annotations\\": "lib/" } }, "extra": { "branch-alias": { "dev-master": "1.3.x-dev" } } } lib/Doctrine/Common/Annotations/Annotation.php000064400000004676144760114530015453 0ustar00. */ namespace Doctrine\Common\Annotations; /** * Annotations class. * * @author Benjamin Eberlei * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel */ 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 Unknown 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)) ); } } lib/Doctrine/Common/Annotations/Annotation/Attribute.php000064400000002636144760114530017410 0ustar00. */ 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 * * @Annotation */ final class Attribute { /** * @var string */ public $name; /** * @var string */ public $type; /** * @var boolean */ public $required = false; } lib/Doctrine/Common/Annotations/Annotation/Attributes.php000064400000002552144760114530017570 0ustar00. */ 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 * * @Annotation */ final class Attributes { /** * @var array */ public $value; } lib/Doctrine/Common/Annotations/Annotation/Enum.php000064400000005047144760114530016350 0ustar00. */ 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 * * @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 constructor. * * @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']; } } lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php000064400000003512144760114530020715 0ustar00. */ 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 */ 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']; } } lib/Doctrine/Common/Annotations/Annotation/Required.php000064400000002372144760114530017222 0ustar00. */ 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 * * @Annotation */ final class Required { } lib/Doctrine/Common/Annotations/Annotation/Target.php000064400000006336144760114530016674 0ustar00. */ 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 * * @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 constructor. * * @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); } } lib/Doctrine/Common/Annotations/AnnotationException.php000064400000013304144760114530017316 0ustar00. */ namespace Doctrine\Common\Annotations; /** * Description of AnnotationException * * @since 2.0 * @author Benjamin Eberlei * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel */ 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 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 a type error. * * @since 1.1 * * @param string $message * * @return AnnotationException */ public static function typeError($message) { return new self('[Type 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 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 attributeTypeError($attributeName, $annotationName, $context, $expected, $actual) { return self::typeError(sprintf( '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 self::typeError(sprintf( '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) { return 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() { return new self( "You have to enable opcache.save_comments=1 or zend_optimizerplus.save_comments=1." ); } /** * @return AnnotationException */ public static function optimizerPlusLoadComments() { return new self( "You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1." ); } } lib/Doctrine/Common/Annotations/AnnotationReader.php000064400000027732144760114530016574 0ustar00. */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation; use Doctrine\Common\Annotations\Annotation\Target; use ReflectionClass; use ReflectionMethod; use ReflectionProperty; /** * A reader for docblock annotations. * * @author Benjamin Eberlei * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel * @author Johannes M. Schmitt */ 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( // Annotation tags 'Annotation' => true, 'Attribute' => true, 'Attributes' => true, /* Can we enable this? 'Enum' => true, */ 'Required' => true, 'Target' => true, // Widely used tags (but not existent in phpdoc) 'fix' => true , 'fixme' => true, 'override' => true, // PHPDocumentor 1 tags 'abstract'=> true, 'access'=> true, 'code' => true, 'deprec'=> true, 'endcode' => true, 'exception'=> true, 'final'=> true, 'ingroup' => true, 'inheritdoc'=> true, 'inheritDoc'=> true, 'magic' => true, 'name'=> true, 'toc' => true, 'tutorial'=> true, 'private' => true, 'static'=> true, 'staticvar'=> true, 'staticVar'=> true, 'throw' => true, // PHPDocumentor 2 tags. 'api' => true, 'author'=> true, 'category'=> true, 'copyright'=> true, 'deprecated'=> true, 'example'=> true, 'filesource'=> true, 'global'=> true, 'ignore'=> true, /* Can we enable this? 'index' => true, */ 'internal'=> true, 'license'=> true, 'link'=> true, 'method' => true, 'package'=> true, 'param'=> true, 'property' => true, 'property-read' => true, 'property-write' => true, 'return'=> true, 'see'=> true, 'since'=> true, 'source' => true, 'subpackage'=> true, 'throws'=> true, 'todo'=> true, 'TODO'=> true, 'usedby'=> true, 'uses' => true, 'var'=> true, 'version'=> true, // PHPUnit tags 'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true, // PHPCheckStyle 'SuppressWarnings' => true, // PHPStorm 'noinspection' => true, // PEAR 'package_version' => true, // PlantUML 'startuml' => true, 'enduml' => 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('Zend OPcache') && ini_get('opcache.save_comments') == 0) { throw AnnotationException::optimizerPlusSaveComments(); } if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.load_comments') === "0" || ini_get('opcache.load_comments') === "0")) { throw AnnotationException::optimizerPlusLoadComments(); } if (extension_loaded('Zend OPcache') && ini_get('opcache.load_comments') == 0) { throw AnnotationException::optimizerPlusLoadComments(); } 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; } /** * {@inheritDoc} */ public function getClassAnnotations(ReflectionClass $class) { $this->parser->setTarget(Target::TARGET_CLASS); $this->parser->setImports($this->getClassImports($class)); $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName()); } /** * {@inheritDoc} */ public function getClassAnnotation(ReflectionClass $class, $annotationName) { $annotations = $this->getClassAnnotations($class); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } /** * {@inheritDoc} */ public function getPropertyAnnotations(ReflectionProperty $property) { $class = $property->getDeclaringClass(); $context = 'property ' . $class->getName() . "::\$" . $property->getName(); $this->parser->setTarget(Target::TARGET_PROPERTY); $this->parser->setImports($this->getPropertyImports($property)); $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); return $this->parser->parse($property->getDocComment(), $context); } /** * {@inheritDoc} */ public function getPropertyAnnotation(ReflectionProperty $property, $annotationName) { $annotations = $this->getPropertyAnnotations($property); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } /** * {@inheritDoc} */ public function getMethodAnnotations(ReflectionMethod $method) { $class = $method->getDeclaringClass(); $context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; $this->parser->setTarget(Target::TARGET_METHOD); $this->parser->setImports($this->getMethodImports($method)); $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); return $this->parser->parse($method->getDocComment(), $context); } /** * {@inheritDoc} */ 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]; } /** * Retrieves imports. * * @param \ReflectionClass $class * * @return array */ private function getClassImports(ReflectionClass $class) { if (isset($this->imports[$name = $class->getName()])) { return $this->imports[$name]; } $this->collectParsingMetadata($class); return $this->imports[$name]; } /** * Retrieves imports for methods. * * @param \ReflectionMethod $method * * @return array */ private function getMethodImports(ReflectionMethod $method) { $class = $method->getDeclaringClass(); $classImports = $this->getClassImports($class); if (!method_exists($class, 'getTraits')) { return $classImports; } $traitImports = array(); foreach ($class->getTraits() as $trait) { if ($trait->hasMethod($method->getName()) && $trait->getFileName() === $method->getFileName() ) { $traitImports = array_merge($traitImports, $this->phpParser->parseClass($trait)); } } return array_merge($classImports, $traitImports); } /** * Retrieves imports for properties. * * @param \ReflectionProperty $property * * @return array */ private function getPropertyImports(ReflectionProperty $property) { $class = $property->getDeclaringClass(); $classImports = $this->getClassImports($class); if (!method_exists($class, 'getTraits')) { return $classImports; } $traitImports = array(); foreach ($class->getTraits() as $trait) { if ($trait->hasProperty($property->getName())) { $traitImports = array_merge($traitImports, $this->phpParser->parseClass($trait)); } } return array_merge($classImports, $traitImports); } /** * 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; } } lib/Doctrine/Common/Annotations/AnnotationRegistry.php000064400000011206144760114530017167 0ustar00. */ 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(); /** * @return void */ static public function reset() { self::$autoloadNamespaces = array(); self::$loaders = array(); } /** * Registers file. * * @param string $file * * @return void */ static public function registerFile($file) { require_once $file; } /** * Adds 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 * * @return void */ static public function registerAutoloadNamespace($namespace, $dirs = null) { self::$autoloadNamespaces[$namespace] = $dirs; } /** * Registers multiple namespaces. * * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. * * @param array $namespaces * * @return void */ static public function registerAutoloadNamespaces(array $namespaces) { self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces); } /** * Registers 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 * * @return void * * @throws \InvalidArgumentException */ static public function registerLoader($callable) { if (!is_callable($callable)) { throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader()."); } self::$loaders[] = $callable; } /** * Autoloads 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; } } lib/Doctrine/Common/Annotations/CachedReader.php000064400000014406144760114530015623 0ustar00. */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Cache\Cache; /** * A cache aware annotation reader. * * @author Johannes M. Schmitt * @author Benjamin Eberlei */ 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 = array(); /** * 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; } /** * {@inheritDoc} */ 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; } /** * {@inheritDoc} */ public function getClassAnnotation(\ReflectionClass $class, $annotationName) { foreach ($this->getClassAnnotations($class) as $annot) { if ($annot instanceof $annotationName) { return $annot; } } return null; } /** * {@inheritDoc} */ 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; } /** * {@inheritDoc} */ public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) { foreach ($this->getPropertyAnnotations($property) as $annot) { if ($annot instanceof $annotationName) { return $annot; } } return null; } /** * {@inheritDoc} */ 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; } /** * {@inheritDoc} */ public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) { foreach ($this->getMethodAnnotations($method) as $annot) { if ($annot instanceof $annotationName) { return $annot; } } return null; } /** * Clears loaded annotations. * * @return void */ 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 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. * * @return void */ private function saveToCache($rawCacheKey, $value) { $cacheKey = $rawCacheKey . self::$CACHE_SALT; $this->cache->save($cacheKey, $value); if ($this->debug) { $this->cache->save('[C]'.$cacheKey, time()); } } /** * Checks if the cache is fresh. * * @param string $cacheKey * @param \ReflectionClass $class * * @return boolean */ private function isCacheFresh($cacheKey, \ReflectionClass $class) { if (false === $filename = $class->getFilename()) { return true; } return $this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename); } } lib/Doctrine/Common/Annotations/DocLexer.php000064400000007732144760114530015042 0ustar00. */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Lexer\AbstractLexer; /** * Simple lexer for docblock annotations. * * @author Benjamin Eberlei * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel * @author Johannes M. Schmitt */ 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; /** * @var array */ 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 ); /** * @var array */ 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_][a-z0-9_]*', '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?', '"(?:[^"]|"")*"', ); } /** * {@inheritdoc} */ protected function getNonCatchablePatterns() { return array('\s+', '\*+', '(.)'); } /** * {@inheritdoc} */ 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; } } lib/Doctrine/Common/Annotations/DocParser.php000064400000112272144760114530015213 0ustar00. */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Annotations\Annotation\Attribute; use ReflectionClass; use Doctrine\Common\Annotations\Annotation\Enum; use Doctrine\Common\Annotations\Annotation\Target; use Doctrine\Common\Annotations\Annotation\Attributes; /** * A parser for docblock annotations. * * It is strongly discouraged to change the default annotation parsing process. * * @author Benjamin Eberlei * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel * @author Johannes M. Schmitt * @author Fabio B. Silva */ final class DocParser { /** * An array of all valid tokens for a class name. * * @var array */ private static $classIdentifiers = array( DocLexer::T_IDENTIFIER, DocLexer::T_TRUE, DocLexer::T_FALSE, DocLexer::T_NULL ); /** * The lexer. * * @var \Doctrine\Common\Annotations\DocLexer */ private $lexer; /** * Current target context. * * @var string */ private $target; /** * Doc parser used to collect annotation target. * * @var \Doctrine\Common\Annotations\DocParser */ private static $metadataParser; /** * Flag to control if the current annotation is nested or not. * * @var boolean */ private $isNestedAnnotation = false; /** * Hashmap containing all use-statements that are to be used when parsing * the given doc block. * * @var array */ private $imports = array(); /** * This hashmap is used internally to cache results of class_exists() * look-ups. * * @var array */ private $classExists = array(); /** * Whether annotations that have not been imported should be ignored. * * @var boolean */ private $ignoreNotImportedAnnotations = false; /** * An array of default namespaces if operating in simple mode. * * @var array */ private $namespaces = array(); /** * A list with annotations that are not causing exceptions when not resolved to an annotation class. * * The names must be the raw names as used in the class, not the fully qualified * class names. * * @var array */ private $ignoredAnnotationNames = array(); /** * @var string */ private $context = ''; /** * Hash-map for caching annotation metadata. * * @var array */ private static $annotationMetadata = array( 'Doctrine\Common\Annotations\Annotation\Target' => array( 'is_annotation' => true, 'has_constructor' => true, 'properties' => array(), 'targets_literal' => 'ANNOTATION_CLASS', 'targets' => Target::TARGET_CLASS, 'default_property' => 'value', 'attribute_types' => array( 'value' => array( 'required' => false, 'type' =>'array', 'array_type'=>'string', 'value' =>'array' ) ), ), 'Doctrine\Common\Annotations\Annotation\Attribute' => array( 'is_annotation' => true, 'has_constructor' => false, 'targets_literal' => 'ANNOTATION_ANNOTATION', 'targets' => Target::TARGET_ANNOTATION, 'default_property' => 'name', 'properties' => array( 'name' => 'name', 'type' => 'type', 'required' => 'required' ), 'attribute_types' => array( 'value' => array( 'required' => true, 'type' =>'string', 'value' =>'string' ), 'type' => array( 'required' =>true, 'type' =>'string', 'value' =>'string' ), 'required' => array( 'required' =>false, 'type' =>'boolean', 'value' =>'boolean' ) ), ), 'Doctrine\Common\Annotations\Annotation\Attributes' => array( 'is_annotation' => true, 'has_constructor' => false, 'targets_literal' => 'ANNOTATION_CLASS', 'targets' => Target::TARGET_CLASS, 'default_property' => 'value', 'properties' => array( 'value' => 'value' ), 'attribute_types' => array( 'value' => array( 'type' =>'array', 'required' =>true, 'array_type'=>'Doctrine\Common\Annotations\Annotation\Attribute', 'value' =>'array' ) ), ), 'Doctrine\Common\Annotations\Annotation\Enum' => array( 'is_annotation' => true, 'has_constructor' => true, 'targets_literal' => 'ANNOTATION_PROPERTY', 'targets' => Target::TARGET_PROPERTY, 'default_property' => 'value', 'properties' => array( 'value' => 'value' ), 'attribute_types' => array( 'value' => array( 'type' => 'array', 'required' => true, ), 'literal' => array( 'type' => 'array', 'required' => false, ), ), ), ); /** * Hash-map for handle types declaration. * * @var array */ private static $typeMap = array( 'float' => 'double', 'bool' => 'boolean', // allow uppercase Boolean in honor of George Boole 'Boolean' => 'boolean', 'int' => 'integer', ); /** * Constructs a new DocParser. */ public function __construct() { $this->lexer = new DocLexer; } /** * Sets the annotation names that are ignored during the parsing process. * * The names are supposed to be the raw names as used in the class, not the * fully qualified class names. * * @param array $names * * @return void */ public function setIgnoredAnnotationNames(array $names) { $this->ignoredAnnotationNames = $names; } /** * Sets ignore on not-imported annotations. * * @param boolean $bool * * @return void */ public function setIgnoreNotImportedAnnotations($bool) { $this->ignoreNotImportedAnnotations = (boolean) $bool; } /** * Sets the default namespaces. * * @param array $namespace * * @return void * * @throws \RuntimeException */ public function addNamespace($namespace) { if ($this->imports) { throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); } $this->namespaces[] = $namespace; } /** * Sets the imports. * * @param array $imports * * @return void * * @throws \RuntimeException */ public function setImports(array $imports) { if ($this->namespaces) { throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); } $this->imports = $imports; } /** * Sets current target context as bitmask. * * @param integer $target * * @return void */ public function setTarget($target) { $this->target = $target; } /** * Parses the given docblock string for annotations. * * @param string $input The docblock string to parse. * @param string $context The parsing context. * * @return array Array of annotations. If no annotations are found, an empty array is returned. */ public function parse($input, $context = '') { $pos = $this->findInitialTokenPosition($input); if ($pos === null) { return array(); } $this->context = $context; $this->lexer->setInput(trim(substr($input, $pos), '* /')); $this->lexer->moveNext(); return $this->Annotations(); } /** * Finds the first valid annotation * * @param string $input The docblock string to parse * * @return int|null */ private function findInitialTokenPosition($input) { $pos = 0; // search for first valid annotation while (($pos = strpos($input, '@', $pos)) !== false) { // if the @ is preceded by a space or * it is valid if ($pos === 0 || $input[$pos - 1] === ' ' || $input[$pos - 1] === '*') { return $pos; } $pos++; } return null; } /** * Attempts to match the given token with the current lookahead token. * If they match, updates the lookahead token; otherwise raises a syntax error. * * @param integer $token Type of token. * * @return boolean True if tokens match; false otherwise. */ private function match($token) { if ( ! $this->lexer->isNextToken($token) ) { $this->syntaxError($this->lexer->getLiteral($token)); } return $this->lexer->moveNext(); } /** * Attempts to match the current lookahead token with any of the given tokens. * * If any of them matches, this method updates the lookahead token; otherwise * a syntax error is raised. * * @param array $tokens * * @return boolean */ private function matchAny(array $tokens) { if ( ! $this->lexer->isNextTokenAny($tokens)) { $this->syntaxError(implode(' or ', array_map(array($this->lexer, 'getLiteral'), $tokens))); } return $this->lexer->moveNext(); } /** * Generates a new syntax error. * * @param string $expected Expected string. * @param array|null $token Optional token. * * @return void * * @throws AnnotationException */ private function syntaxError($expected, $token = null) { if ($token === null) { $token = $this->lexer->lookahead; } $message = sprintf('Expected %s, got ', $expected); $message .= ($this->lexer->lookahead === null) ? 'end of string' : sprintf("'%s' at position %s", $token['value'], $token['position']); if (strlen($this->context)) { $message .= ' in ' . $this->context; } $message .= '.'; throw AnnotationException::syntaxError($message); } /** * Attempts to check if a class exists or not. This never goes through the PHP autoloading mechanism * but uses the {@link AnnotationRegistry} to load classes. * * @param string $fqcn * * @return boolean */ private function classExists($fqcn) { if (isset($this->classExists[$fqcn])) { return $this->classExists[$fqcn]; } // first check if the class already exists, maybe loaded through another AnnotationReader if (class_exists($fqcn, false)) { return $this->classExists[$fqcn] = true; } // final check, does this class exist? return $this->classExists[$fqcn] = AnnotationRegistry::loadAnnotationClass($fqcn); } /** * Collects parsing metadata for a given annotation class * * @param string $name The annotation name * * @return void */ private function collectAnnotationMetadata($name) { if (self::$metadataParser === null) { self::$metadataParser = new self(); self::$metadataParser->setIgnoreNotImportedAnnotations(true); self::$metadataParser->setIgnoredAnnotationNames($this->ignoredAnnotationNames); self::$metadataParser->setImports(array( 'enum' => 'Doctrine\Common\Annotations\Annotation\Enum', 'target' => 'Doctrine\Common\Annotations\Annotation\Target', 'attribute' => 'Doctrine\Common\Annotations\Annotation\Attribute', 'attributes' => 'Doctrine\Common\Annotations\Annotation\Attributes' )); AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Enum.php'); AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Target.php'); AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attribute.php'); AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attributes.php'); } $class = new \ReflectionClass($name); $docComment = $class->getDocComment(); // Sets default values for annotation metadata $metadata = array( 'default_property' => null, 'has_constructor' => (null !== $constructor = $class->getConstructor()) && $constructor->getNumberOfParameters() > 0, 'properties' => array(), 'property_types' => array(), 'attribute_types' => array(), 'targets_literal' => null, 'targets' => Target::TARGET_ALL, 'is_annotation' => false !== strpos($docComment, '@Annotation'), ); // verify that the class is really meant to be an annotation if ($metadata['is_annotation']) { self::$metadataParser->setTarget(Target::TARGET_CLASS); foreach (self::$metadataParser->parse($docComment, 'class @' . $name) as $annotation) { if ($annotation instanceof Target) { $metadata['targets'] = $annotation->targets; $metadata['targets_literal'] = $annotation->literal; continue; } if ($annotation instanceof Attributes) { foreach ($annotation->value as $attribute) { $this->collectAttributeTypeMetadata($metadata, $attribute); } } } // if not has a constructor will inject values into public properties if (false === $metadata['has_constructor']) { // collect all public properties foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $metadata['properties'][$property->name] = $property->name; if (false === ($propertyComment = $property->getDocComment())) { continue; } $attribute = new Attribute(); $attribute->required = (false !== strpos($propertyComment, '@Required')); $attribute->name = $property->name; $attribute->type = (false !== strpos($propertyComment, '@var') && preg_match('/@var\s+([^\s]+)/',$propertyComment, $matches)) ? $matches[1] : 'mixed'; $this->collectAttributeTypeMetadata($metadata, $attribute); // checks if the property has @Enum if (false !== strpos($propertyComment, '@Enum')) { $context = 'property ' . $class->name . "::\$" . $property->name; self::$metadataParser->setTarget(Target::TARGET_PROPERTY); foreach (self::$metadataParser->parse($propertyComment, $context) as $annotation) { if ( ! $annotation instanceof Enum) { continue; } $metadata['enum'][$property->name]['value'] = $annotation->value; $metadata['enum'][$property->name]['literal'] = ( ! empty($annotation->literal)) ? $annotation->literal : $annotation->value; } } } // choose the first property as default property $metadata['default_property'] = reset($metadata['properties']); } } self::$annotationMetadata[$name] = $metadata; } /** * Collects parsing metadata for a given attribute. * * @param array $metadata * @param Attribute $attribute * * @return void */ private function collectAttributeTypeMetadata(&$metadata, Attribute $attribute) { // handle internal type declaration $type = isset(self::$typeMap[$attribute->type]) ? self::$typeMap[$attribute->type] : $attribute->type; // handle the case if the property type is mixed if ('mixed' === $type) { return; } // Evaluate type switch (true) { // Checks if the property has array case (false !== $pos = strpos($type, '<')): $arrayType = substr($type, $pos + 1, -1); $type = 'array'; if (isset(self::$typeMap[$arrayType])) { $arrayType = self::$typeMap[$arrayType]; } $metadata['attribute_types'][$attribute->name]['array_type'] = $arrayType; break; // Checks if the property has type[] case (false !== $pos = strrpos($type, '[')): $arrayType = substr($type, 0, $pos); $type = 'array'; if (isset(self::$typeMap[$arrayType])) { $arrayType = self::$typeMap[$arrayType]; } $metadata['attribute_types'][$attribute->name]['array_type'] = $arrayType; break; } $metadata['attribute_types'][$attribute->name]['type'] = $type; $metadata['attribute_types'][$attribute->name]['value'] = $attribute->type; $metadata['attribute_types'][$attribute->name]['required'] = $attribute->required; } /** * Annotations ::= Annotation {[ "*" ]* [Annotation]}* * * @return array */ private function Annotations() { $annotations = array(); while (null !== $this->lexer->lookahead) { if (DocLexer::T_AT !== $this->lexer->lookahead['type']) { $this->lexer->moveNext(); continue; } // make sure the @ is preceded by non-catchable pattern if (null !== $this->lexer->token && $this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value'])) { $this->lexer->moveNext(); continue; } // make sure the @ is followed by either a namespace separator, or // an identifier token if ((null === $peek = $this->lexer->glimpse()) || (DocLexer::T_NAMESPACE_SEPARATOR !== $peek['type'] && !in_array($peek['type'], self::$classIdentifiers, true)) || $peek['position'] !== $this->lexer->lookahead['position'] + 1) { $this->lexer->moveNext(); continue; } $this->isNestedAnnotation = false; if (false !== $annot = $this->Annotation()) { $annotations[] = $annot; } } return $annotations; } /** * Annotation ::= "@" AnnotationName MethodCall * AnnotationName ::= QualifiedName | SimpleName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * NameSpacePart ::= identifier | null | false | true * SimpleName ::= identifier | null | false | true * * @return mixed False if it is not a valid annotation. * * @throws AnnotationException */ private function Annotation() { $this->match(DocLexer::T_AT); // check if we have an annotation $name = $this->Identifier(); // only process names which are not fully qualified, yet // fully qualified names must start with a \ $originalName = $name; if ('\\' !== $name[0]) { $alias = (false === $pos = strpos($name, '\\'))? $name : substr($name, 0, $pos); $found = false; if ($this->namespaces) { foreach ($this->namespaces as $namespace) { if ($this->classExists($namespace.'\\'.$name)) { $name = $namespace.'\\'.$name; $found = true; break; } } } elseif (isset($this->imports[$loweredAlias = strtolower($alias)])) { $found = true; $name = (false !== $pos) ? $this->imports[$loweredAlias] . substr($name, $pos) : $this->imports[$loweredAlias]; } elseif ( ! isset($this->ignoredAnnotationNames[$name]) && isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'] . '\\' . $name) ) { $name = $this->imports['__NAMESPACE__'].'\\'.$name; $found = true; } elseif (! isset($this->ignoredAnnotationNames[$name]) && $this->classExists($name)) { $found = true; } if ( ! $found) { if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) { return false; } throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported. Did you maybe forget to add a "use" statement for this annotation?', $name, $this->context)); } } if ( ! $this->classExists($name)) { throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context)); } // at this point, $name contains the fully qualified class name of the // annotation, and it is also guaranteed that this class exists, and // that it is loaded // collects the metadata annotation only if there is not yet if ( ! isset(self::$annotationMetadata[$name])) { $this->collectAnnotationMetadata($name); } // verify that the class is really meant to be an annotation and not just any ordinary class if (self::$annotationMetadata[$name]['is_annotation'] === false) { if (isset($this->ignoredAnnotationNames[$originalName])) { return false; } throw AnnotationException::semanticalError(sprintf('The class "%s" 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 "%s". If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s.', $name, $name, $originalName, $this->context)); } //if target is nested annotation $target = $this->isNestedAnnotation ? Target::TARGET_ANNOTATION : $this->target; // Next will be nested $this->isNestedAnnotation = true; //if annotation does not support current target if (0 === (self::$annotationMetadata[$name]['targets'] & $target) && $target) { throw AnnotationException::semanticalError( sprintf('Annotation @%s is not allowed to be declared on %s. You may only use this annotation on these code elements: %s.', $originalName, $this->context, self::$annotationMetadata[$name]['targets_literal']) ); } $values = $this->MethodCall(); if (isset(self::$annotationMetadata[$name]['enum'])) { // checks all declared attributes foreach (self::$annotationMetadata[$name]['enum'] as $property => $enum) { // checks if the attribute is a valid enumerator if (isset($values[$property]) && ! in_array($values[$property], $enum['value'])) { throw AnnotationException::enumeratorError($property, $name, $this->context, $enum['literal'], $values[$property]); } } } // checks all declared attributes foreach (self::$annotationMetadata[$name]['attribute_types'] as $property => $type) { if ($property === self::$annotationMetadata[$name]['default_property'] && !isset($values[$property]) && isset($values['value'])) { $property = 'value'; } // handle a not given attribute or null value if (!isset($values[$property])) { if ($type['required']) { throw AnnotationException::requiredError($property, $originalName, $this->context, 'a(n) '.$type['value']); } continue; } if ($type['type'] === 'array') { // handle the case of a single value if ( ! is_array($values[$property])) { $values[$property] = array($values[$property]); } // checks if the attribute has array type declaration, such as "array" if (isset($type['array_type'])) { foreach ($values[$property] as $item) { if (gettype($item) !== $type['array_type'] && !$item instanceof $type['array_type']) { throw AnnotationException::attributeTypeError($property, $originalName, $this->context, 'either a(n) '.$type['array_type'].', or an array of '.$type['array_type'].'s', $item); } } } } elseif (gettype($values[$property]) !== $type['type'] && !$values[$property] instanceof $type['type']) { throw AnnotationException::attributeTypeError($property, $originalName, $this->context, 'a(n) '.$type['value'], $values[$property]); } } // check if the annotation expects values via the constructor, // or directly injected into public properties if (self::$annotationMetadata[$name]['has_constructor'] === true) { return new $name($values); } $instance = new $name(); foreach ($values as $property => $value) { if (!isset(self::$annotationMetadata[$name]['properties'][$property])) { if ('value' !== $property) { throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not have a property named "%s". Available properties: %s', $originalName, $this->context, $property, implode(', ', self::$annotationMetadata[$name]['properties']))); } // handle the case if the property has no annotations if ( ! $property = self::$annotationMetadata[$name]['default_property']) { throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not accept any values, but got %s.', $originalName, $this->context, json_encode($values))); } } $instance->{$property} = $value; } return $instance; } /** * MethodCall ::= ["(" [Values] ")"] * * @return array */ private function MethodCall() { $values = array(); if ( ! $this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { return $values; } $this->match(DocLexer::T_OPEN_PARENTHESIS); if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(DocLexer::T_CLOSE_PARENTHESIS); return $values; } /** * Values ::= Array | Value {"," Value}* [","] * * @return array */ private function Values() { $values = array($this->Value()); while ($this->lexer->isNextToken(DocLexer::T_COMMA)) { $this->match(DocLexer::T_COMMA); if ($this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { break; } $token = $this->lexer->lookahead; $value = $this->Value(); if ( ! is_object($value) && ! is_array($value)) { $this->syntaxError('Value', $token); } $values[] = $value; } foreach ($values as $k => $value) { if (is_object($value) && $value instanceof \stdClass) { $values[$value->name] = $value->value; } else if ( ! isset($values['value'])){ $values['value'] = $value; } else { if ( ! is_array($values['value'])) { $values['value'] = array($values['value']); } $values['value'][] = $value; } unset($values[$k]); } return $values; } /** * Constant ::= integer | string | float | boolean * * @return mixed * * @throws AnnotationException */ private function Constant() { $identifier = $this->Identifier(); if ( ! defined($identifier) && false !== strpos($identifier, '::') && '\\' !== $identifier[0]) { list($className, $const) = explode('::', $identifier); $alias = (false === $pos = strpos($className, '\\')) ? $className : substr($className, 0, $pos); $found = false; switch (true) { case !empty ($this->namespaces): foreach ($this->namespaces as $ns) { if (class_exists($ns.'\\'.$className) || interface_exists($ns.'\\'.$className)) { $className = $ns.'\\'.$className; $found = true; break; } } break; case isset($this->imports[$loweredAlias = strtolower($alias)]): $found = true; $className = (false !== $pos) ? $this->imports[$loweredAlias] . substr($className, $pos) : $this->imports[$loweredAlias]; break; default: if(isset($this->imports['__NAMESPACE__'])) { $ns = $this->imports['__NAMESPACE__']; if (class_exists($ns.'\\'.$className) || interface_exists($ns.'\\'.$className)) { $className = $ns.'\\'.$className; $found = true; } } break; } if ($found) { $identifier = $className . '::' . $const; } } // checks if identifier ends with ::class, \strlen('::class') === 7 $classPos = stripos($identifier, '::class'); if ($classPos === strlen($identifier) - 7) { return substr($identifier, 0, $classPos); } if (!defined($identifier)) { throw AnnotationException::semanticalErrorConstants($identifier, $this->context); } return constant($identifier); } /** * Identifier ::= string * * @return string */ private function Identifier() { // check if we have an annotation if ( ! $this->lexer->isNextTokenAny(self::$classIdentifiers)) { $this->syntaxError('namespace separator or identifier'); } $this->lexer->moveNext(); $className = $this->lexer->token['value']; while ($this->lexer->lookahead['position'] === ($this->lexer->token['position'] + strlen($this->lexer->token['value'])) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $this->match(DocLexer::T_NAMESPACE_SEPARATOR); $this->matchAny(self::$classIdentifiers); $className .= '\\' . $this->lexer->token['value']; } return $className; } /** * Value ::= PlainValue | FieldAssignment * * @return mixed */ private function Value() { $peek = $this->lexer->glimpse(); if (DocLexer::T_EQUALS === $peek['type']) { return $this->FieldAssignment(); } return $this->PlainValue(); } /** * PlainValue ::= integer | string | float | boolean | Array | Annotation * * @return mixed */ private function PlainValue() { if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) { return $this->Arrayx(); } if ($this->lexer->isNextToken(DocLexer::T_AT)) { return $this->Annotation(); } if ($this->lexer->isNextToken(DocLexer::T_IDENTIFIER)) { return $this->Constant(); } switch ($this->lexer->lookahead['type']) { case DocLexer::T_STRING: $this->match(DocLexer::T_STRING); return $this->lexer->token['value']; case DocLexer::T_INTEGER: $this->match(DocLexer::T_INTEGER); return (int)$this->lexer->token['value']; case DocLexer::T_FLOAT: $this->match(DocLexer::T_FLOAT); return (float)$this->lexer->token['value']; case DocLexer::T_TRUE: $this->match(DocLexer::T_TRUE); return true; case DocLexer::T_FALSE: $this->match(DocLexer::T_FALSE); return false; case DocLexer::T_NULL: $this->match(DocLexer::T_NULL); return null; default: $this->syntaxError('PlainValue'); } } /** * FieldAssignment ::= FieldName "=" PlainValue * FieldName ::= identifier * * @return array */ private function FieldAssignment() { $this->match(DocLexer::T_IDENTIFIER); $fieldName = $this->lexer->token['value']; $this->match(DocLexer::T_EQUALS); $item = new \stdClass(); $item->name = $fieldName; $item->value = $this->PlainValue(); return $item; } /** * Array ::= "{" ArrayEntry {"," ArrayEntry}* [","] "}" * * @return array */ private function Arrayx() { $array = $values = array(); $this->match(DocLexer::T_OPEN_CURLY_BRACES); // If the array is empty, stop parsing and return. if ($this->lexer->isNextToken(DocLexer::T_CLOSE_CURLY_BRACES)) { $this->match(DocLexer::T_CLOSE_CURLY_BRACES); return $array; } $values[] = $this->ArrayEntry(); while ($this->lexer->isNextToken(DocLexer::T_COMMA)) { $this->match(DocLexer::T_COMMA); // optional trailing comma if ($this->lexer->isNextToken(DocLexer::T_CLOSE_CURLY_BRACES)) { break; } $values[] = $this->ArrayEntry(); } $this->match(DocLexer::T_CLOSE_CURLY_BRACES); foreach ($values as $value) { list ($key, $val) = $value; if ($key !== null) { $array[$key] = $val; } else { $array[] = $val; } } return $array; } /** * ArrayEntry ::= Value | KeyValuePair * KeyValuePair ::= Key ("=" | ":") PlainValue | Constant * Key ::= string | integer | Constant * * @return array */ private function ArrayEntry() { $peek = $this->lexer->glimpse(); if (DocLexer::T_EQUALS === $peek['type'] || DocLexer::T_COLON === $peek['type']) { if ($this->lexer->isNextToken(DocLexer::T_IDENTIFIER)) { $key = $this->Constant(); } else { $this->matchAny(array(DocLexer::T_INTEGER, DocLexer::T_STRING)); $key = $this->lexer->token['value']; } $this->matchAny(array(DocLexer::T_EQUALS, DocLexer::T_COLON)); return array($key, $this->PlainValue()); } return array(null, $this->Value()); } } lib/Doctrine/Common/Annotations/FileCacheReader.php000064400000017000144760114530016250 0ustar00. */ namespace Doctrine\Common\Annotations; /** * File cache reader for annotations. * * @author Johannes M. Schmitt * @author Benjamin Eberlei */ class FileCacheReader implements Reader { /** * @var Reader */ private $reader; /** * @var string */ private $dir; /** * @var bool */ private $debug; /** * @var array */ private $loadedAnnotations = array(); /** * @var array */ private $classNameHashes = array(); /** * Constructor. * * @param Reader $reader * @param string $cacheDir * @param boolean $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)); } $this->dir = rtrim($cacheDir, '\\/'); $this->debug = $debug; } /** * {@inheritDoc} */ 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; } /** * {@inheritDoc} */ 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; } /** * {@inheritDoc} */ 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; } /** * Saves the cache file. * * @param string $path * @param mixed $data * * @return void */ private function saveCacheFile($path, $data) { if (!is_writable($this->dir)) { 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.', $this->dir)); } file_put_contents($path, 'getClassAnnotations($class); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } /** * {@inheritDoc} */ public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) { $annotations = $this->getMethodAnnotations($method); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } /** * {@inheritDoc} */ public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) { $annotations = $this->getPropertyAnnotations($property); foreach ($annotations as $annotation) { if ($annotation instanceof $annotationName) { return $annotation; } } return null; } /** * Clears loaded annotations. * * @return void */ public function clearLoadedAnnotations() { $this->loadedAnnotations = array(); } } lib/Doctrine/Common/Annotations/IndexedReader.php000064400000006341144760114530016033 0ustar00. */ namespace Doctrine\Common\Annotations; /** * Allows the reader to be used in-place of Doctrine's reader. * * @author Johannes M. Schmitt */ class IndexedReader implements Reader { /** * @var Reader */ private $delegate; /** * Constructor. * * @param Reader $reader */ public function __construct(Reader $reader) { $this->delegate = $reader; } /** * {@inheritDoc} */ public function getClassAnnotations(\ReflectionClass $class) { $annotations = array(); foreach ($this->delegate->getClassAnnotations($class) as $annot) { $annotations[get_class($annot)] = $annot; } return $annotations; } /** * {@inheritDoc} */ public function getClassAnnotation(\ReflectionClass $class, $annotation) { return $this->delegate->getClassAnnotation($class, $annotation); } /** * {@inheritDoc} */ public function getMethodAnnotations(\ReflectionMethod $method) { $annotations = array(); foreach ($this->delegate->getMethodAnnotations($method) as $annot) { $annotations[get_class($annot)] = $annot; } return $annotations; } /** * {@inheritDoc} */ public function getMethodAnnotation(\ReflectionMethod $method, $annotation) { return $this->delegate->getMethodAnnotation($method, $annotation); } /** * {@inheritDoc} */ public function getPropertyAnnotations(\ReflectionProperty $property) { $annotations = array(); foreach ($this->delegate->getPropertyAnnotations($property) as $annot) { $annotations[get_class($annot)] = $annot; } return $annotations; } /** * {@inheritDoc} */ public function getPropertyAnnotation(\ReflectionProperty $property, $annotation) { return $this->delegate->getPropertyAnnotation($property, $annotation); } /** * Proxies 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); } } lib/Doctrine/Common/Annotations/PhpParser.php000064400000005564144760114530015242 0ustar00. */ namespace Doctrine\Common\Annotations; use SplFileObject; /** * Parses a file for namespaces/use/class declarations. * * @author Fabien Potencier * @author Christian Kaps */ final class PhpParser { /** * Parses a class. * * @param \ReflectionClass $class A ReflectionClass 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('parseUseStatements($class->getNamespaceName()); return $statements; } /** * Gets the content of the file right up to the given line number. * * @param string $filename The name of the file to load. * @param integer $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; } } lib/Doctrine/Common/Annotations/Reader.php000064400000006707144760114530014540 0ustar00. */ namespace Doctrine\Common\Annotations; /** * Interface for annotation readers. * * @author Johannes M. Schmitt */ interface Reader { /** * 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. */ function getClassAnnotations(\ReflectionClass $class); /** * 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 object|null The Annotation or NULL, if the requested annotation does not exist. */ function getClassAnnotation(\ReflectionClass $class, $annotationName); /** * 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. */ function getMethodAnnotations(\ReflectionMethod $method); /** * Gets a method annotation. * * @param \ReflectionMethod $method The ReflectionMethod to read the annotations from. * @param string $annotationName The name of the annotation. * * @return object|null The Annotation or NULL, if the requested annotation does not exist. */ function getMethodAnnotation(\ReflectionMethod $method, $annotationName); /** * 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. */ function getPropertyAnnotations(\ReflectionProperty $property); /** * Gets a property annotation. * * @param \ReflectionProperty $property The ReflectionProperty to read the annotations from. * @param string $annotationName The name of the annotation. * * @return object|null The Annotation or NULL, if the requested annotation does not exist. */ function getPropertyAnnotation(\ReflectionProperty $property, $annotationName); } lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php000064400000007111144760114530017733 0ustar00. */ namespace Doctrine\Common\Annotations; /** * 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 * @author Fabio B. Silva */ 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 * * @return void */ public function addNamespace($namespace) { $this->parser->addNamespace($namespace); } /** * {@inheritDoc} */ public function getClassAnnotations(\ReflectionClass $class) { return $this->parser->parse($class->getDocComment(), 'class '.$class->getName()); } /** * {@inheritDoc} */ public function getMethodAnnotations(\ReflectionMethod $method) { return $this->parser->parse($method->getDocComment(), 'method '.$method->getDeclaringClass()->name.'::'.$method->getName().'()'); } /** * {@inheritDoc} */ public function getPropertyAnnotations(\ReflectionProperty $property) { return $this->parser->parse($property->getDocComment(), 'property '.$property->getDeclaringClass()->name.'::$'.$property->getName()); } /** * {@inheritDoc} */ public function getClassAnnotation(\ReflectionClass $class, $annotationName) { foreach ($this->getClassAnnotations($class) as $annot) { if ($annot instanceof $annotationName) { return $annot; } } return null; } /** * {@inheritDoc} */ public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) { foreach ($this->getMethodAnnotations($method) as $annot) { if ($annot instanceof $annotationName) { return $annot; } } return null; } /** * {@inheritDoc} */ public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) { foreach ($this->getPropertyAnnotations($property) as $annot) { if ($annot instanceof $annotationName) { return $annot; } } return null; } } lib/Doctrine/Common/Annotations/TokenParser.php000064400000013747144760114530015575 0ustar00. */ namespace Doctrine\Common\Annotations; /** * Parses a file for namespaces/use/class declarations. * * @author Fabien Potencier * @author Christian Kaps */ class TokenParser { /** * The token list. * * @var array */ private $tokens; /** * The number of tokens. * * @var int */ private $numTokens; /** * The current array pointer. * * @var int */ private $pointer = 0; /** * @param string $contents */ public function __construct($contents) { $this->tokens = token_get_all($contents); // The PHP parser sets internal compiler globals for certain things. Annoyingly, the last docblock comment it // saw gets stored in doc_comment. When it comes to compile the next thing to be include()d this stored // doc_comment becomes owned by the first thing the compiler sees in the file that it considers might have a // docblock. If the first thing in the file is a class without a doc block this would cause calls to // getDocBlock() on said class to return our long lost doc_comment. Argh. // To workaround, cause the parser to parse an empty docblock. Sure getDocBlock() will return this, but at least // it's harmless to us. token_get_all("numTokens = count($this->tokens); } /** * Gets the next non whitespace and non comment token. * * @param boolean $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|null 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; } /** * Parses 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; } /** * Gets 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; } /** * Gets 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; } /** * Gets the class name. * * @return string The found class 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(); } } phpunit.xml.dist000064400000001467144760114530007734 0ustar00 ./tests/Doctrine/ ./lib/Doctrine/ performance tests/Doctrine/Tests/Common/Annotations/AbstractReaderTest.php000064400000064601144760114530020557 0ustar00getReflectionClass(); $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); } public function testAtInDescription() { $reader = $this->getReader(); $class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAtInDescriptionAndAnnotation'); $this->assertEquals(1, count($fooAnnot = $reader->getPropertyAnnotations($class->getProperty('foo')))); $this->assertEquals(1, count($barAnnot = $reader->getPropertyAnnotations($class->getProperty('bar')))); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetPropertyMethod', $fooAnnot[0]); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetPropertyMethod', $barAnnot[0]); } public function testClassWithWithDanglingComma() { $reader = $this->getReader(); $annots = $reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\DummyClassWithDanglingComma')); $this->assertCount(1, $annots); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @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 testIncludeIgnoreAnnotation() { $reader = $this->getReader(); $reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithIgnoreAnnotation', 'foo')); $this->assertFalse(class_exists('Doctrine\Tests\Common\Annotations\Fixtures\IgnoreAnnotationClass', false)); } 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); } private static $testResetsPhpParserAfterUseRun = false; /** * When getUseStatements isn't available on ReflectionClass the PhpParser has to use token_get_all(). If that * happens various PHP compiler globals get set, and these can have seriously bad effects on the next file to be * parsed. * Notably the doc_comment compiler global can end up containing a docblock comment. The next file to be parsed * on an include() will have this docblock comment attached to the first thing in the file that the compiler * considers to own comments. If this is a class then any later calls to getDocComment() for that class will have * undesirable effects. *sigh* */ public function testResetsPhpParserAfterUse() { // If someone has already included our main test fixture this test is invalid. It's important that our require // causes this file to be parsed and compiled at a certain point. $this->assertFalse(!self::$testResetsPhpParserAfterUseRun && class_exists('Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment'), 'Test invalid if class has already been compiled'); self::$testResetsPhpParserAfterUseRun = true; $reader = $this->getReader(); // First make sure the annotation cache knows about the annotations we want to use. // If we don't do this then loading of annotations into the cache will cause the parser to get out of the bad // state we want to test. $class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithValidAnnotationTarget'); $reader->getClassAnnotations($class); // Now import an incredibly dull class which makes use of the same class level annotation that the previous class does. $class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithClassAnnotationOnly'); $annotations = $reader->getClassAnnotations($class); // This include needs to be here since we need the PHP compiler to run over it as the next thing the PHP // parser sees since PhpParser called token_get_all() on the intro to ClassWithClassAnnotationOnly. // Our test class cannot be in a namespace (some versions of PHP reset the doc_comment compiler global when // you hit a namespace declaration), so cannot be autoloaded. require_once __DIR__ . '/Fixtures/ClassNoNamespaceNoComment.php'; // So, hopefully, if all has gone OK, our class with class annotations should actually have them. // If this fails then something is quite badly wrong elsewhere. // Note that if this happens before the require it can cause other PHP files to be included, resetting the // compiler global state, and invalidating this test case. $this->assertNotEmpty($annotations); $annotations = $reader->getClassAnnotations(new \ReflectionClass(new \Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment())); // And if our workaround for this bug is OK, our class with no doc comment should not have any class annotations. $this->assertEmpty($annotations); } /** * @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 * */ class TestParseAnnotationClass { /** * @var */ private $field; } /** * @Name * @author Johannes M. Schmitt */ 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 Annotation {} /** @Annotation */ class DummyColumn extends Annotation { public $type; } /** @Annotation */ class DummyGeneratedValue extends Annotation {} /** @Annotation */ class DummyAnnotation extends Annotation { public $dummyValue; } /** * @api * @Annotation */ class DummyAnnotationWithIgnoredAnnotation extends Annotation { public $dummyValue; } /** @Annotation */ class DummyJoinColumn extends Annotation { public $name; public $referencedColumnName; } /** @Annotation */ class DummyJoinTable extends Annotation { public $name; public $joinColumns; public $inverseJoinColumns; } /** * @DummyAnnotation(dummyValue = "bar",) */ class DummyClassWithDanglingComma { } /** * @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 */ 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; } tests/Doctrine/Tests/Common/Annotations/Annotation/TargetTest.php000064400000003567144760114530021235 0ustar00. */ namespace Doctrine\Tests\Common\Annotations\Annotation; use Doctrine\Common\Annotations\Annotation\Target; /** * Tests for {@see \Doctrine\Common\Annotations\Annotation\Target} * * @covers \Doctrine\Common\Annotations\Annotation\Target */ class TargetTest extends \PHPUnit_Framework_TestCase { /** * @group DDC-3006 */ public function testValidMixedTargets() { $target = new Target(array("value" => array("ALL"))); $this->assertEquals(Target::TARGET_ALL, $target->targets); $target = new Target(array("value" => array("METHOD", "METHOD"))); $this->assertEquals(Target::TARGET_METHOD, $target->targets); $this->assertNotEquals(Target::TARGET_PROPERTY, $target->targets); $target = new Target(array("value" => array("PROPERTY", "METHOD"))); $this->assertEquals(Target::TARGET_METHOD | Target::TARGET_PROPERTY, $target->targets); } } tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php000064400000004253144760114530021123 0ustar00markTestSkipped('This test requires PHP 5.4 or later.'); } $reader = $this->getReader(); $ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassUsesTrait'); $annotations = $reader->getMethodAnnotations($ref->getMethod('someMethod')); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Bar\Autoload', $annotations[0]); $annotations = $reader->getMethodAnnotations($ref->getMethod('traitMethod')); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Autoload', $annotations[0]); } public function testMethodAnnotationFromOverwrittenTrait() { if (PHP_VERSION_ID < 50400) { $this->markTestSkipped('This test requires PHP 5.4 or later.'); } $reader = $this->getReader(); $ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassOverwritesTrait'); $annotations = $reader->getMethodAnnotations($ref->getMethod('traitMethod')); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Bar2\Autoload', $annotations[0]); } public function testPropertyAnnotationFromTrait() { if (PHP_VERSION_ID < 50400) { $this->markTestSkipped('This test requires PHP 5.4 or later.'); } $reader = $this->getReader(); $ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassUsesTrait'); $annotations = $reader->getPropertyAnnotations($ref->getProperty('aProperty')); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Bar\Autoload', $annotations[0]); $annotations = $reader->getPropertyAnnotations($ref->getProperty('traitProperty')); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Autoload', $annotations[0]); } }tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php000064400000003244144760114530020157 0ustar00getMock('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); } }tests/Doctrine/Tests/Common/Annotations/DocLexerTest.php000064400000011777144760114530017404 0ustar00setInput("@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, ClassWithConstants::CONSTANT_, ClassWithConstants::CONST_ANT3, \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' => 'ClassWithConstants::CONSTANT_', 'position' => 66, 'type' => DocLexer::T_IDENTIFIER, ), array( 'value' => ',', 'position' => 95, 'type' => DocLexer::T_COMMA, ), array( 'value' => 'ClassWithConstants::CONST_ANT3', 'position' => 97, 'type' => DocLexer::T_IDENTIFIER, ), array( 'value' => ',', 'position' => 127, 'type' => DocLexer::T_COMMA, ), array( 'value' => '\\Doctrine\\Tests\\Common\\Annotations\\Fixtures\\IntefaceWithConstants::SOME_VALUE', 'position' => 129, 'type' => DocLexer::T_IDENTIFIER, ), array( 'value' => ')', 'position' => 206, '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()); } }tests/Doctrine/Tests/Common/Annotations/DocParserTest.php000064400000142411144760114530017547 0ustar00createTestParser(); // Nested arrays with nested annotations $result = $parser->parse('@Name(foo={1,2, {"key"=@Name}})'); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertNull($annot->value); $this->assertEquals(3, count($annot->foo)); $this->assertEquals(1, $annot->foo[0]); $this->assertEquals(2, $annot->foo[1]); $this->assertTrue(is_array($annot->foo[2])); $nestedArray = $annot->foo[2]; $this->assertTrue(isset($nestedArray['key'])); $this->assertTrue($nestedArray['key'] instanceof Name); } public function testBasicAnnotations() { $parser = $this->createTestParser(); // Marker annotation $result = $parser->parse("@Name"); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertNull($annot->value); $this->assertNull($annot->foo); // Associative arrays $result = $parser->parse('@Name(foo={"key1" = "value1"})'); $annot = $result[0]; $this->assertNull($annot->value); $this->assertTrue(is_array($annot->foo)); $this->assertTrue(isset($annot->foo['key1'])); // Numerical arrays $result = $parser->parse('@Name({2="foo", 4="bar"})'); $annot = $result[0]; $this->assertTrue(is_array($annot->value)); $this->assertEquals('foo', $annot->value[2]); $this->assertEquals('bar', $annot->value[4]); $this->assertFalse(isset($annot->value[0])); $this->assertFalse(isset($annot->value[1])); $this->assertFalse(isset($annot->value[3])); // Multiple values $result = $parser->parse('@Name(@Name, @Name)'); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertTrue(is_array($annot->value)); $this->assertTrue($annot->value[0] instanceof Name); $this->assertTrue($annot->value[1] instanceof Name); // Multiple types as values $result = $parser->parse('@Name(foo="Bar", @Name, {"key1"="value1", "key2"="value2"})'); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertTrue(is_array($annot->value)); $this->assertTrue($annot->value[0] instanceof Name); $this->assertTrue(is_array($annot->value[1])); $this->assertEquals('value1', $annot->value[1]['key1']); $this->assertEquals('value2', $annot->value[1]['key2']); // Complete docblock $docblock = <<parse($docblock); $this->assertEquals(1, count($result)); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertEquals("bar", $annot->foo); $this->assertNull($annot->value); } public function testDefaultValueAnnotations() { $parser = $this->createTestParser(); // Array as first value $result = $parser->parse('@Name({"key1"="value1"})'); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertTrue(is_array($annot->value)); $this->assertEquals('value1', $annot->value['key1']); // Array as first value and additional values $result = $parser->parse('@Name({"key1"="value1"}, foo="bar")'); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertTrue(is_array($annot->value)); $this->assertEquals('value1', $annot->value['key1']); $this->assertEquals('bar', $annot->foo); } public function testNamespacedAnnotations() { $parser = new DocParser; $parser->setIgnoreNotImportedAnnotations(true); $docblock = << * @Doctrine\Tests\Common\Annotations\Name(foo="bar") * @ignore */ DOCBLOCK; $result = $parser->parse($docblock); $this->assertEquals(1, count($result)); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertEquals("bar", $annot->foo); } /** * @group debug */ public function testTypicalMethodDocBlock() { $parser = $this->createTestParser(); $docblock = <<parse($docblock); $this->assertEquals(2, count($result)); $this->assertTrue(isset($result[0])); $this->assertTrue(isset($result[1])); $annot = $result[0]; $this->assertTrue($annot instanceof Name); $this->assertEquals("bar", $annot->foo); $marker = $result[1]; $this->assertTrue($marker instanceof Marker); } public function testAnnotationWithoutConstructor() { $parser = $this->createTestParser(); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $annot = $result[0]; $this->assertNotNull($annot); $this->assertTrue($annot instanceof SomeAnnotationClassNameWithoutConstructor); $this->assertNull($annot->name); $this->assertNotNull($annot->data); $this->assertEquals($annot->data, "Some data"); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $annot = $result[0]; $this->assertNotNull($annot); $this->assertTrue($annot instanceof SomeAnnotationClassNameWithoutConstructor); $this->assertEquals($annot->name, "Some Name"); $this->assertEquals($annot->data, "Some data"); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $annot = $result[0]; $this->assertEquals($annot->data, "Some data"); $this->assertNull($annot->name); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $annot = $result[0]; $this->assertEquals($annot->name, "Some name"); $this->assertNull($annot->data); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $annot = $result[0]; $this->assertEquals($annot->data, "Some data"); $this->assertNull($annot->name); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $annot = $result[0]; $this->assertEquals($annot->name, "Some name"); $this->assertEquals($annot->data, "Some data"); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $annot = $result[0]; $this->assertEquals($annot->name, "Some name"); $this->assertEquals($annot->data, "Some data"); $docblock = <<parse($docblock); $this->assertEquals(count($result), 1); $this->assertTrue($result[0] instanceof SomeAnnotationClassNameWithoutConstructorAndProperties); } public function testAnnotationTarget() { $parser = new DocParser; $parser->setImports(array( '__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations\Fixtures', )); $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithValidAnnotationTarget'); $context = 'class ' . $class->getName(); $docComment = $class->getDocComment(); $parser->setTarget(Target::TARGET_CLASS); $this->assertNotNull($parser->parse($docComment,$context)); $property = $class->getProperty('foo'); $docComment = $property->getDocComment(); $context = 'property ' . $class->getName() . "::\$" . $property->getName(); $parser->setTarget(Target::TARGET_PROPERTY); $this->assertNotNull($parser->parse($docComment,$context)); $method = $class->getMethod('someFunction'); $docComment = $property->getDocComment(); $context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; $parser->setTarget(Target::TARGET_METHOD); $this->assertNotNull($parser->parse($docComment,$context)); try { $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtClass'); $context = 'class ' . $class->getName(); $docComment = $class->getDocComment(); $parser->setTarget(Target::TARGET_CLASS); $parser->parse($docComment, $context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertNotNull($exc->getMessage()); } try { $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtMethod'); $method = $class->getMethod('functionName'); $docComment = $method->getDocComment(); $context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; $parser->setTarget(Target::TARGET_METHOD); $parser->parse($docComment, $context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertNotNull($exc->getMessage()); } try { $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty'); $property = $class->getProperty('foo'); $docComment = $property->getDocComment(); $context = 'property ' . $class->getName() . "::\$" . $property->getName(); $parser->setTarget(Target::TARGET_PROPERTY); $parser->parse($docComment, $context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertNotNull($exc->getMessage()); } } public function getAnnotationVarTypeProviderValid() { //({attribute name}, {attribute value}) return array( // mixed type array('mixed', '"String Value"'), array('mixed', 'true'), array('mixed', 'false'), array('mixed', '1'), array('mixed', '1.2'), array('mixed', '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll'), // boolean type array('boolean', 'true'), array('boolean', 'false'), // alias for internal type boolean array('bool', 'true'), array('bool', 'false'), // integer type array('integer', '0'), array('integer', '1'), array('integer', '123456789'), array('integer', '9223372036854775807'), // alias for internal type double array('float', '0.1'), array('float', '1.2'), array('float', '123.456'), // string type array('string', '"String Value"'), array('string', '"true"'), array('string', '"123"'), // array type array('array', '{@AnnotationExtendsAnnotationTargetAll}'), array('array', '{@AnnotationExtendsAnnotationTargetAll,@AnnotationExtendsAnnotationTargetAll}'), array('arrayOfIntegers', '1'), array('arrayOfIntegers', '{1}'), array('arrayOfIntegers', '{1,2,3,4}'), array('arrayOfAnnotations', '@AnnotationExtendsAnnotationTargetAll'), array('arrayOfAnnotations', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll}'), array('arrayOfAnnotations', '{@AnnotationExtendsAnnotationTargetAll, @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll}'), // annotation instance array('annotation', '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll'), array('annotation', '@AnnotationExtendsAnnotationTargetAll'), ); } public function getAnnotationVarTypeProviderInvalid() { //({attribute name}, {type declared type}, {attribute value} , {given type or class}) return array( // boolean type array('boolean','boolean','1','integer'), array('boolean','boolean','1.2','double'), array('boolean','boolean','"str"','string'), array('boolean','boolean','{1,2,3}','array'), array('boolean','boolean','@Name', 'an instance of Doctrine\Tests\Common\Annotations\Name'), // alias for internal type boolean array('bool','bool', '1','integer'), array('bool','bool', '1.2','double'), array('bool','bool', '"str"','string'), array('bool','bool', '{"str"}','array'), // integer type array('integer','integer', 'true','boolean'), array('integer','integer', 'false','boolean'), array('integer','integer', '1.2','double'), array('integer','integer', '"str"','string'), array('integer','integer', '{"str"}','array'), array('integer','integer', '{1,2,3,4}','array'), // alias for internal type double array('float','float', 'true','boolean'), array('float','float', 'false','boolean'), array('float','float', '123','integer'), array('float','float', '"str"','string'), array('float','float', '{"str"}','array'), array('float','float', '{12.34}','array'), array('float','float', '{1,2,3}','array'), // string type array('string','string', 'true','boolean'), array('string','string', 'false','boolean'), array('string','string', '12','integer'), array('string','string', '1.2','double'), array('string','string', '{"str"}','array'), array('string','string', '{1,2,3,4}','array'), // annotation instance array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'true','boolean'), array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'false','boolean'), array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '12','integer'), array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '1.2','double'), array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{"str"}','array'), array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{1,2,3,4}','array'), array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '@Name','an instance of Doctrine\Tests\Common\Annotations\Name'), ); } public function getAnnotationVarTypeArrayProviderInvalid() { //({attribute name}, {type declared type}, {attribute value} , {given type or class}) return array( array('arrayOfIntegers', 'integer', 'true', 'boolean'), array('arrayOfIntegers', 'integer', 'false', 'boolean'), array('arrayOfIntegers', 'integer', '{true,true}', 'boolean'), array('arrayOfIntegers', 'integer', '{1,true}', 'boolean'), array('arrayOfIntegers', 'integer', '{1,2,1.2}', 'double'), array('arrayOfIntegers', 'integer', '{1,2,"str"}', 'string'), array('arrayOfStrings', 'string', 'true', 'boolean'), array('arrayOfStrings', 'string', 'false', 'boolean'), array('arrayOfStrings', 'string', '{true,true}', 'boolean'), array('arrayOfStrings', 'string', '{"foo",true}', 'boolean'), array('arrayOfStrings', 'string', '{"foo","bar",1.2}', 'double'), array('arrayOfStrings', 'string', '1', 'integer'), array('arrayOfAnnotations', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'true', 'boolean'), array('arrayOfAnnotations', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'false', 'boolean'), array('arrayOfAnnotations', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,true}', 'boolean'), array('arrayOfAnnotations', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,true}', 'boolean'), array('arrayOfAnnotations', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,1.2}', 'double'), array('arrayOfAnnotations', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,@AnnotationExtendsAnnotationTargetAll,"str"}', 'string'), ); } /** * @dataProvider getAnnotationVarTypeProviderValid */ public function testAnnotationWithVarType($attribute, $value) { $parser = $this->createTestParser(); $context = 'property SomeClassName::$invalidProperty.'; $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value); $parser->setTarget(Target::TARGET_PROPERTY); $result = $parser->parse($docblock, $context); $this->assertTrue(sizeof($result) === 1); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType', $result[0]); $this->assertNotNull($result[0]->$attribute); } /** * @dataProvider getAnnotationVarTypeProviderInvalid */ public function testAnnotationWithVarTypeError($attribute,$type,$value,$given) { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value); $parser->setTarget(Target::TARGET_PROPERTY); try { $parser->parse($docblock, $context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects a(n) $type, but got $given.", $exc->getMessage()); } } /** * @dataProvider getAnnotationVarTypeArrayProviderInvalid */ public function testAnnotationWithVarTypeArrayError($attribute,$type,$value,$given) { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value); $parser->setTarget(Target::TARGET_PROPERTY); try { $parser->parse($docblock, $context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects either a(n) $type, or an array of {$type}s, but got $given.", $exc->getMessage()); } } /** * @dataProvider getAnnotationVarTypeProviderValid */ public function testAnnotationWithAttributes($attribute, $value) { $parser = $this->createTestParser(); $context = 'property SomeClassName::$invalidProperty.'; $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value); $parser->setTarget(Target::TARGET_PROPERTY); $result = $parser->parse($docblock, $context); $this->assertTrue(sizeof($result) === 1); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes', $result[0]); $getter = "get".ucfirst($attribute); $this->assertNotNull($result[0]->$getter()); } /** * @dataProvider getAnnotationVarTypeProviderInvalid */ public function testAnnotationWithAttributesError($attribute,$type,$value,$given) { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value); $parser->setTarget(Target::TARGET_PROPERTY); try { $parser->parse($docblock, $context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes declared on property SomeClassName::invalidProperty. expects a(n) $type, but got $given.", $exc->getMessage()); } } /** * @dataProvider getAnnotationVarTypeArrayProviderInvalid */ public function testAnnotationWithAttributesWithVarTypeArrayError($attribute,$type,$value,$given) { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value); $parser->setTarget(Target::TARGET_PROPERTY); try { $parser->parse($docblock, $context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes declared on property SomeClassName::invalidProperty. expects either a(n) $type, or an array of {$type}s, but got $given.", $exc->getMessage()); } } public function testAnnotationWithRequiredAttributes() { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $parser->setTarget(Target::TARGET_PROPERTY); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes("Some Value", annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)'; $result = $parser->parse($docblock); $this->assertTrue(sizeof($result) === 1); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes', $result[0]); $this->assertEquals("Some Value",$result[0]->getValue()); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation', $result[0]->getAnnot()); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes("Some Value")'; try { $result = $parser->parse($docblock,$context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains('Attribute "annot" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes declared on property SomeClassName::invalidProperty. expects a(n) Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation. This value should not be null.', $exc->getMessage()); } $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes(annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)'; try { $result = $parser->parse($docblock,$context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains('Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes declared on property SomeClassName::invalidProperty. expects a(n) string. This value should not be null.', $exc->getMessage()); } } public function testAnnotationWithRequiredAttributesWithoutContructor() { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $parser->setTarget(Target::TARGET_PROPERTY); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor("Some Value", annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)'; $result = $parser->parse($docblock); $this->assertTrue(sizeof($result) === 1); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor', $result[0]); $this->assertEquals("Some Value", $result[0]->value); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation', $result[0]->annot); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor("Some Value")'; try { $result = $parser->parse($docblock,$context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains('Attribute "annot" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor declared on property SomeClassName::invalidProperty. expects a(n) Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation. This value should not be null.', $exc->getMessage()); } $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor(annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)'; try { $result = $parser->parse($docblock,$context); $this->fail(); } catch (\Doctrine\Common\Annotations\AnnotationException $exc) { $this->assertContains('Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor declared on property SomeClassName::invalidProperty. expects a(n) string. This value should not be null.', $exc->getMessage()); } } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum declared on property SomeClassName::invalidProperty. accept only [ONE, TWO, THREE], but got FOUR. */ public function testAnnotationEnumeratorException() { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum("FOUR")'; $parser->setIgnoreNotImportedAnnotations(false); $parser->setTarget(Target::TARGET_PROPERTY); $parser->parse($docblock, $context); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnumLiteral declared on property SomeClassName::invalidProperty. accept only [AnnotationEnumLiteral::ONE, AnnotationEnumLiteral::TWO, AnnotationEnumLiteral::THREE], but got 4. */ public function testAnnotationEnumeratorLiteralException() { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnumLiteral(4)'; $parser->setIgnoreNotImportedAnnotations(false); $parser->setTarget(Target::TARGET_PROPERTY); $parser->parse($docblock, $context); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage @Enum supports only scalar values "array" given. */ public function testAnnotationEnumInvalidTypeDeclarationException() { $parser = $this->createTestParser(); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnumInvalid("foo")'; $parser->setIgnoreNotImportedAnnotations(false); $parser->parse($docblock); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Undefined enumerator value "3" for literal "AnnotationEnumLiteral::THREE". */ public function testAnnotationEnumInvalidLiteralDeclarationException() { $parser = $this->createTestParser(); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnumLiteralInvalid("foo")'; $parser->setIgnoreNotImportedAnnotations(false); $parser->parse($docblock); } public function getConstantsProvider() { $provider[] = array( '@AnnotationWithConstants(PHP_EOL)', PHP_EOL ); $provider[] = array( '@AnnotationWithConstants(AnnotationWithConstants::INTEGER)', AnnotationWithConstants::INTEGER ); $provider[] = array( '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants(AnnotationWithConstants::STRING)', AnnotationWithConstants::STRING ); $provider[] = array( '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants::FLOAT)', AnnotationWithConstants::FLOAT ); $provider[] = array( '@AnnotationWithConstants(ClassWithConstants::SOME_VALUE)', ClassWithConstants::SOME_VALUE ); $provider[] = array( '@AnnotationWithConstants(ClassWithConstants::OTHER_KEY_)', ClassWithConstants::OTHER_KEY_ ); $provider[] = array( '@AnnotationWithConstants(ClassWithConstants::OTHER_KEY_2)', ClassWithConstants::OTHER_KEY_2 ); $provider[] = array( '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants::SOME_VALUE)', ClassWithConstants::SOME_VALUE ); $provider[] = array( '@AnnotationWithConstants(IntefaceWithConstants::SOME_VALUE)', IntefaceWithConstants::SOME_VALUE ); $provider[] = array( '@AnnotationWithConstants(\Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_VALUE)', IntefaceWithConstants::SOME_VALUE ); $provider[] = array( '@AnnotationWithConstants({AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT})', array(AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT) ); $provider[] = array( '@AnnotationWithConstants({ AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER })', array(AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER) ); $provider[] = array( '@AnnotationWithConstants({ Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER })', array(IntefaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER) ); $provider[] = array( '@AnnotationWithConstants({ \Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER })', array(IntefaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER) ); $provider[] = array( '@AnnotationWithConstants({ AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER, ClassWithConstants::SOME_KEY = ClassWithConstants::SOME_VALUE, Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants::SOME_KEY = IntefaceWithConstants::SOME_VALUE })', array( AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER, ClassWithConstants::SOME_KEY => ClassWithConstants::SOME_VALUE, ClassWithConstants::SOME_KEY => IntefaceWithConstants::SOME_VALUE ) ); $provider[] = array( '@AnnotationWithConstants(AnnotationWithConstants::class)', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants' ); $provider[] = array( '@AnnotationWithConstants({AnnotationWithConstants::class = AnnotationWithConstants::class})', array('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants' => 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants') ); $provider[] = array( '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants::class)', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants' ); $provider[] = array( '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants::class)', 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants' ); return $provider; } /** * @dataProvider getConstantsProvider */ public function testSupportClassConstants($docblock, $expected) { $parser = $this->createTestParser(); $parser->setImports(array( 'classwithconstants' => 'Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants', 'intefacewithconstants' => 'Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants', 'annotationwithconstants' => 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants' )); $result = $parser->parse($docblock); $this->assertInstanceOf('\Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants', $annotation = $result[0]); $this->assertEquals($expected, $annotation->value); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage The annotation @SomeAnnotationClassNameWithoutConstructorAndProperties declared on does not accept any values, but got {"value":"Foo"}. */ public function testWithoutConstructorWhenIsNotDefaultValue() { $parser = $this->createTestParser(); $docblock = <<setTarget(Target::TARGET_CLASS); $parser->parse($docblock); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage The annotation @SomeAnnotationClassNameWithoutConstructorAndProperties declared on does not accept any values, but got {"value":"Foo"}. */ public function testWithoutConstructorWhenHasNoProperties() { $parser = $this->createTestParser(); $docblock = <<setTarget(Target::TARGET_CLASS); $parser->parse($docblock); } /** * @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 testAnnotationTargetSyntaxError() { $parser = $this->createTestParser(); $context = 'class ' . 'SomeClassName'; $docblock = <<setTarget(Target::TARGET_CLASS); $parser->parse($docblock,$context); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Invalid Target "Foo". Available targets: [ALL, CLASS, METHOD, PROPERTY, ANNOTATION] */ public function testAnnotationWithInvalidTargetDeclarationError() { $parser = $this->createTestParser(); $context = 'class ' . 'SomeClassName'; $docblock = <<setTarget(Target::TARGET_CLASS); $parser->parse($docblock,$context); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage @Target expects either a string value, or an array of strings, "NULL" given. */ public function testAnnotationWithTargetEmptyError() { $parser = $this->createTestParser(); $context = 'class ' . 'SomeClassName'; $docblock = <<setTarget(Target::TARGET_CLASS); $parser->parse($docblock,$context); } /** * @group DDC-575 */ public function testRegressionDDC575() { $parser = $this->createTestParser(); $docblock = <<parse($docblock); $this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Name", $result[0]); $docblock = <<parse($docblock); $this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Name", $result[0]); } /** * @group DDC-77 */ public function testAnnotationWithoutClassIsIgnoredWithoutWarning() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $result = $parser->parse("@param"); $this->assertEquals(0, count($result)); } /** * @group DCOM-168 */ public function testNotAnAnnotationClassIsIgnoredWithoutWarning() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $parser->setIgnoredAnnotationNames(array('PHPUnit_Framework_TestCase' => true)); $result = $parser->parse('@PHPUnit_Framework_TestCase'); $this->assertEquals(0, count($result)); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage Expected PlainValue, got ''' at position 10. */ public function testAnnotationDontAcceptSingleQuotes() { $parser = $this->createTestParser(); $parser->parse("@Name(foo='bar')"); } /** * @group DCOM-41 */ public function testAnnotationDoesntThrowExceptionWhenAtSignIsNotFollowedByIdentifier() { $parser = new DocParser(); $result = $parser->parse("'@'"); $this->assertEquals(0, count($result)); } /** * @group DCOM-41 * @expectedException \Doctrine\Common\Annotations\AnnotationException */ public function testAnnotationThrowsExceptionWhenAtSignIsNotFollowedByIdentifierInNestedAnnotation() { $parser = new DocParser(); $parser->parse("@Doctrine\Tests\Common\Annotations\Name(@')"); } /** * @group DCOM-56 */ public function testAutoloadAnnotation() { $this->assertFalse(class_exists('Doctrine\Tests\Common\Annotations\Fixture\Annotation\Autoload', false), 'Pre-condition: Doctrine\Tests\Common\Annotations\Fixture\Annotation\Autoload not allowed to be loaded.'); $parser = new DocParser(); AnnotationRegistry::registerAutoloadNamespace('Doctrine\Tests\Common\Annotations\Fixtures\Annotation', __DIR__ . '/../../../../'); $parser->setImports(array( 'autoload' => 'Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Autoload', )); $annotations = $parser->parse('@Autoload'); $this->assertEquals(1, count($annotations)); $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Autoload', $annotations[0]); } public function createTestParser() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $parser->setImports(array( 'name' => 'Doctrine\Tests\Common\Annotations\Name', '__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations', )); return $parser; } /** * @group DDC-78 * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage Expected PlainValue, got ''' at position 10 in class \Doctrine\Tests\Common\Annotations\Name */ public function testSyntaxErrorWithContextDescription() { $parser = $this->createTestParser(); $parser->parse("@Name(foo='bar')", "class \Doctrine\Tests\Common\Annotations\Name"); } /** * @group DDC-183 */ public function testSyntaxErrorWithUnknownCharacters() { $docblock = <<setInput(trim($docblock, '/ *')); //var_dump($lexer); try { $parser = $this->createTestParser(); $parser->parse($docblock); } catch (\Exception $e) { $this->fail($e->getMessage()); } } /** * @group DCOM-14 */ public function testIgnorePHPDocThrowTag() { $docblock = <<createTestParser(); $parser->parse($docblock); } catch (\Exception $e) { $this->fail($e->getMessage()); } } /** * @group DCOM-38 */ public function testCastInt() { $parser = $this->createTestParser(); $result = $parser->parse("@Name(foo=1234)"); $annot = $result[0]; $this->assertInternalType('int', $annot->foo); } /** * @group DCOM-38 */ public function testCastNegativeInt() { $parser = $this->createTestParser(); $result = $parser->parse("@Name(foo=-1234)"); $annot = $result[0]; $this->assertInternalType('int', $annot->foo); } /** * @group DCOM-38 */ public function testCastFloat() { $parser = $this->createTestParser(); $result = $parser->parse("@Name(foo=1234.345)"); $annot = $result[0]; $this->assertInternalType('float', $annot->foo); } /** * @group DCOM-38 */ public function testCastNegativeFloat() { $parser = $this->createTestParser(); $result = $parser->parse("@Name(foo=-1234.345)"); $annot = $result[0]; $this->assertInternalType('float', $annot->foo); $result = $parser->parse("@Marker(-1234.345)"); $annot = $result[0]; $this->assertInternalType('float', $annot->value); } public function testReservedKeywordsInAnnotations() { $parser = $this->createTestParser(); $result = $parser->parse('@Doctrine\Tests\Common\Annotations\True'); $this->assertTrue($result[0] instanceof True); $result = $parser->parse('@Doctrine\Tests\Common\Annotations\False'); $this->assertTrue($result[0] instanceof False); $result = $parser->parse('@Doctrine\Tests\Common\Annotations\Null'); $this->assertTrue($result[0] instanceof Null); $result = $parser->parse('@True'); $this->assertTrue($result[0] instanceof True); $result = $parser->parse('@False'); $this->assertTrue($result[0] instanceof False); $result = $parser->parse('@Null'); $this->assertTrue($result[0] instanceof Null); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage [Creation Error] The annotation @SomeAnnotationClassNameWithoutConstructor declared on some class does not have a property named "invalidaProperty". Available properties: data, name */ public function testSetValuesExeption() { $docblock = <<createTestParser()->parse($docblock, 'some class'); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage [Syntax Error] Expected Doctrine\Common\Annotations\DocLexer::T_IDENTIFIER or Doctrine\Common\Annotations\DocLexer::T_TRUE or Doctrine\Common\Annotations\DocLexer::T_FALSE or Doctrine\Common\Annotations\DocLexer::T_NULL, got '3.42' at position 5. */ public function testInvalidIdentifierInAnnotation() { $parser = $this->createTestParser(); $parser->parse('@Foo\3.42'); } public function testTrailingCommaIsAllowed() { $parser = $this->createTestParser(); $annots = $parser->parse('@Name({ "Foo", "Bar", })'); $this->assertEquals(1, count($annots)); $this->assertEquals(array('Foo', 'Bar'), $annots[0]->value); } public function testDefaultAnnotationValueIsNotOverwritten() { $parser = $this->createTestParser(); $annots = $parser->parse('@Doctrine\Tests\Common\Annotations\Fixtures\Annotation\AnnotWithDefaultValue'); $this->assertEquals(1, count($annots)); $this->assertEquals('bar', $annots[0]->foo); } public function testArrayWithColon() { $parser = $this->createTestParser(); $annots = $parser->parse('@Name({"foo": "bar"})'); $this->assertEquals(1, count($annots)); $this->assertEquals(array('foo' => 'bar'), $annots[0]->value); } /** * @expectedException \Doctrine\Common\Annotations\AnnotationException * @expectedExceptionMessage [Semantical Error] Couldn't find constant foo. */ public function testInvalidContantName() { $parser = $this->createTestParser(); $parser->parse('@Name(foo: "bar")'); } /** * Tests parsing empty arrays. */ public function testEmptyArray() { $parser = $this->createTestParser(); $annots = $parser->parse('@Name({"foo": {}})'); $this->assertEquals(1, count($annots)); $this->assertEquals(array('foo' => array()), $annots[0]->value); } public function testKeyHasNumber() { $parser = $this->createTestParser(); $annots = $parser->parse('@SettingsAnnotation(foo="test", bar2="test")'); $this->assertEquals(1, count($annots)); $this->assertEquals(array('foo' => 'test', 'bar2' => 'test'), $annots[0]->settings); } } /** @Annotation */ class SettingsAnnotation { public $settings; public function __construct($settings) { $this->settings = $settings; } } /** @Annotation */ class SomeAnnotationClassNameWithoutConstructor { public $data; public $name; } /** @Annotation */ class SomeAnnotationWithConstructorWithoutParams { function __construct() { $this->data = "Some data"; } public $data; public $name; } /** @Annotation */ class SomeAnnotationClassNameWithoutConstructorAndProperties{} /** * @Annotation * @Target("Foo") */ class AnnotationWithInvalidTargetDeclaration{} /** * @Annotation * @Target */ class AnnotationWithTargetEmpty{} /** @Annotation */ class AnnotationExtendsAnnotationTargetAll extends \Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll { } /** @Annotation */ class Name extends \Doctrine\Common\Annotations\Annotation { public $foo; } /** @Annotation */ class Marker { public $value; } /** @Annotation */ class True {} /** @Annotation */ class False {} /** @Annotation */ class Null {} namespace Doctrine\Tests\Common\Annotations\FooBar; /** @Annotation */ class Name extends \Doctrine\Common\Annotations\Annotation { } tests/Doctrine/Tests/Common/Annotations/DummyClass.php000064400000002160144760114530017102 0ustar00cacheDir = 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)); new FileCacheReader(new AnnotationReader(), $this->cacheDir); $this->assertTrue(is_dir($this->cacheDir)); } }tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/AnnotWithDefaultValue.php000064400000000253144760114530025162 0ustar00roles = $values['value']; } }tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/Template.php000064400000000406144760114530022520 0ustar00name = isset($values['value']) ? $values['value'] : null; } }tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation/Version.php000064400000000217144760114530022372 0ustar00"), @Attribute("arrayOfStrings", type = "string[]"), @Attribute("annotation", type = "Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll"), @Attribute("arrayOfAnnotations", type = "array"), }) */ 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 $arrayOfStrings; 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 string[] */ public function getArrayOfStrings() { return $this->arrayOfIntegers; } /** * @return array */ public function getArrayOfIntegers() { return $this->arrayOfIntegers; } /** * @return array */ public function getArrayOfAnnotations() { return $this->arrayOfAnnotations; } }tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithConstants.php000064400000000422144760114530023474 0ustar00 $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; } }Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithRequiredAttributesWithoutContructor.php000064400000000570144760114530030743 0ustar00tests */ public $arrayOfIntegers; /** * @var string[] */ public $arrayOfStrings; /** * @var array */ public $arrayOfAnnotations; }tests/Doctrine/Tests/Common/Annotations/Fixtures/Api.php000064400000000160144760114530017341 0ustar00events->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; } }tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithConstants.php000064400000000475144760114530022437 0ustar00 */ 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)); } } }tests/Doctrine/Tests/Common/Annotations/Fixtures/DifferentNamespacesPerFileWithClassAsFirst.php000064400000000630144760114530027125 0ustar00test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test2() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test3() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test4() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test5() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test6() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test7() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test8() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test9() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test10() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test11() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test12() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test13() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test14() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test15() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test16() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test17() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test18() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test19() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test20() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test21() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test22() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test23() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test24() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test25() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test26() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test27() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test28() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test29() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test30() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test31() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test32() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test33() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test34() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test35() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test36() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test37() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test38() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test39() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } } tests/Doctrine/Tests/Common/Annotations/Fixtures/NoAnnotation.php000064400000000123144760114530021236 0ustar00test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test2() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test3() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test4() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test5() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test6() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test7() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test8() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test9() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test10() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test11() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test12() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test13() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test14() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test15() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test16() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test17() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test18() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test19() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test20() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test21() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test22() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test23() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test24() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test25() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test26() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test27() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test28() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test29() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test30() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test31() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test32() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test33() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test34() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test35() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test36() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test37() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test38() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } public function test39() { echo $this->test1; echo $this->test2; echo $this->test3; $array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); foreach ($array as $key => $value) { echo $key . ' => ' . $value; } $val = (string)self::TEST1; $val .= (string)self::TEST2; $val .= (string)self::TEST3; $val .= (string)self::TEST4; $val .= (string)self::TEST5; $val .= (string)self::TEST6; $val .= (string)self::TEST7; $val .= (string)self::TEST8; $val .= (string)self::TEST9; strtolower($val); return $val; } } tests/Doctrine/Tests/Common/Annotations/Fixtures/TestInterface.php000064400000000317144760114530021374 0ustar00getMethod(); $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"; } }tests/Doctrine/Tests/Common/Annotations/PhpParserTest.php000064400000017334144760114530017576 0ustar00assertEquals(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)); } }tests/Doctrine/Tests/Common/Annotations/SimpleAnnotationReaderTest.php000064400000006775144760114530022310 0ustar00markTestSkipped('The simplified annotation reader would always autoload annotations'); } /** * @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; } }tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM55Test.php000064400000003436144760114530020007 0ustar00getClassAnnotations($class); } public function testAnnotation() { $class = new \ReflectionClass(__NAMESPACE__ . '\\DCOM55Consumer'); $reader = new 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 AnnotationReader(); $annots = $reader->getClassAnnotations($class); $this->assertEquals(0, count($annots)); } } /** * @Controller */ class Dummy { } /** * @Annotation */ class DCOM55Annotation { } /** * @DCOM55Annotation */ class DCOM55Consumer { }tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Entity.php000064400000000141144760114530020335 0ustar00getClassAnnotations(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 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 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 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 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 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 { } tests/Doctrine/Tests/Common/Annotations/TopLevelAnnotation.php000064400000000167144760114530020613 0ustar00