pax_global_header00006660000000000000000000000064135460112110014504gustar00rootroot0000000000000052 comment=377f2cafc0a9895c3402c6dbbbb3b0ca90ca929e php-doctrine-annotations-1.8.0/000077500000000000000000000000001354601121100164415ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/.gitignore000066400000000000000000000001031354601121100204230ustar00rootroot00000000000000/vendor/ /composer.lock /composer.phar /phpbench.json /phpunit.xml php-doctrine-annotations-1.8.0/.travis.yml000066400000000000000000000017011354601121100205510ustar00rootroot00000000000000dist: trusty sudo: false language: php php: - 7.1 - 7.2 - 7.3 - 7.4snapshot - nightly cache: directories: - $HOME/.composer/cache before_install: - mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available" - composer self-update install: travis_retry composer update --prefer-dist script: - ./vendor/bin/phpunit jobs: allow_failures: - php: nightly include: - stage: Lint before_script: - travis_retry composer require --dev --prefer-dist --prefer-stable phpstan/phpstan:^0.7 script: vendor/bin/phpstan analyse -l 3 -c phpstan.neon lib tests - stage: Benchmark install: - travis_retry composer update --prefer-dist - curl -o phpbench.phar https://phpbench.github.io/phpbench/phpbench.phar - curl -o phpbench.phar.pubkey https://phpbench.github.io/phpbench/phpbench.phar.pubkey script: php phpbench.phar run php-doctrine-annotations-1.8.0/CHANGELOG.md000066400000000000000000000217061354601121100202600ustar00rootroot00000000000000## Changelog ### 1.6.1 This release fixes an issue in which annotations such as `@foo-bar` and `@foo-` were incorrectly recognised as valid, and both erroneously parsed as `@foo`. Any annotation with `@name-*` format will now silently be ignored, allowing vendor-specific annotations to be prefixed with the tool name. Total issues resolved: **3** - [165: Update the composer branch alias](https://github.com/doctrine/annotations/pull/165) thanks to @mikeSimonson - [209: Change Annotation::value typehint to mixed](https://github.com/doctrine/annotations/pull/209) thanks to @malarzm - [257: Skip parsing annotations containing dashes, such as `@Foo-bar`, or `@Foo-`](https://github.com/doctrine/annotations/pull/257) thanks to @Ocramius ### 1.6.0 This release brings a new endpoint that make sure that you can't shoot yourself in the foot by calling ```registerLoader``` multiple times and a few tests improvements. Total issues resolved: **7** - [145: Memory leak in AnnotationRegistry::registerLoader() when called multiple times](https://github.com/doctrine/annotations/issues/145) thanks to @TriAnMan - [146: Import error on @experimental Annotation](https://github.com/doctrine/annotations/issues/146) thanks to @aturki - [147: Ignoring @experimental annotation used by Symfony 3.3 CacheAdapter](https://github.com/doctrine/annotations/pull/147) thanks to @aturki - [151: Remove duplicate code in `DCOM58Test`](https://github.com/doctrine/annotations/pull/151) thanks to @tuanphpvn - [161: Prevent loading class_exists multiple times](https://github.com/doctrine/annotations/pull/161) thanks to @jrjohnson - [162: Add registerUniqueLoader to AnnotationRegistry](https://github.com/doctrine/annotations/pull/162) thanks to @jrjohnson - [163: Use assertDirectoryExists and assertDirectoryNotExists](https://github.com/doctrine/annotations/pull/163) thanks to @carusogabriel Thanks to everyone involved in this release. ### 1.5.0 This release increments the minimum supported PHP version to 7.1.0. Also, HHVM official support has been dropped. Some noticeable performance improvements to annotation autoloading have been applied, making failed annotation autoloading less heavy on the filesystem access. - [133: Add @throws annotation in AnnotationReader#__construct()](https://github.com/doctrine/annotations/issues/133) thanks to @SenseException - [134: Require PHP 7.1, drop HHVM support](https://github.com/doctrine/annotations/issues/134) thanks to @lcobucci - [135: Prevent the same loader from being registered twice](https://github.com/doctrine/annotations/issues/135) thanks to @jrjohnson - [137: #135 optimise multiple class load attempts in AnnotationRegistry](https://github.com/doctrine/annotations/issues/137) thanks to @Ocramius ### 1.4.0 This release fix an issue were some annotations could be not loaded if the namespace in the use statement started with a backslash. It also update the tests and drop the support for php 5.X - [115: Missing annotations with the latest composer version](https://github.com/doctrine/annotations/issues/115) thanks to @pascalporedda - [120: Missing annotations with the latest composer version](https://github.com/doctrine/annotations/pull/120) thanks to @gnat42 - [121: Adding a more detailed explanation of the test](https://github.com/doctrine/annotations/pull/121) thanks to @mikeSimonson - [101: Test annotation parameters containing space](https://github.com/doctrine/annotations/pull/101) thanks to @mikeSimonson - [111: Cleanup: move to correct phpunit assertions](https://github.com/doctrine/annotations/pull/111) thanks to @Ocramius - [112: Removes support for PHP 5.x](https://github.com/doctrine/annotations/pull/112) thanks to @railto - [113: bumped phpunit version to 5.7](https://github.com/doctrine/annotations/pull/113) thanks to @gabbydgab - [114: Enhancement: Use SVG Travis build badge](https://github.com/doctrine/annotations/pull/114) thanks to @localheinz - [118: Integrating PHPStan](https://github.com/doctrine/annotations/pull/118) thanks to @ondrejmirtes ### 1.3.1 - 2016-12-30 This release fixes an issue with ignored annotations that were already autoloaded, causing the `SimpleAnnotationReader` to pick them up anyway. [#110](https://github.com/doctrine/annotations/pull/110) Additionally, an issue was fixed in the `CachedReader`, which was not correctly checking the freshness of cached annotations when traits were defined on a class. [#105](https://github.com/doctrine/annotations/pull/105) Total issues resolved: **2** - [105: Return single max timestamp](https://github.com/doctrine/annotations/pull/105) - [110: setIgnoreNotImportedAnnotations(true) didn’t work for existing classes](https://github.com/doctrine/annotations/pull/110) ### 1.3.0 This release introduces a PHP version bump. `doctrine/annotations` now requires PHP 5.6 or later to be installed. A series of additional improvements have been introduced: * support for PHP 7 "grouped use statements" * support for ignoring entire namespace names via `Doctrine\Common\Annotations\AnnotationReader::addGlobalIgnoredNamespace()` and `Doctrine\Common\Annotations\DocParser::setIgnoredAnnotationNamespaces()`. This will allow you to ignore annotations from namespaces that you cannot autoload * testing all parent classes and interfaces when checking if the annotation cache in the `CachedReader` is fresh * simplifying the cache keys used by the `CachedReader`: keys are no longer artificially namespaced, since `Doctrine\Common\Cache` already supports that * corrected parsing of multibyte strings when `mbstring.func_overload` is enabled * corrected parsing of annotations when `"\t"` is put before the first annotation in a docblock * allow skipping non-imported annotations when a custom `DocParser` is passed to the `AnnotationReader` constructor Total issues resolved: **15** - [45: DocParser can now ignore whole namespaces](https://github.com/doctrine/annotations/pull/45) - [57: Switch to the docker-based infrastructure on Travis](https://github.com/doctrine/annotations/pull/57) - [59: opcache.load_comments has been removed from PHP 7](https://github.com/doctrine/annotations/pull/59) - [62: [CachedReader\ Test traits and parent class to see if cache is fresh](https://github.com/doctrine/annotations/pull/62) - [65: Remove cache salt making key unnecessarily long](https://github.com/doctrine/annotations/pull/65) - [66: Fix of incorrect parsing multibyte strings](https://github.com/doctrine/annotations/pull/66) - [68: Annotations that are indented by tab are not processed.](https://github.com/doctrine/annotations/issues/68) - [69: Support for Group Use Statements](https://github.com/doctrine/annotations/pull/69) - [70: Allow tab character before first annotation in DocBlock](https://github.com/doctrine/annotations/pull/70) - [74: Ignore not registered annotations fix](https://github.com/doctrine/annotations/pull/74) - [92: Added tests for AnnotationRegistry class.](https://github.com/doctrine/annotations/pull/92) - [96: Fix/#62 check trait and parent class ttl in annotations](https://github.com/doctrine/annotations/pull/96) - [97: Feature - #45 - allow ignoring entire namespaces](https://github.com/doctrine/annotations/pull/97) - [98: Enhancement/#65 remove cache salt from cached reader](https://github.com/doctrine/annotations/pull/98) - [99: Fix - #70 - allow tab character before first annotation in docblock](https://github.com/doctrine/annotations/pull/99) ### 1.2.4 Total issues resolved: **1** - [51: FileCacheReader::saveCacheFile::unlink fix](https://github.com/doctrine/annotations/pull/51) ### 1.2.3 Total issues resolved: [**2**](https://github.com/doctrine/annotations/milestones/v1.2.3) - [49: #46 - applying correct `chmod()` to generated cache file](https://github.com/doctrine/annotations/pull/49) - [50: Hotfix: match escaped quotes (revert #44)](https://github.com/doctrine/annotations/pull/50) ### 1.2.2 Total issues resolved: **4** - [43: Exclude files from distribution with .gitattributes](https://github.com/doctrine/annotations/pull/43) - [44: Update DocLexer.php](https://github.com/doctrine/annotations/pull/44) - [46: A plain "file_put_contents" can cause havoc](https://github.com/doctrine/annotations/pull/46) - [48: Deprecating the `FileCacheReader` in 1.2.2: will be removed in 2.0.0](https://github.com/doctrine/annotations/pull/48) ### 1.2.1 Total issues resolved: **4** - [38: fixes doctrine/common#326](https://github.com/doctrine/annotations/pull/38) - [39: Remove superfluous NS](https://github.com/doctrine/annotations/pull/39) - [41: Warn if load_comments is not enabled.](https://github.com/doctrine/annotations/pull/41) - [42: Clean up unused uses](https://github.com/doctrine/annotations/pull/42) ### 1.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 ### 1.1.0 * Add Exception when ZendOptimizer+ or Opcache is configured to drop comments php-doctrine-annotations-1.8.0/LICENSE000066400000000000000000000020511354601121100174440ustar00rootroot00000000000000Copyright (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. php-doctrine-annotations-1.8.0/README.md000066400000000000000000000020131354601121100177140ustar00rootroot00000000000000# Doctrine Annotations [![Build Status](https://travis-ci.org/doctrine/annotations.svg?branch=master)](https://travis-ci.org/doctrine/annotations) [![Dependency Status](https://www.versioneye.com/package/php--doctrine--annotations/badge.png)](https://www.versioneye.com/package/php--doctrine--annotations) [![Reference Status](https://www.versioneye.com/php/doctrine:annotations/reference_badge.svg)](https://www.versioneye.com/php/doctrine:annotations/references) [![Total Downloads](https://poser.pugx.org/doctrine/annotations/downloads.png)](https://packagist.org/packages/doctrine/annotations) [![Latest Stable Version](https://poser.pugx.org/doctrine/annotations/v/stable.png)](https://packagist.org/packages/doctrine/annotations) Docblock Annotations Parser library (extracted from [Doctrine Common](https://github.com/doctrine/common)). ## Documentation See the [doctrine-project website](https://www.doctrine-project.org/projects/doctrine-annotations/en/latest/index.html). ## Changelog See [CHANGELOG.md](CHANGELOG.md). php-doctrine-annotations-1.8.0/composer.json000066400000000000000000000026311354601121100211650ustar00rootroot00000000000000{ "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": "^7.1", "doctrine/lexer": "1.*" }, "require-dev": { "doctrine/cache": "1.*", "phpunit/phpunit": "^7.5" }, "config": { "sort-packages": true }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" } }, "autoload-dev": { "psr-4": { "Doctrine\\Performance\\Common\\Annotations\\": "tests/Doctrine/Performance/Common/Annotations", "Doctrine\\Tests\\Common\\Annotations\\": "tests/Doctrine/Tests/Common/Annotations" }, "files": [ "tests/Doctrine/Tests/Common/Annotations/Fixtures/SingleClassLOC1000.php" ] }, "extra": { "branch-alias": { "dev-master": "1.7.x-dev" } } } php-doctrine-annotations-1.8.0/docs/000077500000000000000000000000001354601121100173715ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/docs/en/000077500000000000000000000000001354601121100177735ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/docs/en/annotations.rst000066400000000000000000000240771354601121100230740ustar00rootroot00000000000000Handling Annotations ==================== There are several different approaches to handling annotations in PHP. Doctrine Annotations maps docblock annotations to PHP classes. Because not all docblock annotations are used for metadata purposes a filter is applied to ignore or skip classes that are not Doctrine annotations. Take a look at the following code snippet: .. code-block:: php namespace MyProject\Entities; use Doctrine\ORM\Mapping AS ORM; use Symfony\Component\Validation\Constraints AS Assert; /** * @author Benjamin Eberlei * @ORM\Entity * @MyProject\Annotations\Foobarable */ class User { /** * @ORM\Id @ORM\Column @ORM\GeneratedValue * @dummy * @var int */ private $id; /** * @ORM\Column(type="string") * @Assert\NotEmpty * @Assert\Email * @var string */ private $email; } In this snippet you can see a variety of different docblock annotations: - Documentation annotations such as ``@var`` and ``@author``. These annotations are on a blacklist and never considered for throwing an exception due to wrongly used annotations. - Annotations imported through use statements. The statement ``use Doctrine\ORM\Mapping AS ORM`` makes all classes under that namespace available as ``@ORM\ClassName``. Same goes for the import of ``@Assert``. - The ``@dummy`` annotation. It is not a documentation annotation and not blacklisted. For Doctrine Annotations it is not entirely clear how to handle this annotation. Depending on the configuration an exception (unknown annotation) will be thrown when parsing this annotation. - The fully qualified annotation ``@MyProject\Annotations\Foobarable``. This is transformed directly into the given class name. How are these annotations loaded? From looking at the code you could guess that the ORM Mapping, Assert Validation and the fully qualified annotation can just be loaded using the defined PHP autoloaders. This is not the case however: For error handling reasons every check for class existence inside the AnnotationReader sets the second parameter $autoload of ``class_exists($name, $autoload)`` to false. To work flawlessly the AnnotationReader requires silent autoloaders which many autoloaders are not. Silent autoloading is NOT part of the `PSR-0 specification `_ for autoloading. This is why Doctrine Annotations uses its own autoloading mechanism through a global registry. If you are wondering about the annotation registry being global, there is no other way to solve the architectural problems of autoloading annotation classes in a straightforward fashion. Additionally if you think about PHP autoloading then you recognize it is a global as well. To anticipate the configuration section, making the above PHP class work with Doctrine Annotations requires this setup: .. code-block:: php use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\AnnotationRegistry; AnnotationRegistry::registerFile("/path/to/doctrine/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php"); AnnotationRegistry::registerAutoloadNamespace("Symfony\Component\Validator\Constraint", "/path/to/symfony/src"); AnnotationRegistry::registerAutoloadNamespace("MyProject\Annotations", "/path/to/myproject/src"); $reader = new AnnotationReader(); AnnotationReader::addGlobalIgnoredName('dummy'); The second block with the annotation registry calls registers all the three different annotation namespaces that are used. Doctrine saves all its annotations in a single file, that is why ``AnnotationRegistry#registerFile`` is used in contrast to ``AnnotationRegistry#registerAutoloadNamespace`` which creates a PSR-0 compatible loading mechanism for class to file names. In the third block, we create the actual AnnotationReader instance. Note that we also add "dummy" to the global list of annotations for which we do not throw exceptions. Setting this is necessary in our example case, otherwise ``@dummy`` would trigger an exception to be thrown during the parsing of the docblock of ``MyProject\Entities\User#id``. Setup and Configuration ----------------------- To use the annotations library is simple, you just need to create a new ``AnnotationReader`` instance: .. code-block:: php $reader = new \Doctrine\Common\Annotations\AnnotationReader(); This creates a simple annotation reader with no caching other than in memory (in php arrays). Since parsing docblocks can be expensive you should cache this process by using a caching reader. You can use a file caching reader: .. code-block:: php use Doctrine\Common\Annotations\FileCacheReader; use Doctrine\Common\Annotations\AnnotationReader; $reader = new FileCacheReader( new AnnotationReader(), "/path/to/cache", $debug = true ); If you set the debug flag to true the cache reader will check for changes in the original files, which is very important during development. If you don't set it to true you have to delete the directory to clear the cache. This gives faster performance, however should only be used in production, because of its inconvenience during development. You can also use one of the ``Doctrine\Common\Cache\Cache`` cache implementations to cache the annotations: .. code-block:: php use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\CachedReader; use Doctrine\Common\Cache\ApcCache; $reader = new CachedReader( new AnnotationReader(), new ApcCache(), $debug = true ); The debug flag is used here as well to invalidate the cache files when the PHP class with annotations changed and should be used during development. .. warning :: The AnnotationReader works and caches under the assumption that all annotations of a doc-block are processed at once. That means that annotation classes that do not exist and aren't loaded and cannot be autoloaded (using the AnnotationRegistry) would never be visible and not accessible if a cache is used unless the cache is cleared and the annotations requested again, this time with all annotations defined. By default the annotation reader returns a list of annotations with numeric indexes. If you want your annotations to be indexed by their class name you can wrap the reader in an IndexedReader: .. code-block:: php use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\IndexedReader; $reader = new IndexedReader(new AnnotationReader()); .. warning:: You should never wrap the indexed reader inside a cached reader only the other way around. This way you can re-use the cache with indexed or numeric keys, otherwise your code may experience failures due to caching in an numerical or indexed format. Registering Annotations ~~~~~~~~~~~~~~~~~~~~~~~ As explained in the Introduction Doctrine Annotations uses its own autoloading mechanism to determine if a given annotation has a corresponding PHP class that can be autoloaded. For Annotation Autoloading you have to configure the ``Doctrine\Common\Annotations\AnnotationRegistry``. There are three different mechanisms to configure annotation autoloading: - Calling ``AnnotationRegistry#registerFile($file)`` to register a file that contains one or more Annotation classes. - Calling ``AnnotationRegistry#registerNamespace($namespace, $dirs = null)`` to register that the given namespace contains annotations and that their base directory is located at the given $dirs or in the include path if NULL is passed. The given directories should *NOT* be the directory where classes of the namespace are in, but the base directory of the root namespace. The AnnotationRegistry uses a namespace to directory separator approach to resolve the correct path. - Calling ``AnnotationRegistry#registerLoader($callable)`` to register an autoloader callback. The callback accepts the class as first and only parameter and has to return true if the corresponding file was found and included. .. note:: Loaders have to fail silently, if a class is not found even if it matches for example the namespace prefix of that loader. Never is a loader to throw a warning or exception if the loading failed otherwise parsing doc block annotations will become a huge pain. A sample loader callback could look like: .. code-block:: php use Doctrine\Common\Annotations\AnnotationRegistry; use Symfony\Component\ClassLoader\UniversalClassLoader; AnnotationRegistry::registerLoader(function($class) { $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php"; if (file_exists("/my/base/path/" . $file)) { // file exists makes sure that the loader fails silently require "/my/base/path/" . $file; } }); $loader = new UniversalClassLoader(); AnnotationRegistry::registerLoader(array($loader, "loadClass")); Ignoring missing exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~~~ By default an exception is thrown from the AnnotationReader if an annotation was found that: - Is not part of the blacklist of ignored "documentation annotations". - Was not imported through a use statement - Is not a fully qualified class that exists You can disable this behavior for specific names if your docblocks do not follow strict requirements: .. code-block:: php $reader = new \Doctrine\Common\Annotations\AnnotationReader(); AnnotationReader::addGlobalIgnoredName('foo'); PHP Imports ~~~~~~~~~~~ By default the annotation reader parses the use-statement of a php file to gain access to the import rules and register them for the annotation processing. Only if you are using PHP Imports you can validate the correct usage of annotations and throw exceptions if you misspelled an annotation. This mechanism is enabled by default. To ease the upgrade path, we still allow you to disable this mechanism. Note however that we will remove this in future versions: .. code-block:: php $reader = new \Doctrine\Common\Annotations\AnnotationReader(); $reader->setEnabledPhpImports(false); php-doctrine-annotations-1.8.0/docs/en/custom.rst000066400000000000000000000167121354601121100220460ustar00rootroot00000000000000Custom Annotation Classes ========================= If you want to define your own annotations you just have to group them in a namespace and register this namespace in the AnnotationRegistry. Annotation classes have to contain a class-level docblock with the text ``@Annotation``: .. code-block:: php namespace MyCompany\Annotations; /** @Annotation */ class Bar { // some code } Inject annotation values ------------------------ The annotation parser check if the annotation constructor has arguments, if so then we will pass the value array, otherwise will try to inject values into public properties directly: .. code-block:: php namespace MyCompany\Annotations; /** * @Annotation * * Some Annotation using a constructor */ class Bar { private $foo; public function __construct(array $values) { $this->foo = $values['foo']; } } /** * @Annotation * * Some Annotation without a constructor */ class Foo { public $bar; } Annotation Target ----------------- ``@Target`` indicates the kinds of class element to which an annotation type is applicable. Then you could define one or more targets: - ``CLASS`` Allowed in the class docblock - ``PROPERTY`` Allowed in the property docblock - ``METHOD`` Allowed in the method docblock - ``ALL`` Allowed in the class, property and method docblock - ``ANNOTATION`` Allowed inside other annotations If the annotations is not allowed in the current context you got an ``AnnotationException`` .. code-block:: php namespace MyCompany\Annotations; /** * @Annotation * @Target({"METHOD","PROPERTY"}) */ class Bar { // some code } /** * @Annotation * @Target("CLASS") */ class Foo { // some code } Attribute types --------------- Annotation parser check the given parameters using the phpdoc annotation ``@var``, The data type could be validated using the ``@var`` annotation on the annotation properties or using the annotations ``@Attributes`` and ``@Attribute``. If the data type not match you got an ``AnnotationException`` .. code-block:: php namespace MyCompany\Annotations; /** * @Annotation * @Target({"METHOD","PROPERTY"}) */ class Bar { /** @var mixed */ public $mixed; /** @var boolean */ public $boolean; /** @var bool */ public $bool; /** @var float */ public $float; /** @var string */ public $string; /** @var integer */ public $integer; /** @var array */ public $array; /** @var SomeAnnotationClass */ public $annotation; /** @var array */ public $arrayOfIntegers; /** @var array */ public $arrayOfAnnotations; } /** * @Annotation * @Target({"METHOD","PROPERTY"}) * @Attributes({ * @Attribute("stringProperty", type = "string"), * @Attribute("annotProperty", type = "SomeAnnotationClass"), * }) */ class Foo { public function __construct(array $values) { $this->stringProperty = $values['stringProperty']; $this->annotProperty = $values['annotProperty']; } // some code } Annotation Required ------------------- ``@Required`` indicates that the field must be specified when the annotation is used. If it is not used you get an ``AnnotationException`` stating that this value can not be null. Declaring a required field: .. code-block:: php /** * @Annotation * @Target("ALL") */ class Foo { /** @Required */ public $requiredField; } Usage: .. code-block:: php /** @Foo(requiredField="value") */ public $direction; // Valid /** @Foo */ public $direction; // Required field missing, throws an AnnotationException Enumerated values ----------------- - An annotation property marked with ``@Enum`` is a field that accept a fixed set of scalar values. - You should use ``@Enum`` fields any time you need to represent fixed values. - The annotation parser check the given value and throws an ``AnnotationException`` if the value not match. Declaring an enumerated property: .. code-block:: php /** * @Annotation * @Target("ALL") */ class Direction { /** * @Enum({"NORTH", "SOUTH", "EAST", "WEST"}) */ public $value; } Annotation usage: .. code-block:: php /** @Direction("NORTH") */ public $direction; // Valid value /** @Direction("NORTHEAST") */ public $direction; // Invalid value, throws an AnnotationException Constants --------- The use of constants and class constants are available on the annotations parser. The following usage are allowed: .. code-block:: php namespace MyCompany\Entity; use MyCompany\Annotations\Foo; use MyCompany\Annotations\Bar; use MyCompany\Entity\SomeClass; /** * @Foo(PHP_EOL) * @Bar(Bar::FOO) * @Foo({SomeClass::FOO, SomeClass::BAR}) * @Bar({SomeClass::FOO_KEY = SomeClass::BAR_VALUE}) */ class User { } Be careful with constants and the cache ! .. note:: The cached reader will not re-evaluate each time an annotation is loaded from cache. When a constant is changed the cache must be cleaned. Usage ----- Using the library API is simple. Using the annotations described in the previous section you can now annotate other classes with your annotations: .. code-block:: php namespace MyCompany\Entity; use MyCompany\Annotations\Foo; use MyCompany\Annotations\Bar; /** * @Foo(bar="foo") * @Bar(foo="bar") */ class User { } Now we can write a script to get the annotations above: .. code-block:: php $reflClass = new ReflectionClass('MyCompany\Entity\User'); $classAnnotations = $reader->getClassAnnotations($reflClass); foreach ($classAnnotations AS $annot) { if ($annot instanceof \MyCompany\Annotations\Foo) { echo $annot->bar; // prints "foo"; } else if ($annot instanceof \MyCompany\Annotations\Bar) { echo $annot->foo; // prints "bar"; } } You have a complete API for retrieving annotation class instances from a class, property or method docblock: Reader API ~~~~~~~~~~ Access all annotations of a class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: php public function getClassAnnotations(\ReflectionClass $class); Access one annotation of a class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: php public function getClassAnnotation(\ReflectionClass $class, $annotationName); Access all annotations of a method ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: php public function getMethodAnnotations(\ReflectionMethod $method); Access one annotation of a method ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: php public function getMethodAnnotation(\ReflectionMethod $method, $annotationName); Access all annotations of a property ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: php public function getPropertyAnnotations(\ReflectionProperty $property); Access one annotation of a property ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: php public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName); php-doctrine-annotations-1.8.0/docs/en/index.rst000066400000000000000000000044751354601121100216460ustar00rootroot00000000000000Introduction ============ Doctrine Annotations offers to implement custom annotation functionality for PHP classes. .. code-block:: php class Foo { /** * @MyAnnotation(myProperty="value") */ private $bar; } Annotations aren't implemented in PHP itself which is why this component offers a way to use the PHP doc-blocks as a place for the well known annotation syntax using the ``@`` char. Annotations in Doctrine are used for the ORM configuration to build the class mapping, but it can be used in other projects for other purposes too. Installation ============ You can install the Annotation component with composer: .. code-block::   $ composer require doctrine/annotations Create an annotation class ========================== An annotation class is a representation of the later used annotation configuration in classes. The annotation class of the previous example looks like this: .. code-block:: php /** * @Annotation */ final class MyAnnotation { public $myProperty; } The annotation class is declared as an annotation by ``@Annotation``. :ref:`Read more about custom annotations. ` Reading annotations =================== The access to the annotations happens by reflection of the class containing them. There are multiple reader-classes implementing the ``Doctrine\Common\Annotations\Reader`` interface, that can access the annotations of a class. A common one is ``Doctrine\Common\Annotations\AnnotationReader``: .. code-block:: php $reflectionClass = new ReflectionClass(Foo::class); $property = $reflectionClass->getProperty('bar'); $reader = new AnnotationReader(); $myAnnotation = $reader->getPropertyAnnotation($property, 'bar'); echo $myAnnotation->myProperty; // result: "value" A reader has multiple methods to access the annotations of a class. :ref:`Read more about handling annotations. ` IDE Support ----------- Some IDEs already provide support for annotations: - Eclipse via the `Symfony2 Plugin `_ - PHPStorm via the `PHP Annotations Plugin `_ or the `Symfony2 Plugin `_ .. _Read more about handling annotations.: annotations .. _Read more about custom annotations.: custom php-doctrine-annotations-1.8.0/docs/en/sidebar.rst000066400000000000000000000001011354601121100221260ustar00rootroot00000000000000.. toctree:: :depth: 3 index annotations custom php-doctrine-annotations-1.8.0/lib/000077500000000000000000000000001354601121100172075ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/lib/Doctrine/000077500000000000000000000000001354601121100207565ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/lib/Doctrine/Common/000077500000000000000000000000001354601121100222065ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/000077500000000000000000000000001354601121100245035ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation.php000066400000000000000000000046761354601121100273430ustar00rootroot00000000000000. */ 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)) ); } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation/000077500000000000000000000000001354601121100266155ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation/Attribute.php000066400000000000000000000026361354601121100313000ustar00rootroot00000000000000. */ 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; } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation/Attributes.php000066400000000000000000000025521354601121100314600ustar00rootroot00000000000000. */ 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; } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation/Enum.php000066400000000000000000000050421354601121100302330ustar00rootroot00000000000000. */ 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'] = []; } 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']; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php000066400000000000000000000035051354601121100326070ustar00rootroot00000000000000. */ 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'] = [$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']; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation/Required.php000066400000000000000000000023721354601121100311120ustar00rootroot00000000000000. */ 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 { } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Annotation/Target.php000066400000000000000000000063241354601121100305610ustar00rootroot00000000000000. */ 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 = [ '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'] = [$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); } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/AnnotationException.php000066400000000000000000000133041354601121100312060ustar00rootroot00000000000000. */ 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." ); } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/AnnotationReader.php000066400000000000000000000311551354601121100304560ustar00rootroot00000000000000. */ 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 = [ '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 = [ // 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, // Symfony 3.3 Cache Adapter 'experimental' => true, // Slevomat Coding Standard 'phpcsSuppress' => true, // PHP CodeSniffer 'codingStandardsIgnoreStart' => true, 'codingStandardsIgnoreEnd' => true, ]; /** * 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 $globalIgnoredNamespaces = []; /** * 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; } /** * Add a new annotation to the globally ignored annotation namespaces with regard to exception handling. * * @param string $namespace */ static public function addGlobalIgnoredNamespace($namespace) { self::$globalIgnoredNamespaces[$namespace] = 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 = []; /** * In-memory cache mechanism to store ignored annotations per class. * * @var array */ private $ignoredAnnotationNames = []; /** * Constructor. * * Initializes a new AnnotationReader. * * @param DocParser $parser * * @throws AnnotationException */ public function __construct(DocParser $parser = null) { 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(); } AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php'); $this->parser = $parser ?: new DocParser(); $this->preParser = new DocParser; $this->preParser->setImports(self::$globalImports); $this->preParser->setIgnoreNotImportedAnnotations(true); $this->preParser->setIgnoredAnnotationNames(self::$globalIgnoredNames); $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)); $this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces); 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)); $this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces); 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)); $this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces); 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) { $name = $class->getName(); if (isset($this->ignoredAnnotationNames[$name])) { return $this->ignoredAnnotationNames[$name]; } $this->collectParsingMetadata($class); return $this->ignoredAnnotationNames[$name]; } /** * Retrieves imports. * * @param \ReflectionClass $class * * @return array */ private function getClassImports(ReflectionClass $class) { $name = $class->getName(); if (isset($this->imports[$name])) { 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); $traitImports = []; 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); $traitImports = []; 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), ['__NAMESPACE__' => $class->getNamespaceName()] ); $this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/AnnotationRegistry.php000066400000000000000000000145011354601121100310600ustar00rootroot00000000000000. */ namespace Doctrine\Common\Annotations; 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 string[][]|string[]|null[] */ static private $autoloadNamespaces = []; /** * A map of autoloader callables. * * @var callable[] */ static private $loaders = []; /** * An array of classes which cannot be found * * @var null[] indexed by class name */ static private $failedToAutoload = []; public static function reset() : void { self::$autoloadNamespaces = []; self::$loaders = []; self::$failedToAutoload = []; } /** * Registers file. * * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0 * autoloading should be deferred to the globally registered autoloader by then. For now, * use @example AnnotationRegistry::registerLoader('class_exists') */ public static function registerFile(string $file) : void { 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 * * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0 * autoloading should be deferred to the globally registered autoloader by then. For now, * use @example AnnotationRegistry::registerLoader('class_exists') */ public static function registerAutoloadNamespace(string $namespace, $dirs = null) : void { self::$autoloadNamespaces[$namespace] = $dirs; } /** * Registers multiple namespaces. * * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. * * @param string[][]|string[]|null[] $namespaces indexed by namespace name * * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0 * autoloading should be deferred to the globally registered autoloader by then. For now, * use @example AnnotationRegistry::registerLoader('class_exists') */ public static function registerAutoloadNamespaces(array $namespaces) : void { 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. * * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0 * autoloading should be deferred to the globally registered autoloader by then. For now, * use @example AnnotationRegistry::registerLoader('class_exists') */ public static function registerLoader(callable $callable) : void { // Reset our static cache now that we have a new loader to work with self::$failedToAutoload = []; self::$loaders[] = $callable; } /** * Registers an autoloading callable for annotations, if it is not already registered * * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0 */ public static function registerUniqueLoader(callable $callable) : void { if ( ! in_array($callable, self::$loaders, true) ) { self::registerLoader($callable); } } /** * Autoloads an annotation class silently. */ public static function loadAnnotationClass(string $class) : bool { if (\class_exists($class, false)) { return true; } if (\array_key_exists($class, self::$failedToAutoload)) { return false; } 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 ($loader($class) === true) { return true; } } self::$failedToAutoload[$class] = null; return false; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/CachedReader.php000066400000000000000000000162001354601121100275050ustar00rootroot00000000000000. */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Cache\Cache; use ReflectionClass; /** * A cache aware annotation reader. * * @author Johannes M. Schmitt * @author Benjamin Eberlei */ final class CachedReader implements Reader { /** * @var Reader */ private $delegate; /** * @var Cache */ private $cache; /** * @var boolean */ private $debug; /** * @var array */ private $loadedAnnotations = []; /** * Constructor. * * @param Reader $reader * @param Cache $cache * @param bool $debug */ public function __construct(Reader $reader, Cache $cache, $debug = false) { $this->delegate = $reader; $this->cache = $cache; $this->debug = (boolean) $debug; } /** * {@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 = []; } /** * Fetches a value from the cache. * * @param string $cacheKey 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($cacheKey, ReflectionClass $class) { 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 $cacheKey The cache key. * @param mixed $value The value. * * @return void */ private function saveToCache($cacheKey, $value) { $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 (null === $lastModification = $this->getLastModification($class)) { return true; } return $this->cache->fetch('[C]'.$cacheKey) >= $lastModification; } /** * Returns the time the class was last modified, testing traits and parents * * @param ReflectionClass $class * @return int */ private function getLastModification(ReflectionClass $class) { $filename = $class->getFileName(); $parent = $class->getParentClass(); return max(array_merge( [$filename ? filemtime($filename) : 0], array_map([$this, 'getTraitLastModificationTime'], $class->getTraits()), array_map([$this, 'getLastModification'], $class->getInterfaces()), $parent ? [$this->getLastModification($parent)] : [] )); } /** * @param ReflectionClass $reflectionTrait * @return int */ private function getTraitLastModificationTime(ReflectionClass $reflectionTrait) { $fileName = $reflectionTrait->getFileName(); return max(array_merge( [$fileName ? filemtime($fileName) : 0], array_map([$this, 'getTraitLastModificationTime'], $reflectionTrait->getTraits()) )); } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/DocLexer.php000066400000000000000000000106061354601121100267240ustar00rootroot00000000000000. */ 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; const T_MINUS = 113; /** * @var array */ protected $noCase = [ '@' => 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_MINUS, '\\' => self::T_NAMESPACE_SEPARATOR ]; /** * @var array */ protected $withCase = [ 'true' => self::T_TRUE, 'false' => self::T_FALSE, 'null' => self::T_NULL ]; /** * Whether the next token starts immediately, or if there were * non-captured symbols before that */ public function nextTokenIsAdjacent() : bool { return $this->token === null || ($this->lookahead !== null && ($this->lookahead['position'] - $this->token['position']) === strlen($this->token['value'])); } /** * {@inheritdoc} */ protected function getCatchablePatterns() { return [ '[a-z_\\\][a-z0-9_\:\\\]*[a-z_][a-z0-9_]*', '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?', '"(?:""|[^"])*+"', ]; } /** * {@inheritdoc} */ protected function getNonCatchablePatterns() { return ['\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; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/DocParser.php000066400000000000000000001154411354601121100271040ustar00rootroot00000000000000. */ 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 = [ 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 integer */ 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 = []; /** * This hashmap is used internally to cache results of class_exists() * look-ups. * * @var array */ private $classExists = []; /** * 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 string[] */ private $namespaces = []; /** * 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 bool[] indexed by annotation name */ private $ignoredAnnotationNames = []; /** * A list with annotations in namespaced format * that are not causing exceptions when not resolved to an annotation class. * * @var bool[] indexed by namespace name */ private $ignoredAnnotationNamespaces = []; /** * @var string */ private $context = ''; /** * Hash-map for caching annotation metadata. * * @var array */ private static $annotationMetadata = [ 'Doctrine\Common\Annotations\Annotation\Target' => [ 'is_annotation' => true, 'has_constructor' => true, 'properties' => [], 'targets_literal' => 'ANNOTATION_CLASS', 'targets' => Target::TARGET_CLASS, 'default_property' => 'value', 'attribute_types' => [ 'value' => [ 'required' => false, 'type' =>'array', 'array_type'=>'string', 'value' =>'array' ] ], ], 'Doctrine\Common\Annotations\Annotation\Attribute' => [ 'is_annotation' => true, 'has_constructor' => false, 'targets_literal' => 'ANNOTATION_ANNOTATION', 'targets' => Target::TARGET_ANNOTATION, 'default_property' => 'name', 'properties' => [ 'name' => 'name', 'type' => 'type', 'required' => 'required' ], 'attribute_types' => [ 'value' => [ 'required' => true, 'type' =>'string', 'value' =>'string' ], 'type' => [ 'required' =>true, 'type' =>'string', 'value' =>'string' ], 'required' => [ 'required' =>false, 'type' =>'boolean', 'value' =>'boolean' ] ], ], 'Doctrine\Common\Annotations\Annotation\Attributes' => [ 'is_annotation' => true, 'has_constructor' => false, 'targets_literal' => 'ANNOTATION_CLASS', 'targets' => Target::TARGET_CLASS, 'default_property' => 'value', 'properties' => [ 'value' => 'value' ], 'attribute_types' => [ 'value' => [ 'type' =>'array', 'required' =>true, 'array_type'=>'Doctrine\Common\Annotations\Annotation\Attribute', 'value' =>'array' ] ], ], 'Doctrine\Common\Annotations\Annotation\Enum' => [ 'is_annotation' => true, 'has_constructor' => true, 'targets_literal' => 'ANNOTATION_PROPERTY', 'targets' => Target::TARGET_PROPERTY, 'default_property' => 'value', 'properties' => [ 'value' => 'value' ], 'attribute_types' => [ 'value' => [ 'type' => 'array', 'required' => true, ], 'literal' => [ 'type' => 'array', 'required' => false, ], ], ], ]; /** * Hash-map for handle types declaration. * * @var array */ private static $typeMap = [ '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 bool[] $names indexed by annotation name * * @return void */ public function setIgnoredAnnotationNames(array $names) { $this->ignoredAnnotationNames = $names; } /** * Sets the annotation namespaces that are ignored during the parsing process. * * @param bool[] $ignoredAnnotationNamespaces indexed by annotation namespace name * * @return void */ public function setIgnoredAnnotationNamespaces($ignoredAnnotationNamespaces) { $this->ignoredAnnotationNamespaces = $ignoredAnnotationNamespaces; } /** * Sets ignore on not-imported annotations. * * @param boolean $bool * * @return void */ public function setIgnoreNotImportedAnnotations($bool) { $this->ignoreNotImportedAnnotations = (boolean) $bool; } /** * Sets the default namespaces. * * @param string $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 []; } $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) { $preceding = substr($input, $pos - 1, 1); // if the @ is preceded by a space, a tab or * it is valid if ($pos === 0 || $preceding === ' ' || $preceding === '*' || $preceding === "\t") { 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([$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([ '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 = [ 'default_property' => null, 'has_constructor' => (null !== $constructor = $class->getConstructor()) && $constructor->getNumberOfParameters() > 0, 'properties' => [], 'property_types' => [], 'attribute_types' => [], '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 = 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 = []; 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(); if ($this->lexer->isNextToken(DocLexer::T_MINUS) && $this->lexer->nextTokenIsAdjacent() ) { // Annotations with dashes, such as "@foo-" or "@foo-bar", are to be discarded return false; } // only process names which are not fully qualified, yet // fully qualified names must start with a \ $originalName = $name; if ('\\' !== $name[0]) { $pos = strpos($name, '\\'); $alias = (false === $pos)? $name : substr($name, 0, $pos); $found = false; $loweredAlias = strtolower($alias); if ($this->namespaces) { foreach ($this->namespaces as $namespace) { if ($this->classExists($namespace.'\\'.$name)) { $name = $namespace.'\\'.$name; $found = true; break; } } } elseif (isset($this->imports[$loweredAlias])) { $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->isIgnoredAnnotation($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)); } } $name = ltrim($name,'\\'); 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 ($this->ignoreNotImportedAnnotations || 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] = [$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 = []; 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 = [$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'] = [$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); $pos = strpos($className, '\\'); $alias = (false === $pos) ? $className : substr($className, 0, $pos); $found = false; $loweredAlias = strtolower($alias); 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]): $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 ( null !== $this->lexer->lookahead && $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 \stdClass */ 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 = []; $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([DocLexer::T_INTEGER, DocLexer::T_STRING]); $key = $this->lexer->token['value']; } $this->matchAny([DocLexer::T_EQUALS, DocLexer::T_COLON]); return [$key, $this->PlainValue()]; } return [null, $this->Value()]; } /** * Checks whether the given $name matches any ignored annotation name or namespace * * @param string $name * * @return bool */ private function isIgnoredAnnotation($name) { if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) { return true; } foreach (array_keys($this->ignoredAnnotationNamespaces) as $ignoredAnnotationNamespace) { $ignoredAnnotationNamespace = rtrim($ignoredAnnotationNamespace, '\\') . '\\'; if (0 === stripos(rtrim($name, '\\') . '\\', $ignoredAnnotationNamespace)) { return true; } } return false; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/FileCacheReader.php000066400000000000000000000212641354601121100301470ustar00rootroot00000000000000. */ namespace Doctrine\Common\Annotations; /** * File cache reader for annotations. * * @author Johannes M. Schmitt * @author Benjamin Eberlei * * @deprecated the FileCacheReader is deprecated and will be removed * in version 2.0.0 of doctrine/annotations. Please use the * {@see \Doctrine\Common\Annotations\CachedReader} instead. */ class FileCacheReader implements Reader { /** * @var Reader */ private $reader; /** * @var string */ private $dir; /** * @var bool */ private $debug; /** * @var array */ private $loadedAnnotations = []; /** * @var array */ private $classNameHashes = []; /** * @var int */ private $umask; /** * Constructor. * * @param Reader $reader * @param string $cacheDir * @param boolean $debug * * @throws \InvalidArgumentException */ public function __construct(Reader $reader, $cacheDir, $debug = false, $umask = 0002) { if ( ! is_int($umask)) { throw new \InvalidArgumentException(sprintf( 'The parameter umask must be an integer, was: %s', gettype($umask) )); } $this->reader = $reader; $this->umask = $umask; if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777 & (~$this->umask), 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)); } $tempfile = tempnam($this->dir, uniqid('', true)); if (false === $tempfile) { throw new \RuntimeException(sprintf('Unable to create tempfile in directory: %s', $this->dir)); } @chmod($tempfile, 0666 & (~$this->umask)); $written = file_put_contents($tempfile, 'umask)); if (false === rename($tempfile, $path)) { @unlink($tempfile); throw new \RuntimeException(sprintf('Unable to rename %s to %s', $tempfile, $path)); } } /** * {@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 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 = []; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/IndexedReader.php000066400000000000000000000063151354601121100277240ustar00rootroot00000000000000. */ 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 = []; 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 = []; 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 = []; 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([$this->delegate, $method], $args); } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/PhpParser.php000066400000000000000000000056221354601121100271250ustar00rootroot00000000000000. */ 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 []; } $content = $this->getFileContent($filename, $class->getStartLine()); if (null === $content) { return []; } $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|null The content of the file or null if the file does not exist. */ 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; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/Reader.php000066400000000000000000000067071354601121100264300ustar00rootroot00000000000000. */ 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); } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php000066400000000000000000000071111354601121100316230ustar00rootroot00000000000000. */ 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; } } php-doctrine-annotations-1.8.0/lib/Doctrine/Common/Annotations/TokenParser.php000066400000000000000000000142741354601121100274610ustar00rootroot00000000000000. */ 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() { $groupRoot = ''; $class = ''; $alias = ''; $statements = []; $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)] = $groupRoot . $class; $class = ''; $alias = ''; $explicitAlias = false; } else if ($token === ';') { $statements[strtolower($alias)] = $groupRoot . $class; break; } else if ($token === '{' ) { $groupRoot = $class; $class = ''; } else if ($token === '}' ) { continue; } 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 = []; 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 = []; } 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(); } } php-doctrine-annotations-1.8.0/phpbench.json.dist000066400000000000000000000002041354601121100220610ustar00rootroot00000000000000{ "bootstrap": "tests/Doctrine/Performance/Common/bootstrap.php", "path": "tests/Doctrine/Performance/Common/Annotations" } php-doctrine-annotations-1.8.0/phpstan.neon000066400000000000000000000017001354601121100207750ustar00rootroot00000000000000parameters: autoload_files: - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Annotations/DocParserTest.php excludes_analyse: - %currentWorkingDirectory%/tests/*/Fixtures/* - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Annotations/ReservedKeywordsClasses.php - %currentWorkingDirectory%/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Entity.php - %currentWorkingDirectory%/tests/Doctrine/Tests/DoctrineTestCase.php polluteScopeWithLoopInitialAssignments: true ignoreErrors: - '#Class Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment not found#' - '#Instantiated class Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment not found#' - '#Property Doctrine\\Tests\\Common\\Annotations\\DummyClassNonAnnotationProblem::\$foo has unknown class#' - '#Call to an undefined method ReflectionClass::getUseStatements\(\)#' php-doctrine-annotations-1.8.0/phpunit.xml.dist000066400000000000000000000014361354601121100216200ustar00rootroot00000000000000 ./tests/Doctrine/ ./lib/Doctrine/ php-doctrine-annotations-1.8.0/tests/000077500000000000000000000000001354601121100176035ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/000077500000000000000000000000001354601121100213525ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/000077500000000000000000000000001354601121100236135ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/000077500000000000000000000000001354601121100250435ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotations/000077500000000000000000000000001354601121100273405ustar00rootroot00000000000000CachedReadPerformanceWithInMemoryBench.php000066400000000000000000000015641354601121100374010ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotationsreader = new CachedReader(new AnnotationReader(), new ArrayCache()); $this->method = new ReflectionMethod(Controller::class, 'helloAction'); } /** * @Revs(500) * @Iterations(5) */ public function bench() : void { $this->reader->getMethodAnnotations($this->method); } } DocLexerPerformanceBench.php000066400000000000000000000013241354601121100346210ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotationslexer = new DocLexer(); } /** * @Revs(500) * @Iterations(5) */ public function benchMethod() : void { $this->lexer->setInput($this->methodDocBlock); } /** * @Revs(500) * @Iterations(5) */ public function benchClass() : void { $this->lexer->setInput($this->classDocBlock); } } DocParserPerformanceBench.php000066400000000000000000000033061354601121100350000ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotations 'Annotations\Annotation\IgnorePhpDoc', 'ignoreannotation' => 'Annotations\Annotation\IgnoreAnnotation', 'route' => Route::class, 'template' => Template::class, '__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations\Fixtures', ]; private const IGNORED = [ 'access', 'author', 'copyright', 'deprecated', 'example', 'ignore', 'internal', 'link', 'see', 'since', 'tutorial', 'version', 'package', 'subpackage', 'name', 'global', 'param', 'return', 'staticvar', 'static', 'var', 'throws', 'inheritdoc', ]; /** @var DocParser */ private $parser; public function initialize() : void { $this->parser = new DocParser(); $this->parser->setImports(self::IMPORTS); $this->parser->setIgnoredAnnotationNames(array_fill_keys(self::IGNORED, true)); $this->parser->setIgnoreNotImportedAnnotations(true); } /** * @Revs(200) * @Iterations(5) */ public function benchMethodParsing() : void { $this->parser->parse($this->methodDocBlock); } /** * @Revs(200) * @Iterations(5) */ public function benchClassParsing() : void { $this->parser->parse($this->classDocBlock); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotations/MethodInitializer.php000066400000000000000000000012121354601121100334710ustar00rootroot00000000000000method = new ReflectionMethod(Controller::class, 'helloAction'); $this->methodDocBlock = $this->method->getDocComment(); $this->classDocBlock = $this->method->getDeclaringClass()->getDocComment(); } } PhpParserPerformanceWithShortCutBench.php000066400000000000000000000013601354601121100373500ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotationsclass = new ReflectionClass(NamespacedSingleClassLOC1000::class); $this->parser = new PhpParser(); } /** * @Revs(500) * @Iterations(5) */ public function bench() : void { $this->parser->parseClass($this->class); } } PhpParserPerformanceWithoutShortCutBench.php000066400000000000000000000012641354601121100401030ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotationsclass = new ReflectionClass(SingleClassLOC1000::class); $this->parser = new PhpParser(); } /** * @Revs(500) * @Iterations(5) */ public function bench() : void { $this->parser->parseClass($this->class); } } ReadPerformanceBench.php000066400000000000000000000011061354601121100337650ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/Annotationsreader = new AnnotationReader(); } /** * @Revs(500) * @Iterations(5) */ public function bench() : void { $this->reader->getMethodAnnotations($this->method); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Performance/Common/bootstrap.php000066400000000000000000000005501354601121100275710ustar00rootroot00000000000000getReflectionClass(); $reader = $this->getReader(); self::assertCount(1, $reader->getClassAnnotations($class)); self::assertInstanceOf($annotName = DummyAnnotation::class, $annot = $reader->getClassAnnotation($class, $annotName)); self::assertEquals('hello', $annot->dummyValue); $field1Prop = $class->getProperty('field1'); $propAnnots = $reader->getPropertyAnnotations($field1Prop); self::assertCount(1, $propAnnots); self::assertInstanceOf($annotName, $annot = $reader->getPropertyAnnotation($field1Prop, $annotName)); self::assertEquals('fieldHello', $annot->dummyValue); $getField1Method = $class->getMethod('getField1'); $methodAnnots = $reader->getMethodAnnotations($getField1Method); self::assertCount(1, $methodAnnots); self::assertInstanceOf($annotName, $annot = $reader->getMethodAnnotation($getField1Method, $annotName)); self::assertEquals([1, 2, 'three'], $annot->value); $field2Prop = $class->getProperty('field2'); $propAnnots = $reader->getPropertyAnnotations($field2Prop); self::assertCount(1, $propAnnots); self::assertInstanceOf($annotName = DummyJoinTable::class, $joinTableAnnot = $reader->getPropertyAnnotation($field2Prop, $annotName)); self::assertCount(1, $joinTableAnnot->joinColumns); self::assertCount(1, $joinTableAnnot->inverseJoinColumns); self::assertInstanceOf(DummyJoinColumn::class, $joinTableAnnot->joinColumns[0]); self::assertInstanceOf(DummyJoinColumn::class, $joinTableAnnot->inverseJoinColumns[0]); self::assertEquals('col1', $joinTableAnnot->joinColumns[0]->name); self::assertEquals('col2', $joinTableAnnot->joinColumns[0]->referencedColumnName); self::assertEquals('col3', $joinTableAnnot->inverseJoinColumns[0]->name); self::assertEquals('col4', $joinTableAnnot->inverseJoinColumns[0]->referencedColumnName); $dummyAnnot = $reader->getMethodAnnotation($class->getMethod('getField1'), DummyAnnotation::class); self::assertEquals('', $dummyAnnot->dummyValue); self::assertEquals([1, 2, 'three'], $dummyAnnot->value); $dummyAnnot = $reader->getMethodAnnotation($class->getMethod('getField3'), DummyAnnotation::class); self::assertEquals('\d{4}-[01]\d-[0-3]\d [0-2]\d:[0-5]\d:[0-5]\d', $dummyAnnot->value); $dummyAnnot = $reader->getPropertyAnnotation($class->getProperty('field1'), DummyAnnotation::class); self::assertEquals('fieldHello', $dummyAnnot->dummyValue); $classAnnot = $reader->getClassAnnotation($class, DummyAnnotation::class); self::assertEquals('hello', $classAnnot->dummyValue); } public function testAnnotationsWithValidTargets() { $reader = $this->getReader(); $class = new ReflectionClass(Fixtures\ClassWithValidAnnotationTarget::class); self::assertCount(1, $reader->getClassAnnotations($class)); self::assertCount(1, $reader->getPropertyAnnotations($class->getProperty('foo'))); self::assertCount(1, $reader->getMethodAnnotations($class->getMethod('someFunction'))); self::assertCount(1, $reader->getPropertyAnnotations($class->getProperty('nested'))); } public function testAnnotationsWithVarType() { $reader = $this->getReader(); $class = new ReflectionClass(Fixtures\ClassWithAnnotationWithVarType::class); self::assertCount(1, $fooAnnot = $reader->getPropertyAnnotations($class->getProperty('foo'))); self::assertCount(1, $barAnnot = $reader->getMethodAnnotations($class->getMethod('bar'))); self::assertInternalType('string', $fooAnnot[0]->string); self::assertInstanceOf(Fixtures\AnnotationTargetAll::class, $barAnnot[0]->annotation); } public function testAtInDescription() { $reader = $this->getReader(); $class = new ReflectionClass(Fixtures\ClassWithAtInDescriptionAndAnnotation::class); self::assertCount(1, $fooAnnot = $reader->getPropertyAnnotations($class->getProperty('foo'))); self::assertCount(1, $barAnnot = $reader->getPropertyAnnotations($class->getProperty('bar'))); self::assertInstanceOf(Fixtures\AnnotationTargetPropertyMethod::class, $fooAnnot[0]); self::assertInstanceOf(Fixtures\AnnotationTargetPropertyMethod::class, $barAnnot[0]); } public function testClassWithWithDanglingComma() { $reader = $this->getReader(); $annots = $reader->getClassAnnotations(new \ReflectionClass(DummyClassWithDanglingComma::class)); self::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(Fixtures\ClassWithInvalidAnnotationTargetAtClass::class)); } public function testClassWithWithInclude() { $reader = $this->getReader(); $annots = $reader->getClassAnnotations(new \ReflectionClass(Fixtures\ClassWithRequire::class)); self::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(Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class, '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(Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class, '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(Fixtures\ClassWithInvalidAnnotationTargetAtMethod::class, '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(Fixtures\ClassWithAnnotationWithTargetSyntaxError::class)); } /** * @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(Fixtures\ClassWithAnnotationWithTargetSyntaxError::class,'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(Fixtures\ClassWithAnnotationWithTargetSyntaxError::class,'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(Fixtures\ClassWithAnnotationWithVarType::class); $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(Fixtures\ClassWithAnnotationWithVarType::class); $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(DummyClassSyntaxError::class)); } /** * @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(DummyClassMethodSyntaxError::class, '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(DummyClassPropertySyntaxError::class, 'foo')); } /** * @group regression */ public function testMultipleAnnotationsOnSameLine() { $reader = $this->getReader(); $annots = $reader->getPropertyAnnotations(new \ReflectionProperty(DummyClass2::class, 'id')); self::assertCount(3, $annots); } public function testNonAnnotationProblem() { $reader = $this->getReader(); self::assertNotNull($annot = $reader->getPropertyAnnotation(new \ReflectionProperty(DummyClassNonAnnotationProblem::class, 'foo'), $name = DummyAnnotation::class)); self::assertInstanceOf($name, $annot); } public function testIncludeIgnoreAnnotation() { $reader = $this->getReader(); $reader->getPropertyAnnotations(new \ReflectionProperty(Fixtures\ClassWithIgnoreAnnotation::class, 'foo')); self::assertFalse(class_exists(Fixtures\IgnoreAnnotationClass::class, false)); } public function testImportWithConcreteAnnotation() { $reader = $this->getReader(); $property = new \ReflectionProperty(TestImportWithConcreteAnnotation::class, 'field'); $annotations = $reader->getPropertyAnnotations($property); self::assertCount(1, $annotations); self::assertNotNull($reader->getPropertyAnnotation($property, DummyAnnotation::class)); } public function testImportWithInheritance() { $reader = $this->getReader(); $class = new TestParentClass(); $ref = new \ReflectionClass($class); $childAnnotations = $reader->getPropertyAnnotations($ref->getProperty('child')); self::assertCount(1, $childAnnotations); self::assertInstanceOf(Foo\Name::class, reset($childAnnotations)); $parentAnnotations = $reader->getPropertyAnnotations($ref->getProperty('parent')); self::assertCount(1, $parentAnnotations); self::assertInstanceOf(Bar\Name::class, 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(TestAnnotationNotImportedClass::class, '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(TestNonExistentAnnotationClass::class, 'field')); } public function testTopLevelAnnotation() { $reader = $this->getReader(); $annotations = $reader->getPropertyAnnotations(new \ReflectionProperty(TestTopLevelAnnotationClass::class, 'field')); self::assertCount(1, $annotations); self::assertInstanceOf(\TopLevelAnnotation::class, reset($annotations)); } public function testIgnoresAnnotationsNotPrefixedWithWhitespace() { $reader = $this->getReader(); $annotation = $reader->getClassAnnotation(new \ReflectionClass(new TestIgnoresNonAnnotationsClass()), Name::class); self::assertInstanceOf(Name::class, $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. self::assertFalse(!self::$testResetsPhpParserAfterUseRun && class_exists(\Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment::class), '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(Fixtures\ClassWithValidAnnotationTarget::class); $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(Fixtures\ClassWithClassAnnotationOnly::class); $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. self::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. self::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(Fixtures\InvalidAnnotationUsageClass::class); $reader->getClassAnnotations($ref); } public function testInvalidAnnotationUsageButIgnoredClass() { $reader = $this->getReader(); $ref = new \ReflectionClass(Fixtures\InvalidAnnotationUsageButIgnoredClass::class); $annots = $reader->getClassAnnotations($ref); self::assertCount(2, $annots); } /** * @group DDC-1660 * @group regression */ public function testInvalidAnnotationButIgnored() { $reader = $this->getReader(); $class = new \ReflectionClass(Fixtures\ClassDDC1660::class); self::assertTrue(class_exists(Fixtures\Annotation\Version::class)); self::assertEmpty($reader->getClassAnnotations($class)); self::assertEmpty($reader->getMethodAnnotations($class->getMethod('bar'))); self::assertEmpty($reader->getPropertyAnnotations($class->getProperty('foo'))); } public function testAnnotationEnumeratorException() { $reader = $this->getReader(); $class = new \ReflectionClass(Fixtures\ClassWithAnnotationEnum::class); self::assertCount(1, $bar = $reader->getMethodAnnotations($class->getMethod('bar'))); self::assertCount(1, $foo = $reader->getPropertyAnnotations($class->getProperty('foo'))); self::assertInstanceOf(Fixtures\AnnotationEnum::class, $bar[0]); self::assertInstanceOf(Fixtures\AnnotationEnum::class, $foo[0]); try { $reader->getPropertyAnnotations($class->getProperty('invalidProperty')); $this->fail(); } catch (AnnotationException $exc) { self::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 (AnnotationException $exc) { self::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(DCOM106::class); self::assertEmpty($reader->getClassAnnotations($ref)); } public function testWillSkipAnnotationsContainingDashes() { self::assertEmpty( $this ->getReader() ->getClassAnnotations(new \ReflectionClass( Fixtures\ClassWithInvalidAnnotationContainingDashes::class )) ); } public function testWillFailOnAnnotationConstantReferenceContainingDashes() { $reader = $this->getReader(); $reflection = new \ReflectionClass(Fixtures\ClassWithAnnotationConstantReferenceWithDashes::class); $this->expectExceptionMessage( '[Syntax Error] Expected Doctrine\Common\Annotations\DocLexer::T_CLOSE_PARENTHESIS, got \'-\' at' . ' position 14 in class ' . Fixtures\ClassWithAnnotationConstantReferenceWithDashes::class . '.' ); $reader->getClassAnnotations($reflection); } /** * @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; use Doctrine\Common\Annotations\Annotation; /** @Annotation */ class Name extends Annotation { public $name; } namespace Doctrine\Tests\Common\Annotations\Bar; use Doctrine\Common\Annotations\Annotation; /** @Annotation */ class Name extends Annotation { public $name; } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Annotation/000077500000000000000000000000001354601121100303135ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Annotation/TargetTest.php000066400000000000000000000035421354601121100331160ustar00rootroot00000000000000. */ namespace Doctrine\Tests\Common\Annotations\Annotation; use Doctrine\Common\Annotations\Annotation\Target; use PHPUnit\Framework\TestCase; /** * Tests for {@see \Doctrine\Common\Annotations\Annotation\Target} * * @covers \Doctrine\Common\Annotations\Annotation\Target */ class TargetTest extends TestCase { /** * @group DDC-3006 */ public function testValidMixedTargets() { $target = new Target(['value' => ['ALL']]); self::assertEquals(Target::TARGET_ALL, $target->targets); $target = new Target(['value' => ['METHOD', 'METHOD']]); self::assertEquals(Target::TARGET_METHOD, $target->targets); self::assertNotEquals(Target::TARGET_PROPERTY, $target->targets); $target = new Target(['value' => ['PROPERTY', 'METHOD']]); self::assertEquals(Target::TARGET_METHOD | Target::TARGET_PROPERTY, $target->targets); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php000066400000000000000000000135521354601121100330150ustar00rootroot00000000000000getReader(); $ref = new \ReflectionClass(Fixtures\ClassUsesTrait::class); $annotations = $reader->getMethodAnnotations($ref->getMethod('someMethod')); self::assertInstanceOf(Bar\Autoload::class, $annotations[0]); $annotations = $reader->getMethodAnnotations($ref->getMethod('traitMethod')); self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotations[0]); } public function testMethodAnnotationFromOverwrittenTrait() { $reader = $this->getReader(); $ref = new \ReflectionClass(Fixtures\ClassOverwritesTrait::class); $annotations = $reader->getMethodAnnotations($ref->getMethod('traitMethod')); self::assertInstanceOf(Bar2\Autoload::class, $annotations[0]); } public function testPropertyAnnotationFromTrait() { $reader = $this->getReader(); $ref = new \ReflectionClass(Fixtures\ClassUsesTrait::class); $annotations = $reader->getPropertyAnnotations($ref->getProperty('aProperty')); self::assertInstanceOf(Bar\Autoload::class, $annotations[0]); $annotations = $reader->getPropertyAnnotations($ref->getProperty('traitProperty')); self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotations[0]); } public function testOmitNotRegisteredAnnotation() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $reader = $this->getReader($parser); $ref = new \ReflectionClass(Fixtures\ClassWithNotRegisteredAnnotationUsed::class); $annotations = $reader->getMethodAnnotations($ref->getMethod('methodWithNotRegisteredAnnotation')); self::assertEquals([], $annotations); } /** * @group 45 * * @runInSeparateProcess */ public function testClassAnnotationIsIgnored() { $reader = $this->getReader(); $ref = new \ReflectionClass(AnnotatedAtClassLevel::class); $reader::addGlobalIgnoredNamespace('SomeClassAnnotationNamespace'); self::assertEmpty($reader->getClassAnnotations($ref)); } /** * @group 45 * * @runInSeparateProcess */ public function testMethodAnnotationIsIgnored() { $reader = $this->getReader(); $ref = new \ReflectionClass(AnnotatedAtMethodLevel::class); $reader::addGlobalIgnoredNamespace('SomeMethodAnnotationNamespace'); self::assertEmpty($reader->getMethodAnnotations($ref->getMethod('test'))); } /** * @group 45 * * @runInSeparateProcess */ public function testPropertyAnnotationIsIgnored() { $reader = $this->getReader(); $ref = new \ReflectionClass(AnnotatedAtPropertyLevel::class); $reader::addGlobalIgnoredNamespace('SomePropertyAnnotationNamespace'); self::assertEmpty($reader->getPropertyAnnotations($ref->getProperty('property'))); } public function testClassWithFullPathUseStatement() { if (class_exists(SingleUseAnnotation::class, false)) { throw new \LogicException( 'The SingleUseAnnotation must not be used in other tests for this test to be useful.' . 'If the class is already loaded then the code path that finds the class to load is not used and ' . 'this test becomes useless.' ); } $reader = $this->getReader(); $ref = new \ReflectionClass(ClassWithFullPathUseStatement::class); $annotations = $reader->getClassAnnotations($ref); self::assertInstanceOf(SingleUseAnnotation::class,$annotations[0]); } public function testPhpCsSuppressAnnotationIsIgnored() { $reader = $this->getReader(); $ref = new \ReflectionClass(ClassWithPhpCsSuppressAnnotation::class); self::assertEmpty($reader->getMethodAnnotations($ref->getMethod('foo'))); } public function testGloballyIgnoredAnnotationNotIgnored() : void { $reader = $this->getReader(); $class = new \ReflectionClass(Fixtures\ClassDDC1660::class); $testLoader = static function (string $className) : bool { if ($className === 'since') { throw new \InvalidArgumentException('Globally ignored annotation names should never be passed to an autoloader.'); } return false; }; spl_autoload_register($testLoader, true, true); try { self::assertEmpty($reader->getClassAnnotations($class)); } finally { spl_autoload_unregister($testLoader); } } public function testPHPCodeSnifferAnnotationsAreIgnored() { $reader = $this->getReader(); $ref = new \ReflectionClass(ClassWithPHPCodeSnifferAnnotation::class); self::assertEmpty($reader->getClassAnnotations($ref)); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/AnnotationRegistryTest.php000066400000000000000000000130441354601121100334170ustar00rootroot00000000000000 'bar']; $this->setStaticField($this->class, 'autoloadNamespaces', $data); $this->setStaticField($this->class, 'loaders', $data); self::assertSame($data, $this->getStaticField($this->class, 'autoloadNamespaces')); self::assertSame($data, $this->getStaticField($this->class, 'loaders')); AnnotationRegistry::reset(); self::assertEmpty($this->getStaticField($this->class, 'autoloadNamespaces')); self::assertEmpty($this->getStaticField($this->class, 'loaders')); } /** * @runInSeparateProcess */ public function testRegisterAutoloadNamespaces() : void { $this->setStaticField($this->class, 'autoloadNamespaces', ['foo' => 'bar']); AnnotationRegistry::registerAutoloadNamespaces(['test' => 'bar']); self::assertSame(['foo' => 'bar', 'test' => 'bar'], $this->getStaticField($this->class, 'autoloadNamespaces')); } /** * @runInSeparateProcess */ public function testRegisterLoaderNoCallable() : void { $this->expectException(\TypeError::class); AnnotationRegistry::registerLoader('test' . random_int(10, 10000)); } protected function setStaticField($class, $field, $value) { $reflection = new \ReflectionProperty($class, $field); $reflection->setAccessible(true); $reflection->setValue(null, $value); } protected function getStaticField($class, $field) { $reflection = new \ReflectionProperty($class, $field); $reflection->setAccessible(true); return $reflection->getValue(); } /** * @runInSeparateProcess */ public function testStopCallingLoadersIfClassIsNotFound() : void { AnnotationRegistry::reset(); $i = 0; $autoLoader = function () use (&$i) : bool { $i += 1; return false; }; AnnotationRegistry::registerLoader($autoLoader); AnnotationRegistry::loadAnnotationClass('unloadableClass'); AnnotationRegistry::loadAnnotationClass('unloadableClass'); AnnotationRegistry::loadAnnotationClass('unloadableClass'); self::assertSame(1, $i, 'Autoloader should only be called once'); } /** * @runInSeparateProcess */ public function testStopCallingLoadersAfterClassIsFound() : void { $className = 'autoloadedClass' . random_int(10, 100000); AnnotationRegistry::reset(); $i = 0; $autoLoader = function () use (&$i, $className) : bool { eval('class ' . $className . ' {}'); $i += 1; return true; }; AnnotationRegistry::registerLoader($autoLoader); AnnotationRegistry::loadAnnotationClass($className); AnnotationRegistry::loadAnnotationClass($className); AnnotationRegistry::loadAnnotationClass($className); self::assertSame(1, $i, 'Autoloader should only be called once'); } /** * @runInSeparateProcess */ public function testAddingANewLoaderClearsTheCache() : void { $failures = 0; $failingLoader = function () use (& $failures) : bool { $failures += 1; return false; }; AnnotationRegistry::reset(); AnnotationRegistry::registerLoader($failingLoader); self::assertSame(0, $failures); AnnotationRegistry::loadAnnotationClass('unloadableClass'); self::assertSame(1, $failures); AnnotationRegistry::loadAnnotationClass('unloadableClass'); self::assertSame(1, $failures); AnnotationRegistry::registerLoader(function () : bool { return false; }); AnnotationRegistry::loadAnnotationClass('unloadableClass'); self::assertSame(2, $failures); } /** * @runInSeparateProcess */ public function testResetClearsRegisteredAutoloaderFailures() : void { $failures = 0; $failingLoader = function () use (& $failures) : bool { $failures += 1; return false; }; AnnotationRegistry::reset(); AnnotationRegistry::registerLoader($failingLoader); self::assertSame(0, $failures); AnnotationRegistry::loadAnnotationClass('unloadableClass'); self::assertSame(1, $failures); AnnotationRegistry::loadAnnotationClass('unloadableClass'); self::assertSame(1, $failures); AnnotationRegistry::reset(); AnnotationRegistry::registerLoader($failingLoader); AnnotationRegistry::loadAnnotationClass('unloadableClass'); self::assertSame(2, $failures); } /** * @runInSeparateProcess */ public function testRegisterLoaderIfNotExistsOnlyRegisteresSameLoaderOnce() : void { $className = 'autoloadedClassThatDoesNotExist'; AnnotationRegistry::reset(); $autoLoader = self::createPartialMock(\stdClass::class, ['__invoke']); $autoLoader->expects($this->once())->method('__invoke'); AnnotationRegistry::registerUniqueLoader($autoLoader); AnnotationRegistry::registerUniqueLoader($autoLoader); AnnotationRegistry::loadAnnotationClass($className); AnnotationRegistry::loadAnnotationClass($className); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/AnnotationTest.php000066400000000000000000000017361354601121100316730ustar00rootroot00000000000000expectException(\BadMethodCallException::class); $this->expectExceptionMessage(sprintf( "Unknown property '%s' on annotation '%s'.", $name, Annotation::class )); $annotation->{$name}; } public function testMagicSetThrowsBadMethodCallException() { $name = 'foo'; $annotation = new Annotation([]); $this->expectException(\BadMethodCallException::class); $this->expectExceptionMessage(sprintf( "Unknown property '%s' on annotation '%s'.", $name, Annotation::class )); $annotation->{$name} = 9001; } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php000066400000000000000000000117321354601121100320500ustar00rootroot00000000000000doTestCacheStale(Fixtures\Controller::class, $cache); } /** * @group 62 */ public function testIgnoresStaleCacheWithParentClass() { $cache = time() - 10; touch(__DIR__.'/Fixtures/ControllerWithParentClass.php', $cache - 10); touch(__DIR__.'/Fixtures/AbstractController.php', $cache + 10); $this->doTestCacheStale(Fixtures\ControllerWithParentClass::class, $cache); } /** * @group 62 */ public function testIgnoresStaleCacheWithTraits() { $cache = time() - 10; touch(__DIR__.'/Fixtures/ControllerWithTrait.php', $cache - 10); touch(__DIR__.'/Fixtures/Traits/SecretRouteTrait.php', $cache + 10); $this->doTestCacheStale(Fixtures\ControllerWithTrait::class, $cache); } /** * @group 62 */ public function testIgnoresStaleCacheWithTraitsThatUseOtherTraits() { $cache = time() - 10; touch(__DIR__ . '/Fixtures/ClassThatUsesTraitThatUsesAnotherTrait.php', $cache - 10); touch(__DIR__ . '/Fixtures/Traits/EmptyTrait.php', $cache + 10); $this->doTestCacheStale( Fixtures\ClassThatUsesTraitThatUsesAnotherTrait::class, $cache ); } /** * @group 62 */ public function testIgnoresStaleCacheWithInterfacesThatExtendOtherInterfaces() { $cache = time() - 10; touch(__DIR__ . '/Fixtures/InterfaceThatExtendsAnInterface.php', $cache - 10); touch(__DIR__ . '/Fixtures/EmptyInterface.php', $cache + 10); $this->doTestCacheStale( Fixtures\InterfaceThatExtendsAnInterface::class, $cache ); } /** * @group 62 * @group 105 */ public function testUsesFreshCacheWithTraitsThatUseOtherTraits() { $cacheTime = time(); touch(__DIR__ . '/Fixtures/ClassThatUsesTraitThatUsesAnotherTrait.php', $cacheTime - 10); touch(__DIR__ . '/Fixtures/Traits/EmptyTrait.php', $cacheTime - 10); $this->doTestCacheFresh( 'Doctrine\Tests\Common\Annotations\Fixtures\ClassThatUsesTraitThatUsesAnotherTrait', $cacheTime ); } protected function doTestCacheStale($className, $lastCacheModification) { $cacheKey = $className; /* @var $cache Cache|\PHPUnit_Framework_MockObject_MockObject */ $cache = $this->createMock(Cache::class); $cache ->expects($this->at(0)) ->method('fetch') ->with($this->equalTo($cacheKey)) ->will($this->returnValue([])) // Result was cached, but there was no annotation ; $cache ->expects($this->at(1)) ->method('fetch') ->with($this->equalTo('[C]'.$cacheKey)) ->will($this->returnValue($lastCacheModification)) ; $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'; self::assertEquals([$route], $reader->getClassAnnotations(new \ReflectionClass($className))); } protected function doTestCacheFresh($className, $lastCacheModification) { $cacheKey = $className; $route = new Route(); $route->pattern = '/someprefix'; /* @var $cache Cache|\PHPUnit_Framework_MockObject_MockObject */ $cache = $this->createMock('Doctrine\Common\Cache\Cache'); $cache ->expects($this->at(0)) ->method('fetch') ->with($this->equalTo($cacheKey)) ->will($this->returnValue([$route])); // Result was cached, but there was an annotation; $cache ->expects($this->at(1)) ->method('fetch') ->with($this->equalTo('[C]' . $cacheKey)) ->will($this->returnValue($lastCacheModification)); $cache->expects(self::never())->method('save'); $reader = new CachedReader(new AnnotationReader(), $cache, true); $this->assertEquals([$route], $reader->getClassAnnotations(new \ReflectionClass($className))); } protected function getReader() { $this->cache = new ArrayCache(); return new CachedReader(new AnnotationReader(), $this->cache); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/DocLexerTest.php000066400000000000000000000226511354601121100312650ustar00rootroot00000000000000setInput('@Name'); self::assertNull($lexer->token); self::assertNull($lexer->lookahead); self::assertTrue($lexer->moveNext()); self::assertNull($lexer->token); self::assertEquals('@', $lexer->lookahead['value']); self::assertTrue($lexer->moveNext()); self::assertEquals('@', $lexer->token['value']); self::assertEquals('Name', $lexer->lookahead['value']); self::assertFalse($lexer->moveNext()); } public function testScannerTokenizesDocBlockWhitConstants() : void { $lexer = new DocLexer(); $docblock = '@AnnotationWithConstants(PHP_EOL, ClassWithConstants::SOME_VALUE, ClassWithConstants::CONSTANT_, ClassWithConstants::CONST_ANT3, \Doctrine\Tests\Common\Annotations\Fixtures\InterfaceWithConstants::SOME_VALUE)'; $tokens = [ [ 'value' => '@', 'position' => 0, 'type' => DocLexer::T_AT, ], [ 'value' => 'AnnotationWithConstants', 'position' => 1, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => '(', 'position' => 24, 'type' => DocLexer::T_OPEN_PARENTHESIS, ], [ 'value' => 'PHP_EOL', 'position' => 25, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => ',', 'position' => 32, 'type' => DocLexer::T_COMMA, ], [ 'value' => 'ClassWithConstants::SOME_VALUE', 'position' => 34, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => ',', 'position' => 64, 'type' => DocLexer::T_COMMA, ], [ 'value' => 'ClassWithConstants::CONSTANT_', 'position' => 66, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => ',', 'position' => 95, 'type' => DocLexer::T_COMMA, ], [ 'value' => 'ClassWithConstants::CONST_ANT3', 'position' => 97, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => ',', 'position' => 127, 'type' => DocLexer::T_COMMA, ], [ 'value' => '\\Doctrine\\Tests\\Common\\Annotations\\Fixtures\\InterfaceWithConstants::SOME_VALUE', 'position' => 129, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => ')', 'position' => 207, 'type' => DocLexer::T_CLOSE_PARENTHESIS, ] ]; $lexer->setInput($docblock); foreach ($tokens as $expected) { $lexer->moveNext(); $lookahead = $lexer->lookahead; self::assertEquals($expected['value'], $lookahead['value']); self::assertEquals($expected['type'], $lookahead['type']); self::assertEquals($expected['position'], $lookahead['position']); } self::assertFalse($lexer->moveNext()); } public function testScannerTokenizesDocBlockWhitInvalidIdentifier() : void { $lexer = new DocLexer(); $docblock = '@Foo\3.42'; $tokens = [ [ 'value' => '@', 'position' => 0, 'type' => DocLexer::T_AT, ], [ 'value' => 'Foo', 'position' => 1, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => '\\', 'position' => 4, 'type' => DocLexer::T_NAMESPACE_SEPARATOR, ], [ 'value' => 3.42, 'position' => 5, 'type' => DocLexer::T_FLOAT, ] ]; $lexer->setInput($docblock); foreach ($tokens as $expected) { $lexer->moveNext(); $lookahead = $lexer->lookahead; self::assertEquals($expected['value'], $lookahead['value']); self::assertEquals($expected['type'], $lookahead['type']); self::assertEquals($expected['position'], $lookahead['position']); } self::assertFalse($lexer->moveNext()); } /** * @group 44 */ public function testWithinDoubleQuotesVeryVeryLongStringWillNotOverflowPregSplitStackLimit() : void { $lexer = new DocLexer(); $lexer->setInput('"' . str_repeat('.', 20240) . '"'); self::assertInternalType('array', $lexer->glimpse()); } /** * @group 44 */ public function testRecognizesDoubleQuotesEscapeSequence() : void { $lexer = new DocLexer(); $docblock = '@Foo("""' . "\n" . '""")'; $tokens = [ [ 'value' => '@', 'position' => 0, 'type' => DocLexer::T_AT, ], [ 'value' => 'Foo', 'position' => 1, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => '(', 'position' => 4, 'type' => DocLexer::T_OPEN_PARENTHESIS, ], [ 'value' => "\"\n\"", 'position' => 5, 'type' => DocLexer::T_STRING, ], [ 'value' => ')', 'position' => 12, 'type' => DocLexer::T_CLOSE_PARENTHESIS, ], ]; $lexer->setInput($docblock); foreach ($tokens as $expected) { $lexer->moveNext(); $lookahead = $lexer->lookahead; self::assertEquals($expected['value'], $lookahead['value']); self::assertEquals($expected['type'], $lookahead['type']); self::assertEquals($expected['position'], $lookahead['position']); } self::assertFalse($lexer->moveNext()); } public function testDoesNotRecognizeFullAnnotationWithDashInIt() : void { $this->expectDocblockTokens( '@foo-bar--', [ [ 'value' => '@', 'position' => 0, 'type' => DocLexer::T_AT, ], [ 'value' => 'foo', 'position' => 1, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => '-', 'position' => 4, 'type' => DocLexer::T_MINUS, ], [ 'value' => 'bar', 'position' => 5, 'type' => DocLexer::T_IDENTIFIER, ], [ 'value' => '-', 'position' => 8, 'type' => DocLexer::T_MINUS, ], [ 'value' => '-', 'position' => 9, 'type' => DocLexer::T_MINUS, ], ] ); } public function testRecognizesNegativeNumbers() : void { $this->expectDocblockTokens( '-12.34 -56', [ [ 'value' => '-12.34', 'position' => 0, 'type' => DocLexer::T_FLOAT, ], [ 'value' => '-56', 'position' => 7, 'type' => DocLexer::T_INTEGER, ] ] ); } private function expectDocblockTokens(string $docBlock, array $expectedTokens) : void { $lexer = new DocLexer(); $lexer->setInput($docBlock); $actualTokens = []; while ($lexer->moveNext()) { $lookahead = $lexer->lookahead; $actualTokens[] = [ 'value' => $lookahead['value'], 'type' => $lookahead['type'], 'position' => $lookahead['position'], ]; } self::assertEquals($expectedTokens, $actualTokens); } public function testTokenAdjacency() : void { $lexer = new DocLexer(); $lexer->setInput('-- -'); self::assertTrue($lexer->nextTokenIsAdjacent()); self::assertTrue($lexer->moveNext()); self::assertTrue($lexer->nextTokenIsAdjacent()); self::assertTrue($lexer->moveNext()); self::assertTrue($lexer->nextTokenIsAdjacent()); self::assertTrue($lexer->moveNext()); self::assertFalse($lexer->nextTokenIsAdjacent()); self::assertFalse($lexer->moveNext()); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/DocParserTest.php000066400000000000000000001447301354601121100314450ustar00rootroot00000000000000createTestParser(); // Nested arrays with nested annotations $result = $parser->parse('@Name(foo={1,2, {"key"=@Name}})'); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertNull($annot->value); self::assertCount(3, $annot->foo); self::assertEquals(1, $annot->foo[0]); self::assertEquals(2, $annot->foo[1]); self::assertInternalType('array', $annot->foo[2]); $nestedArray = $annot->foo[2]; self::assertTrue(isset($nestedArray['key'])); self::assertInstanceOf(Name::class, $nestedArray['key']); } public function testBasicAnnotations() { $parser = $this->createTestParser(); // Marker annotation $result = $parser->parse('@Name'); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertNull($annot->value); self::assertNull($annot->foo); // Associative arrays $result = $parser->parse('@Name(foo={"key1" = "value1"})'); $annot = $result[0]; self::assertNull($annot->value); self::assertInternalType('array', $annot->foo); self::assertTrue(isset($annot->foo['key1'])); // Numerical arrays $result = $parser->parse('@Name({2="foo", 4="bar"})'); $annot = $result[0]; self::assertInternalType('array', $annot->value); self::assertEquals('foo', $annot->value[2]); self::assertEquals('bar', $annot->value[4]); self::assertFalse(isset($annot->value[0])); self::assertFalse(isset($annot->value[1])); self::assertFalse(isset($annot->value[3])); // Multiple values $result = $parser->parse('@Name(@Name, @Name)'); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertInternalType('array', $annot->value); self::assertInstanceOf(Name::class, $annot->value[0]); self::assertInstanceOf(Name::class, $annot->value[1]); // Multiple types as values $result = $parser->parse('@Name(foo="Bar", @Name, {"key1"="value1", "key2"="value2"})'); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertInternalType('array', $annot->value); self::assertInstanceOf(Name::class, $annot->value[0]); self::assertInternalType('array', $annot->value[1]); self::assertEquals('value1', $annot->value[1]['key1']); self::assertEquals('value2', $annot->value[1]['key2']); // Complete docblock $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertEquals('bar', $annot->foo); self::assertNull($annot->value); } public function testDefaultValueAnnotations() { $parser = $this->createTestParser(); // Array as first value $result = $parser->parse('@Name({"key1"="value1"})'); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertInternalType('array', $annot->value); self::assertEquals('value1', $annot->value['key1']); // Array as first value and additional values $result = $parser->parse('@Name({"key1"="value1"}, foo="bar")'); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertInternalType('array', $annot->value); self::assertEquals('value1', $annot->value['key1']); self::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); self::assertCount(1, $result); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertEquals('bar', $annot->foo); } /** * @group debug */ public function testTypicalMethodDocBlock() { $parser = $this->createTestParser(); $docblock = <<parse($docblock); self::assertCount(2, $result); self::assertTrue(isset($result[0])); self::assertTrue(isset($result[1])); $annot = $result[0]; self::assertInstanceOf(Name::class, $annot); self::assertEquals('bar', $annot->foo); $marker = $result[1]; self::assertInstanceOf(Marker::class, $marker); } public function testAnnotationWithoutConstructor() { $parser = $this->createTestParser(); $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertInstanceOf(SomeAnnotationClassNameWithoutConstructor::class, $annot); self::assertNull($annot->name); self::assertNotNull($annot->data); self::assertEquals($annot->data, 'Some data'); $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertNotNull($annot); self::assertInstanceOf(SomeAnnotationClassNameWithoutConstructor::class, $annot); self::assertEquals($annot->name, 'Some Name'); self::assertEquals($annot->data, 'Some data'); $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertEquals($annot->data, 'Some data'); self::assertNull($annot->name); $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertEquals($annot->name, 'Some name'); self::assertNull($annot->data); $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertEquals($annot->data, 'Some data'); self::assertNull($annot->name); $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertEquals($annot->name, 'Some name'); self::assertEquals($annot->data, 'Some data'); $docblock = <<parse($docblock); self::assertCount(1, $result); $annot = $result[0]; self::assertEquals($annot->name, 'Some name'); self::assertEquals($annot->data, 'Some data'); $docblock = <<parse($docblock); self::assertCount(1, $result); self::assertInstanceOf(SomeAnnotationClassNameWithoutConstructorAndProperties::class, $result[0]); } public function testAnnotationTarget() { $parser = new DocParser; $parser->setImports([ '__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations\Fixtures', ]); $class = new \ReflectionClass(Fixtures\ClassWithValidAnnotationTarget::class); $context = 'class ' . $class->getName(); $docComment = $class->getDocComment(); $parser->setTarget(Target::TARGET_CLASS); self::assertNotNull($parser->parse($docComment,$context)); $property = $class->getProperty('foo'); $docComment = $property->getDocComment(); $context = 'property ' . $class->getName() . "::\$" . $property->getName(); $parser->setTarget(Target::TARGET_PROPERTY); self::assertNotNull($parser->parse($docComment,$context)); $method = $class->getMethod('someFunction'); $docComment = $property->getDocComment(); $context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; $parser->setTarget(Target::TARGET_METHOD); self::assertNotNull($parser->parse($docComment,$context)); try { $class = new \ReflectionClass(Fixtures\ClassWithInvalidAnnotationTargetAtClass::class); $context = 'class ' . $class->getName(); $docComment = $class->getDocComment(); $parser->setTarget(Target::TARGET_CLASS); $parser->parse($docComment, $context); $this->fail(); } catch (AnnotationException $exc) { self::assertNotNull($exc->getMessage()); } try { $class = new \ReflectionClass(Fixtures\ClassWithInvalidAnnotationTargetAtMethod::class); $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 (AnnotationException $exc) { self::assertNotNull($exc->getMessage()); } try { $class = new \ReflectionClass(Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class); $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 (AnnotationException $exc) { self::assertNotNull($exc->getMessage()); } } public function getAnnotationVarTypeProviderValid() { //({attribute name}, {attribute value}) return [ // mixed type ['mixed', '"String Value"'], ['mixed', 'true'], ['mixed', 'false'], ['mixed', '1'], ['mixed', '1.2'], ['mixed', '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll'], // boolean type ['boolean', 'true'], ['boolean', 'false'], // alias for internal type boolean ['bool', 'true'], ['bool', 'false'], // integer type ['integer', '0'], ['integer', '1'], ['integer', '123456789'], ['integer', '9223372036854775807'], // alias for internal type double ['float', '0.1'], ['float', '1.2'], ['float', '123.456'], // string type ['string', '"String Value"'], ['string', '"true"'], ['string', '"123"'], // array type ['array', '{@AnnotationExtendsAnnotationTargetAll}'], ['array', '{@AnnotationExtendsAnnotationTargetAll,@AnnotationExtendsAnnotationTargetAll}'], ['arrayOfIntegers', '1'], ['arrayOfIntegers', '{1}'], ['arrayOfIntegers', '{1,2,3,4}'], ['arrayOfAnnotations', '@AnnotationExtendsAnnotationTargetAll'], ['arrayOfAnnotations', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll}'], ['arrayOfAnnotations', '{@AnnotationExtendsAnnotationTargetAll, @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll}'], // annotation instance ['annotation', '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll'], ['annotation', '@AnnotationExtendsAnnotationTargetAll'], ]; } public function getAnnotationVarTypeProviderInvalid() { //({attribute name}, {type declared type}, {attribute value} , {given type or class}) return [ // boolean type ['boolean','boolean','1','integer'], ['boolean','boolean','1.2','double'], ['boolean','boolean','"str"','string'], ['boolean','boolean','{1,2,3}','array'], ['boolean','boolean','@Name', 'an instance of Doctrine\Tests\Common\Annotations\Name'], // alias for internal type boolean ['bool','bool', '1','integer'], ['bool','bool', '1.2','double'], ['bool','bool', '"str"','string'], ['bool','bool', '{"str"}','array'], // integer type ['integer','integer', 'true','boolean'], ['integer','integer', 'false','boolean'], ['integer','integer', '1.2','double'], ['integer','integer', '"str"','string'], ['integer','integer', '{"str"}','array'], ['integer','integer', '{1,2,3,4}','array'], // alias for internal type double ['float','float', 'true','boolean'], ['float','float', 'false','boolean'], ['float','float', '123','integer'], ['float','float', '"str"','string'], ['float','float', '{"str"}','array'], ['float','float', '{12.34}','array'], ['float','float', '{1,2,3}','array'], // string type ['string','string', 'true','boolean'], ['string','string', 'false','boolean'], ['string','string', '12','integer'], ['string','string', '1.2','double'], ['string','string', '{"str"}','array'], ['string','string', '{1,2,3,4}','array'], // annotation instance ['annotation', AnnotationTargetAll::class, 'true','boolean'], ['annotation', AnnotationTargetAll::class, 'false','boolean'], ['annotation', AnnotationTargetAll::class, '12','integer'], ['annotation', AnnotationTargetAll::class, '1.2','double'], ['annotation', AnnotationTargetAll::class, '{"str"}','array'], ['annotation', AnnotationTargetAll::class, '{1,2,3,4}','array'], ['annotation', AnnotationTargetAll::class, '@Name','an instance of Doctrine\Tests\Common\Annotations\Name'], ]; } public function getAnnotationVarTypeArrayProviderInvalid() { //({attribute name}, {type declared type}, {attribute value} , {given type or class}) return [ ['arrayOfIntegers', 'integer', 'true', 'boolean'], ['arrayOfIntegers', 'integer', 'false', 'boolean'], ['arrayOfIntegers', 'integer', '{true,true}', 'boolean'], ['arrayOfIntegers', 'integer', '{1,true}', 'boolean'], ['arrayOfIntegers', 'integer', '{1,2,1.2}', 'double'], ['arrayOfIntegers', 'integer', '{1,2,"str"}', 'string'], ['arrayOfStrings', 'string', 'true', 'boolean'], ['arrayOfStrings', 'string', 'false', 'boolean'], ['arrayOfStrings', 'string', '{true,true}', 'boolean'], ['arrayOfStrings', 'string', '{"foo",true}', 'boolean'], ['arrayOfStrings', 'string', '{"foo","bar",1.2}', 'double'], ['arrayOfStrings', 'string', '1', 'integer'], ['arrayOfAnnotations', AnnotationTargetAll::class, 'true', 'boolean'], ['arrayOfAnnotations', AnnotationTargetAll::class, 'false', 'boolean'], ['arrayOfAnnotations', AnnotationTargetAll::class, '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,true}', 'boolean'], ['arrayOfAnnotations', AnnotationTargetAll::class, '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,true}', 'boolean'], ['arrayOfAnnotations', AnnotationTargetAll::class, '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,1.2}', 'double'], ['arrayOfAnnotations', AnnotationTargetAll::class, '{@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); self::assertCount(1, $result); self::assertInstanceOf(Fixtures\AnnotationWithVarType::class, $result[0]); self::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 (AnnotationException $exc) { self::assertStringMatchesFormat( '[Type Error] Attribute "' . $attribute . '" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects a(n) %A' . $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 (AnnotationException $exc) { self::assertStringMatchesFormat( '[Type Error] Attribute "' . $attribute . '" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects either a(n) %A' . $type . ', or an array of %A' . $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); self::assertCount(1, $result); self::assertInstanceOf(Fixtures\AnnotationWithAttributes::class, $result[0]); $getter = 'get' .ucfirst($attribute); self::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 (AnnotationException $exc) { self::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 (AnnotationException $exc) { self::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); self::assertCount(1, $result); /* @var $annotation Fixtures\AnnotationWithRequiredAttributes */ $annotation = $result[0]; self::assertInstanceOf(Fixtures\AnnotationWithRequiredAttributes::class, $annotation); self::assertEquals('Some Value', $annotation->getValue()); self::assertInstanceOf(Fixtures\AnnotationTargetAnnotation::class, $annotation->getAnnot()); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes("Some Value")'; try { $parser->parse($docblock, $context); $this->fail(); } catch (AnnotationException $exc) { self::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 { $parser->parse($docblock, $context); $this->fail(); } catch (AnnotationException $exc) { self::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 testAnnotationWithRequiredAttributesWithoutConstructor() { $parser = $this->createTestParser(); $context = 'property SomeClassName::invalidProperty.'; $parser->setTarget(Target::TARGET_PROPERTY); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor("Some Value", annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)'; $result = $parser->parse($docblock); self::assertCount(1, $result); self::assertInstanceOf(Fixtures\AnnotationWithRequiredAttributesWithoutConstructor::class, $result[0]); self::assertEquals('Some Value', $result[0]->value); self::assertInstanceOf(Fixtures\AnnotationTargetAnnotation::class, $result[0]->annot); $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor("Some Value")'; try { $parser->parse($docblock, $context); $this->fail(); } catch (AnnotationException $exc) { self::assertContains('Attribute "annot" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor 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\AnnotationWithRequiredAttributesWithoutConstructor(annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)'; try { $parser->parse($docblock, $context); $this->fail(); } catch (AnnotationException $exc) { self::assertContains('Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor 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[] = [ '@AnnotationWithConstants(PHP_EOL)', PHP_EOL ]; $provider[] = [ '@AnnotationWithConstants(AnnotationWithConstants::INTEGER)', AnnotationWithConstants::INTEGER ]; $provider[] = [ '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants(AnnotationWithConstants::STRING)', AnnotationWithConstants::STRING ]; $provider[] = [ '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants::FLOAT)', AnnotationWithConstants::FLOAT ]; $provider[] = [ '@AnnotationWithConstants(ClassWithConstants::SOME_VALUE)', ClassWithConstants::SOME_VALUE ]; $provider[] = [ '@AnnotationWithConstants(ClassWithConstants::OTHER_KEY_)', ClassWithConstants::OTHER_KEY_ ]; $provider[] = [ '@AnnotationWithConstants(ClassWithConstants::OTHER_KEY_2)', ClassWithConstants::OTHER_KEY_2 ]; $provider[] = [ '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants::SOME_VALUE)', ClassWithConstants::SOME_VALUE ]; $provider[] = [ '@AnnotationWithConstants(InterfaceWithConstants::SOME_VALUE)', InterfaceWithConstants::SOME_VALUE ]; $provider[] = [ '@AnnotationWithConstants(\Doctrine\Tests\Common\Annotations\Fixtures\InterfaceWithConstants::SOME_VALUE)', InterfaceWithConstants::SOME_VALUE ]; $provider[] = [ '@AnnotationWithConstants({AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT})', [AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT] ]; $provider[] = [ '@AnnotationWithConstants({ AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER })', [AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER] ]; $provider[] = [ '@AnnotationWithConstants({ Doctrine\Tests\Common\Annotations\Fixtures\InterfaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER })', [InterfaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER] ]; $provider[] = [ '@AnnotationWithConstants({ \Doctrine\Tests\Common\Annotations\Fixtures\InterfaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER })', [InterfaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER] ]; $provider[] = [ '@AnnotationWithConstants({ AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER, ClassWithConstants::SOME_KEY = ClassWithConstants::SOME_VALUE, Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants::SOME_KEY = InterfaceWithConstants::SOME_VALUE })', [ AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER, ClassWithConstants::SOME_KEY => ClassWithConstants::SOME_VALUE, ClassWithConstants::SOME_KEY => InterfaceWithConstants::SOME_VALUE ] ]; $provider[] = [ '@AnnotationWithConstants(AnnotationWithConstants::class)', AnnotationWithConstants::class ]; $provider[] = [ '@AnnotationWithConstants({AnnotationWithConstants::class = AnnotationWithConstants::class})', [AnnotationWithConstants::class => AnnotationWithConstants::class] ]; $provider[] = [ '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants::class)', AnnotationWithConstants::class ]; $provider[] = [ '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants::class)', AnnotationWithConstants::class ]; return array_combine(array_column($provider, 0), $provider); } /** * @dataProvider getConstantsProvider */ public function testSupportClassConstants($docblock, $expected) { $parser = $this->createTestParser(); $parser->setImports([ 'classwithconstants' => ClassWithConstants::class, 'interfacewithconstants' => InterfaceWithConstants::class, 'annotationwithconstants' => AnnotationWithConstants::class ]); $result = $parser->parse($docblock); self::assertInstanceOf(AnnotationWithConstants::class, $annotation = $result[0]); self::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); self::assertInstanceOf(Name::class, $result[0]); $docblock = <<parse($docblock); self::assertInstanceOf(Name::class, $result[0]); } /** * @group DDC-77 */ public function testAnnotationWithoutClassIsIgnoredWithoutWarning() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $result = $parser->parse('@param'); self::assertEmpty($result); } /** * Tests if it's possible to ignore whole namespaces * * @param string $ignoreAnnotationName annotation/namespace to ignore * @param string $input annotation/namespace from the docblock * * @return void * * @dataProvider provideTestIgnoreWholeNamespaces * @group 45 */ public function testIgnoreWholeNamespaces($ignoreAnnotationName, $input) { $parser = new DocParser(); $parser->setIgnoredAnnotationNamespaces([$ignoreAnnotationName => true]); $result = $parser->parse($input); self::assertEmpty($result); } public function provideTestIgnoreWholeNamespaces() { return [ ['Namespace', '@Namespace'], ['Namespace\\', '@Namespace'], ['Namespace', '@Namespace\Subnamespace'], ['Namespace\\', '@Namespace\Subnamespace'], ['Namespace', '@Namespace\Subnamespace\SubSubNamespace'], ['Namespace\\', '@Namespace\Subnamespace\SubSubNamespace'], ['Namespace\Subnamespace', '@Namespace\Subnamespace'], ['Namespace\Subnamespace\\', '@Namespace\Subnamespace'], ['Namespace\Subnamespace', '@Namespace\Subnamespace\SubSubNamespace'], ['Namespace\Subnamespace\\', '@Namespace\Subnamespace\SubSubNamespace'], ['Namespace\Subnamespace\SubSubNamespace', '@Namespace\Subnamespace\SubSubNamespace'], ['Namespace\Subnamespace\SubSubNamespace\\', '@Namespace\Subnamespace\SubSubNamespace'], ]; } /** * @group DCOM-168 */ public function testNotAnAnnotationClassIsIgnoredWithoutWarning() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $parser->setIgnoredAnnotationNames([\PHPUnit\Framework\TestCase::class => true]); $result = $parser->parse('@\PHPUnit\Framework\TestCase'); self::assertEmpty($result); } public function testNotAnAnnotationClassIsIgnoredWithoutWarningWithoutCheating() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $result = $parser->parse('@\PHPUnit\Framework\TestCase'); self::assertEmpty($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("'@'"); self::assertEmpty($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() { self::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([ 'autoload' => Fixtures\Annotation\Autoload::class, ]); $annotations = $parser->parse('@Autoload'); self::assertCount(1, $annotations); self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotations[0]); } public function createTestParser() { $parser = new DocParser(); $parser->setIgnoreNotImportedAnnotations(true); $parser->setImports([ 'name' => Name::class, '__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(); self::assertEmpty($parser->parse($docblock)); } catch (AnnotationException $e) { $this->fail($e->getMessage()); } } /** * @group DCOM-14 */ public function testIgnorePHPDocThrowTag() { $docblock = <<createTestParser(); self::assertEmpty($parser->parse($docblock)); } catch (AnnotationException $e) { $this->fail($e->getMessage()); } } /** * @group DCOM-38 */ public function testCastInt() { $parser = $this->createTestParser(); $result = $parser->parse('@Name(foo=1234)'); $annot = $result[0]; self::assertInternalType('int', $annot->foo); } /** * @group DCOM-38 */ public function testCastNegativeInt() { $parser = $this->createTestParser(); $result = $parser->parse('@Name(foo=-1234)'); $annot = $result[0]; self::assertInternalType('int', $annot->foo); } /** * @group DCOM-38 */ public function testCastFloat() { $parser = $this->createTestParser(); $result = $parser->parse('@Name(foo=1234.345)'); $annot = $result[0]; self::assertInternalType('float', $annot->foo); } /** * @group DCOM-38 */ public function testCastNegativeFloat() { $parser = $this->createTestParser(); $result = $parser->parse('@Name(foo=-1234.345)'); $annot = $result[0]; self::assertInternalType('float', $annot->foo); $result = $parser->parse('@Marker(-1234.345)'); $annot = $result[0]; self::assertInternalType('float', $annot->value); } /** * @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", })'); self::assertCount(1, $annots); self::assertEquals(['Foo', 'Bar'], $annots[0]->value); } public function testTabPrefixIsAllowed() { $docblock = <<createTestParser(); $result = $parser->parse($docblock); self::assertCount(1, $result); self::assertInstanceOf(Name::class, $result[0]); } public function testDefaultAnnotationValueIsNotOverwritten() { $parser = $this->createTestParser(); $annots = $parser->parse('@Doctrine\Tests\Common\Annotations\Fixtures\Annotation\AnnotWithDefaultValue'); self::assertCount(1, $annots); self::assertEquals('bar', $annots[0]->foo); } public function testArrayWithColon() { $parser = $this->createTestParser(); $annots = $parser->parse('@Name({"foo": "bar"})'); self::assertCount(1, $annots); self::assertEquals(['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": {}})'); self::assertCount(1, $annots); self::assertEquals(['foo' => []], $annots[0]->value); } public function testKeyHasNumber() { $parser = $this->createTestParser(); $annots = $parser->parse('@SettingsAnnotation(foo="test", bar2="test")'); self::assertCount(1, $annots); self::assertEquals(['foo' => 'test', 'bar2' => 'test'], $annots[0]->settings); } /** * @group 44 */ public function testSupportsEscapedQuotedValues() { $result = $this->createTestParser()->parse('@Doctrine\Tests\Common\Annotations\Name(foo="""bar""")'); self::assertCount(1, $result); self::assertInstanceOf(Name::class, $result[0]); self::assertEquals('"bar"', $result[0]->foo); } /** * @see http://php.net/manual/en/mbstring.configuration.php * mbstring.func_overload can be changed only in php.ini * so for testing this case instead of skipping it you need to manually configure your php installation */ public function testMultiByteAnnotation() { $overloadStringFunctions = 2; if (!extension_loaded('mbstring') || (ini_get('mbstring.func_overload') & $overloadStringFunctions) == 0) { $this->markTestSkipped('This test requires mbstring function overloading is turned on'); } $docblock = <<createTestParser(); $result = $docParser->parse($docblock); self::assertCount(1, $result); } public function testWillNotParseAnnotationSucceededByAnImmediateDash() { $parser = $this->createTestParser(); self::assertEmpty($parser->parse('@SomeAnnotationClassNameWithoutConstructorAndProperties-')); } public function testWillParseAnnotationSucceededByANonImmediateDash() { $result = $this ->createTestParser() ->parse('@SomeAnnotationClassNameWithoutConstructorAndProperties -'); self::assertCount(1, $result); self::assertInstanceOf(SomeAnnotationClassNameWithoutConstructorAndProperties::class, $result[0]); } } /** @Annotation */ class SettingsAnnotation { public $settings; public function __construct($settings) { $this->settings = $settings; } } /** @Annotation */ class SomeAnnotationClassNameWithoutConstructor { public $data; public $name; } /** @Annotation */ class SomeAnnotationWithConstructorWithoutParams { public 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 AnnotationTargetAll { } /** @Annotation */ class Name extends Annotation { public $foo; } /** @Annotation */ class Marker { public $value; } namespace Doctrine\Tests\Common\Annotations\FooBar; use Doctrine\Common\Annotations\Annotation; /** @Annotation */ class Name extends Annotation { } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/DummyClass.php000066400000000000000000000024511354601121100307750ustar00rootroot00000000000000cacheDir = sys_get_temp_dir() . '/annotations_' . uniqid('', true); @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('', true); self::assertDirectoryNotExists($this->cacheDir); new FileCacheReader(new AnnotationReader(), $this->cacheDir); self::assertDirectoryExists($this->cacheDir); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures/000077500000000000000000000000001354601121100300125ustar00rootroot00000000000000AbstractController.php000066400000000000000000000001441354601121100342520ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixturesroles = $values['value']; } }SingleUseAnnotation.php000066400000000000000000000001771354601121100365140ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotationname = $values['value'] ?? null; } } Version.php000066400000000000000000000002171354601121100342030ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures/Annotation"), @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; } }AnnotationWithConstants.php000066400000000000000000000004221354601121100353050ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures $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; } }AnnotationWithRequiredAttributesWithoutConstructor.php000066400000000000000000000005721354601121100430200ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures */ public $arrayOfIntegers; /** * @var string[] */ public $arrayOfStrings; /** * @var \Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll[] */ public $arrayOfAnnotations; }php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures/Api.php000066400000000000000000000001601354601121100312310ustar00rootroot00000000000000events->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; } } ClassWithConstants.php000066400000000000000000000004751354601121100342500ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures */ class Controller { /** * @Route("/", name="_demo") * @Template() */ public function indexAction() { return []; } /** * @Route("/hello/{name}", name="_demo_hello") * @Template() */ public function helloAction($name) { return ['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 ['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 = []; 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, (int) $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 = []; 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, (int) $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 = []; 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)); } } }ControllerWithParentClass.php000066400000000000000000000007371354601121100355720ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures */ class ControllerWithParentClass extends AbstractController { /** * @Route("/", name="_demo") * @Template() */ public function indexAction() { return []; } } ControllerWithTrait.php000066400000000000000000000010411354601121100344230ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures */ class ControllerWithTrait { use SecretRouteTrait; /** * @Route("/", name="_demo") * @Template() */ public function indexAction() { return []; } } DifferentNamespacesPerFileWithClassAsFirst.php000066400000000000000000000006301354601121100407360ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixturestest1; echo $this->test2; echo $this->test3; $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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 =[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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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; } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures/NoAnnotation.php000066400000000000000000000001231354601121100331260ustar00rootroot00000000000000test1; echo $this->test2; echo $this->test3; $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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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 = [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; } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Fixtures/TestInterface.php000066400000000000000000000003271354601121100332650ustar00rootroot00000000000000 __NAMESPACE__ . '\Fixtures\Annotation\Route', 'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', ], $parser->parseClass($class)); } public function testParseClassWithMultipleImportsInUseStatement() { $class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\MultipleImportsInUseStatement'); $parser = new PhpParser(); self::assertEquals([ 'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', 'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', ], $parser->parseClass($class)); } /** * @requires PHP 7.0 */ public function testParseClassWithGroupUseStatement() { $class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\GroupUseStatement'); $parser = new PhpParser(); self::assertEquals([ 'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', 'supersecure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', 'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', ], $parser->parseClass($class)); } public function testParseClassWhenNotUserDefined() { $parser = new PhpParser(); self::assertEquals([], $parser->parseClass(new \ReflectionClass(\stdClass::class))); } public function testClassFileDoesNotExist() { /* @var $class ReflectionClass|\PHPUnit_Framework_MockObject_MockObject */ $class = $this->getMockBuilder(ReflectionClass::class) ->disableOriginalConstructor() ->getMock(); $class->expects($this->once()) ->method('getFilename') ->will($this->returnValue('/valid/class/Fake.php(35) : eval()d code')); $parser = new PhpParser(); self::assertEquals([], $parser->parseClass($class)); } public function testParseClassWhenClassIsNotNamespaced() { $parser = new PhpParser(); $class = new ReflectionClass(\AnnotationsTestsFixturesNonNamespacedClass::class); self::assertEquals([ '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'); self::assertEquals([ 'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', ], $parser->parseClass($class)); } public function testClassWithFullyQualifiedUseStatements() { $parser = new PhpParser(); $class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\ClassWithFullyQualifiedUseStatements'); self::assertEquals([ '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'); self::assertEquals([ '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'); self::assertEquals([ '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'); self::assertEquals([ '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'); self::assertEquals([ 'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', ], $parser->parseClass($class)); } public function testDifferentNamespacesPerFileWithClassAsLast() { $parser = new PhpParser(); $class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\DifferentNamespacesPerFileWithClassAsLast'); self::assertEquals([ 'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', ], $parser->parseClass($class)); } public function testGlobalNamespacesPerFileWithClassAsFirst() { $parser = new PhpParser(); $class = new \ReflectionClass(\GlobalNamespacesPerFileWithClassAsFirst::class); self::assertEquals([ 'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', 'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', ], $parser->parseClass($class)); } public function testGlobalNamespacesPerFileWithClassAsLast() { $parser = new PhpParser(); $class = new ReflectionClass(\GlobalNamespacesPerFileWithClassAsLast::class); self::assertEquals([ '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'); self::assertEquals([ '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'); self::assertEquals([ 'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', 'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', 'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', ], $parser->parseClass($class)); self::assertEquals([ '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'); self::assertEquals([ 'annotationtargetall' => __NAMESPACE__ . '\Fixtures\AnnotationTargetAll', 'annotationtargetannotation' => __NAMESPACE__ . '\Fixtures\AnnotationTargetAnnotation', ], $parser->parseClass($class)); } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/ReservedKeywordsClasses.php000066400000000000000000000002331354601121100335350ustar00rootroot00000000000000getReader(); $ref = new \ReflectionClass(Fixtures\InvalidAnnotationUsageButIgnoredClass::class); $annots = $reader->getClassAnnotations($ref); self::assertCount(1, $annots); } public function testIncludeIgnoreAnnotation() { $this->markTestSkipped('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(Fixtures\ClassDDC1660::class); self::assertTrue(class_exists(Fixtures\Annotation\Version::class)); self::assertCount(1, $reader->getClassAnnotations($class)); self::assertCount(1, $reader->getMethodAnnotations($class->getMethod('bar'))); self::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; } } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Ticket/000077500000000000000000000000001354601121100274245ustar00rootroot00000000000000php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM55Test.php000066400000000000000000000034261354601121100316760ustar00rootroot00000000000000getClassAnnotations($class); } public function testAnnotation() { $class = new \ReflectionClass(__NAMESPACE__ . '\\DCOM55Consumer'); $reader = new AnnotationReader(); $annots = $reader->getClassAnnotations($class); self::assertCount(1, $annots); self::assertInstanceOf(__NAMESPACE__.'\\DCOM55Annotation', $annots[0]); } public function testParseAnnotationDocblocks() { $class = new \ReflectionClass(__NAMESPACE__ . '\\DCOM55Annotation'); $reader = new AnnotationReader(); $annots = $reader->getClassAnnotations($class); self::assertEmpty($annots); } } /** * @Controller */ class Dummy { } /** * @Annotation */ class DCOM55Annotation { } /** * @DCOM55Annotation */ class DCOM55Consumer { } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Entity.php000066400000000000000000000001411354601121100322250ustar00rootroot00000000000000getClassAnnotations(new \ReflectionClass(__NAMESPACE__ . '\MappedClass')); $classAnnotations = array_combine( array_map('get_class', $result), $result ); self::assertArrayNotHasKey('', $classAnnotations, 'Class "xxx" is not a valid entity or mapped super class.'); } public function testIssueGlobalNamespace() { $docblock = '@Entity'; $parser = new DocParser(); $parser->setImports([ '__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping' ]); $annots = $parser->parse($docblock); self::assertCount(1, $annots); self::assertInstanceOf(Doctrine\ORM\Mapping\Entity::class, $annots[0]); } public function testIssueNamespaces() { $docblock = '@Entity'; $parser = new DocParser(); $parser->addNamespace('Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM'); $annots = $parser->parse($docblock); self::assertCount(1, $annots); self::assertInstanceOf(Doctrine\ORM\Entity::class, $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); self::assertCount(1, $annots); self::assertInstanceOf(Doctrine\ORM\Mapping\Entity::class, $annots[0]); } public function testIssueWithNamespacesOrImports() { $docblock = '@Entity'; $parser = new DocParser(); $annots = $parser->parse($docblock); self::assertCount(1, $annots); self::assertInstanceOf(\Entity::class, $annots[0]); } public function testIssueSimpleAnnotationReader() { $reader = new SimpleAnnotationReader(); $reader->addNamespace('Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping'); $annots = $reader->getClassAnnotations(new \ReflectionClass(__NAMESPACE__."\MappedClass")); self::assertCount(1, $annots); self::assertInstanceOf(Doctrine\ORM\Mapping\Entity::class, $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 { } php-doctrine-annotations-1.8.0/tests/Doctrine/Tests/Common/Annotations/TopLevelAnnotation.php000066400000000000000000000001671354601121100325030ustar00rootroot00000000000000