parent
75ef83696e
commit
28ea16582a
@ -0,0 +1,3 @@ |
||||
vendor/ |
||||
composer.lock |
||||
composer.phar |
@ -0,0 +1,9 @@ |
||||
language: php |
||||
|
||||
php: |
||||
- 5.3 |
||||
- 5.4 |
||||
|
||||
before_script: |
||||
- composer --prefer-source --dev install |
||||
- phpunit |
@ -0,0 +1,11 @@ |
||||
# Doctrine Annotations |
||||
|
||||
[![Build Status](https://travis-ci.org/doctrine/annotations.png?branch=master)](https://travis-ci.org/doctrine/annotations) |
||||
|
||||
Docblock Annotations Parser library (extracted from Doctrine Common). |
||||
|
||||
## Changelog |
||||
|
||||
### v1.1 |
||||
|
||||
* Add Exception when ZendOptimizer+ or Opcache is configured to drop comments |
@ -0,0 +1,30 @@ |
||||
{ |
||||
"name": "doctrine/annotations", |
||||
"type": "library", |
||||
"description": "Docblock Annotations Parser", |
||||
"keywords": ["annotations", "docblock", "parser"], |
||||
"homepage": "http://www.doctrine-project.org", |
||||
"license": "MIT", |
||||
"authors": [ |
||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, |
||||
{"name": "Roman Borschel", "email": "roman@code-factory.org"}, |
||||
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, |
||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, |
||||
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} |
||||
], |
||||
"require": { |
||||
"php": ">=5.3.2", |
||||
"doctrine/lexer": "1.*" |
||||
}, |
||||
"require-dev": { |
||||
"doctrine/cache": "1.*" |
||||
}, |
||||
"autoload": { |
||||
"psr-0": { "Doctrine\\Common\\Annotations\\": "lib/" } |
||||
}, |
||||
"extra": { |
||||
"branch-alias": { |
||||
"dev-master": "1.0.x-dev" |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,79 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
/** |
||||
* Annotations class |
||||
* |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
*/ |
||||
class Annotation |
||||
{ |
||||
/** |
||||
* Value property. Common among all derived classes. |
||||
* |
||||
* @var string |
||||
*/ |
||||
public $value; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param array $data Key-value for properties to be defined in this class |
||||
*/ |
||||
public final function __construct(array $data) |
||||
{ |
||||
foreach ($data as $key => $value) { |
||||
$this->$key = $value; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Error handler for unknown property accessor in Annotation class. |
||||
* |
||||
* @param string $name Unknown property name |
||||
* |
||||
* @throws \BadMethodCallException |
||||
*/ |
||||
public function __get($name) |
||||
{ |
||||
throw new \BadMethodCallException( |
||||
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this)) |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Error handler for unknown property mutator in Annotation class. |
||||
* |
||||
* @param string $name Unkown property name |
||||
* @param mixed $value Property value |
||||
* |
||||
* @throws \BadMethodCallException |
||||
*/ |
||||
public function __set($name, $value) |
||||
{ |
||||
throw new \BadMethodCallException( |
||||
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this)) |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,47 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation; |
||||
|
||||
/** |
||||
* Annotation that can be used to signal to the parser |
||||
* to check the attribute type during the parsing process. |
||||
* |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
* |
||||
* @Annotation |
||||
*/ |
||||
final class Attribute |
||||
{ |
||||
/** |
||||
* @var string |
||||
*/ |
||||
public $name; |
||||
|
||||
/** |
||||
* @var string |
||||
*/ |
||||
public $type; |
||||
|
||||
/** |
||||
* @var boolean |
||||
*/ |
||||
public $required = false; |
||||
} |
@ -0,0 +1,37 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation; |
||||
|
||||
/** |
||||
* Annotation that can be used to signal to the parser |
||||
* to check the types of all declared attributes during the parsing process. |
||||
* |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
* |
||||
* @Annotation |
||||
*/ |
||||
final class Attributes |
||||
{ |
||||
/** |
||||
* @var array<Doctrine\Common\Annotations\Annotation\Attribute> |
||||
*/ |
||||
public $value; |
||||
} |
@ -0,0 +1,85 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation; |
||||
|
||||
/** |
||||
* Annotation that can be used to signal to the parser |
||||
* to check the available values during the parsing process. |
||||
* |
||||
* @since 2.4 |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
* |
||||
* @Annotation |
||||
* @Attributes({ |
||||
* @Attribute("value", required = true, type = "array"), |
||||
* @Attribute("literal", required = false, type = "array") |
||||
* }) |
||||
*/ |
||||
final class Enum |
||||
{ |
||||
/** |
||||
* @var array |
||||
*/ |
||||
public $value; |
||||
|
||||
/** |
||||
* Literal target declaration. |
||||
* |
||||
* @var array |
||||
*/ |
||||
public $literal; |
||||
|
||||
/** |
||||
* Annotation construct |
||||
* |
||||
* @param array $values |
||||
* |
||||
* @throws \InvalidArgumentException |
||||
*/ |
||||
public function __construct(array $values) |
||||
{ |
||||
if ( ! isset($values['literal'])) { |
||||
$values['literal'] = array(); |
||||
} |
||||
|
||||
foreach ($values['value'] as $var) { |
||||
if( ! is_scalar($var)) { |
||||
throw new \InvalidArgumentException(sprintf( |
||||
'@Enum supports only scalar values "%s" given.', |
||||
is_object($var) ? get_class($var) : gettype($var) |
||||
)); |
||||
} |
||||
} |
||||
|
||||
foreach ($values['literal'] as $key => $var) { |
||||
if( ! in_array($key, $values['value'])) { |
||||
throw new \InvalidArgumentException(sprintf( |
||||
'Undefined enumerator value "%s" for literal "%s".', |
||||
$key , $var |
||||
)); |
||||
} |
||||
} |
||||
|
||||
$this->value = $values['value']; |
||||
$this->literal = $values['literal']; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,54 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation; |
||||
|
||||
/** |
||||
* Annotation that can be used to signal to the parser to ignore specific |
||||
* annotations during the parsing process. |
||||
* |
||||
* @Annotation |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
*/ |
||||
final class IgnoreAnnotation |
||||
{ |
||||
/** |
||||
* @var array |
||||
*/ |
||||
public $names; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param array $values |
||||
* |
||||
* @throws \RuntimeException |
||||
*/ |
||||
public function __construct(array $values) |
||||
{ |
||||
if (is_string($values['value'])) { |
||||
$values['value'] = array($values['value']); |
||||
} |
||||
if (!is_array($values['value'])) { |
||||
throw new \RuntimeException(sprintf('@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', json_encode($values['value']))); |
||||
} |
||||
|
||||
$this->names = $values['value']; |
||||
} |
||||
} |
@ -0,0 +1,33 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation; |
||||
|
||||
/** |
||||
* Annotation that can be used to signal to the parser |
||||
* to check if that attribute is required during the parsing process. |
||||
* |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
* |
||||
* @Annotation |
||||
*/ |
||||
final class Required |
||||
{ |
||||
} |
@ -0,0 +1,107 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation; |
||||
|
||||
/** |
||||
* Annotation that can be used to signal to the parser |
||||
* to check the annotation target during the parsing process. |
||||
* |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
* |
||||
* @Annotation |
||||
*/ |
||||
final class Target |
||||
{ |
||||
const TARGET_CLASS = 1; |
||||
const TARGET_METHOD = 2; |
||||
const TARGET_PROPERTY = 4; |
||||
const TARGET_ANNOTATION = 8; |
||||
const TARGET_ALL = 15; |
||||
|
||||
/** |
||||
* @var array |
||||
*/ |
||||
private static $map = array( |
||||
'ALL' => self::TARGET_ALL, |
||||
'CLASS' => self::TARGET_CLASS, |
||||
'METHOD' => self::TARGET_METHOD, |
||||
'PROPERTY' => self::TARGET_PROPERTY, |
||||
'ANNOTATION' => self::TARGET_ANNOTATION, |
||||
); |
||||
|
||||
/** |
||||
* @var array |
||||
*/ |
||||
public $value; |
||||
|
||||
/** |
||||
* Targets as bitmask. |
||||
* |
||||
* @var integer |
||||
*/ |
||||
public $targets; |
||||
|
||||
/** |
||||
* Literal target declaration. |
||||
* |
||||
* @var integer |
||||
*/ |
||||
public $literal; |
||||
|
||||
/** |
||||
* Annotation construct |
||||
* |
||||
* @param array $values |
||||
* |
||||
* @throws \InvalidArgumentException |
||||
*/ |
||||
public function __construct(array $values) |
||||
{ |
||||
if (!isset($values['value'])){ |
||||
$values['value'] = null; |
||||
} |
||||
if (is_string($values['value'])){ |
||||
$values['value'] = array($values['value']); |
||||
} |
||||
if (!is_array($values['value'])){ |
||||
throw new \InvalidArgumentException( |
||||
sprintf('@Target expects either a string value, or an array of strings, "%s" given.', |
||||
is_object($values['value']) ? get_class($values['value']) : gettype($values['value']) |
||||
) |
||||
); |
||||
} |
||||
|
||||
$bitmask = 0; |
||||
foreach ($values['value'] as $literal) { |
||||
if(!isset(self::$map[$literal])){ |
||||
throw new \InvalidArgumentException( |
||||
sprintf('Invalid Target "%s". Available targets: [%s]', |
||||
$literal, implode(', ', array_keys(self::$map))) |
||||
); |
||||
} |
||||
$bitmask += self::$map[$literal]; |
||||
} |
||||
|
||||
$this->targets = $bitmask; |
||||
$this->value = $values['value']; |
||||
$this->literal = implode(', ', $this->value); |
||||
} |
||||
} |
@ -0,0 +1,158 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
/** |
||||
* Description of AnnotationException |
||||
* |
||||
* @since 2.0 |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
*/ |
||||
class AnnotationException extends \Exception |
||||
{ |
||||
/** |
||||
* Creates a new AnnotationException describing a Syntax error. |
||||
* |
||||
* @param string $message Exception message |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function syntaxError($message) |
||||
{ |
||||
return new self('[Syntax Error] ' . $message); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new AnnotationException describing a Semantical error. |
||||
* |
||||
* @param string $message Exception message |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function semanticalError($message) |
||||
{ |
||||
return new self('[Semantical Error] ' . $message); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new AnnotationException describing a constant semantical error. |
||||
* |
||||
* @since 2.3 |
||||
* @param string $identifier |
||||
* @param string $context |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function semanticalErrorConstants($identifier, $context = null) |
||||
{ |
||||
return self::semanticalError(sprintf( |
||||
"Couldn't find constant %s%s", $identifier, |
||||
$context ? ", $context." : "." |
||||
)); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new AnnotationException describing an error which occurred during |
||||
* the creation of the annotation. |
||||
* |
||||
* @since 2.2 |
||||
* @param string $message |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function creationError($message) |
||||
{ |
||||
return new self('[Creation Error] ' . $message); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new AnnotationException describing an type error of an attribute. |
||||
* |
||||
* @since 2.2 |
||||
* @param string $attributeName |
||||
* @param string $annotationName |
||||
* @param string $context |
||||
* @param string $expected |
||||
* @param mixed $actual |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function typeError($attributeName, $annotationName, $context, $expected, $actual) |
||||
{ |
||||
return new self(sprintf( |
||||
'[Type Error] Attribute "%s" of @%s declared on %s expects %s, but got %s.', |
||||
$attributeName, |
||||
$annotationName, |
||||
$context, |
||||
$expected, |
||||
is_object($actual) ? 'an instance of '.get_class($actual) : gettype($actual) |
||||
)); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new AnnotationException describing an required error of an attribute. |
||||
* |
||||
* @since 2.2 |
||||
* @param string $attributeName |
||||
* @param string $annotationName |
||||
* @param string $context |
||||
* @param string $expected |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function requiredError($attributeName, $annotationName, $context, $expected) |
||||
{ |
||||
return new self(sprintf( |
||||
'[Type Error] Attribute "%s" of @%s declared on %s expects %s. This value should not be null.', |
||||
$attributeName, |
||||
$annotationName, |
||||
$context, |
||||
$expected |
||||
)); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new AnnotationException describing a invalid enummerator. |
||||
* |
||||
* @since 2.4 |
||||
* @param string $attributeName |
||||
* @param string $annotationName |
||||
* @param string $context |
||||
* @param array $available |
||||
* @param mixed $given |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function enumeratorError($attributeName, $annotationName, $context, $available, $given) |
||||
{ |
||||
throw new self(sprintf( |
||||
'[Enum Error] Attribute "%s" of @%s declared on %s accept only [%s], but got %s.', |
||||
$attributeName, |
||||
$annotationName, |
||||
$context, |
||||
implode(', ', $available), |
||||
is_object($given) ? get_class($given) : $given |
||||
)); |
||||
} |
||||
|
||||
/** |
||||
* @return AnnotationException |
||||
*/ |
||||
public static function optimizerPlusSaveComments() |
||||
{ |
||||
throw new self("You have to enable opcache.save_comments=1 or zend_optimizerplus.save_comments=1."); |
||||
} |
||||
} |
@ -0,0 +1,318 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation; |
||||
use Doctrine\Common\Annotations\Annotation\Target; |
||||
use Closure; |
||||
use ReflectionClass; |
||||
use ReflectionMethod; |
||||
use ReflectionProperty; |
||||
|
||||
/** |
||||
* A reader for docblock annotations. |
||||
* |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
*/ |
||||
class AnnotationReader implements Reader |
||||
{ |
||||
/** |
||||
* Global map for imports. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private static $globalImports = array( |
||||
'ignoreannotation' => 'Doctrine\Common\Annotations\Annotation\IgnoreAnnotation', |
||||
); |
||||
|
||||
/** |
||||
* A list with annotations that are not causing exceptions when not resolved to an annotation class. |
||||
* |
||||
* The names are case sensitive. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private static $globalIgnoredNames = array( |
||||
'access'=> true, 'author'=> true, 'copyright'=> true, 'deprecated'=> true, |
||||
'example'=> true, 'ignore'=> true, 'internal'=> true, 'link'=> true, 'see'=> true, |
||||
'since'=> true, 'tutorial'=> true, 'version'=> true, 'package'=> true, |
||||
'subpackage'=> true, 'name'=> true, 'global'=> true, 'param'=> true, |
||||
'return'=> true, 'staticvar'=> true, 'category'=> true, 'staticVar'=> true, |
||||
'static'=> true, 'var'=> true, 'throws'=> true, 'inheritdoc'=> true, |
||||
'inheritDoc'=> true, 'license'=> true, 'todo'=> true, 'TODO'=> true, |
||||
'deprec'=> true, 'property' => true, 'method' => true, |
||||
'abstract'=> true, 'exception'=> true, 'magic' => true, 'api' => true, |
||||
'final'=> true, 'filesource'=> true, 'throw' => true, 'uses' => true, |
||||
'usedby'=> true, 'private' => true, 'Annotation' => true, 'override' => true, |
||||
'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true, |
||||
'Required' => true, 'Attribute' => true, 'Attributes' => true, |
||||
'Target' => true, 'SuppressWarnings' => true, |
||||
'ingroup' => true, 'code' => true, 'endcode' => true, |
||||
'package_version' => true, 'fixme' => true |
||||
); |
||||
|
||||
/** |
||||
* Add a new annotation to the globally ignored annotation names with regard to exception handling. |
||||
* |
||||
* @param string $name |
||||
*/ |
||||
static public function addGlobalIgnoredName($name) |
||||
{ |
||||
self::$globalIgnoredNames[$name] = true; |
||||
} |
||||
|
||||
/** |
||||
* Annotations Parser |
||||
* |
||||
* @var \Doctrine\Common\Annotations\DocParser |
||||
*/ |
||||
private $parser; |
||||
|
||||
/** |
||||
* Annotations Parser used to collect parsing metadata |
||||
* |
||||
* @var \Doctrine\Common\Annotations\DocParser |
||||
*/ |
||||
private $preParser; |
||||
|
||||
/** |
||||
* PHP Parser used to collect imports. |
||||
* |
||||
* @var \Doctrine\Common\Annotations\PhpParser |
||||
*/ |
||||
private $phpParser; |
||||
|
||||
/** |
||||
* In-memory cache mechanism to store imported annotations per class. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $imports = array(); |
||||
|
||||
/** |
||||
* In-memory cache mechanism to store ignored annotations per class. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $ignoredAnnotationNames = array(); |
||||
|
||||
/** |
||||
* Constructor. |
||||
* |
||||
* Initializes a new AnnotationReader. |
||||
*/ |
||||
public function __construct() |
||||
{ |
||||
if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === "0" || ini_get('opcache.save_comments') === "0")) { |
||||
throw AnnotationException::optimizerPlusSaveComments(); |
||||
} |
||||
|
||||
if (extension_loaded('opcache') && ini_get('opcache.save_comments') == 0) { |
||||
throw AnnotationException::optimizerPlusSaveComments(); |
||||
} |
||||
|
||||
AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php'); |
||||
|
||||
$this->parser = new DocParser; |
||||
|
||||
$this->preParser = new DocParser; |
||||
$this->preParser->setImports(self::$globalImports); |
||||
$this->preParser->setIgnoreNotImportedAnnotations(true); |
||||
|
||||
$this->phpParser = new PhpParser; |
||||
} |
||||
|
||||
/** |
||||
* Gets the annotations applied to a class. |
||||
* |
||||
* @param ReflectionClass $class The ReflectionClass of the class from which |
||||
* the class annotations should be read. |
||||
* @return array An array of Annotations. |
||||
*/ |
||||
public function getClassAnnotations(ReflectionClass $class) |
||||
{ |
||||
$this->parser->setTarget(Target::TARGET_CLASS); |
||||
$this->parser->setImports($this->getImports($class)); |
||||
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); |
||||
|
||||
return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName()); |
||||
} |
||||
|
||||
/** |
||||
* Gets a class annotation. |
||||
* |
||||
* @param ReflectionClass $class The ReflectionClass of the class from which |
||||
* the class annotations should be read. |
||||
* @param string $annotationName The name of the annotation. |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName) |
||||
{ |
||||
$annotations = $this->getClassAnnotations($class); |
||||
|
||||
foreach ($annotations as $annotation) { |
||||
if ($annotation instanceof $annotationName) { |
||||
return $annotation; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Gets the annotations applied to a property. |
||||
* |
||||
* @param ReflectionProperty $property The ReflectionProperty of the property |
||||
* from which the annotations should be read. |
||||
* @return array An array of Annotations. |
||||
*/ |
||||
public function getPropertyAnnotations(ReflectionProperty $property) |
||||
{ |
||||
$class = $property->getDeclaringClass(); |
||||
$context = 'property ' . $class->getName() . "::\$" . $property->getName(); |
||||
$this->parser->setTarget(Target::TARGET_PROPERTY); |
||||
$this->parser->setImports($this->getImports($class)); |
||||
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); |
||||
|
||||
return $this->parser->parse($property->getDocComment(), $context); |
||||
} |
||||
|
||||
/** |
||||
* Gets a property annotation. |
||||
* |
||||
* @param ReflectionProperty $property |
||||
* @param string $annotationName The name of the annotation. |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName) |
||||
{ |
||||
$annotations = $this->getPropertyAnnotations($property); |
||||
|
||||
foreach ($annotations as $annotation) { |
||||
if ($annotation instanceof $annotationName) { |
||||
return $annotation; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Gets the annotations applied to a method. |
||||
* |
||||
* @param \ReflectionMethod $method The ReflectionMethod of the method from which |
||||
* the annotations should be read. |
||||
* |
||||
* @return array An array of Annotations. |
||||
*/ |
||||
public function getMethodAnnotations(ReflectionMethod $method) |
||||
{ |
||||
$class = $method->getDeclaringClass(); |
||||
$context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; |
||||
$this->parser->setTarget(Target::TARGET_METHOD); |
||||
$this->parser->setImports($this->getImports($class)); |
||||
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); |
||||
|
||||
return $this->parser->parse($method->getDocComment(), $context); |
||||
} |
||||
|
||||
/** |
||||
* Gets a method annotation. |
||||
* |
||||
* @param ReflectionMethod $method |
||||
* @param string $annotationName The name of the annotation. |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName) |
||||
{ |
||||
$annotations = $this->getMethodAnnotations($method); |
||||
|
||||
foreach ($annotations as $annotation) { |
||||
if ($annotation instanceof $annotationName) { |
||||
return $annotation; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Returns the ignored annotations for the given class. |
||||
* |
||||
* @param ReflectionClass $class |
||||
* @return array |
||||
*/ |
||||
private function getIgnoredAnnotationNames(ReflectionClass $class) |
||||
{ |
||||
if (isset($this->ignoredAnnotationNames[$name = $class->getName()])) { |
||||
return $this->ignoredAnnotationNames[$name]; |
||||
} |
||||
$this->collectParsingMetadata($class); |
||||
|
||||
return $this->ignoredAnnotationNames[$name]; |
||||
} |
||||
|
||||
/** |
||||
* Retrieve imports |
||||
* |
||||
* @param \ReflectionClass $class |
||||
* @return array |
||||
*/ |
||||
private function getImports(ReflectionClass $class) |
||||
{ |
||||
if (isset($this->imports[$name = $class->getName()])) { |
||||
return $this->imports[$name]; |
||||
} |
||||
$this->collectParsingMetadata($class); |
||||
|
||||
return $this->imports[$name]; |
||||
} |
||||
|
||||
/** |
||||
* Collects parsing metadata for a given class |
||||
* |
||||
* @param ReflectionClass $class |
||||
*/ |
||||
private function collectParsingMetadata(ReflectionClass $class) |
||||
{ |
||||
$ignoredAnnotationNames = self::$globalIgnoredNames; |
||||
|
||||
$annotations = $this->preParser->parse($class->getDocComment(), 'class '.$class->name); |
||||
foreach ($annotations as $annotation) { |
||||
if ($annotation instanceof IgnoreAnnotation) { |
||||
foreach ($annotation->names AS $annot) { |
||||
$ignoredAnnotationNames[$annot] = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
$name = $class->getName(); |
||||
$this->imports[$name] = array_merge( |
||||
self::$globalImports, |
||||
$this->phpParser->parseClass($class), |
||||
array('__NAMESPACE__' => $class->getNamespaceName()) |
||||
); |
||||
$this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames; |
||||
} |
||||
} |
@ -0,0 +1,139 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
/** |
||||
* AnnotationRegistry |
||||
*/ |
||||
final class AnnotationRegistry |
||||
{ |
||||
/** |
||||
* A map of namespaces to use for autoloading purposes based on a PSR-0 convention. |
||||
* |
||||
* Contains the namespace as key and an array of directories as value. If the value is NULL |
||||
* the include path is used for checking for the corresponding file. |
||||
* |
||||
* This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own. |
||||
* |
||||
* @var array |
||||
*/ |
||||
static private $autoloadNamespaces = array(); |
||||
|
||||
/** |
||||
* A map of autoloader callables. |
||||
* |
||||
* @var array |
||||
*/ |
||||
static private $loaders = array(); |
||||
|
||||
static public function reset() |
||||
{ |
||||
self::$autoloadNamespaces = array(); |
||||
self::$loaders = array(); |
||||
} |
||||
|
||||
/** |
||||
* Register file |
||||
* |
||||
* @param string $file |
||||
*/ |
||||
static public function registerFile($file) |
||||
{ |
||||
require_once $file; |
||||
} |
||||
|
||||
/** |
||||
* Add a namespace with one or many directories to look for files or null for the include path. |
||||
* |
||||
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. |
||||
* |
||||
* @param string $namespace |
||||
* @param string|array|null $dirs |
||||
*/ |
||||
static public function registerAutoloadNamespace($namespace, $dirs = null) |
||||
{ |
||||
self::$autoloadNamespaces[$namespace] = $dirs; |
||||
} |
||||
|
||||
/** |
||||
* Register multiple namespaces |
||||
* |
||||
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. |
||||
* |
||||
* @param array $namespaces |
||||
*/ |
||||
static public function registerAutoloadNamespaces(array $namespaces) |
||||
{ |
||||
self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces); |
||||
} |
||||
|
||||
/** |
||||
* Register an autoloading callable for annotations, much like spl_autoload_register(). |
||||
* |
||||
* NOTE: These class loaders HAVE to be silent when a class was not found! |
||||
* IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class. |
||||
* |
||||
* @param callable $callable |
||||
* |
||||
* @throws \InvalidArgumentException |
||||
*/ |
||||
static public function registerLoader($callable) |
||||
{ |
||||
if (!is_callable($callable)) { |
||||
throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader()."); |
||||
} |
||||
self::$loaders[] = $callable; |
||||
} |
||||
|
||||
/** |
||||
* Autoload an annotation class silently. |
||||
* |
||||
* @param string $class |
||||
* @return boolean |
||||
*/ |
||||
static public function loadAnnotationClass($class) |
||||
{ |
||||
foreach (self::$autoloadNamespaces AS $namespace => $dirs) { |
||||
if (strpos($class, $namespace) === 0) { |
||||
$file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php"; |
||||
if ($dirs === null) { |
||||
if ($path = stream_resolve_include_path($file)) { |
||||
require $path; |
||||
return true; |
||||
} |
||||
} else { |
||||
foreach((array)$dirs AS $dir) { |
||||
if (is_file($dir . DIRECTORY_SEPARATOR . $file)) { |
||||
require $dir . DIRECTORY_SEPARATOR . $file; |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
foreach (self::$loaders AS $loader) { |
||||
if (call_user_func($loader, $class) === true) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
} |
@ -0,0 +1,250 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Cache\Cache; |
||||
|
||||
/** |
||||
* A cache aware annotation reader. |
||||
* |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
*/ |
||||
final class CachedReader implements Reader |
||||
{ |
||||
/** |
||||
* @var string |
||||
*/ |
||||
private static $CACHE_SALT = '@[Annot]'; |
||||
|
||||
/** |
||||
* @var Reader |
||||
*/ |
||||
private $delegate; |
||||
|
||||
/** |
||||
* @var Cache |
||||
*/ |
||||
private $cache; |
||||
|
||||
/** |
||||
* @var boolean |
||||
*/ |
||||
private $debug; |
||||
|
||||
/** |
||||
* @var array |
||||
*/ |
||||
private $loadedAnnotations; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param Reader $reader |
||||
* @param Cache $cache |
||||
* @param bool $debug |
||||
*/ |
||||
public function __construct(Reader $reader, Cache $cache, $debug = false) |
||||
{ |
||||
$this->delegate = $reader; |
||||
$this->cache = $cache; |
||||
$this->debug = (Boolean) $debug; |
||||
} |
||||
|
||||
/** |
||||
* Get annotations for class |
||||
* |
||||
* @param \ReflectionClass $class |
||||
* @return array |
||||
*/ |
||||
public function getClassAnnotations(\ReflectionClass $class) |
||||
{ |
||||
$cacheKey = $class->getName(); |
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) { |
||||
return $this->loadedAnnotations[$cacheKey]; |
||||
} |
||||
|
||||
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) { |
||||
$annots = $this->delegate->getClassAnnotations($class); |
||||
$this->saveToCache($cacheKey, $annots); |
||||
} |
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots; |
||||
} |
||||
|
||||
/** |
||||
* Get selected annotation for class |
||||
* |
||||
* @param \ReflectionClass $class |
||||
* @param string $annotationName |
||||
* @return null |
||||
*/ |
||||
public function getClassAnnotation(\ReflectionClass $class, $annotationName) |
||||
{ |
||||
foreach ($this->getClassAnnotations($class) as $annot) { |
||||
if ($annot instanceof $annotationName) { |
||||
return $annot; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Get annotations for property |
||||
* |
||||
* @param \ReflectionProperty $property |
||||
* @return array |
||||
*/ |
||||
public function getPropertyAnnotations(\ReflectionProperty $property) |
||||
{ |
||||
$class = $property->getDeclaringClass(); |
||||
$cacheKey = $class->getName().'$'.$property->getName(); |
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) { |
||||
return $this->loadedAnnotations[$cacheKey]; |
||||
} |
||||
|
||||
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) { |
||||
$annots = $this->delegate->getPropertyAnnotations($property); |
||||
$this->saveToCache($cacheKey, $annots); |
||||
} |
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots; |
||||
} |
||||
|
||||
/** |
||||
* Get selected annotation for property |
||||
* |
||||
* @param \ReflectionProperty $property |
||||
* @param string $annotationName |
||||
* @return null |
||||
*/ |
||||
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) |
||||
{ |
||||
foreach ($this->getPropertyAnnotations($property) as $annot) { |
||||
if ($annot instanceof $annotationName) { |
||||
return $annot; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Get method annotations |
||||
* |
||||
* @param \ReflectionMethod $method |
||||
* @return array |
||||
*/ |
||||
public function getMethodAnnotations(\ReflectionMethod $method) |
||||
{ |
||||
$class = $method->getDeclaringClass(); |
||||
$cacheKey = $class->getName().'#'.$method->getName(); |
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) { |
||||
return $this->loadedAnnotations[$cacheKey]; |
||||
} |
||||
|
||||
if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) { |
||||
$annots = $this->delegate->getMethodAnnotations($method); |
||||
$this->saveToCache($cacheKey, $annots); |
||||
} |
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots; |
||||
} |
||||
|
||||
/** |
||||
* Get selected method annotation |
||||
* |
||||
* @param \ReflectionMethod $method |
||||
* @param string $annotationName |
||||
* @return null |
||||
*/ |
||||
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) |
||||
{ |
||||
foreach ($this->getMethodAnnotations($method) as $annot) { |
||||
if ($annot instanceof $annotationName) { |
||||
return $annot; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Clear loaded annotations |
||||
*/ |
||||
public function clearLoadedAnnotations() |
||||
{ |
||||
$this->loadedAnnotations = array(); |
||||
} |
||||
|
||||
/** |
||||
* Fetches a value from the cache. |
||||
* |
||||
* @param string $rawCacheKey The cache key. |
||||
* @param \ReflectionClass $class The related class. |
||||
* @return mixed|boolean The cached value or false when the value is not in cache. |
||||
*/ |
||||
private function fetchFromCache($rawCacheKey, \ReflectionClass $class) |
||||
{ |
||||
$cacheKey = $rawCacheKey . self::$CACHE_SALT; |
||||
if (($data = $this->cache->fetch($cacheKey)) !== false) { |
||||
if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) { |
||||
return $data; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Saves a value to the cache |
||||
* |
||||
* @param string $rawCacheKey The cache key. |
||||
* @param mixed $value The value. |
||||
*/ |
||||
private function saveToCache($rawCacheKey, $value) |
||||
{ |
||||
$cacheKey = $rawCacheKey . self::$CACHE_SALT; |
||||
$this->cache->save($cacheKey, $value); |
||||
if ($this->debug) { |
||||
$this->cache->save('[C]'.$cacheKey, time()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Check if cache is fresh |
||||
* |
||||
* @param string $cacheKey |
||||
* @param \ReflectionClass $class |
||||
* @return bool |
||||
*/ |
||||
private function isCacheFresh($cacheKey, \ReflectionClass $class) |
||||
{ |
||||
if (false === $filename = $class->getFilename()) { |
||||
return true; |
||||
} |
||||
|
||||
return $this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename); |
||||
} |
||||
} |
@ -0,0 +1,132 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Lexer\AbstractLexer; |
||||
|
||||
/** |
||||
* Simple lexer for docblock annotations. |
||||
* |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> |
||||
* @author Jonathan Wage <jonwage@gmail.com> |
||||
* @author Roman Borschel <roman@code-factory.org> |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
*/ |
||||
final class DocLexer extends AbstractLexer |
||||
{ |
||||
const T_NONE = 1; |
||||
const T_INTEGER = 2; |
||||
const T_STRING = 3; |
||||
const T_FLOAT = 4; |
||||
|
||||
// All tokens that are also identifiers should be >= 100 |
||||
const T_IDENTIFIER = 100; |
||||
const T_AT = 101; |
||||
const T_CLOSE_CURLY_BRACES = 102; |
||||
const T_CLOSE_PARENTHESIS = 103; |
||||
const T_COMMA = 104; |
||||
const T_EQUALS = 105; |
||||
const T_FALSE = 106; |
||||
const T_NAMESPACE_SEPARATOR = 107; |
||||
const T_OPEN_CURLY_BRACES = 108; |
||||
const T_OPEN_PARENTHESIS = 109; |
||||
const T_TRUE = 110; |
||||
const T_NULL = 111; |
||||
const T_COLON = 112; |
||||
|
||||
protected $noCase = array( |
||||
'@' => self::T_AT, |
||||
',' => self::T_COMMA, |
||||
'(' => self::T_OPEN_PARENTHESIS, |
||||
')' => self::T_CLOSE_PARENTHESIS, |
||||
'{' => self::T_OPEN_CURLY_BRACES, |
||||
'}' => self::T_CLOSE_CURLY_BRACES, |
||||
'=' => self::T_EQUALS, |
||||
':' => self::T_COLON, |
||||
'\\' => self::T_NAMESPACE_SEPARATOR |
||||
); |
||||
|
||||
protected $withCase = array( |
||||
'true' => self::T_TRUE, |
||||
'false' => self::T_FALSE, |
||||
'null' => self::T_NULL |
||||
); |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function getCatchablePatterns() |
||||
{ |
||||
return array( |
||||
'[a-z_\\\][a-z0-9_\:\\\]*[a-z]{1}', |
||||
'(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?', |
||||
'"(?:[^"]|"")*"', |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
protected function getNonCatchablePatterns() |
||||
{ |
||||
return array('\s+', '\*+', '(.)'); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
* |
||||
* @param string $value |
||||
* |
||||
* @return int |
||||
*/ |
||||
protected function getType(&$value) |
||||
{ |
||||
$type = self::T_NONE; |
||||
|
||||
if ($value[0] === '"') { |
||||
$value = str_replace('""', '"', substr($value, 1, strlen($value) - 2)); |
||||
|
||||
return self::T_STRING; |
||||
} |
||||
|
||||
if (isset($this->noCase[$value])) { |
||||
return $this->noCase[$value]; |
||||
} |
||||
|
||||
if ($value[0] === '_' || $value[0] === '\\' || ctype_alpha($value[0])) { |
||||
return self::T_IDENTIFIER; |
||||
} |
||||
|
||||
$lowerValue = strtolower($value); |
||||
|
||||
if (isset($this->withCase[$lowerValue])) { |
||||
return $this->withCase[$lowerValue]; |
||||
} |
||||
|
||||
// Checking numeric value |
||||
if (is_numeric($value)) { |
||||
return (strpos($value, '.') !== false || stripos($value, 'e') !== false) |
||||
? self::T_FLOAT : self::T_INTEGER; |
||||
} |
||||
|
||||
return $type; |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,269 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
|
||||
/** |
||||
* File cache reader for annotations. |
||||
* |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
* @author Benjamin Eberlei <kontakt@beberlei.de> |
||||
*/ |
||||
class FileCacheReader implements Reader |
||||
{ |
||||
/** |
||||
* @var Reader |
||||
*/ |
||||
private $reader; |
||||
|
||||
/** |
||||
* @var string |
||||
*/ |
||||
private $dir; |
||||
|
||||
/** |
||||
* @var bool |
||||
*/ |
||||
private $debug; |
||||
|
||||
/** |
||||
* @var array |
||||
*/ |
||||
private $loadedAnnotations = array(); |
||||
|
||||
private $classNameHashes = array(); |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param Reader $reader |
||||
* @param string $cacheDir |
||||
* @param bool $debug |
||||
* |
||||
* @throws \InvalidArgumentException |
||||
*/ |
||||
public function __construct(Reader $reader, $cacheDir, $debug = false) |
||||
{ |
||||
$this->reader = $reader; |
||||
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true)) { |
||||
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir)); |
||||
} |
||||
if (!is_writable($cacheDir)) { |
||||
throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $cacheDir)); |
||||
} |
||||
|
||||
$this->dir = rtrim($cacheDir, '\\/'); |
||||
$this->debug = $debug; |
||||
} |
||||
|
||||
/** |
||||
* Retrieve annotations for class |
||||
* |
||||
* @param \ReflectionClass $class |
||||
* @return array |
||||
*/ |
||||
public function getClassAnnotations(\ReflectionClass $class) |
||||
{ |
||||
if ( ! isset($this->classNameHashes[$class->name])) { |
||||
$this->classNameHashes[$class->name] = sha1($class->name); |
||||
} |
||||
$key = $this->classNameHashes[$class->name]; |
||||
|
||||
if (isset($this->loadedAnnotations[$key])) { |
||||
return $this->loadedAnnotations[$key]; |
||||
} |
||||
|
||||
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; |
||||
if (!is_file($path)) { |
||||
$annot = $this->reader->getClassAnnotations($class); |
||||
$this->saveCacheFile($path, $annot); |
||||
return $this->loadedAnnotations[$key] = $annot; |
||||
} |
||||
|
||||
if ($this->debug |
||||
&& (false !== $filename = $class->getFilename()) |
||||
&& filemtime($path) < filemtime($filename)) { |
||||
@unlink($path); |
||||
|
||||
$annot = $this->reader->getClassAnnotations($class); |
||||
$this->saveCacheFile($path, $annot); |
||||
return $this->loadedAnnotations[$key] = $annot; |
||||
} |
||||
|
||||
return $this->loadedAnnotations[$key] = include $path; |
||||
} |
||||
|
||||
/** |
||||
* Get annotations for property |
||||
* |
||||
* @param \ReflectionProperty $property |
||||
* @return array |
||||
*/ |
||||
public function getPropertyAnnotations(\ReflectionProperty $property) |
||||
{ |
||||
$class = $property->getDeclaringClass(); |
||||
if ( ! isset($this->classNameHashes[$class->name])) { |
||||
$this->classNameHashes[$class->name] = sha1($class->name); |
||||
} |
||||
$key = $this->classNameHashes[$class->name].'$'.$property->getName(); |
||||
|
||||
if (isset($this->loadedAnnotations[$key])) { |
||||
return $this->loadedAnnotations[$key]; |
||||
} |
||||
|
||||
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; |
||||
if (!is_file($path)) { |
||||
$annot = $this->reader->getPropertyAnnotations($property); |
||||
$this->saveCacheFile($path, $annot); |
||||
return $this->loadedAnnotations[$key] = $annot; |
||||
} |
||||
|
||||
if ($this->debug |
||||
&& (false !== $filename = $class->getFilename()) |
||||
&& filemtime($path) < filemtime($filename)) { |
||||
@unlink($path); |
||||
|
||||
$annot = $this->reader->getPropertyAnnotations($property); |
||||
$this->saveCacheFile($path, $annot); |
||||
return $this->loadedAnnotations[$key] = $annot; |
||||
} |
||||
|
||||
return $this->loadedAnnotations[$key] = include $path; |
||||
} |
||||
|
||||
/** |
||||
* Retrieve annotations for method |
||||
* |
||||
* @param \ReflectionMethod $method |
||||
* @return array |
||||
*/ |
||||
public function getMethodAnnotations(\ReflectionMethod $method) |
||||
{ |
||||
$class = $method->getDeclaringClass(); |
||||
if ( ! isset($this->classNameHashes[$class->name])) { |
||||
$this->classNameHashes[$class->name] = sha1($class->name); |
||||
} |
||||
$key = $this->classNameHashes[$class->name].'#'.$method->getName(); |
||||
|
||||
if (isset($this->loadedAnnotations[$key])) { |
||||
return $this->loadedAnnotations[$key]; |
||||
} |
||||
|
||||
$path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; |
||||
if (!is_file($path)) { |
||||
$annot = $this->reader->getMethodAnnotations($method); |
||||
$this->saveCacheFile($path, $annot); |
||||
return $this->loadedAnnotations[$key] = $annot; |
||||
} |
||||
|
||||
if ($this->debug |
||||
&& (false !== $filename = $class->getFilename()) |
||||
&& filemtime($path) < filemtime($filename)) { |
||||
@unlink($path); |
||||
|
||||
$annot = $this->reader->getMethodAnnotations($method); |
||||
$this->saveCacheFile($path, $annot); |
||||
return $this->loadedAnnotations[$key] = $annot; |
||||
} |
||||
|
||||
return $this->loadedAnnotations[$key] = include $path; |
||||
} |
||||
|
||||
/** |
||||
* Save cache file |
||||
* |
||||
* @param string $path |
||||
* @param mixed $data |
||||
*/ |
||||
private function saveCacheFile($path, $data) |
||||
{ |
||||
file_put_contents($path, '<?php return unserialize('.var_export(serialize($data), true).');'); |
||||
} |
||||
|
||||
/** |
||||
* Gets a class annotation. |
||||
* |
||||
* @param \ReflectionClass $class The ReflectionClass of the class from which |
||||
* the class annotations should be read. |
||||
* @param string $annotationName The name of the annotation. |
||||
* |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getClassAnnotation(\ReflectionClass $class, $annotationName) |
||||
{ |
||||
$annotations = $this->getClassAnnotations($class); |
||||
|
||||
foreach ($annotations as $annotation) { |
||||
if ($annotation instanceof $annotationName) { |
||||
return $annotation; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Gets a method annotation. |
||||
* |
||||
* @param \ReflectionMethod $method |
||||
* @param string $annotationName The name of the annotation. |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) |
||||
{ |
||||
$annotations = $this->getMethodAnnotations($method); |
||||
|
||||
foreach ($annotations as $annotation) { |
||||
if ($annotation instanceof $annotationName) { |
||||
return $annotation; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Gets a property annotation. |
||||
* |
||||
* @param \ReflectionProperty $property |
||||
* @param string $annotationName The name of the annotation. |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) |
||||
{ |
||||
$annotations = $this->getPropertyAnnotations($property); |
||||
|
||||
foreach ($annotations as $annotation) { |
||||
if ($annotation instanceof $annotationName) { |
||||
return $annotation; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Clear stores annotations |
||||
*/ |
||||
public function clearLoadedAnnotations() |
||||
{ |
||||
$this->loadedAnnotations = array(); |
||||
} |
||||
} |
@ -0,0 +1,141 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\Reader; |
||||
|
||||
/** |
||||
* Allows the reader to be used in-place of Doctrine's reader. |
||||
* |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
*/ |
||||
class IndexedReader implements Reader |
||||
{ |
||||
/** |
||||
* @var Reader |
||||
*/ |
||||
private $delegate; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* @param Reader $reader |
||||
*/ |
||||
public function __construct(Reader $reader) |
||||
{ |
||||
$this->delegate = $reader; |
||||
} |
||||
|
||||
/** |
||||
* Get Annotations for class |
||||
* |
||||
* @param \ReflectionClass $class |
||||
* @return array |
||||
*/ |
||||
public function getClassAnnotations(\ReflectionClass $class) |
||||
{ |
||||
$annotations = array(); |
||||
foreach ($this->delegate->getClassAnnotations($class) as $annot) { |
||||
$annotations[get_class($annot)] = $annot; |
||||
} |
||||
|
||||
return $annotations; |
||||
} |
||||
|
||||
/** |
||||
* Get selected annotation for class |
||||
* |
||||
* @param \ReflectionClass $class |
||||
* @param string $annotation |
||||
* @return mixed |
||||
*/ |
||||
public function getClassAnnotation(\ReflectionClass $class, $annotation) |
||||
{ |
||||
return $this->delegate->getClassAnnotation($class, $annotation); |
||||
} |
||||
|
||||
/** |
||||
* Get Annotations for method |
||||
* |
||||
* @param \ReflectionMethod $method |
||||
* @return array |
||||
*/ |
||||
public function getMethodAnnotations(\ReflectionMethod $method) |
||||
{ |
||||
$annotations = array(); |
||||
foreach ($this->delegate->getMethodAnnotations($method) as $annot) { |
||||
$annotations[get_class($annot)] = $annot; |
||||
} |
||||
|
||||
return $annotations; |
||||
} |
||||
|
||||
/** |
||||
* Get selected annotation for method |
||||
* |
||||
* @param \ReflectionMethod $method |
||||
* @param string $annotation |
||||
* @return mixed |
||||
*/ |
||||
public function getMethodAnnotation(\ReflectionMethod $method, $annotation) |
||||
{ |
||||
return $this->delegate->getMethodAnnotation($method, $annotation); |
||||
} |
||||
|
||||
/** |
||||
* Get annotations for property |
||||
* |
||||
* @param \ReflectionProperty $property |
||||
* @return array |
||||
*/ |
||||
public function getPropertyAnnotations(\ReflectionProperty $property) |
||||
{ |
||||
$annotations = array(); |
||||
foreach ($this->delegate->getPropertyAnnotations($property) as $annot) { |
||||
$annotations[get_class($annot)] = $annot; |
||||
} |
||||
|
||||
return $annotations; |
||||
} |
||||
|
||||
/** |
||||
* Get selected annotation for property |
||||
* |
||||
* @param \ReflectionProperty $property |
||||
* @param string $annotation |
||||
* @return mixed |
||||
*/ |
||||
public function getPropertyAnnotation(\ReflectionProperty $property, $annotation) |
||||
{ |
||||
return $this->delegate->getPropertyAnnotation($property, $annotation); |
||||
} |
||||
|
||||
/** |
||||
* Proxy all methods to the delegate. |
||||
* |
||||
* @param string $method |
||||
* @param array $args |
||||
* @return mixed |
||||
*/ |
||||
public function __call($method, $args) |
||||
{ |
||||
return call_user_func_array(array($this->delegate, $method), $args); |
||||
} |
||||
} |
@ -0,0 +1,89 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
use SplFileObject; |
||||
|
||||
/** |
||||
* Parses a file for namespaces/use/class declarations. |
||||
* |
||||
* @author Fabien Potencier <fabien@symfony.com> |
||||
* @author Christian Kaps <christian.kaps@mohiva.com> |
||||
*/ |
||||
final class PhpParser |
||||
{ |
||||
/** |
||||
* Parses a class. |
||||
* |
||||
* @param \ReflectionClass $class A <code>ReflectionClass</code> object. |
||||
* @return array A list with use statements in the form (Alias => FQN). |
||||
*/ |
||||
public function parseClass(\ReflectionClass $class) |
||||
{ |
||||
if (method_exists($class, 'getUseStatements')) { |
||||
return $class->getUseStatements(); |
||||
} |
||||
|
||||
if (false === $filename = $class->getFilename()) { |
||||
return array(); |
||||
} |
||||
|
||||
$content = $this->getFileContent($filename, $class->getStartLine()); |
||||
|
||||
if (null === $content) { |
||||
return array(); |
||||
} |
||||
|
||||
$namespace = preg_quote($class->getNamespaceName()); |
||||
$content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content); |
||||
$tokenizer = new TokenParser('<?php ' . $content); |
||||
|
||||
$statements = $tokenizer->parseUseStatements($class->getNamespaceName()); |
||||
|
||||
return $statements; |
||||
} |
||||
|
||||
/** |
||||
* Get the content of the file right up to the given line number. |
||||
* |
||||
* @param string $filename The name of the file to load. |
||||
* @param int $lineNumber The number of lines to read from file. |
||||
* @return string The content of the file. |
||||
*/ |
||||
private function getFileContent($filename, $lineNumber) |
||||
{ |
||||
if ( ! is_file($filename)) { |
||||
return null; |
||||
} |
||||
|
||||
$content = ''; |
||||
$lineCnt = 0; |
||||
$file = new SplFileObject($filename); |
||||
while (!$file->eof()) { |
||||
if ($lineCnt++ == $lineNumber) { |
||||
break; |
||||
} |
||||
|
||||
$content .= $file->fgets(); |
||||
} |
||||
|
||||
return $content; |
||||
} |
||||
} |
@ -0,0 +1,67 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
/** |
||||
* Interface for annotation readers. |
||||
* |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
*/ |
||||
interface Reader |
||||
{ |
||||
/** |
||||
* @param \ReflectionClass $class |
||||
* @return mixed |
||||
*/ |
||||
function getClassAnnotations(\ReflectionClass $class); |
||||
|
||||
/** |
||||
* @param \ReflectionClass $class |
||||
* @param string $annotationName |
||||
* @return mixed |
||||
*/ |
||||
function getClassAnnotation(\ReflectionClass $class, $annotationName); |
||||
|
||||
/** |
||||
* @param \ReflectionMethod $method |
||||
* @return mixed |
||||
*/ |
||||
function getMethodAnnotations(\ReflectionMethod $method); |
||||
|
||||
/** |
||||
* @param \ReflectionMethod $method |
||||
* @param string $annotationName |
||||
* @return mixed |
||||
*/ |
||||
function getMethodAnnotation(\ReflectionMethod $method, $annotationName); |
||||
|
||||
/** |
||||
* @param \ReflectionProperty $property |
||||
* @return mixed |
||||
*/ |
||||
function getPropertyAnnotations(\ReflectionProperty $property); |
||||
|
||||
/** |
||||
* @param \ReflectionProperty $property |
||||
* @param string $annotationName |
||||
* @return mixed |
||||
*/ |
||||
function getPropertyAnnotation(\ReflectionProperty $property, $annotationName); |
||||
} |
@ -0,0 +1,157 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\Annotation\Target; |
||||
|
||||
/** |
||||
* Simple Annotation Reader. |
||||
* |
||||
* This annotation reader is intended to be used in projects where you have |
||||
* full-control over all annotations that are available. |
||||
* |
||||
* @since 2.2 |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com> |
||||
*/ |
||||
class SimpleAnnotationReader implements Reader |
||||
{ |
||||
/** |
||||
* @var DocParser |
||||
*/ |
||||
private $parser; |
||||
|
||||
/** |
||||
* Constructor. |
||||
* |
||||
* Initializes a new SimpleAnnotationReader. |
||||
*/ |
||||
public function __construct() |
||||
{ |
||||
$this->parser = new DocParser(); |
||||
$this->parser->setIgnoreNotImportedAnnotations(true); |
||||
} |
||||
|
||||
/** |
||||
* Adds a namespace in which we will look for annotations. |
||||
* |
||||
* @param string $namespace |
||||
*/ |
||||
public function addNamespace($namespace) |
||||
{ |
||||
$this->parser->addNamespace($namespace); |
||||
} |
||||
|
||||
/** |
||||
* Gets the annotations applied to a class. |
||||
* |
||||
* @param \ReflectionClass $class The ReflectionClass of the class from which |
||||
* the class annotations should be read. |
||||
* |
||||
* @return array An array of Annotations. |
||||
*/ |
||||
public function getClassAnnotations(\ReflectionClass $class) |
||||
{ |
||||
return $this->parser->parse($class->getDocComment(), 'class '.$class->getName()); |
||||
} |
||||
|
||||
/** |
||||
* Gets the annotations applied to a method. |
||||
* |
||||
* @param \ReflectionMethod $method The ReflectionMethod of the method from which |
||||
* the annotations should be read. |
||||
* |
||||
* @return array An array of Annotations. |
||||
*/ |
||||
public function getMethodAnnotations(\ReflectionMethod $method) |
||||
{ |
||||
return $this->parser->parse($method->getDocComment(), 'method '.$method->getDeclaringClass()->name.'::'.$method->getName().'()'); |
||||
} |
||||
|
||||
/** |
||||
* Gets the annotations applied to a property. |
||||
* |
||||
* @param \ReflectionProperty $property The ReflectionProperty of the property |
||||
* from which the annotations should be read. |
||||
* |
||||
* @return array An array of Annotations. |
||||
*/ |
||||
public function getPropertyAnnotations(\ReflectionProperty $property) |
||||
{ |
||||
return $this->parser->parse($property->getDocComment(), 'property '.$property->getDeclaringClass()->name.'::$'.$property->getName()); |
||||
} |
||||
|
||||
/** |
||||
* Gets a class annotation. |
||||
* |
||||
* @param \ReflectionClass $class The ReflectionClass of the class from which |
||||
* the class annotations should be read. |
||||
* @param string $annotationName The name of the annotation. |
||||
* |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getClassAnnotation(\ReflectionClass $class, $annotationName) |
||||
{ |
||||
foreach ($this->getClassAnnotations($class) as $annot) { |
||||
if ($annot instanceof $annotationName) { |
||||
return $annot; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Gets a method annotation. |
||||
* |
||||
* @param \ReflectionMethod $method |
||||
* @param string $annotationName The name of the annotation. |
||||
* |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) |
||||
{ |
||||
foreach ($this->getMethodAnnotations($method) as $annot) { |
||||
if ($annot instanceof $annotationName) { |
||||
return $annot; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Gets a property annotation. |
||||
* |
||||
* @param \ReflectionProperty $property |
||||
* @param string $annotationName The name of the annotation. |
||||
* @return mixed The Annotation or NULL, if the requested annotation does not exist. |
||||
*/ |
||||
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) |
||||
{ |
||||
foreach ($this->getPropertyAnnotations($property) as $annot) { |
||||
if ($annot instanceof $annotationName) { |
||||
return $annot; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,175 @@ |
||||
<?php |
||||
/* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* This software consists of voluntary contributions made by many individuals |
||||
* and is licensed under the MIT license. For more information, see |
||||
* <http://www.doctrine-project.org>. |
||||
*/ |
||||
|
||||
namespace Doctrine\Common\Annotations; |
||||
|
||||
/** |
||||
* Parses a file for namespaces/use/class declarations. |
||||
* |
||||
* @author Fabien Potencier <fabien@symfony.com> |
||||
* @author Christian Kaps <christian.kaps@mohiva.com> |
||||
*/ |
||||
class TokenParser |
||||
{ |
||||
/** |
||||
* The token list. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $tokens; |
||||
|
||||
/** |
||||
* The number of tokens. |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $numTokens = 0; |
||||
|
||||
/** |
||||
* The current array pointer. |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $pointer = 0; |
||||
|
||||
public function __construct($contents) |
||||
{ |
||||
$this->tokens = token_get_all($contents); |
||||
$this->numTokens = count($this->tokens); |
||||
$this->pointer = 0; |
||||
} |
||||
|
||||
/** |
||||
* Gets the next non whitespace and non comment token. |
||||
* |
||||
* @param $docCommentIsComment |
||||
* If TRUE then a doc comment is considered a comment and skipped. |
||||
* If FALSE then only whitespace and normal comments are skipped. |
||||
* |
||||
* @return array The token if exists, null otherwise. |
||||
*/ |
||||
public function next($docCommentIsComment = TRUE) |
||||
{ |
||||
for ($i = $this->pointer; $i < $this->numTokens; $i++) { |
||||
$this->pointer++; |
||||
if ($this->tokens[$i][0] === T_WHITESPACE || |
||||
$this->tokens[$i][0] === T_COMMENT || |
||||
($docCommentIsComment && $this->tokens[$i][0] === T_DOC_COMMENT)) { |
||||
|
||||
continue; |
||||
} |
||||
|
||||
return $this->tokens[$i]; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Parse a single use statement. |
||||
* |
||||
* @return array A list with all found class names for a use statement. |
||||
*/ |
||||
public function parseUseStatement() |
||||
{ |
||||
$class = ''; |
||||
$alias = ''; |
||||
$statements = array(); |
||||
$explicitAlias = false; |
||||
while (($token = $this->next())) { |
||||
$isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR; |
||||
if (!$explicitAlias && $isNameToken) { |
||||
$class .= $token[1]; |
||||
$alias = $token[1]; |
||||
} else if ($explicitAlias && $isNameToken) { |
||||
$alias .= $token[1]; |
||||
} else if ($token[0] === T_AS) { |
||||
$explicitAlias = true; |
||||
$alias = ''; |
||||
} else if ($token === ',') { |
||||
$statements[strtolower($alias)] = $class; |
||||
$class = ''; |
||||
$alias = ''; |
||||
$explicitAlias = false; |
||||
} else if ($token === ';') { |
||||
$statements[strtolower($alias)] = $class; |
||||
break; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return $statements; |
||||
} |
||||
|
||||
/** |
||||
* Get all use statements. |
||||
* |
||||
* @param string $namespaceName The namespace name of the reflected class. |
||||
* @return array A list with all found use statements. |
||||
*/ |
||||
public function parseUseStatements($namespaceName) |
||||
{ |
||||
$statements = array(); |
||||
while (($token = $this->next())) { |
||||
if ($token[0] === T_USE) { |
||||
$statements = array_merge($statements, $this->parseUseStatement()); |
||||
continue; |
||||
} |
||||
if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) { |
||||
continue; |
||||
} |
||||
|
||||
// Get fresh array for new namespace. This is to prevent the parser to collect the use statements |
||||
// for a previous namespace with the same name. This is the case if a namespace is defined twice |
||||
// or if a namespace with the same name is commented out. |
||||
$statements = array(); |
||||
} |
||||
|
||||
return $statements; |
||||
} |
||||
|
||||
/** |
||||
* Get the namespace. |
||||
* |
||||
* @return string The found namespace. |
||||
*/ |
||||
public function parseNamespace() |
||||
{ |
||||
$name = ''; |
||||
while (($token = $this->next()) && ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR)) { |
||||
$name .= $token[1]; |
||||
} |
||||
|
||||
return $name; |
||||
} |
||||
|
||||
/** |
||||
* Get the class name. |
||||
* |
||||
* @return string The foundclass name. |
||||
*/ |
||||
public function parseClass() |
||||
{ |
||||
// Namespaces and class names are tokenized the same: T_STRINGs |
||||
// separated by T_NS_SEPARATOR so we can use one function to provide |
||||
// both. |
||||
return $this->parseNamespace(); |
||||
} |
||||
} |
@ -0,0 +1,31 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<phpunit backupGlobals="false" |
||||
backupStaticAttributes="false" |
||||
colors="true" |
||||
convertErrorsToExceptions="true" |
||||
convertNoticesToExceptions="true" |
||||
convertWarningsToExceptions="true" |
||||
processIsolation="false" |
||||
stopOnFailure="false" |
||||
syntaxCheck="false" |
||||
bootstrap="./tests/Doctrine/Tests/TestInit.php" |
||||
> |
||||
<testsuites> |
||||
<testsuite name="Doctrine Annotations Test Suite"> |
||||
<directory>./tests/Doctrine/</directory> |
||||
</testsuite> |
||||
</testsuites> |
||||
|
||||
<filter> |
||||
<whitelist> |
||||
<directory>./lib/Doctrine/</directory> |
||||
</whitelist> |
||||
</filter> |
||||
|
||||
<groups> |
||||
<exclude> |
||||
<group>performance</group> |
||||
</exclude> |
||||
</groups> |
||||
</phpunit> |
@ -0,0 +1,571 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\DoctrineReader; |
||||
use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation; |
||||
use Doctrine\Common\Annotations\Annotation\IgnorePhpDoc; |
||||
use ReflectionClass, Doctrine\Common\Annotations\AnnotationReader; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\DummyAnnotation; |
||||
use Doctrine\Tests\Common\Annotations\Name; |
||||
use Doctrine\Tests\Common\Annotations\DummyId; |
||||
use Doctrine\Tests\Common\Annotations\DummyJoinTable; |
||||
use Doctrine\Tests\Common\Annotations\DummyJoinColumn; |
||||
use Doctrine\Tests\Common\Annotations\DummyColumn; |
||||
use Doctrine\Tests\Common\Annotations\DummyGeneratedValue; |
||||
|
||||
require_once __DIR__ . '/TopLevelAnnotation.php'; |
||||
|
||||
abstract class AbstractReaderTest extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
public function getReflectionClass() |
||||
{ |
||||
$className = 'Doctrine\Tests\Common\Annotations\DummyClass'; |
||||
return new ReflectionClass($className); |
||||
} |
||||
|
||||
public function testAnnotations() |
||||
{ |
||||
$class = $this->getReflectionClass(); |
||||
$reader = $this->getReader(); |
||||
|
||||
$this->assertEquals(1, count($reader->getClassAnnotations($class))); |
||||
$this->assertInstanceOf($annotName = 'Doctrine\Tests\Common\Annotations\DummyAnnotation', $annot = $reader->getClassAnnotation($class, $annotName)); |
||||
$this->assertEquals("hello", $annot->dummyValue); |
||||
|
||||
$field1Prop = $class->getProperty('field1'); |
||||
$propAnnots = $reader->getPropertyAnnotations($field1Prop); |
||||
$this->assertEquals(1, count($propAnnots)); |
||||
$this->assertInstanceOf($annotName, $annot = $reader->getPropertyAnnotation($field1Prop, $annotName)); |
||||
$this->assertEquals("fieldHello", $annot->dummyValue); |
||||
|
||||
$getField1Method = $class->getMethod('getField1'); |
||||
$methodAnnots = $reader->getMethodAnnotations($getField1Method); |
||||
$this->assertEquals(1, count($methodAnnots)); |
||||
$this->assertInstanceOf($annotName, $annot = $reader->getMethodAnnotation($getField1Method, $annotName)); |
||||
$this->assertEquals(array(1, 2, "three"), $annot->value); |
||||
|
||||
$field2Prop = $class->getProperty('field2'); |
||||
$propAnnots = $reader->getPropertyAnnotations($field2Prop); |
||||
$this->assertEquals(1, count($propAnnots)); |
||||
$this->assertInstanceOf($annotName = 'Doctrine\Tests\Common\Annotations\DummyJoinTable', $joinTableAnnot = $reader->getPropertyAnnotation($field2Prop, $annotName)); |
||||
$this->assertEquals(1, count($joinTableAnnot->joinColumns)); |
||||
$this->assertEquals(1, count($joinTableAnnot->inverseJoinColumns)); |
||||
$this->assertTrue($joinTableAnnot->joinColumns[0] instanceof DummyJoinColumn); |
||||
$this->assertTrue($joinTableAnnot->inverseJoinColumns[0] instanceof DummyJoinColumn); |
||||
$this->assertEquals('col1', $joinTableAnnot->joinColumns[0]->name); |
||||
$this->assertEquals('col2', $joinTableAnnot->joinColumns[0]->referencedColumnName); |
||||
$this->assertEquals('col3', $joinTableAnnot->inverseJoinColumns[0]->name); |
||||
$this->assertEquals('col4', $joinTableAnnot->inverseJoinColumns[0]->referencedColumnName); |
||||
|
||||
$dummyAnnot = $reader->getMethodAnnotation($class->getMethod('getField1'), 'Doctrine\Tests\Common\Annotations\DummyAnnotation'); |
||||
$this->assertEquals('', $dummyAnnot->dummyValue); |
||||
$this->assertEquals(array(1, 2, 'three'), $dummyAnnot->value); |
||||
|
||||
$dummyAnnot = $reader->getPropertyAnnotation($class->getProperty('field1'), 'Doctrine\Tests\Common\Annotations\DummyAnnotation'); |
||||
$this->assertEquals('fieldHello', $dummyAnnot->dummyValue); |
||||
|
||||
$classAnnot = $reader->getClassAnnotation($class, 'Doctrine\Tests\Common\Annotations\DummyAnnotation'); |
||||
$this->assertEquals('hello', $classAnnot->dummyValue); |
||||
} |
||||
|
||||
public function testAnnotationsWithValidTargets() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithValidAnnotationTarget'); |
||||
|
||||
$this->assertEquals(1,count($reader->getClassAnnotations($class))); |
||||
$this->assertEquals(1,count($reader->getPropertyAnnotations($class->getProperty('foo')))); |
||||
$this->assertEquals(1,count($reader->getMethodAnnotations($class->getMethod('someFunction')))); |
||||
$this->assertEquals(1,count($reader->getPropertyAnnotations($class->getProperty('nested')))); |
||||
} |
||||
|
||||
public function testAnnotationsWithVarType() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType'); |
||||
|
||||
$this->assertEquals(1,count($fooAnnot = $reader->getPropertyAnnotations($class->getProperty('foo')))); |
||||
$this->assertEquals(1,count($barAnnot = $reader->getMethodAnnotations($class->getMethod('bar')))); |
||||
|
||||
$this->assertInternalType('string', $fooAnnot[0]->string); |
||||
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', $barAnnot[0]->annotation); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetPropertyMethod is not allowed to be declared on class Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtClass. You may only use this annotation on these code elements: METHOD, PROPERTY |
||||
*/ |
||||
public function testClassWithInvalidAnnotationTargetAtClassDocBlock() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtClass')); |
||||
} |
||||
|
||||
public function testClassWithWithInclude() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$annots = $reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithRequire')); |
||||
$this->assertCount(1, $annots); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetClass is not allowed to be declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty::$foo. You may only use this annotation on these code elements: CLASS |
||||
*/ |
||||
public function testClassWithInvalidAnnotationTargetAtPropertyDocBlock() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty', 'foo')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetAnnotation is not allowed to be declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty::$bar. You may only use this annotation on these code elements: ANNOTATION |
||||
*/ |
||||
public function testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty', 'bar')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage [Semantical Error] Annotation @AnnotationTargetClass is not allowed to be declared on method Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtMethod::functionName(). You may only use this annotation on these code elements: CLASS |
||||
*/ |
||||
public function testClassWithInvalidAnnotationTargetAtMethodDocBlock() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getMethodAnnotations(new \ReflectionMethod('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtMethod', 'functionName')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError. |
||||
*/ |
||||
public function testClassWithAnnotationWithTargetSyntaxErrorAtClassDocBlock() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithTargetSyntaxError')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError. |
||||
*/ |
||||
public function testClassWithAnnotationWithTargetSyntaxErrorAtPropertyDocBlock() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithTargetSyntaxError','foo')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError. |
||||
*/ |
||||
public function testClassWithAnnotationWithTargetSyntaxErrorAtMethodDocBlock() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getMethodAnnotations(new \ReflectionMethod('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithTargetSyntaxError','bar')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage [Type Error] Attribute "string" of @AnnotationWithVarType declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType::$invalidProperty expects a(n) string, but got integer. |
||||
*/ |
||||
public function testClassWithPropertyInvalidVarTypeError() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType'); |
||||
|
||||
$reader->getPropertyAnnotations($class->getProperty('invalidProperty')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage [Type Error] Attribute "annotation" of @AnnotationWithVarType declared on method Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType::invalidMethod() expects a(n) Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll, but got an instance of Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation. |
||||
*/ |
||||
public function testClassWithMethodInvalidVarTypeError() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$class = new ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType'); |
||||
|
||||
$reader->getMethodAnnotations($class->getMethod('invalidMethod')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 18 in class Doctrine\Tests\Common\Annotations\DummyClassSyntaxError. |
||||
*/ |
||||
public function testClassSyntaxErrorContext() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getClassAnnotations(new \ReflectionClass('Doctrine\Tests\Common\Annotations\DummyClassSyntaxError')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 18 in method Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError::foo(). |
||||
*/ |
||||
public function testMethodSyntaxErrorContext() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getMethodAnnotations(new \ReflectionMethod('Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError', 'foo')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 18 in property Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError::$foo. |
||||
*/ |
||||
public function testPropertySyntaxErrorContext() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError', 'foo')); |
||||
} |
||||
|
||||
/** |
||||
* @group regression |
||||
*/ |
||||
public function testMultipleAnnotationsOnSameLine() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$annots = $reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\DummyClass2', 'id')); |
||||
$this->assertEquals(3, count($annots)); |
||||
} |
||||
|
||||
public function testNonAnnotationProblem() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
|
||||
$this->assertNotNull($annot = $reader->getPropertyAnnotation(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\DummyClassNonAnnotationProblem', 'foo'), $name = 'Doctrine\Tests\Common\Annotations\DummyAnnotation')); |
||||
$this->assertInstanceOf($name, $annot); |
||||
} |
||||
|
||||
public function testImportWithConcreteAnnotation() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$property = new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestImportWithConcreteAnnotation', 'field'); |
||||
$annotations = $reader->getPropertyAnnotations($property); |
||||
$this->assertEquals(1, count($annotations)); |
||||
$this->assertNotNull($reader->getPropertyAnnotation($property, 'Doctrine\Tests\Common\Annotations\DummyAnnotation')); |
||||
} |
||||
|
||||
public function testImportWithInheritance() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
|
||||
$class = new TestParentClass(); |
||||
$ref = new \ReflectionClass($class); |
||||
|
||||
$childAnnotations = $reader->getPropertyAnnotations($ref->getProperty('child')); |
||||
$this->assertEquals(1, count($childAnnotations)); |
||||
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Foo\Name', reset($childAnnotations)); |
||||
|
||||
$parentAnnotations = $reader->getPropertyAnnotations($ref->getProperty('parent')); |
||||
$this->assertEquals(1, count($parentAnnotations)); |
||||
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Bar\Name', reset($parentAnnotations)); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage The annotation "@NameFoo" in property Doctrine\Tests\Common\Annotations\TestAnnotationNotImportedClass::$field was never imported. |
||||
*/ |
||||
public function testImportDetectsNotImportedAnnotation() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestAnnotationNotImportedClass', 'field')); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage The annotation "@Foo\Bar\Name" in property Doctrine\Tests\Common\Annotations\TestNonExistentAnnotationClass::$field was never imported. |
||||
*/ |
||||
public function testImportDetectsNonExistentAnnotation() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestNonExistentAnnotationClass', 'field')); |
||||
} |
||||
|
||||
public function testTopLevelAnnotation() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$annotations = $reader->getPropertyAnnotations(new \ReflectionProperty('Doctrine\Tests\Common\Annotations\TestTopLevelAnnotationClass', 'field')); |
||||
|
||||
$this->assertEquals(1, count($annotations)); |
||||
$this->assertInstanceOf('\TopLevelAnnotation', reset($annotations)); |
||||
} |
||||
|
||||
public function testIgnoresAnnotationsNotPrefixedWithWhitespace() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
|
||||
$annotation = $reader->getClassAnnotation(new \ReflectionClass(new TestIgnoresNonAnnotationsClass()), 'Doctrine\Tests\Common\Annotations\Name'); |
||||
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Name', $annotation); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage The class "Doctrine\Tests\Common\Annotations\Fixtures\NoAnnotation" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "Doctrine\Tests\Common\Annotations\Fixtures\NoAnnotation". If it is indeed no annotation, then you need to add @IgnoreAnnotation("NoAnnotation") to the _class_ doc comment of class Doctrine\Tests\Common\Annotations\Fixtures\InvalidAnnotationUsageClass. |
||||
*/ |
||||
public function testErrorWhenInvalidAnnotationIsUsed() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\InvalidAnnotationUsageClass'); |
||||
$reader->getClassAnnotations($ref); |
||||
} |
||||
|
||||
public function testInvalidAnnotationUsageButIgnoredClass() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\InvalidAnnotationUsageButIgnoredClass'); |
||||
$annots = $reader->getClassAnnotations($ref); |
||||
|
||||
$this->assertEquals(2, count($annots)); |
||||
} |
||||
|
||||
/** |
||||
* @group DDC-1660 |
||||
* @group regression |
||||
*/ |
||||
public function testInvalidAnnotationButIgnored() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassDDC1660'); |
||||
|
||||
$this->assertTrue(class_exists('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Version')); |
||||
$this->assertCount(0, $reader->getClassAnnotations($class)); |
||||
$this->assertCount(0, $reader->getMethodAnnotations($class->getMethod('bar'))); |
||||
$this->assertCount(0, $reader->getPropertyAnnotations($class->getProperty('foo'))); |
||||
} |
||||
|
||||
public function testAnnotationEnumeratorException() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum'); |
||||
|
||||
$this->assertCount(1, $bar = $reader->getMethodAnnotations($class->getMethod('bar'))); |
||||
$this->assertCount(1, $foo = $reader->getPropertyAnnotations($class->getProperty('foo'))); |
||||
|
||||
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum', $bar[0]); |
||||
$this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum', $foo[0]); |
||||
|
||||
try { |
||||
$reader->getPropertyAnnotations($class->getProperty('invalidProperty')); |
||||
$this->fail(); |
||||
} catch (\Doctrine\Common\Annotations\AnnotationException $exc) { |
||||
$this->assertEquals('[Enum Error] Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum::$invalidProperty accept only [ONE, TWO, THREE], but got FOUR.', $exc->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
$reader->getMethodAnnotations($class->getMethod('invalidMethod')); |
||||
$this->fail(); |
||||
} catch (\Doctrine\Common\Annotations\AnnotationException $exc) { |
||||
$this->assertEquals('[Enum Error] Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum declared on method Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum::invalidMethod() accept only [ONE, TWO, THREE], but got 5.', $exc->getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @group DCOM-106 |
||||
*/ |
||||
public function testIgnoreFixMeAndUpperCaseToDo() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$ref = new \ReflectionClass('Doctrine\Tests\Common\Annotations\DCOM106'); |
||||
$reader->getClassAnnotations($ref); |
||||
} |
||||
|
||||
/** |
||||
* @return AnnotationReader |
||||
*/ |
||||
abstract protected function getReader(); |
||||
} |
||||
|
||||
/** |
||||
* @parseAnnotation("var") |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
* |
||||
*/ |
||||
class TestParseAnnotationClass |
||||
{ |
||||
/** |
||||
* @var |
||||
*/ |
||||
private $field; |
||||
} |
||||
|
||||
/** |
||||
* @Name |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
*/ |
||||
class TestIgnoresNonAnnotationsClass |
||||
{ |
||||
} |
||||
|
||||
class TestTopLevelAnnotationClass |
||||
{ |
||||
/** |
||||
* @\TopLevelAnnotation |
||||
*/ |
||||
private $field; |
||||
} |
||||
|
||||
class TestNonExistentAnnotationClass |
||||
{ |
||||
/** |
||||
* @Foo\Bar\Name |
||||
*/ |
||||
private $field; |
||||
} |
||||
|
||||
class TestAnnotationNotImportedClass |
||||
{ |
||||
/** |
||||
* @NameFoo |
||||
*/ |
||||
private $field; |
||||
} |
||||
|
||||
class TestChildClass |
||||
{ |
||||
/** |
||||
* @\Doctrine\Tests\Common\Annotations\Foo\Name(name = "foo") |
||||
*/ |
||||
protected $child; |
||||
} |
||||
|
||||
class TestParentClass extends TestChildClass |
||||
{ |
||||
/** |
||||
* @\Doctrine\Tests\Common\Annotations\Bar\Name(name = "bar") |
||||
*/ |
||||
private $parent; |
||||
} |
||||
|
||||
class TestImportWithConcreteAnnotation |
||||
{ |
||||
/** |
||||
* @DummyAnnotation(dummyValue = "bar") |
||||
*/ |
||||
private $field; |
||||
} |
||||
|
||||
/** |
||||
* @ignoreAnnotation("var") |
||||
*/ |
||||
class DummyClass2 { |
||||
/** |
||||
* @DummyId @DummyColumn(type="integer") @DummyGeneratedValue |
||||
* @var integer |
||||
*/ |
||||
private $id; |
||||
} |
||||
|
||||
/** @Annotation */ |
||||
class DummyId extends \Doctrine\Common\Annotations\Annotation {} |
||||
/** @Annotation */ |
||||
class DummyColumn extends \Doctrine\Common\Annotations\Annotation { |
||||
public $type; |
||||
} |
||||
/** @Annotation */ |
||||
class DummyGeneratedValue extends \Doctrine\Common\Annotations\Annotation {} |
||||
/** @Annotation */ |
||||
class DummyAnnotation extends \Doctrine\Common\Annotations\Annotation { |
||||
public $dummyValue; |
||||
} |
||||
|
||||
/** |
||||
* @api |
||||
* @Annotation |
||||
*/ |
||||
class DummyAnnotationWithIgnoredAnnotation extends \Doctrine\Common\Annotations\Annotation { |
||||
public $dummyValue; |
||||
} |
||||
|
||||
/** @Annotation */ |
||||
class DummyJoinColumn extends \Doctrine\Common\Annotations\Annotation { |
||||
public $name; |
||||
public $referencedColumnName; |
||||
} |
||||
/** @Annotation */ |
||||
class DummyJoinTable extends \Doctrine\Common\Annotations\Annotation { |
||||
public $name; |
||||
public $joinColumns; |
||||
public $inverseJoinColumns; |
||||
} |
||||
|
||||
/** |
||||
* @DummyAnnotation(@) |
||||
*/ |
||||
class DummyClassSyntaxError |
||||
{ |
||||
|
||||
} |
||||
|
||||
class DummyClassMethodSyntaxError |
||||
{ |
||||
/** |
||||
* @DummyAnnotation(@) |
||||
*/ |
||||
public function foo() |
||||
{ |
||||
|
||||
} |
||||
} |
||||
|
||||
class DummyClassPropertySyntaxError |
||||
{ |
||||
/** |
||||
* @DummyAnnotation(@) |
||||
*/ |
||||
public $foo; |
||||
} |
||||
|
||||
/** |
||||
* @ignoreAnnotation({"since", "var"}) |
||||
*/ |
||||
class DummyClassNonAnnotationProblem |
||||
{ |
||||
/** |
||||
* @DummyAnnotation |
||||
* |
||||
* @var \Test |
||||
* @since 0.1 |
||||
*/ |
||||
public $foo; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* @DummyAnnotation Foo bar <foobar@1domain.com> |
||||
*/ |
||||
class DummyClassWithEmail |
||||
{ |
||||
|
||||
} |
||||
|
||||
|
||||
/** |
||||
* @fixme public |
||||
* @TODO |
||||
*/ |
||||
class DCOM106 |
||||
{ |
||||
|
||||
} |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Foo; |
||||
|
||||
/** @Annotation */ |
||||
class Name extends \Doctrine\Common\Annotations\Annotation |
||||
{ |
||||
public $name; |
||||
} |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Bar; |
||||
|
||||
/** @Annotation */ |
||||
class Name extends \Doctrine\Common\Annotations\Annotation |
||||
{ |
||||
public $name; |
||||
} |
@ -0,0 +1,13 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader; |
||||
|
||||
class AnnotationReaderTest extends AbstractReaderTest |
||||
{ |
||||
protected function getReader() |
||||
{ |
||||
return new AnnotationReader(); |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
use Doctrine\Common\Annotations\AnnotationReader; |
||||
use Doctrine\Common\Annotations\CachedReader; |
||||
use Doctrine\Common\Cache\ArrayCache; |
||||
|
||||
class CachedReaderTest extends AbstractReaderTest |
||||
{ |
||||
private $cache; |
||||
|
||||
public function testIgnoresStaleCache() |
||||
{ |
||||
$file = __DIR__.'/Fixtures/Controller.php'; |
||||
touch($file); |
||||
$name = 'Doctrine\Tests\Common\Annotations\Fixtures\Controller'; |
||||
$cacheKey = $name.'@[Annot]'; |
||||
|
||||
$cache = $this->getMock('Doctrine\Common\Cache\Cache'); |
||||
$cache |
||||
->expects($this->at(0)) |
||||
->method('fetch') |
||||
->with($this->equalTo($cacheKey)) |
||||
->will($this->returnValue(array())) |
||||
; |
||||
$cache |
||||
->expects($this->at(1)) |
||||
->method('fetch') |
||||
->with($this->equalTo('[C]'.$cacheKey)) |
||||
->will($this->returnValue(time() - 10)) |
||||
; |
||||
$cache |
||||
->expects($this->at(2)) |
||||
->method('save') |
||||
->with($this->equalTo($cacheKey)) |
||||
; |
||||
$cache |
||||
->expects($this->at(3)) |
||||
->method('save') |
||||
->with($this->equalTo('[C]'.$cacheKey)) |
||||
; |
||||
|
||||
$reader = new CachedReader(new AnnotationReader(), $cache, true); |
||||
$route = new Route(); |
||||
$route->pattern = '/someprefix'; |
||||
$this->assertEquals(array($route), $reader->getClassAnnotations(new \ReflectionClass($name))); |
||||
} |
||||
|
||||
protected function getReader() |
||||
{ |
||||
$this->cache = new ArrayCache(); |
||||
return new CachedReader(new AnnotationReader(), $this->cache); |
||||
} |
||||
} |
@ -0,0 +1,137 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\DocLexer; |
||||
|
||||
class DocLexerTest extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
public function testMarkerAnnotation() |
||||
{ |
||||
$lexer = new DocLexer; |
||||
|
||||
$lexer->setInput("@Name"); |
||||
$this->assertNull($lexer->token); |
||||
$this->assertNull($lexer->lookahead); |
||||
|
||||
$this->assertTrue($lexer->moveNext()); |
||||
$this->assertNull($lexer->token); |
||||
$this->assertEquals('@', $lexer->lookahead['value']); |
||||
|
||||
$this->assertTrue($lexer->moveNext()); |
||||
$this->assertEquals('@', $lexer->token['value']); |
||||
$this->assertEquals('Name', $lexer->lookahead['value']); |
||||
|
||||
$this->assertFalse($lexer->moveNext()); |
||||
} |
||||
|
||||
public function testScannerTokenizesDocBlockWhitConstants() |
||||
{ |
||||
$lexer = new DocLexer(); |
||||
$docblock = '@AnnotationWithConstants(PHP_EOL, ClassWithConstants::SOME_VALUE, \Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_VALUE)'; |
||||
|
||||
$tokens = array ( |
||||
array( |
||||
'value' => '@', |
||||
'position' => 0, |
||||
'type' => DocLexer::T_AT, |
||||
), |
||||
array( |
||||
'value' => 'AnnotationWithConstants', |
||||
'position' => 1, |
||||
'type' => DocLexer::T_IDENTIFIER, |
||||
), |
||||
array( |
||||
'value' => '(', |
||||
'position' => 24, |
||||
'type' => DocLexer::T_OPEN_PARENTHESIS, |
||||
), |
||||
array( |
||||
'value' => 'PHP_EOL', |
||||
'position' => 25, |
||||
'type' => DocLexer::T_IDENTIFIER, |
||||
), |
||||
array( |
||||
'value' => ',', |
||||
'position' => 32, |
||||
'type' => DocLexer::T_COMMA, |
||||
), |
||||
array( |
||||
'value' => 'ClassWithConstants::SOME_VALUE', |
||||
'position' => 34, |
||||
'type' => DocLexer::T_IDENTIFIER, |
||||
), |
||||
array( |
||||
'value' => ',', |
||||
'position' => 64, |
||||
'type' => DocLexer::T_COMMA, |
||||
), |
||||
array( |
||||
'value' => '\\Doctrine\\Tests\\Common\\Annotations\\Fixtures\\IntefaceWithConstants::SOME_VALUE', |
||||
'position' => 66, |
||||
'type' => DocLexer::T_IDENTIFIER, |
||||
), |
||||
array( |
||||
'value' => ')', |
||||
'position' => 143, |
||||
'type' => DocLexer::T_CLOSE_PARENTHESIS, |
||||
) |
||||
|
||||
); |
||||
|
||||
$lexer->setInput($docblock); |
||||
|
||||
foreach ($tokens as $expected) { |
||||
$lexer->moveNext(); |
||||
$lookahead = $lexer->lookahead; |
||||
$this->assertEquals($expected['value'], $lookahead['value']); |
||||
$this->assertEquals($expected['type'], $lookahead['type']); |
||||
$this->assertEquals($expected['position'], $lookahead['position']); |
||||
} |
||||
|
||||
$this->assertFalse($lexer->moveNext()); |
||||
} |
||||
|
||||
|
||||
public function testScannerTokenizesDocBlockWhitInvalidIdentifier() |
||||
{ |
||||
$lexer = new DocLexer(); |
||||
$docblock = '@Foo\3.42'; |
||||
|
||||
$tokens = array ( |
||||
array( |
||||
'value' => '@', |
||||
'position' => 0, |
||||
'type' => DocLexer::T_AT, |
||||
), |
||||
array( |
||||
'value' => 'Foo', |
||||
'position' => 1, |
||||
'type' => DocLexer::T_IDENTIFIER, |
||||
), |
||||
array( |
||||
'value' => '\\', |
||||
'position' => 4, |
||||
'type' => DocLexer::T_NAMESPACE_SEPARATOR, |
||||
), |
||||
array( |
||||
'value' => 3.42, |
||||
'position' => 5, |
||||
'type' => DocLexer::T_FLOAT, |
||||
) |
||||
); |
||||
|
||||
$lexer->setInput($docblock); |
||||
|
||||
foreach ($tokens as $expected) { |
||||
$lexer->moveNext(); |
||||
$lookahead = $lexer->lookahead; |
||||
$this->assertEquals($expected['value'], $lookahead['value']); |
||||
$this->assertEquals($expected['type'], $lookahead['type']); |
||||
$this->assertEquals($expected['position'], $lookahead['position']); |
||||
} |
||||
|
||||
$this->assertFalse($lexer->moveNext()); |
||||
} |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\DummyAnnotation; |
||||
use Doctrine\Tests\Common\Annotations\Name; |
||||
use Doctrine\Tests\Common\Annotations\DummyJoinTable; |
||||
use Doctrine\Tests\Common\Annotations\DummyJoinColumn; |
||||
|
||||
/** |
||||
* A description of this class. |
||||
* |
||||
* Let's see if the parser recognizes that this @ is not really referring to an |
||||
* annotation. Also make sure that @var \ is not concated to "@var\is". |
||||
* |
||||
* @author robo |
||||
* @since 2.0 |
||||
* @DummyAnnotation(dummyValue="hello") |
||||
*/ |
||||
class DummyClass |
||||
{ |
||||
/** |
||||
* A nice property. |
||||
* |
||||
* @var mixed |
||||
* @DummyAnnotation(dummyValue="fieldHello") |
||||
*/ |
||||
private $field1; |
||||
|
||||
/** |
||||
* @DummyJoinTable(name="join_table", |
||||
* joinColumns={@DummyJoinColumn(name="col1", referencedColumnName="col2")}, |
||||
* inverseJoinColumns={ |
||||
* @DummyJoinColumn(name="col3", referencedColumnName="col4") |
||||
* }) |
||||
*/ |
||||
private $field2; |
||||
|
||||
/** |
||||
* Gets the value of field1. |
||||
* |
||||
* @return mixed |
||||
* @DummyAnnotation({1,2,"three"}) |
||||
*/ |
||||
public function getField1() |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,40 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader; |
||||
use Doctrine\Common\Annotations\FileCacheReader; |
||||
|
||||
class FileCacheReaderTest extends AbstractReaderTest |
||||
{ |
||||
private $cacheDir; |
||||
|
||||
protected function getReader() |
||||
{ |
||||
$this->cacheDir = sys_get_temp_dir() . "/annotations_". uniqid(); |
||||
@mkdir($this->cacheDir); |
||||
return new FileCacheReader(new AnnotationReader(), $this->cacheDir); |
||||
} |
||||
|
||||
public function tearDown() |
||||
{ |
||||
foreach (glob($this->cacheDir.'/*.php') AS $file) { |
||||
unlink($file); |
||||
} |
||||
rmdir($this->cacheDir); |
||||
} |
||||
|
||||
/** |
||||
* @group DCOM-81 |
||||
*/ |
||||
public function testAttemptToCreateAnnotationCacheDir() |
||||
{ |
||||
$this->cacheDir = sys_get_temp_dir() . "/not_existed_dir_". uniqid(); |
||||
|
||||
$this->assertFalse(is_dir($this->cacheDir)); |
||||
|
||||
$cache = new FileCacheReader(new AnnotationReader(), $this->cacheDir); |
||||
|
||||
$this->assertTrue(is_dir($this->cacheDir)); |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation; |
||||
|
||||
/** @Annotation */ |
||||
class AnnotWithDefaultValue |
||||
{ |
||||
/** @var string */ |
||||
public $foo = 'bar'; |
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation; |
||||
|
||||
/** |
||||
* @Annotation |
||||
*/ |
||||
class Autoload |
||||
{ |
||||
} |
@ -0,0 +1,11 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation; |
||||
|
||||
/** @Annotation */ |
||||
class Route |
||||
{ |
||||
/** @var string @Required */ |
||||
public $pattern; |
||||
public $name; |
||||
} |
@ -0,0 +1,18 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation; |
||||
|
||||
/** @Annotation */ |
||||
class Secure |
||||
{ |
||||
private $roles; |
||||
|
||||
public function __construct(array $values) |
||||
{ |
||||
if (is_string($values['value'])) { |
||||
$values['value'] = array($values['value']); |
||||
} |
||||
|
||||
$this->roles = $values['value']; |
||||
} |
||||
} |
@ -0,0 +1,14 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation; |
||||
|
||||
/** @Annotation */ |
||||
class Template |
||||
{ |
||||
private $name; |
||||
|
||||
public function __construct(array $values) |
||||
{ |
||||
$this->name = isset($values['value']) ? $values['value'] : null; |
||||
} |
||||
} |
@ -0,0 +1,11 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("PROPERTY") |
||||
*/ |
||||
final class Version |
||||
{ |
||||
} |
@ -0,0 +1,21 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
final class AnnotationEnum |
||||
{ |
||||
const ONE = 'ONE'; |
||||
const TWO = 'TWO'; |
||||
const THREE = 'THREE'; |
||||
|
||||
/** |
||||
* @var mixed |
||||
* |
||||
* @Enum({"ONE","TWO","THREE"}) |
||||
*/ |
||||
public $value; |
||||
} |
@ -0,0 +1,17 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
final class AnnotationEnumInvalid |
||||
{ |
||||
/** |
||||
* @var mixed |
||||
* |
||||
* @Enum({1, 2, "foo", "bar", {"foo":"bar"}}) |
||||
*/ |
||||
public $value; |
||||
} |
@ -0,0 +1,34 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnumLiteral as SelfEnum; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
final class AnnotationEnumLiteral |
||||
{ |
||||
const ONE = 1; |
||||
const TWO = 2; |
||||
const THREE = 3; |
||||
|
||||
/** |
||||
* @var mixed |
||||
* |
||||
* @Enum( |
||||
* value = { |
||||
* 1, |
||||
* 2, |
||||
* 3, |
||||
* }, |
||||
* literal = { |
||||
* 1 : "AnnotationEnumLiteral::ONE", |
||||
* 2 : "AnnotationEnumLiteral::TWO", |
||||
* 3 : "AnnotationEnumLiteral::THREE", |
||||
* } |
||||
* ) |
||||
*/ |
||||
public $value; |
||||
} |
@ -0,0 +1,31 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
final class AnnotationEnumLiteralInvalid |
||||
{ |
||||
const ONE = 1; |
||||
const TWO = 2; |
||||
const THREE = 3; |
||||
|
||||
/** |
||||
* @var mixed |
||||
* |
||||
* @Enum( |
||||
* value = { |
||||
* 1, |
||||
* 2 |
||||
* }, |
||||
* literal = { |
||||
* 1 : "AnnotationEnumLiteral::ONE", |
||||
* 2 : "AnnotationEnumLiteral::TWO", |
||||
* 3 : "AnnotationEnumLiteral::THREE" |
||||
* } |
||||
* ) |
||||
*/ |
||||
public $value; |
||||
} |
@ -0,0 +1,14 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
class AnnotationTargetAll |
||||
{ |
||||
public $data; |
||||
public $name; |
||||
public $target; |
||||
} |
@ -0,0 +1,14 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target({ "ANNOTATION" }) |
||||
*/ |
||||
final class AnnotationTargetAnnotation |
||||
{ |
||||
public $data; |
||||
public $name; |
||||
public $target; |
||||
} |
@ -0,0 +1,15 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("CLASS") |
||||
*/ |
||||
final class AnnotationTargetClass |
||||
{ |
||||
public $data; |
||||
public $name; |
||||
public $target; |
||||
} |
@ -0,0 +1,15 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("METHOD") |
||||
*/ |
||||
final class AnnotationTargetMethod |
||||
{ |
||||
public $data; |
||||
public $name; |
||||
public $target; |
||||
} |
@ -0,0 +1,14 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target({ "METHOD", "PROPERTY" }) |
||||
*/ |
||||
final class AnnotationTargetPropertyMethod |
||||
{ |
||||
public $data; |
||||
public $name; |
||||
public $target; |
||||
} |
@ -0,0 +1,119 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
* @Attributes({ |
||||
@Attribute("mixed", type = "mixed"), |
||||
@Attribute("boolean", type = "boolean"), |
||||
@Attribute("bool", type = "bool"), |
||||
@Attribute("float", type = "float"), |
||||
@Attribute("string", type = "string"), |
||||
@Attribute("integer", type = "integer"), |
||||
@Attribute("array", type = "array"), |
||||
@Attribute("arrayOfIntegers", type = "array<integer>"), |
||||
@Attribute("annotation", type = "Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll"), |
||||
@Attribute("arrayOfAnnotations", type = "array<Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll>"), |
||||
}) |
||||
*/ |
||||
final class AnnotationWithAttributes |
||||
{ |
||||
|
||||
public final function __construct(array $data) |
||||
{ |
||||
foreach ($data as $key => $value) { |
||||
$this->$key = $value; |
||||
} |
||||
} |
||||
|
||||
private $mixed; |
||||
private $boolean; |
||||
private $bool; |
||||
private $float; |
||||
private $string; |
||||
private $integer; |
||||
private $array; |
||||
private $annotation; |
||||
private $arrayOfIntegers; |
||||
private $arrayOfAnnotations; |
||||
|
||||
/** |
||||
* @return mixed |
||||
*/ |
||||
public function getMixed() |
||||
{ |
||||
return $this->mixed; |
||||
} |
||||
|
||||
/** |
||||
* @return boolean |
||||
*/ |
||||
public function getBoolean() |
||||
{ |
||||
return $this->boolean; |
||||
} |
||||
|
||||
/** |
||||
* @return bool |
||||
*/ |
||||
public function getBool() |
||||
{ |
||||
return $this->bool; |
||||
} |
||||
|
||||
/** |
||||
* @return float |
||||
*/ |
||||
public function getFloat() |
||||
{ |
||||
return $this->float; |
||||
} |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function getString() |
||||
{ |
||||
return $this->string; |
||||
} |
||||
|
||||
public function getInteger() |
||||
{ |
||||
return $this->integer; |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
public function getArray() |
||||
{ |
||||
return $this->array; |
||||
} |
||||
|
||||
/** |
||||
* @return Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll |
||||
*/ |
||||
public function getAnnotation() |
||||
{ |
||||
return $this->annotation; |
||||
} |
||||
|
||||
/** |
||||
* @return array<integer> |
||||
*/ |
||||
public function getArrayOfIntegers() |
||||
{ |
||||
return $this->arrayOfIntegers; |
||||
} |
||||
|
||||
/** |
||||
* @return array<Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll> |
||||
*/ |
||||
public function getArrayOfAnnotations() |
||||
{ |
||||
return $this->arrayOfAnnotations; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,20 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
final class AnnotationWithConstants |
||||
{ |
||||
|
||||
const INTEGER = 1; |
||||
const FLOAT = 1.2; |
||||
const STRING = '1.2.3'; |
||||
|
||||
/** |
||||
* @var mixed |
||||
*/ |
||||
public $value; |
||||
} |
@ -0,0 +1,50 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
* @Attributes({ |
||||
@Attribute("value", required = true , type = "string"), |
||||
@Attribute("annot", required = true , type = "Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation"), |
||||
}) |
||||
*/ |
||||
final class AnnotationWithRequiredAttributes |
||||
{ |
||||
|
||||
public final function __construct(array $data) |
||||
{ |
||||
foreach ($data as $key => $value) { |
||||
$this->$key = $value; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @var string |
||||
*/ |
||||
private $value; |
||||
|
||||
/** |
||||
* |
||||
* @var Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation |
||||
*/ |
||||
private $annot; |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function getValue() |
||||
{ |
||||
return $this->value; |
||||
} |
||||
|
||||
/** |
||||
* @return Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation |
||||
*/ |
||||
public function getAnnot() |
||||
{ |
||||
return $this->annot; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,24 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
final class AnnotationWithRequiredAttributesWithoutContructor |
||||
{ |
||||
|
||||
/** |
||||
* @Required |
||||
* @var string |
||||
*/ |
||||
public $value; |
||||
|
||||
/** |
||||
* @Required |
||||
* @var Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation |
||||
*/ |
||||
public $annot; |
||||
|
||||
} |
@ -0,0 +1,11 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target(@) |
||||
*/ |
||||
final class AnnotationWithTargetSyntaxError |
||||
{ |
||||
} |
@ -0,0 +1,62 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @Annotation |
||||
* @Target("ALL") |
||||
*/ |
||||
final class AnnotationWithVarType |
||||
{ |
||||
|
||||
/** |
||||
* @var mixed |
||||
*/ |
||||
public $mixed; |
||||
|
||||
/** |
||||
* @var boolean |
||||
*/ |
||||
public $boolean; |
||||
|
||||
/** |
||||
* @var bool |
||||
*/ |
||||
public $bool; |
||||
|
||||
/** |
||||
* @var float |
||||
*/ |
||||
public $float; |
||||
|
||||
/** |
||||
* @var string |
||||
*/ |
||||
public $string; |
||||
|
||||
/** |
||||
* @var integer |
||||
*/ |
||||
public $integer; |
||||
|
||||
/** |
||||
* @var array |
||||
*/ |
||||
public $array; |
||||
|
||||
/** |
||||
* @var Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll |
||||
*/ |
||||
public $annotation; |
||||
|
||||
/** |
||||
* @var array<integer> |
||||
*/ |
||||
public $arrayOfIntegers; |
||||
|
||||
/** |
||||
* @var array<Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll> |
||||
*/ |
||||
public $arrayOfAnnotations; |
||||
|
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* This class is not an annotation |
||||
* It's a class build to test ClassWithInclude |
||||
*/ |
||||
class Api |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,30 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @since 2.0 |
||||
* @version $Id: SomeEntityClass.php 509 2012-02-03 09:38:48Z mf $ |
||||
*/ |
||||
class ClassDDC1660 |
||||
{ |
||||
|
||||
/** |
||||
* @var string |
||||
* @since 2.0 |
||||
* @version 1 |
||||
*/ |
||||
public $foo; |
||||
|
||||
/** |
||||
* @param string |
||||
* @return string |
||||
* @since 2.0 |
||||
* @version 1 |
||||
*/ |
||||
public function bar($param) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,29 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum; |
||||
|
||||
class ClassWithAnnotationEnum |
||||
{ |
||||
/** |
||||
* @AnnotationEnum(AnnotationEnum::ONE) |
||||
*/ |
||||
public $foo; |
||||
|
||||
/** |
||||
* @AnnotationEnum("TWO") |
||||
*/ |
||||
public function bar(){} |
||||
|
||||
|
||||
/** |
||||
* @AnnotationEnum("FOUR") |
||||
*/ |
||||
public $invalidProperty; |
||||
|
||||
/** |
||||
* @AnnotationEnum(5) |
||||
*/ |
||||
public function invalidMethod(){} |
||||
} |
@ -0,0 +1,21 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError; |
||||
|
||||
/** |
||||
* @AnnotationWithTargetSyntaxError() |
||||
*/ |
||||
class ClassWithAnnotationWithTargetSyntaxError |
||||
{ |
||||
/** |
||||
* @AnnotationWithTargetSyntaxError() |
||||
*/ |
||||
public $foo; |
||||
|
||||
/** |
||||
* @AnnotationWithTargetSyntaxError() |
||||
*/ |
||||
public function bar(){} |
||||
} |
@ -0,0 +1,31 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation; |
||||
|
||||
class ClassWithAnnotationWithVarType |
||||
{ |
||||
/** |
||||
* @AnnotationWithVarType(string = "String Value") |
||||
*/ |
||||
public $foo; |
||||
|
||||
/** |
||||
* @AnnotationWithVarType(annotation = @AnnotationTargetAll) |
||||
*/ |
||||
public function bar(){} |
||||
|
||||
|
||||
/** |
||||
* @AnnotationWithVarType(string = 123) |
||||
*/ |
||||
public $invalidProperty; |
||||
|
||||
/** |
||||
* @AnnotationWithVarType(annotation = @AnnotationTargetAnnotation) |
||||
*/ |
||||
public function invalidMethod(){} |
||||
} |
@ -0,0 +1,52 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation; |
||||
|
||||
/** |
||||
* @AnnotationTargetAll("Foo") |
||||
*/ |
||||
final class ClassWithClosure |
||||
{ |
||||
|
||||
/** |
||||
* @AnnotationTargetAll(@AnnotationTargetAnnotation) |
||||
* @var string |
||||
*/ |
||||
public $value; |
||||
|
||||
/** |
||||
* @AnnotationTargetAll(@AnnotationTargetAnnotation) |
||||
* |
||||
* @param \Closure $callback |
||||
* @return \Closure |
||||
*/ |
||||
public function methodName(\Closure $callback) |
||||
{ |
||||
$self = $this; |
||||
return function() use ($self, $callback) { |
||||
return $callback; |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* @param integer $year |
||||
* @param integer $month |
||||
* @param integer $day |
||||
* @return \Doctrine\Common\Collections\ArrayCollection |
||||
*/ |
||||
public function getEventsForDate($year, $month, $day){ |
||||
$extractEvents = null; // check if date of item is inside day given |
||||
$extractEvents = $this->events->filter(function ($item) use ($year, $month, $day) { |
||||
$leftDate = new \DateTime($year.'-'.$month.'-'.$day.' 00:00'); |
||||
$rigthDate = new \DateTime($year.'-'.$month.'-'.$day.' +1 day 00:00'); |
||||
return ( ( $leftDate <= $item->getDateStart() ) && ( $item->getDateStart() < $rigthDate ) ); |
||||
|
||||
} |
||||
); |
||||
return $extractEvents; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
class ClassWithConstants |
||||
{ |
||||
|
||||
const SOME_VALUE = 'ClassWithConstants.SOME_VALUE'; |
||||
const SOME_KEY = 'ClassWithConstants.SOME_KEY'; |
||||
} |
@ -0,0 +1,11 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use |
||||
\Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure, |
||||
\Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route |
||||
; |
||||
use \Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
|
||||
class ClassWithFullyQualifiedUseStatements {} |
@ -0,0 +1,17 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetPropertyMethod; |
||||
|
||||
/** |
||||
* @AnnotationTargetPropertyMethod("Some data") |
||||
*/ |
||||
class ClassWithInvalidAnnotationTargetAtClass |
||||
{ |
||||
|
||||
/** |
||||
* @AnnotationTargetPropertyMethod("Bar") |
||||
*/ |
||||
public $foo; |
||||
} |
@ -0,0 +1,20 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass; |
||||
|
||||
/** |
||||
* @AnnotationTargetClass("Some data") |
||||
*/ |
||||
class ClassWithInvalidAnnotationTargetAtMethod |
||||
{ |
||||
|
||||
/** |
||||
* @AnnotationTargetClass("functionName") |
||||
*/ |
||||
public function functionName($param) |
||||
{ |
||||
|
||||
} |
||||
} |
@ -0,0 +1,24 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation; |
||||
|
||||
/** |
||||
* @AnnotationTargetClass("Some data") |
||||
*/ |
||||
class ClassWithInvalidAnnotationTargetAtProperty |
||||
{ |
||||
|
||||
/** |
||||
* @AnnotationTargetClass("Bar") |
||||
*/ |
||||
public $foo; |
||||
|
||||
|
||||
/** |
||||
* @AnnotationTargetAnnotation("Foo") |
||||
*/ |
||||
public $bar; |
||||
} |
@ -0,0 +1,15 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
// Include a class named Api |
||||
require_once(__DIR__ . '/Api.php'); |
||||
|
||||
use Doctrine\Tests\Common\Annotations\DummyAnnotationWithIgnoredAnnotation; |
||||
|
||||
/** |
||||
* @DummyAnnotationWithIgnoredAnnotation(dummyValue="hello") |
||||
*/ |
||||
class ClassWithRequire |
||||
{ |
||||
} |
@ -0,0 +1,41 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetPropertyMethod; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetNestedAnnotation; |
||||
|
||||
/** |
||||
* @AnnotationTargetClass("Some data") |
||||
*/ |
||||
class ClassWithValidAnnotationTarget |
||||
{ |
||||
|
||||
/** |
||||
* @AnnotationTargetPropertyMethod("Some data") |
||||
*/ |
||||
public $foo; |
||||
|
||||
|
||||
/** |
||||
* @AnnotationTargetAll("Some data",name="Some name") |
||||
*/ |
||||
public $name; |
||||
|
||||
/** |
||||
* @AnnotationTargetPropertyMethod("Some data",name="Some name") |
||||
*/ |
||||
public function someFunction() |
||||
{ |
||||
|
||||
} |
||||
|
||||
|
||||
/** |
||||
* @AnnotationTargetAll(@AnnotationTargetAnnotation) |
||||
*/ |
||||
public $nested; |
||||
|
||||
} |
@ -0,0 +1,300 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
|
||||
/** |
||||
* @Route("/someprefix") |
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com> |
||||
*/ |
||||
class Controller |
||||
{ |
||||
/** |
||||
* @Route("/", name="_demo") |
||||
* @Template() |
||||
*/ |
||||
public function indexAction() |
||||
{ |
||||
return array(); |
||||
} |
||||
|
||||
/** |
||||
* @Route("/hello/{name}", name="_demo_hello") |
||||
* @Template() |
||||
*/ |
||||
public function helloAction($name) |
||||
{ |
||||
return array('name' => $name); |
||||
} |
||||
|
||||
/** |
||||
* @Route("/contact", name="_demo_contact") |
||||
* @Template() |
||||
*/ |
||||
public function contactAction() |
||||
{ |
||||
$form = ContactForm::create($this->get('form.context'), 'contact'); |
||||
|
||||
$form->bind($this->container->get('request'), $form); |
||||
if ($form->isValid()) { |
||||
$form->send($this->get('mailer')); |
||||
|
||||
$this->get('session')->setFlash('notice', 'Message sent!'); |
||||
|
||||
return new RedirectResponse($this->generateUrl('_demo')); |
||||
} |
||||
|
||||
return array('form' => $form); |
||||
} |
||||
|
||||
/** |
||||
* Creates the ACL for the passed object identity |
||||
* |
||||
* @param ObjectIdentityInterface $oid |
||||
* @return void |
||||
*/ |
||||
private function createObjectIdentity(ObjectIdentityInterface $oid) |
||||
{ |
||||
$classId = $this->createOrRetrieveClassId($oid->getType()); |
||||
|
||||
$this->connection->executeQuery($this->getInsertObjectIdentitySql($oid->getIdentifier(), $classId, true)); |
||||
} |
||||
|
||||
/** |
||||
* Returns the primary key for the passed class type. |
||||
* |
||||
* If the type does not yet exist in the database, it will be created. |
||||
* |
||||
* @param string $classType |
||||
* @return integer |
||||
*/ |
||||
private function createOrRetrieveClassId($classType) |
||||
{ |
||||
if (false !== $id = $this->connection->executeQuery($this->getSelectClassIdSql($classType))->fetchColumn()) { |
||||
return $id; |
||||
} |
||||
|
||||
$this->connection->executeQuery($this->getInsertClassSql($classType)); |
||||
|
||||
return $this->connection->executeQuery($this->getSelectClassIdSql($classType))->fetchColumn(); |
||||
} |
||||
|
||||
/** |
||||
* Returns the primary key for the passed security identity. |
||||
* |
||||
* If the security identity does not yet exist in the database, it will be |
||||
* created. |
||||
* |
||||
* @param SecurityIdentityInterface $sid |
||||
* @return integer |
||||
*/ |
||||
private function createOrRetrieveSecurityIdentityId(SecurityIdentityInterface $sid) |
||||
{ |
||||
if (false !== $id = $this->connection->executeQuery($this->getSelectSecurityIdentityIdSql($sid))->fetchColumn()) { |
||||
return $id; |
||||
} |
||||
|
||||
$this->connection->executeQuery($this->getInsertSecurityIdentitySql($sid)); |
||||
|
||||
return $this->connection->executeQuery($this->getSelectSecurityIdentityIdSql($sid))->fetchColumn(); |
||||
} |
||||
|
||||
/** |
||||
* Deletes all ACEs for the given object identity primary key. |
||||
* |
||||
* @param integer $oidPK |
||||
* @return void |
||||
*/ |
||||
private function deleteAccessControlEntries($oidPK) |
||||
{ |
||||
$this->connection->executeQuery($this->getDeleteAccessControlEntriesSql($oidPK)); |
||||
} |
||||
|
||||
/** |
||||
* Deletes the object identity from the database. |
||||
* |
||||
* @param integer $pk |
||||
* @return void |
||||
*/ |
||||
private function deleteObjectIdentity($pk) |
||||
{ |
||||
$this->connection->executeQuery($this->getDeleteObjectIdentitySql($pk)); |
||||
} |
||||
|
||||
/** |
||||
* Deletes all entries from the relations table from the database. |
||||
* |
||||
* @param integer $pk |
||||
* @return void |
||||
*/ |
||||
private function deleteObjectIdentityRelations($pk) |
||||
{ |
||||
$this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk)); |
||||
} |
||||
|
||||
/** |
||||
* This regenerates the ancestor table which is used for fast read access. |
||||
* |
||||
* @param AclInterface $acl |
||||
* @return void |
||||
*/ |
||||
private function regenerateAncestorRelations(AclInterface $acl) |
||||
{ |
||||
$pk = $acl->getId(); |
||||
$this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk)); |
||||
$this->connection->executeQuery($this->getInsertObjectIdentityRelationSql($pk, $pk)); |
||||
|
||||
$parentAcl = $acl->getParentAcl(); |
||||
while (null !== $parentAcl) { |
||||
$this->connection->executeQuery($this->getInsertObjectIdentityRelationSql($pk, $parentAcl->getId())); |
||||
|
||||
$parentAcl = $parentAcl->getParentAcl(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* This processes changes on an ACE related property (classFieldAces, or objectFieldAces). |
||||
* |
||||
* @param string $name |
||||
* @param array $changes |
||||
* @return void |
||||
*/ |
||||
private function updateFieldAceProperty($name, array $changes) |
||||
{ |
||||
$sids = new \SplObjectStorage(); |
||||
$classIds = new \SplObjectStorage(); |
||||
$currentIds = array(); |
||||
foreach ($changes[1] as $field => $new) { |
||||
for ($i=0,$c=count($new); $i<$c; $i++) { |
||||
$ace = $new[$i]; |
||||
|
||||
if (null === $ace->getId()) { |
||||
if ($sids->contains($ace->getSecurityIdentity())) { |
||||
$sid = $sids->offsetGet($ace->getSecurityIdentity()); |
||||
} else { |
||||
$sid = $this->createOrRetrieveSecurityIdentityId($ace->getSecurityIdentity()); |
||||
} |
||||
|
||||
$oid = $ace->getAcl()->getObjectIdentity(); |
||||
if ($classIds->contains($oid)) { |
||||
$classId = $classIds->offsetGet($oid); |
||||
} else { |
||||
$classId = $this->createOrRetrieveClassId($oid->getType()); |
||||
} |
||||
|
||||
$objectIdentityId = $name === 'classFieldAces' ? null : $ace->getAcl()->getId(); |
||||
|
||||
$this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, $field, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure())); |
||||
$aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, $field, $i))->fetchColumn(); |
||||
$this->loadedAces[$aceId] = $ace; |
||||
|
||||
$aceIdProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Entry', 'id'); |
||||
$aceIdProperty->setAccessible(true); |
||||
$aceIdProperty->setValue($ace, intval($aceId)); |
||||
} else { |
||||
$currentIds[$ace->getId()] = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
foreach ($changes[0] as $old) { |
||||
for ($i=0,$c=count($old); $i<$c; $i++) { |
||||
$ace = $old[$i]; |
||||
|
||||
if (!isset($currentIds[$ace->getId()])) { |
||||
$this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId())); |
||||
unset($this->loadedAces[$ace->getId()]); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* This processes changes on an ACE related property (classAces, or objectAces). |
||||
* |
||||
* @param string $name |
||||
* @param array $changes |
||||
* @return void |
||||
*/ |
||||
private function updateAceProperty($name, array $changes) |
||||
{ |
||||
list($old, $new) = $changes; |
||||
|
||||
$sids = new \SplObjectStorage(); |
||||
$classIds = new \SplObjectStorage(); |
||||
$currentIds = array(); |
||||
for ($i=0,$c=count($new); $i<$c; $i++) { |
||||
$ace = $new[$i]; |
||||
|
||||
if (null === $ace->getId()) { |
||||
if ($sids->contains($ace->getSecurityIdentity())) { |
||||
$sid = $sids->offsetGet($ace->getSecurityIdentity()); |
||||
} else { |
||||
$sid = $this->createOrRetrieveSecurityIdentityId($ace->getSecurityIdentity()); |
||||
} |
||||
|
||||
$oid = $ace->getAcl()->getObjectIdentity(); |
||||
if ($classIds->contains($oid)) { |
||||
$classId = $classIds->offsetGet($oid); |
||||
} else { |
||||
$classId = $this->createOrRetrieveClassId($oid->getType()); |
||||
} |
||||
|
||||
$objectIdentityId = $name === 'classAces' ? null : $ace->getAcl()->getId(); |
||||
|
||||
$this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, null, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure())); |
||||
$aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, null, $i))->fetchColumn(); |
||||
$this->loadedAces[$aceId] = $ace; |
||||
|
||||
$aceIdProperty = new \ReflectionProperty($ace, 'id'); |
||||
$aceIdProperty->setAccessible(true); |
||||
$aceIdProperty->setValue($ace, intval($aceId)); |
||||
} else { |
||||
$currentIds[$ace->getId()] = true; |
||||
} |
||||
} |
||||
|
||||
for ($i=0,$c=count($old); $i<$c; $i++) { |
||||
$ace = $old[$i]; |
||||
|
||||
if (!isset($currentIds[$ace->getId()])) { |
||||
$this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId())); |
||||
unset($this->loadedAces[$ace->getId()]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Persists the changes which were made to ACEs to the database. |
||||
* |
||||
* @param \SplObjectStorage $aces |
||||
* @return void |
||||
*/ |
||||
private function updateAces(\SplObjectStorage $aces) |
||||
{ |
||||
foreach ($aces as $ace) { |
||||
$propertyChanges = $aces->offsetGet($ace); |
||||
$sets = array(); |
||||
|
||||
if (isset($propertyChanges['mask'])) { |
||||
$sets[] = sprintf('mask = %d', $propertyChanges['mask'][1]); |
||||
} |
||||
if (isset($propertyChanges['strategy'])) { |
||||
$sets[] = sprintf('granting_strategy = %s', $this->connection->quote($propertyChanges['strategy'])); |
||||
} |
||||
if (isset($propertyChanges['aceOrder'])) { |
||||
$sets[] = sprintf('ace_order = %d', $propertyChanges['aceOrder'][1]); |
||||
} |
||||
if (isset($propertyChanges['auditSuccess'])) { |
||||
$sets[] = sprintf('audit_success = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditSuccess'][1])); |
||||
} |
||||
if (isset($propertyChanges['auditFailure'])) { |
||||
$sets[] = sprintf('audit_failure = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditFailure'][1])); |
||||
} |
||||
|
||||
$this->connection->executeQuery($this->getUpdateAccessControlEntrySql($ace->getId(), $sets)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
|
||||
class DifferentNamespacesPerFileWithClassAsFirst {} |
||||
} |
||||
|
||||
namespace { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
} |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Foo { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
} |
@ -0,0 +1,15 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Foo { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
} |
||||
|
||||
namespace { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
} |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
|
||||
class DifferentNamespacesPerFileWithClassAsLast {} |
||||
} |
@ -0,0 +1,13 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
|
||||
class EqualNamespacesPerFileWithClassAsFirst {} |
||||
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
@ -0,0 +1,12 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
|
||||
class EqualNamespacesPerFileWithClassAsLast {} |
@ -0,0 +1,12 @@ |
||||
<?php |
||||
|
||||
namespace { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
|
||||
class GlobalNamespacesPerFileWithClassAsFirst {} |
||||
} |
||||
|
||||
namespace { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
} |
@ -0,0 +1,12 @@ |
||||
<?php |
||||
|
||||
namespace { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
} |
||||
|
||||
namespace { |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
|
||||
class GlobalNamespacesPerFileWithClassAsLast {} |
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
interface IntefaceWithConstants |
||||
{ |
||||
|
||||
const SOME_VALUE = 'IntefaceWithConstants.SOME_VALUE'; |
||||
const SOME_KEY = 'IntefaceWithConstants.SOME_KEY'; |
||||
} |
@ -0,0 +1,14 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
|
||||
/** |
||||
* @NoAnnotation |
||||
* @IgnoreAnnotation("NoAnnotation") |
||||
* @Route("foo") |
||||
*/ |
||||
class InvalidAnnotationUsageButIgnoredClass |
||||
{ |
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
/** |
||||
* @NoAnnotation |
||||
*/ |
||||
class InvalidAnnotationUsageClass |
||||
{ |
||||
} |
@ -0,0 +1,9 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
|
||||
class AnotherClass { } |
||||
class MultipleClassesInFile { } |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use |
||||
Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route, |
||||
Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure |
||||
; |
||||
|
||||
class MultipleImportsInUseStatement {} |
@ -0,0 +1,20 @@ |
||||
<?php |
||||
|
||||
// namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Foo { |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
|
||||
// class NamespaceAndClassCommentedOut {} |
||||
} |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures { |
||||
|
||||
// class NamespaceAndClassCommentedOut {} |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
|
||||
// namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
|
||||
class NamespaceAndClassCommentedOut {} |
||||
} |
@ -0,0 +1,12 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
|
||||
$var = 1; |
||||
function () use ($var) {}; |
||||
|
||||
class NamespaceWithClosureDeclaration {} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,5 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
class NoAnnotation {} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template; |
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; |
||||
|
||||
/** |
||||
* @Route("foo") |
||||
* @Template |
||||
*/ |
||||
class AnnotationsTestsFixturesNonNamespacedClass { } |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Secure; |
||||
|
||||
interface TestInterface |
||||
{ |
||||
/** |
||||
* @Secure |
||||
*/ |
||||
function foo(); |
||||
} |
@ -0,0 +1,194 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\FileCacheReader; |
||||
use Doctrine\Common\Cache\ArrayCache; |
||||
use Doctrine\Common\Annotations\CachedReader; |
||||
use Doctrine\Common\Annotations\DocLexer; |
||||
use Doctrine\Common\Annotations\DocParser; |
||||
use Doctrine\Common\Annotations\PhpParser; |
||||
use Doctrine\Common\Annotations\AnnotationReader; |
||||
|
||||
require_once __DIR__ . '/Fixtures/Annotation/Route.php'; |
||||
require_once __DIR__ . '/Fixtures/Annotation/Template.php'; |
||||
require_once __DIR__ . '/Fixtures/Annotation/Secure.php'; |
||||
require_once __DIR__ . '/Fixtures/SingleClassLOC1000.php'; |
||||
|
||||
class PerformanceTest extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
/** |
||||
* @group performance |
||||
*/ |
||||
public function testCachedReadPerformanceWithInMemory() |
||||
{ |
||||
$reader = new CachedReader(new AnnotationReader(), new ArrayCache()); |
||||
$method = $this->getMethod(); |
||||
|
||||
$time = microtime(true); |
||||
for ($i=0,$c=500; $i<$c; $i++) { |
||||
$reader->getMethodAnnotations($method); |
||||
} |
||||
$time = microtime(true) - $time; |
||||
|
||||
$this->printResults('cached reader (in-memory)', $time, $c); |
||||
} |
||||
|
||||
/** |
||||
* @group performance |
||||
*/ |
||||
public function testCachedReadPerformanceWithFileCache() |
||||
{ |
||||
$method = $this->getMethod(); |
||||
|
||||
// prime cache |
||||
$reader = new FileCacheReader(new AnnotationReader(), sys_get_temp_dir()); |
||||
$reader->getMethodAnnotations($method); |
||||
|
||||
$time = microtime(true); |
||||
for ($i=0,$c=500; $i<$c; $i++) { |
||||
$reader = new FileCacheReader(new AnnotationReader(), sys_get_temp_dir()); |
||||
$reader->getMethodAnnotations($method); |
||||
clearstatcache(); |
||||
} |
||||
$time = microtime(true) - $time; |
||||
|
||||
$this->printResults('cached reader (file)', $time, $c); |
||||
} |
||||
|
||||
/** |
||||
* @group performance |
||||
*/ |
||||
public function testReadPerformance() |
||||
{ |
||||
$method = $this->getMethod(); |
||||
|
||||
$time = microtime(true); |
||||
for ($i=0,$c=150; $i<$c; $i++) { |
||||
$reader = new AnnotationReader(); |
||||
$reader->getMethodAnnotations($method); |
||||
} |
||||
$time = microtime(true) - $time; |
||||
|
||||
$this->printResults('reader', $time, $c); |
||||
} |
||||
|
||||
/** |
||||
* @group performance |
||||
*/ |
||||
public function testDocParsePerformance() |
||||
{ |
||||
$imports = array( |
||||
'ignorephpdoc' => 'Annotations\Annotation\IgnorePhpDoc', |
||||
'ignoreannotation' => 'Annotations\Annotation\IgnoreAnnotation', |
||||
'route' => 'Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route', |
||||
'template' => 'Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template', |
||||
'__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations\Fixtures', |
||||
); |
||||
$ignored = array( |
||||
'access', 'author', 'copyright', 'deprecated', 'example', 'ignore', |
||||
'internal', 'link', 'see', 'since', 'tutorial', 'version', 'package', |
||||
'subpackage', 'name', 'global', 'param', 'return', 'staticvar', |
||||
'static', 'var', 'throws', 'inheritdoc', |
||||
); |
||||
|
||||
$method = $this->getMethod(); |
||||
$methodComment = $method->getDocComment(); |
||||
$classComment = $method->getDeclaringClass()->getDocComment(); |
||||
|
||||
$time = microtime(true); |
||||
for ($i=0,$c=200; $i<$c; $i++) { |
||||
$parser = new DocParser(); |
||||
$parser->setImports($imports); |
||||
$parser->setIgnoredAnnotationNames($ignored); |
||||
$parser->setIgnoreNotImportedAnnotations(true); |
||||
|
||||
$parser->parse($methodComment); |
||||
$parser->parse($classComment); |
||||
} |
||||
$time = microtime(true) - $time; |
||||
|
||||
$this->printResults('doc-parser', $time, $c); |
||||
} |
||||
|
||||
/** |
||||
* @group performance |
||||
*/ |
||||
public function testDocLexerPerformance() |
||||
{ |
||||
$method = $this->getMethod(); |
||||
$methodComment = $method->getDocComment(); |
||||
$classComment = $method->getDeclaringClass()->getDocComment(); |
||||
|
||||
$time = microtime(true); |
||||
for ($i=0,$c=500; $i<$c; $i++) { |
||||
$lexer = new DocLexer(); |
||||
$lexer->setInput($methodComment); |
||||
$lexer->setInput($classComment); |
||||
} |
||||
$time = microtime(true) - $time; |
||||
|
||||
$this->printResults('doc-lexer', $time, $c); |
||||
} |
||||
|
||||
/** |
||||
* @group performance |
||||
*/ |
||||
public function testPhpParserPerformanceWithShortCut() |
||||
{ |
||||
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\NamespacedSingleClassLOC1000'); |
||||
|
||||
$time = microtime(true); |
||||
for ($i=0,$c=500; $i<$c; $i++) { |
||||
$parser = new PhpParser(); |
||||
$parser->parseClass($class); |
||||
} |
||||
$time = microtime(true) - $time; |
||||
|
||||
$this->printResults('doc-parser-with-short-cut', $time, $c); |
||||
} |
||||
|
||||
/** |
||||
* @group performance |
||||
*/ |
||||
public function testPhpParserPerformanceWithoutShortCut() |
||||
{ |
||||
$class = new \ReflectionClass('SingleClassLOC1000'); |
||||
|
||||
$time = microtime(true); |
||||
for ($i=0,$c=500; $i<$c; $i++) { |
||||
$parser = new PhpParser(); |
||||
$parser->parseClass($class); |
||||
} |
||||
$time = microtime(true) - $time; |
||||
|
||||
$this->printResults('doc-parser-without-short-cut', $time, $c); |
||||
} |
||||
|
||||
private function getMethod() |
||||
{ |
||||
return new \ReflectionMethod('Doctrine\Tests\Common\Annotations\Fixtures\Controller', 'helloAction'); |
||||
} |
||||
|
||||
private function printResults($test, $time, $iterations) |
||||
{ |
||||
if (0 == $iterations) { |
||||
throw new \InvalidArgumentException('$iterations cannot be zero.'); |
||||
} |
||||
|
||||
$title = $test." results:\n"; |
||||
$iterationsText = sprintf("Iterations: %d\n", $iterations); |
||||
$totalTime = sprintf("Total Time: %.3f s\n", $time); |
||||
$iterationTime = sprintf("Time per iteration: %.3f ms\n", $time/$iterations * 1000); |
||||
|
||||
$max = max(strlen($title), strlen($iterationTime)) - 1; |
||||
|
||||
echo "\n".str_repeat('-', $max)."\n"; |
||||
echo $title; |
||||
echo str_repeat('=', $max)."\n"; |
||||
echo $iterationsText; |
||||
echo $totalTime; |
||||
echo $iterationTime; |
||||
echo str_repeat('-', $max)."\n"; |
||||
} |
||||
} |
@ -0,0 +1,207 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use ReflectionClass; |
||||
use Doctrine\Common\Annotations\PhpParser; |
||||
|
||||
require_once __DIR__.'/Fixtures/NonNamespacedClass.php'; |
||||
require_once __DIR__.'/Fixtures/GlobalNamespacesPerFileWithClassAsFirst.php'; |
||||
require_once __DIR__.'/Fixtures/GlobalNamespacesPerFileWithClassAsLast.php'; |
||||
|
||||
class PhpParserTest extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
public function testParseClassWithMultipleClassesInFile() |
||||
{ |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\MultipleClassesInFile'); |
||||
$parser = new PhpParser(); |
||||
|
||||
$this->assertEquals(array( |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testParseClassWithMultipleImportsInUseStatement() |
||||
{ |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\MultipleImportsInUseStatement'); |
||||
$parser = new PhpParser(); |
||||
|
||||
$this->assertEquals(array( |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testParseClassWhenNotUserDefined() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$this->assertEquals(array(), $parser->parseClass(new \ReflectionClass('\stdClass'))); |
||||
} |
||||
|
||||
public function testClassFileDoesNotExist() |
||||
{ |
||||
$class = $this->getMockBuilder('\ReflectionClass') |
||||
->disableOriginalConstructor() |
||||
->getMock(); |
||||
$class->expects($this->once()) |
||||
->method('getFilename') |
||||
->will($this->returnValue('/valid/class/Fake.php(35) : eval()d code')); |
||||
|
||||
$parser = new PhpParser(); |
||||
$this->assertEquals(array(), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testParseClassWhenClassIsNotNamespaced() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass('\AnnotationsTestsFixturesNonNamespacedClass'); |
||||
|
||||
$this->assertEquals(array( |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testParseClassWhenClassIsInterface() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\TestInterface'); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testClassWithFullyQualifiedUseStatements() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\ClassWithFullyQualifiedUseStatements'); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => '\\' . __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
'route' => '\\' . __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => '\\' . __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testNamespaceAndClassCommentedOut() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\NamespaceAndClassCommentedOut'); |
||||
|
||||
$this->assertEquals(array( |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testEqualNamespacesPerFileWithClassAsFirst() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\EqualNamespacesPerFileWithClassAsFirst'); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testEqualNamespacesPerFileWithClassAsLast() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\EqualNamespacesPerFileWithClassAsLast'); |
||||
|
||||
$this->assertEquals(array( |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testDifferentNamespacesPerFileWithClassAsFirst() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\DifferentNamespacesPerFileWithClassAsFirst'); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testDifferentNamespacesPerFileWithClassAsLast() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\DifferentNamespacesPerFileWithClassAsLast'); |
||||
|
||||
$this->assertEquals(array( |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testGlobalNamespacesPerFileWithClassAsFirst() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new \ReflectionClass('\GlobalNamespacesPerFileWithClassAsFirst'); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testGlobalNamespacesPerFileWithClassAsLast() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass('\GlobalNamespacesPerFileWithClassAsLast'); |
||||
|
||||
$this->assertEquals(array( |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testNamespaceWithClosureDeclaration() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\NamespaceWithClosureDeclaration'); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
public function testIfPointerResetsOnMultipleParsingTries() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\NamespaceWithClosureDeclaration'); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
|
||||
$this->assertEquals(array( |
||||
'secure' => __NAMESPACE__ . '\Fixtures\Annotation\Secure', |
||||
'route' => __NAMESPACE__ . '\Fixtures\Annotation\Route', |
||||
'template' => __NAMESPACE__ . '\Fixtures\Annotation\Template', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
|
||||
/** |
||||
* @group DCOM-97 |
||||
* @group regression |
||||
*/ |
||||
public function testClassWithClosure() |
||||
{ |
||||
$parser = new PhpParser(); |
||||
$class = new ReflectionClass(__NAMESPACE__ . '\Fixtures\ClassWithClosure'); |
||||
|
||||
$this->assertEquals(array( |
||||
'annotationtargetall' => __NAMESPACE__ . '\Fixtures\AnnotationTargetAll', |
||||
'annotationtargetannotation' => __NAMESPACE__ . '\Fixtures\AnnotationTargetAnnotation', |
||||
), $parser->parseClass($class)); |
||||
} |
||||
} |
@ -0,0 +1,97 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations; |
||||
|
||||
use Doctrine\Common\Annotations\SimpleAnnotationReader; |
||||
|
||||
class SimpleAnnotationReaderTest extends AbstractReaderTest |
||||
{ |
||||
/** |
||||
* Contrary to the behavior of the default annotation reader, we do just ignore |
||||
* these in the simple annotation reader (so, no expected exception here). |
||||
*/ |
||||
public function testImportDetectsNotImportedAnnotation() |
||||
{ |
||||
parent::testImportDetectsNotImportedAnnotation(); |
||||
} |
||||
|
||||
/** |
||||
* Contrary to the behavior of the default annotation reader, we do just ignore |
||||
* these in the simple annotation reader (so, no expected exception here). |
||||
*/ |
||||
public function testImportDetectsNonExistentAnnotation() |
||||
{ |
||||
parent::testImportDetectsNonExistentAnnotation(); |
||||
} |
||||
|
||||
/** |
||||
* Contrary to the behavior of the default annotation reader, we do just ignore |
||||
* these in the simple annotation reader (so, no expected exception here). |
||||
*/ |
||||
public function testClassWithInvalidAnnotationTargetAtClassDocBlock() |
||||
{ |
||||
parent::testClassWithInvalidAnnotationTargetAtClassDocBlock(); |
||||
} |
||||
|
||||
/** |
||||
* Contrary to the behavior of the default annotation reader, we do just ignore |
||||
* these in the simple annotation reader (so, no expected exception here). |
||||
*/ |
||||
public function testClassWithInvalidAnnotationTargetAtPropertyDocBlock() |
||||
{ |
||||
parent::testClassWithInvalidAnnotationTargetAtPropertyDocBlock(); |
||||
} |
||||
|
||||
/** |
||||
* Contrary to the behavior of the default annotation reader, we do just ignore |
||||
* these in the simple annotation reader (so, no expected exception here). |
||||
*/ |
||||
public function testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock() |
||||
{ |
||||
parent::testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock(); |
||||
} |
||||
|
||||
/** |
||||
* Contrary to the behavior of the default annotation reader, we do just ignore |
||||
* these in the simple annotation reader (so, no expected exception here). |
||||
*/ |
||||
public function testClassWithInvalidAnnotationTargetAtMethodDocBlock() |
||||
{ |
||||
parent::testClassWithInvalidAnnotationTargetAtMethodDocBlock(); |
||||
} |
||||
|
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
*/ |
||||
public function testInvalidAnnotationUsageButIgnoredClass() |
||||
{ |
||||
parent::testInvalidAnnotationUsageButIgnoredClass(); |
||||
} |
||||
|
||||
/** |
||||
* @group DDC-1660 |
||||
* @group regression |
||||
* |
||||
* Contrary to the behavior of the default annotation reader, @version is not ignored |
||||
*/ |
||||
public function testInvalidAnnotationButIgnored() |
||||
{ |
||||
$reader = $this->getReader(); |
||||
$class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassDDC1660'); |
||||
|
||||
$this->assertTrue(class_exists('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Version')); |
||||
$this->assertCount(1, $reader->getClassAnnotations($class)); |
||||
$this->assertCount(1, $reader->getMethodAnnotations($class->getMethod('bar'))); |
||||
$this->assertCount(1, $reader->getPropertyAnnotations($class->getProperty('foo'))); |
||||
} |
||||
|
||||
protected function getReader() |
||||
{ |
||||
$reader = new SimpleAnnotationReader(); |
||||
$reader->addNamespace(__NAMESPACE__); |
||||
$reader->addNamespace(__NAMESPACE__ . '\Fixtures'); |
||||
$reader->addNamespace(__NAMESPACE__ . '\Fixtures\Annotation'); |
||||
|
||||
return $reader; |
||||
} |
||||
} |
@ -0,0 +1,65 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Ticket; |
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Controller; |
||||
|
||||
/** |
||||
* @group |
||||
*/ |
||||
class DCOM55Test extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
/** |
||||
* @expectedException Doctrine\Common\Annotations\AnnotationException |
||||
* @expectedExceptionMessage [Semantical Error] The class "Doctrine\Tests\Common\Annotations\Fixtures\Controller" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "Doctrine\Tests\Common\Annotations\Fixtures\Controller". If it is indeed no annotation, then you need to add @IgnoreAnnotation("Controller") to the _class_ doc comment of class Doctrine\Tests\Common\Annotations\Ticket\Dummy. |
||||
*/ |
||||
public function testIssue() |
||||
{ |
||||
$class = new \ReflectionClass(__NAMESPACE__ . '\\Dummy'); |
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader(); |
||||
$reader->getClassAnnotations($class); |
||||
} |
||||
|
||||
public function testAnnotation() |
||||
{ |
||||
$class = new \ReflectionClass(__NAMESPACE__ . '\\DCOM55Consumer'); |
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader(); |
||||
$annots = $reader->getClassAnnotations($class); |
||||
|
||||
$this->assertEquals(1, count($annots)); |
||||
$this->assertInstanceOf(__NAMESPACE__.'\\DCOM55Annotation', $annots[0]); |
||||
} |
||||
|
||||
public function testParseAnnotationDocblocks() |
||||
{ |
||||
$class = new \ReflectionClass(__NAMESPACE__ . '\\DCOM55Annotation'); |
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader(); |
||||
$annots = $reader->getClassAnnotations($class); |
||||
|
||||
$this->assertEquals(0, count($annots)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @Controller |
||||
*/ |
||||
class Dummy |
||||
{ |
||||
|
||||
} |
||||
|
||||
/** |
||||
* @Annotation |
||||
*/ |
||||
class DCOM55Annotation |
||||
{ |
||||
|
||||
} |
||||
|
||||
/** |
||||
* @DCOM55Annotation |
||||
*/ |
||||
class DCOM55Consumer |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,8 @@ |
||||
<?php |
||||
// Some class named Entity in the global namespace |
||||
/** |
||||
* @Annotation |
||||
*/ |
||||
class Entity |
||||
{ |
||||
} |
@ -0,0 +1,112 @@ |
||||
<?php |
||||
namespace Doctrine\Tests\Common\Annotations\Ticket; |
||||
|
||||
//Some class named Entity in the global namespace |
||||
include __DIR__ .'/DCOM58Entity.php'; |
||||
|
||||
/** |
||||
* @group DCOM58 |
||||
*/ |
||||
class DCOM58Test extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
public function testIssue() |
||||
{ |
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader(); |
||||
$result = $reader->getClassAnnotations(new \ReflectionClass(__NAMESPACE__."\MappedClass")); |
||||
|
||||
foreach ($result as $annot) { |
||||
$classAnnotations[get_class($annot)] = $annot; |
||||
} |
||||
|
||||
$this->assertTrue(!isset($classAnnotations['']), 'Class "xxx" is not a valid entity or mapped super class.'); |
||||
} |
||||
|
||||
public function testIssueGlobalNamespace() |
||||
{ |
||||
$docblock = "@Entity"; |
||||
$parser = new \Doctrine\Common\Annotations\DocParser(); |
||||
$parser->setImports(array( |
||||
"__NAMESPACE__" =>"Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping" |
||||
)); |
||||
|
||||
$annots = $parser->parse($docblock); |
||||
|
||||
$this->assertEquals(1, count($annots)); |
||||
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping\Entity", $annots[0]); |
||||
} |
||||
|
||||
public function testIssueNamespaces() |
||||
{ |
||||
$docblock = "@Entity"; |
||||
$parser = new \Doctrine\Common\Annotations\DocParser(); |
||||
$parser->addNamespace("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM"); |
||||
|
||||
$annots = $parser->parse($docblock); |
||||
|
||||
$this->assertEquals(1, count($annots)); |
||||
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Entity", $annots[0]); |
||||
} |
||||
|
||||
public function testIssueMultipleNamespaces() |
||||
{ |
||||
$docblock = "@Entity"; |
||||
$parser = new \Doctrine\Common\Annotations\DocParser(); |
||||
$parser->addNamespace("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping"); |
||||
$parser->addNamespace("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM"); |
||||
|
||||
$annots = $parser->parse($docblock); |
||||
|
||||
$this->assertEquals(1, count($annots)); |
||||
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping\Entity", $annots[0]); |
||||
} |
||||
|
||||
public function testIssueWithNamespacesOrImports() |
||||
{ |
||||
$docblock = "@Entity"; |
||||
$parser = new \Doctrine\Common\Annotations\DocParser(); |
||||
$annots = $parser->parse($docblock); |
||||
|
||||
$this->assertEquals(1, count($annots)); |
||||
$this->assertInstanceOf("Entity", $annots[0]); |
||||
$this->assertEquals(1, count($annots)); |
||||
} |
||||
|
||||
|
||||
public function testIssueSimpleAnnotationReader() |
||||
{ |
||||
$reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader(); |
||||
$reader->addNamespace('Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping'); |
||||
$annots = $reader->getClassAnnotations(new \ReflectionClass(__NAMESPACE__."\MappedClass")); |
||||
|
||||
$this->assertEquals(1, count($annots)); |
||||
$this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping\Entity", $annots[0]); |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* @Entity |
||||
*/ |
||||
class MappedClass |
||||
{ |
||||
|
||||
} |
||||
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM\Mapping; |
||||
/** |
||||
* @Annotation |
||||
*/ |
||||
class Entity |
||||
{ |
||||
|
||||
} |
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Ticket\Doctrine\ORM; |
||||
/** |
||||
* @Annotation |
||||
*/ |
||||
class Entity |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,8 @@ |
||||
<?php |
||||
|
||||
use Doctrine\Common\Annotations\Annotation; |
||||
|
||||
/** @Annotation */ |
||||
class TopLevelAnnotation extends Annotation |
||||
{ |
||||
} |
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
namespace Doctrine\Tests; |
||||
|
||||
/** |
||||
* Base testcase class for all Doctrine testcases. |
||||
*/ |
||||
abstract class DoctrineTestCase extends \PHPUnit_Framework_TestCase |
||||
{ |
||||
} |
@ -0,0 +1,26 @@ |
||||
<?php |
||||
/* |
||||
* This file bootstraps the test environment. |
||||
*/ |
||||
namespace Doctrine\Tests; |
||||
|
||||
error_reporting(E_ALL | E_STRICT); |
||||
|
||||
// register silently failing autoloader |
||||
spl_autoload_register(function($class) |
||||
{ |
||||
if (0 === strpos($class, 'Doctrine\Tests\\')) { |
||||
$path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php'; |
||||
if (is_file($path) && is_readable($path)) { |
||||
require_once $path; |
||||
|
||||
return true; |
||||
} |
||||
} |
||||
}); |
||||
|
||||
require_once __DIR__ . "/../../../vendor/autoload.php"; |
||||
|
||||
\Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace( |
||||
'Doctrine\Tests\Common\Annotations\Fixtures', __DIR__ . '/../../' |
||||
); |
@ -0,0 +1,2 @@ |
||||
vendor/ |
||||
phpunit.xml |
@ -0,0 +1,9 @@ |
||||
language: php |
||||
|
||||
php: |
||||
- 5.3 |
||||
- 5.4 |
||||
- 5.5 |
||||
|
||||
before_script: |
||||
- composer --prefer-source --dev install |
@ -0,0 +1,19 @@ |
||||
Copyright (c) 2006-2012 Doctrine Project |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||
this software and associated documentation files (the "Software"), to deal in |
||||
the Software without restriction, including without limitation the rights to |
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
||||
of the Software, and to permit persons to whom the Software is furnished to do |
||||
so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
@ -0,0 +1,10 @@ |
||||
# Doctrine Cache |
||||
|
||||
Cache component extracted from the Doctrine Common project. |
||||
|
||||
## Changelog |
||||
|
||||
### v1.2 |
||||
|
||||
* Added support for MongoDB as Cache Provider |
||||
* Fix namespace version reset |
@ -0,0 +1,3 @@ |
||||
# Version class and file |
||||
project.version_class = Doctrine\\Common\\Cache\\Version |
||||
project.version_file = lib/Doctrine/Common/Cache/Version.php |
@ -0,0 +1,101 @@ |
||||
<?xml version="1.0"?> |
||||
<project name="DoctrineCommonCache" default="build" basedir="."> |
||||
<property file="build.properties" /> |
||||
|
||||
<target name="php"> |
||||
<exec executable="which" outputproperty="php_executable"> |
||||
<arg value="php" /> |
||||
</exec> |
||||
</target> |
||||
|
||||
<target name="prepare"> |
||||
<mkdir dir="build" /> |
||||
</target> |
||||
|
||||
<target name="build" depends="check-git-checkout-clean,prepare,php,composer"> |
||||
<exec executable="${php_executable}"> |
||||
<arg value="build/composer.phar" /> |
||||
<arg value="archive" /> |
||||
<arg value="--dir=build" /> |
||||
</exec> |
||||
</target> |
||||
|
||||
<target name="composer" depends="php,composer-check,composer-download"> |
||||
<exec executable="${php_executable}"> |
||||
<arg value="build/composer.phar" /> |
||||
<arg value="install" /> |
||||
</exec> |
||||
</target> |
||||
|
||||
<target name="composer-check" depends="prepare"> |
||||
<available file="build/composer.phar" property="composer.present"/> |
||||
</target> |
||||
|
||||
<target name="composer-download" unless="composer.present"> |
||||
<exec executable="wget"> |
||||
<arg value="-Obuild/composer.phar" /> |
||||
<arg value="http://getcomposer.org/composer.phar" /> |
||||
</exec> |
||||
</target> |
||||
|
||||
<target name="make-release" depends="check-git-checkout-clean,prepare,php"> |
||||
<replace file="${project.version_file}" token="-DEV" value="" failOnNoReplacements="true" /> |
||||
<exec executable="${php_executable}" outputproperty="doctrine.current_version" failonerror="true"> |
||||
<arg value="-r" /> |
||||
<arg value="require_once '${project.version_file}';echo ${project.version_class}::VERSION;" /> |
||||
</exec> |
||||
<exec executable="${php_executable}" outputproperty="doctrine.next_version" failonerror="true"> |
||||
<arg value="-r" /> |
||||
<arg value="$parts = explode('.', str_ireplace(array('-DEV', '-ALPHA', '-BETA'), '', '${doctrine.current_version}')); |
||||
if (count($parts) != 3) { |
||||
throw new \InvalidArgumentException('Version is assumed in format x.y.z, ${doctrine.current_version} given'); |
||||
} |
||||
$parts[2]++; |
||||
echo implode('.', $parts); |
||||
" /> |
||||
</exec> |
||||
|
||||
<git-commit file="${project.version_file}" message="Release ${doctrine.current_version}" /> |
||||
<git-tag version="${doctrine.current_version}" /> |
||||
<replace file="${project.version_file}" token="${doctrine.current_version}" value="${doctrine.next_version}-DEV" /> |
||||
<git-commit file="${project.version_file}" message="Bump version to ${doctrine.next_version}" /> |
||||
</target> |
||||
|
||||
<target name="check-git-checkout-clean"> |
||||
<exec executable="git" failonerror="true"> |
||||
<arg value="diff-index" /> |
||||
<arg value="--quiet" /> |
||||
<arg value="HEAD" /> |
||||
</exec> |
||||
</target> |
||||
|
||||
<macrodef name="git-commit"> |
||||
<attribute name="file" default="NOT SET"/> |
||||
<attribute name="message" default="NOT SET"/> |
||||
|
||||
<sequential> |
||||
<exec executable="git"> |
||||
<arg value="add" /> |
||||
<arg value="@{file}" /> |
||||
</exec> |
||||
<exec executable="git"> |
||||
<arg value="commit" /> |
||||
<arg value="-m" /> |
||||
<arg value="@{message}" /> |
||||
</exec> |
||||
</sequential> |
||||
</macrodef> |
||||
|
||||
<macrodef name="git-tag"> |
||||
<attribute name="version" default="NOT SET" /> |
||||
|
||||
<sequential> |
||||
<exec executable="git"> |
||||
<arg value="tag" /> |
||||
<arg value="-m" /> |
||||
<arg value="v@{version}" /> |
||||
<arg value="v@{version}" /> |
||||
</exec> |
||||
</sequential> |
||||
</macrodef> |
||||
</project> |
@ -0,0 +1,29 @@ |
||||
{ |
||||
"name": "doctrine/cache", |
||||
"type": "library", |
||||
"description": "Caching library offering an object-oriented API for many cache backends", |
||||
"keywords": ["cache", "caching"], |
||||
"homepage": "http://www.doctrine-project.org", |
||||
"license": "MIT", |
||||
"authors": [ |
||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, |
||||
{"name": "Roman Borschel", "email": "roman@code-factory.org"}, |
||||
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, |
||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, |
||||
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} |
||||
], |
||||
"require": { |
||||
"php": ">=5.3.2" |
||||
}, |
||||
"conflict": { |
||||
"doctrine/common": ">2.2,<2.4" |
||||
}, |
||||
"autoload": { |
||||
"psr-0": { "Doctrine\\Common\\Cache\\": "lib/" } |
||||
}, |
||||
"extra": { |
||||
"branch-alias": { |
||||
"dev-master": "1.0.x-dev" |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue