chore: 添加缺失的静态资源文件
添加多个前端界面所需的图片、字体、音频等静态资源文件,包括: - 管理员后台的图标、背景图、组件图片 - 移动端页面的商品图片、用户中心图片、活动图标 - 第三方库的示例图片和字体文件 - 浏览器兼容性配置文件 - 图标字体文件(eot、ttf、woff、woff2格式) 这些资源是前端界面正常显示所必需的,之前可能因版本控制忽略或遗漏而缺失。
This commit is contained in:
67
vendor/doctrine/annotations/.doctrine-project.json
vendored
Normal file
67
vendor/doctrine/annotations/.doctrine-project.json
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"active": true,
|
||||
"name": "Annotations",
|
||||
"slug": "annotations",
|
||||
"docsSlug": "doctrine-annotations",
|
||||
"versions": [
|
||||
{
|
||||
"name": "1.14",
|
||||
"branchName": "1.14.x",
|
||||
"slug": "latest",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "1.13",
|
||||
"branchName": "1.13.x",
|
||||
"slug": "1.13",
|
||||
"aliases": [
|
||||
"current",
|
||||
"stable"
|
||||
],
|
||||
"current": true,
|
||||
"maintained": true
|
||||
},
|
||||
{
|
||||
"name": "1.12",
|
||||
"branchName": "1.12.x",
|
||||
"slug": "1.12",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "1.11",
|
||||
"branchName": "1.11.x",
|
||||
"slug": "1.11",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "1.10",
|
||||
"branchName": "1.10.x",
|
||||
"slug": "1.10",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "1.9",
|
||||
"branchName": "1.9.x",
|
||||
"slug": "1.9",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "1.8",
|
||||
"branchName": "1.8",
|
||||
"slug": "1.8",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "1.7",
|
||||
"branchName": "1.7",
|
||||
"slug": "1.7",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "1.6",
|
||||
"branchName": "1.6",
|
||||
"slug": "1.6",
|
||||
"maintained": false
|
||||
}
|
||||
]
|
||||
}
|
||||
6
vendor/doctrine/annotations/.gitattributes
vendored
Normal file
6
vendor/doctrine/annotations/.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/.* export-ignore
|
||||
/tests export-ignore
|
||||
/phpbench.json.dist export-ignore
|
||||
/phpcs.xml.dist export-ignore
|
||||
/phpstan.neon export-ignore
|
||||
/phpunit.xml.dist export-ignore
|
||||
15
vendor/doctrine/annotations/.github/workflows/coding-standards.yml
vendored
Normal file
15
vendor/doctrine/annotations/.github/workflows/coding-standards.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
name: "Coding Standards"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*.x"
|
||||
push:
|
||||
branches:
|
||||
- "*.x"
|
||||
|
||||
jobs:
|
||||
coding-standards:
|
||||
name: "Coding Standards"
|
||||
uses: "doctrine/.github/.github/workflows/coding-standards.yml@2.1.0"
|
||||
18
vendor/doctrine/annotations/.github/workflows/composer-lint.yml
vendored
Normal file
18
vendor/doctrine/annotations/.github/workflows/composer-lint.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: "Composer Lint"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*.x"
|
||||
paths:
|
||||
- "composer.json"
|
||||
push:
|
||||
branches:
|
||||
- "*.x"
|
||||
paths:
|
||||
- "composer.json"
|
||||
|
||||
jobs:
|
||||
composer-lint:
|
||||
name: "Composer Lint"
|
||||
uses: "doctrine/.github/.github/workflows/composer-lint.yml@2.1.0"
|
||||
19
vendor/doctrine/annotations/.github/workflows/continuous-integration.yml
vendored
Normal file
19
vendor/doctrine/annotations/.github/workflows/continuous-integration.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: "Continuous Integration"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*.x"
|
||||
push:
|
||||
branches:
|
||||
- "*.x"
|
||||
|
||||
env:
|
||||
fail-fast: true
|
||||
|
||||
jobs:
|
||||
phpunit:
|
||||
name: "PHPUnit"
|
||||
uses: "doctrine/.github/.github/workflows/continuous-integration.yml@2.1.0"
|
||||
with:
|
||||
php-versions: '["7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]'
|
||||
16
vendor/doctrine/annotations/.github/workflows/release-on-milestone-closed.yml
vendored
Normal file
16
vendor/doctrine/annotations/.github/workflows/release-on-milestone-closed.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: "Automatic Releases"
|
||||
|
||||
on:
|
||||
milestone:
|
||||
types:
|
||||
- "closed"
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: "Git tag, release & create merge-up PR"
|
||||
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@2.1.0"
|
||||
secrets:
|
||||
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
ORGANIZATION_ADMIN_TOKEN: ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
|
||||
SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
15
vendor/doctrine/annotations/.github/workflows/static-analysis.yml
vendored
Normal file
15
vendor/doctrine/annotations/.github/workflows/static-analysis.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
name: "Static Analysis"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*.x"
|
||||
push:
|
||||
branches:
|
||||
- "*.x"
|
||||
|
||||
jobs:
|
||||
static-analysis:
|
||||
name: "Static Analysis"
|
||||
uses: "doctrine/.github/.github/workflows/static-analysis.yml@2.1.0"
|
||||
7
vendor/doctrine/annotations/.gitignore
vendored
Normal file
7
vendor/doctrine/annotations/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/vendor/
|
||||
/composer.lock
|
||||
/composer.phar
|
||||
/phpbench.json
|
||||
/phpunit.xml
|
||||
/.phpcs-cache
|
||||
/.phpunit.result.cache
|
||||
19
vendor/doctrine/annotations/LICENSE
vendored
Normal file
19
vendor/doctrine/annotations/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2006-2013 Doctrine Project
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
24
vendor/doctrine/annotations/README.md
vendored
Normal file
24
vendor/doctrine/annotations/README.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
⚠️ PHP 8 introduced
|
||||
[attributes](https://www.php.net/manual/en/language.attributes.overview.php),
|
||||
which are a native replacement for annotations. As such, this library is
|
||||
considered feature complete, and should receive exclusively bugfixes and
|
||||
security fixes.
|
||||
|
||||
# Doctrine Annotations
|
||||
|
||||
[](https://github.com/doctrine/persistence/actions)
|
||||
[](https://www.versioneye.com/package/php--doctrine--annotations)
|
||||
[](https://www.versioneye.com/php/doctrine:annotations/references)
|
||||
[](https://packagist.org/packages/doctrine/annotations)
|
||||
[](https://packagist.org/packages/doctrine/annotations)
|
||||
|
||||
Docblock Annotations Parser library (extracted from [Doctrine Common](https://github.com/doctrine/common)).
|
||||
|
||||
## Documentation
|
||||
|
||||
See the [doctrine-project website](https://www.doctrine-project.org/projects/doctrine-annotations/en/latest/index.html).
|
||||
|
||||
## Contributing
|
||||
|
||||
When making a pull request, make sure your changes follow the
|
||||
[Coding Standard Guidelines](https://www.doctrine-project.org/projects/doctrine-coding-standard/en/current/reference/index.html#introduction).
|
||||
72
vendor/doctrine/annotations/composer.json
vendored
Normal file
72
vendor/doctrine/annotations/composer.json
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"description": "Docblock Annotations Parser",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"annotations",
|
||||
"docblock",
|
||||
"parser"
|
||||
],
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"homepage": "https://www.doctrine-project.org/projects/annotations.html",
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0",
|
||||
"ext-tokenizer": "*",
|
||||
"doctrine/lexer": "^1 || ^2",
|
||||
"psr/cache": "^1 || ^2 || ^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "^1.11 || ^2.0",
|
||||
"doctrine/coding-standard": "^9 || ^10",
|
||||
"phpstan/phpstan": "~1.4.10 || ^1.8.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6",
|
||||
"vimeo/psalm": "^4.10"
|
||||
},
|
||||
"suggest": {
|
||||
"php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Performance\\Common\\Annotations\\": "tests/Doctrine/Performance/Common/Annotations",
|
||||
"Doctrine\\Tests\\Common\\Annotations\\": "tests/Doctrine/Tests/Common/Annotations"
|
||||
},
|
||||
"files": [
|
||||
"tests/Doctrine/Tests/Common/Annotations/Fixtures/functions.php",
|
||||
"tests/Doctrine/Tests/Common/Annotations/Fixtures/SingleClassLOC1000.php"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
},
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
252
vendor/doctrine/annotations/docs/en/annotations.rst
vendored
Normal file
252
vendor/doctrine/annotations/docs/en/annotations.rst
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
Handling Annotations
|
||||
====================
|
||||
|
||||
There are several different approaches to handling annotations in PHP.
|
||||
Doctrine Annotations maps docblock annotations to PHP classes. Because
|
||||
not all docblock annotations are used for metadata purposes a filter is
|
||||
applied to ignore or skip classes that are not Doctrine annotations.
|
||||
|
||||
Take a look at the following code snippet:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyProject\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
use Symfony\Component\Validator\Constraints AS Assert;
|
||||
|
||||
/**
|
||||
* @author Benjamin Eberlei
|
||||
* @ORM\Entity
|
||||
* @MyProject\Annotations\Foobarable
|
||||
*/
|
||||
class User
|
||||
{
|
||||
/**
|
||||
* @ORM\Id @ORM\Column @ORM\GeneratedValue
|
||||
* @dummy
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string")
|
||||
* @Assert\NotEmpty
|
||||
* @Assert\Email
|
||||
* @var string
|
||||
*/
|
||||
private $email;
|
||||
}
|
||||
|
||||
In this snippet you can see a variety of different docblock annotations:
|
||||
|
||||
- Documentation annotations such as ``@var`` and ``@author``. These
|
||||
annotations are ignored and never considered for throwing an
|
||||
exception due to wrongly used annotations.
|
||||
- Annotations imported through use statements. The statement ``use
|
||||
Doctrine\ORM\Mapping AS ORM`` makes all classes under that namespace
|
||||
available as ``@ORM\ClassName``. Same goes for the import of
|
||||
``@Assert``.
|
||||
- The ``@dummy`` annotation. It is not a documentation annotation and
|
||||
not ignored. For Doctrine Annotations it is not entirely clear how
|
||||
to handle this annotation. Depending on the configuration an exception
|
||||
(unknown annotation) will be thrown when parsing this annotation.
|
||||
- The fully qualified annotation ``@MyProject\Annotations\Foobarable``.
|
||||
This is transformed directly into the given class name.
|
||||
|
||||
How are these annotations loaded? From looking at the code you could
|
||||
guess that the ORM Mapping, Assert Validation and the fully qualified
|
||||
annotation can just be loaded using
|
||||
the defined PHP autoloaders. This is not the case however: For error
|
||||
handling reasons every check for class existence inside the
|
||||
``AnnotationReader`` sets the second parameter $autoload
|
||||
of ``class_exists($name, $autoload)`` to false. To work flawlessly the
|
||||
``AnnotationReader`` requires silent autoloaders which many autoloaders are
|
||||
not. Silent autoloading is NOT part of the `PSR-0 specification
|
||||
<https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md>`_
|
||||
for autoloading.
|
||||
|
||||
This is why Doctrine Annotations uses its own autoloading mechanism
|
||||
through a global registry. If you are wondering about the annotation
|
||||
registry being global, there is no other way to solve the architectural
|
||||
problems of autoloading annotation classes in a straightforward fashion.
|
||||
Additionally if you think about PHP autoloading then you recognize it is
|
||||
a global as well.
|
||||
|
||||
To anticipate the configuration section, making the above PHP class work
|
||||
with Doctrine Annotations requires this setup:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
|
||||
AnnotationRegistry::registerFile("/path/to/doctrine/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php");
|
||||
AnnotationRegistry::registerAutoloadNamespace("Symfony\Component\Validator\Constraint", "/path/to/symfony/src");
|
||||
AnnotationRegistry::registerAutoloadNamespace("MyProject\Annotations", "/path/to/myproject/src");
|
||||
|
||||
$reader = new AnnotationReader();
|
||||
AnnotationReader::addGlobalIgnoredName('dummy');
|
||||
|
||||
The second block with the annotation registry calls registers all the
|
||||
three different annotation namespaces that are used.
|
||||
Doctrine Annotations saves all its annotations in a single file, that is
|
||||
why ``AnnotationRegistry#registerFile`` is used in contrast to
|
||||
``AnnotationRegistry#registerAutoloadNamespace`` which creates a PSR-0
|
||||
compatible loading mechanism for class to file names.
|
||||
|
||||
In the third block, we create the actual ``AnnotationReader`` instance.
|
||||
Note that we also add ``dummy`` to the global list of ignored
|
||||
annotations for which we do not throw exceptions. Setting this is
|
||||
necessary in our example case, otherwise ``@dummy`` would trigger an
|
||||
exception to be thrown during the parsing of the docblock of
|
||||
``MyProject\Entities\User#id``.
|
||||
|
||||
Setup and Configuration
|
||||
-----------------------
|
||||
|
||||
To use the annotations library is simple, you just need to create a new
|
||||
``AnnotationReader`` instance:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
|
||||
|
||||
This creates a simple annotation reader with no caching other than in
|
||||
memory (in php arrays). Since parsing docblocks can be expensive you
|
||||
should cache this process by using a caching reader.
|
||||
|
||||
To cache annotations, you can create a ``Doctrine\Common\Annotations\PsrCachedReader``.
|
||||
This reader decorates the original reader and stores all annotations in a PSR-6
|
||||
cache:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\PsrCachedReader;
|
||||
|
||||
$cache = ... // instantiate a PSR-6 Cache pool
|
||||
|
||||
$reader = new PsrCachedReader(
|
||||
new AnnotationReader(),
|
||||
$cache,
|
||||
$debug = true
|
||||
);
|
||||
|
||||
The ``debug`` flag is used here as well to invalidate the cache files
|
||||
when the PHP class with annotations changed and should be used during
|
||||
development.
|
||||
|
||||
.. warning ::
|
||||
|
||||
The ``AnnotationReader`` works and caches under the
|
||||
assumption that all annotations of a doc-block are processed at
|
||||
once. That means that annotation classes that do not exist and
|
||||
aren't loaded and cannot be autoloaded (using the
|
||||
AnnotationRegistry) would never be visible and not accessible if a
|
||||
cache is used unless the cache is cleared and the annotations
|
||||
requested again, this time with all annotations defined.
|
||||
|
||||
By default the annotation reader returns a list of annotations with
|
||||
numeric indexes. If you want your annotations to be indexed by their
|
||||
class name you can wrap the reader in an ``IndexedReader``:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\IndexedReader;
|
||||
|
||||
$reader = new IndexedReader(new AnnotationReader());
|
||||
|
||||
.. warning::
|
||||
|
||||
You should never wrap the indexed reader inside a cached reader,
|
||||
only the other way around. This way you can re-use the cache with
|
||||
indexed or numeric keys, otherwise your code may experience failures
|
||||
due to caching in a numerical or indexed format.
|
||||
|
||||
Registering Annotations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As explained in the introduction, Doctrine Annotations uses its own
|
||||
autoloading mechanism to determine if a given annotation has a
|
||||
corresponding PHP class that can be autoloaded. For annotation
|
||||
autoloading you have to configure the
|
||||
``Doctrine\Common\Annotations\AnnotationRegistry``. There are three
|
||||
different mechanisms to configure annotation autoloading:
|
||||
|
||||
- Calling ``AnnotationRegistry#registerFile($file)`` to register a file
|
||||
that contains one or more annotation classes.
|
||||
- Calling ``AnnotationRegistry#registerNamespace($namespace, $dirs =
|
||||
null)`` to register that the given namespace contains annotations and
|
||||
that their base directory is located at the given $dirs or in the
|
||||
include path if ``NULL`` is passed. The given directories should *NOT*
|
||||
be the directory where classes of the namespace are in, but the base
|
||||
directory of the root namespace. The AnnotationRegistry uses a
|
||||
namespace to directory separator approach to resolve the correct path.
|
||||
- Calling ``AnnotationRegistry#registerLoader($callable)`` to register
|
||||
an autoloader callback. The callback accepts the class as first and
|
||||
only parameter and has to return ``true`` if the corresponding file
|
||||
was found and included.
|
||||
|
||||
.. note::
|
||||
|
||||
Loaders have to fail silently, if a class is not found even if it
|
||||
matches for example the namespace prefix of that loader. Never is a
|
||||
loader to throw a warning or exception if the loading failed
|
||||
otherwise parsing doc block annotations will become a huge pain.
|
||||
|
||||
A sample loader callback could look like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use Symfony\Component\ClassLoader\UniversalClassLoader;
|
||||
|
||||
AnnotationRegistry::registerLoader(function($class) {
|
||||
$file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php";
|
||||
|
||||
if (file_exists("/my/base/path/" . $file)) {
|
||||
// file_exists() makes sure that the loader fails silently
|
||||
require "/my/base/path/" . $file;
|
||||
}
|
||||
});
|
||||
|
||||
$loader = new UniversalClassLoader();
|
||||
AnnotationRegistry::registerLoader(array($loader, "loadClass"));
|
||||
|
||||
|
||||
Ignoring missing exceptions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default an exception is thrown from the ``AnnotationReader`` if an
|
||||
annotation was found that:
|
||||
|
||||
- is not part of the list of ignored "documentation annotations";
|
||||
- was not imported through a use statement;
|
||||
- is not a fully qualified class that exists.
|
||||
|
||||
You can disable this behavior for specific names if your docblocks do
|
||||
not follow strict requirements:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
|
||||
AnnotationReader::addGlobalIgnoredName('foo');
|
||||
|
||||
PHP Imports
|
||||
~~~~~~~~~~~
|
||||
|
||||
By default the annotation reader parses the use-statement of a php file
|
||||
to gain access to the import rules and register them for the annotation
|
||||
processing. Only if you are using PHP Imports can you validate the
|
||||
correct usage of annotations and throw exceptions if you misspelled an
|
||||
annotation. This mechanism is enabled by default.
|
||||
|
||||
To ease the upgrade path, we still allow you to disable this mechanism.
|
||||
Note however that we will remove this in future versions:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
|
||||
$reader->setEnabledPhpImports(false);
|
||||
443
vendor/doctrine/annotations/docs/en/custom.rst
vendored
Normal file
443
vendor/doctrine/annotations/docs/en/custom.rst
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
Custom Annotation Classes
|
||||
=========================
|
||||
|
||||
If you want to define your own annotations, you just have to group them
|
||||
in a namespace and register this namespace in the ``AnnotationRegistry``.
|
||||
Annotation classes have to contain a class-level docblock with the text
|
||||
``@Annotation``:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Annotations;
|
||||
|
||||
/** @Annotation */
|
||||
class Bar
|
||||
{
|
||||
// some code
|
||||
}
|
||||
|
||||
Inject annotation values
|
||||
------------------------
|
||||
|
||||
The annotation parser checks if the annotation constructor has arguments,
|
||||
if so then it will pass the value array, otherwise it will try to inject
|
||||
values into public properties directly:
|
||||
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*
|
||||
* Some Annotation using a constructor
|
||||
*/
|
||||
class Bar
|
||||
{
|
||||
private $foo;
|
||||
|
||||
public function __construct(array $values)
|
||||
{
|
||||
$this->foo = $values['foo'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*
|
||||
* Some Annotation without a constructor
|
||||
*/
|
||||
class Foo
|
||||
{
|
||||
public $bar;
|
||||
}
|
||||
|
||||
Optional: Constructors with Named Parameters
|
||||
--------------------------------------------
|
||||
|
||||
Starting with Annotations v1.11 a new annotation instantiation strategy
|
||||
is available that aims at compatibility of Annotation classes with the PHP 8
|
||||
attribute feature. You need to declare a constructor with regular parameter
|
||||
names that match the named arguments in the annotation syntax.
|
||||
|
||||
To enable this feature, you can tag your annotation class with
|
||||
``@NamedArgumentConstructor`` (available from v1.12) or implement the
|
||||
``Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation`` interface
|
||||
(available from v1.11 and deprecated as of v1.12).
|
||||
When using the ``@NamedArgumentConstructor`` tag, the first argument of the
|
||||
constructor is considered as the default one.
|
||||
|
||||
|
||||
Usage with the ``@NamedArgumentConstructor`` tag
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @NamedArgumentConstructor
|
||||
*/
|
||||
class Bar implements NamedArgumentConstructorAnnotation
|
||||
{
|
||||
private $foo;
|
||||
|
||||
public function __construct(string $foo)
|
||||
{
|
||||
$this->foo = $foo;
|
||||
}
|
||||
}
|
||||
|
||||
/** Usable with @Bar(foo="baz") */
|
||||
/** Usable with @Bar("baz") */
|
||||
|
||||
In combination with PHP 8's constructor property promotion feature
|
||||
you can simplify this to:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @NamedArgumentConstructor
|
||||
*/
|
||||
class Bar implements NamedArgumentConstructorAnnotation
|
||||
{
|
||||
public function __construct(private string $foo) {}
|
||||
}
|
||||
|
||||
|
||||
Usage with the
|
||||
``Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation``
|
||||
interface (v1.11, deprecated as of v1.12):
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation;
|
||||
|
||||
/** @Annotation */
|
||||
class Bar implements NamedArgumentConstructorAnnotation
|
||||
{
|
||||
private $foo;
|
||||
|
||||
public function __construct(private string $foo) {}
|
||||
}
|
||||
|
||||
/** Usable with @Bar(foo="baz") */
|
||||
|
||||
Annotation Target
|
||||
-----------------
|
||||
|
||||
``@Target`` indicates the kinds of class elements to which an annotation
|
||||
type is applicable. Then you could define one or more targets:
|
||||
|
||||
- ``CLASS`` Allowed in class docblocks
|
||||
- ``PROPERTY`` Allowed in property docblocks
|
||||
- ``METHOD`` Allowed in the method docblocks
|
||||
- ``FUNCTION`` Allowed in function dockblocks
|
||||
- ``ALL`` Allowed in class, property, method and function docblocks
|
||||
- ``ANNOTATION`` Allowed inside other annotations
|
||||
|
||||
If the annotations is not allowed in the current context, an
|
||||
``AnnotationException`` is thrown.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"METHOD","PROPERTY"})
|
||||
*/
|
||||
class Bar
|
||||
{
|
||||
// some code
|
||||
}
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("CLASS")
|
||||
*/
|
||||
class Foo
|
||||
{
|
||||
// some code
|
||||
}
|
||||
|
||||
Attribute types
|
||||
---------------
|
||||
|
||||
The annotation parser checks the given parameters using the phpdoc
|
||||
annotation ``@var``, The data type could be validated using the ``@var``
|
||||
annotation on the annotation properties or using the ``@Attributes`` and
|
||||
``@Attribute`` annotations.
|
||||
|
||||
If the data type does not match you get an ``AnnotationException``
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Annotations;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"METHOD","PROPERTY"})
|
||||
*/
|
||||
class Bar
|
||||
{
|
||||
/** @var mixed */
|
||||
public $mixed;
|
||||
|
||||
/** @var boolean */
|
||||
public $boolean;
|
||||
|
||||
/** @var bool */
|
||||
public $bool;
|
||||
|
||||
/** @var float */
|
||||
public $float;
|
||||
|
||||
/** @var string */
|
||||
public $string;
|
||||
|
||||
/** @var integer */
|
||||
public $integer;
|
||||
|
||||
/** @var array */
|
||||
public $array;
|
||||
|
||||
/** @var SomeAnnotationClass */
|
||||
public $annotation;
|
||||
|
||||
/** @var array<integer> */
|
||||
public $arrayOfIntegers;
|
||||
|
||||
/** @var array<SomeAnnotationClass> */
|
||||
public $arrayOfAnnotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"METHOD","PROPERTY"})
|
||||
* @Attributes({
|
||||
* @Attribute("stringProperty", type = "string"),
|
||||
* @Attribute("annotProperty", type = "SomeAnnotationClass"),
|
||||
* })
|
||||
*/
|
||||
class Foo
|
||||
{
|
||||
public function __construct(array $values)
|
||||
{
|
||||
$this->stringProperty = $values['stringProperty'];
|
||||
$this->annotProperty = $values['annotProperty'];
|
||||
}
|
||||
|
||||
// some code
|
||||
}
|
||||
|
||||
Annotation Required
|
||||
-------------------
|
||||
|
||||
``@Required`` indicates that the field must be specified when the
|
||||
annotation is used. If it is not used you get an ``AnnotationException``
|
||||
stating that this value can not be null.
|
||||
|
||||
Declaring a required field:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
class Foo
|
||||
{
|
||||
/** @Required */
|
||||
public $requiredField;
|
||||
}
|
||||
|
||||
Usage:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
/** @Foo(requiredField="value") */
|
||||
public $direction; // Valid
|
||||
|
||||
/** @Foo */
|
||||
public $direction; // Required field missing, throws an AnnotationException
|
||||
|
||||
|
||||
Enumerated values
|
||||
-----------------
|
||||
|
||||
- An annotation property marked with ``@Enum`` is a field that accepts a
|
||||
fixed set of scalar values.
|
||||
- You should use ``@Enum`` fields any time you need to represent fixed
|
||||
values.
|
||||
- The annotation parser checks the given value and throws an
|
||||
``AnnotationException`` if the value does not match.
|
||||
|
||||
|
||||
Declaring an enumerated property:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
class Direction
|
||||
{
|
||||
/**
|
||||
* @Enum({"NORTH", "SOUTH", "EAST", "WEST"})
|
||||
*/
|
||||
public $value;
|
||||
}
|
||||
|
||||
Annotation usage:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
/** @Direction("NORTH") */
|
||||
public $direction; // Valid value
|
||||
|
||||
/** @Direction("NORTHEAST") */
|
||||
public $direction; // Invalid value, throws an AnnotationException
|
||||
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
The use of constants and class constants is available on the annotations
|
||||
parser.
|
||||
|
||||
The following usages are allowed:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Entity;
|
||||
|
||||
use MyCompany\Annotations\Foo;
|
||||
use MyCompany\Annotations\Bar;
|
||||
use MyCompany\Entity\SomeClass;
|
||||
|
||||
/**
|
||||
* @Foo(PHP_EOL)
|
||||
* @Bar(Bar::FOO)
|
||||
* @Foo({SomeClass::FOO, SomeClass::BAR})
|
||||
* @Bar({SomeClass::FOO_KEY = SomeClass::BAR_VALUE})
|
||||
*/
|
||||
class User
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Be careful with constants and the cache !
|
||||
|
||||
.. note::
|
||||
|
||||
The cached reader will not re-evaluate each time an annotation is
|
||||
loaded from cache. When a constant is changed the cache must be
|
||||
cleaned.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Using the library API is simple. Using the annotations described in the
|
||||
previous section, you can now annotate other classes with your
|
||||
annotations:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace MyCompany\Entity;
|
||||
|
||||
use MyCompany\Annotations\Foo;
|
||||
use MyCompany\Annotations\Bar;
|
||||
|
||||
/**
|
||||
* @Foo(bar="foo")
|
||||
* @Bar(foo="bar")
|
||||
*/
|
||||
class User
|
||||
{
|
||||
}
|
||||
|
||||
Now we can write a script to get the annotations above:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$reflClass = new ReflectionClass('MyCompany\Entity\User');
|
||||
$classAnnotations = $reader->getClassAnnotations($reflClass);
|
||||
|
||||
foreach ($classAnnotations AS $annot) {
|
||||
if ($annot instanceof \MyCompany\Annotations\Foo) {
|
||||
echo $annot->bar; // prints "foo";
|
||||
} else if ($annot instanceof \MyCompany\Annotations\Bar) {
|
||||
echo $annot->foo; // prints "bar";
|
||||
}
|
||||
}
|
||||
|
||||
You have a complete API for retrieving annotation class instances from a
|
||||
class, property or method docblock:
|
||||
|
||||
|
||||
Reader API
|
||||
~~~~~~~~~~
|
||||
|
||||
Access all annotations of a class
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getClassAnnotations(\ReflectionClass $class);
|
||||
|
||||
Access one annotation of a class
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getClassAnnotation(\ReflectionClass $class, $annotationName);
|
||||
|
||||
Access all annotations of a method
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getMethodAnnotations(\ReflectionMethod $method);
|
||||
|
||||
Access one annotation of a method
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getMethodAnnotation(\ReflectionMethod $method, $annotationName);
|
||||
|
||||
Access all annotations of a property
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getPropertyAnnotations(\ReflectionProperty $property);
|
||||
|
||||
Access one annotation of a property
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);
|
||||
|
||||
Access all annotations of a function
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getFunctionAnnotations(\ReflectionFunction $property);
|
||||
|
||||
Access one annotation of a function
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function getFunctionAnnotation(\ReflectionFunction $property, $annotationName);
|
||||
110
vendor/doctrine/annotations/docs/en/index.rst
vendored
Normal file
110
vendor/doctrine/annotations/docs/en/index.rst
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
Deprecation notice
|
||||
==================
|
||||
|
||||
PHP 8 introduced `attributes
|
||||
<https://www.php.net/manual/en/language.attributes.overview.php>`_,
|
||||
which are a native replacement for annotations. As such, this library is
|
||||
considered feature complete, and should receive exclusively bugfixes and
|
||||
security fixes.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Doctrine Annotations allows to implement custom annotation
|
||||
functionality for PHP classes and functions.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
class Foo
|
||||
{
|
||||
/**
|
||||
* @MyAnnotation(myProperty="value")
|
||||
*/
|
||||
private $bar;
|
||||
}
|
||||
|
||||
Annotations aren't implemented in PHP itself which is why this component
|
||||
offers a way to use the PHP doc-blocks as a place for the well known
|
||||
annotation syntax using the ``@`` char.
|
||||
|
||||
Annotations in Doctrine are used for the ORM configuration to build the
|
||||
class mapping, but it can be used in other projects for other purposes
|
||||
too.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
You can install the Annotation component with composer:
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ composer require doctrine/annotations
|
||||
|
||||
Create an annotation class
|
||||
==========================
|
||||
|
||||
An annotation class is a representation of the later used annotation
|
||||
configuration in classes. The annotation class of the previous example
|
||||
looks like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
final class MyAnnotation
|
||||
{
|
||||
public $myProperty;
|
||||
}
|
||||
|
||||
The annotation class is declared as an annotation by ``@Annotation``.
|
||||
|
||||
:ref:`Read more about custom annotations. <custom>`
|
||||
|
||||
Reading annotations
|
||||
===================
|
||||
|
||||
The access to the annotations happens by reflection of the class or function
|
||||
containing them. There are multiple reader-classes implementing the
|
||||
``Doctrine\Common\Annotations\Reader`` interface, that can access the
|
||||
annotations of a class. A common one is
|
||||
``Doctrine\Common\Annotations\AnnotationReader``:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
|
||||
// Deprecated and will be removed in 2.0 but currently needed
|
||||
AnnotationRegistry::registerLoader('class_exists');
|
||||
|
||||
$reflectionClass = new ReflectionClass(Foo::class);
|
||||
$property = $reflectionClass->getProperty('bar');
|
||||
|
||||
$reader = new AnnotationReader();
|
||||
$myAnnotation = $reader->getPropertyAnnotation(
|
||||
$property,
|
||||
MyAnnotation::class
|
||||
);
|
||||
|
||||
echo $myAnnotation->myProperty; // result: "value"
|
||||
|
||||
Note that ``AnnotationRegistry::registerLoader('class_exists')`` only works
|
||||
if you already have an autoloader configured (i.e. composer autoloader).
|
||||
Otherwise, :ref:`please take a look to the other annotation autoload mechanisms <annotations>`.
|
||||
|
||||
A reader has multiple methods to access the annotations of a class or
|
||||
function.
|
||||
|
||||
:ref:`Read more about handling annotations. <annotations>`
|
||||
|
||||
IDE Support
|
||||
-----------
|
||||
|
||||
Some IDEs already provide support for annotations:
|
||||
|
||||
- Eclipse via the `Symfony2 Plugin <https://github.com/pulse00/Symfony-2-Eclipse-Plugin>`_
|
||||
- PhpStorm via the `PHP Annotations Plugin <https://plugins.jetbrains.com/plugin/7320-php-annotations>`_ or the `Symfony Plugin <https://plugins.jetbrains.com/plugin/7219-symfony-support>`_
|
||||
|
||||
.. _Read more about handling annotations.: annotations
|
||||
.. _Read more about custom annotations.: custom
|
||||
6
vendor/doctrine/annotations/docs/en/sidebar.rst
vendored
Normal file
6
vendor/doctrine/annotations/docs/en/sidebar.rst
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
.. toctree::
|
||||
:depth: 3
|
||||
|
||||
index
|
||||
annotations
|
||||
custom
|
||||
57
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php
vendored
Normal file
57
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use BadMethodCallException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Annotations class.
|
||||
*/
|
||||
class Annotation
|
||||
{
|
||||
/**
|
||||
* Value property. Common among all derived classes.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/** @param array<string, mixed> $data Key-value for properties to be defined in this class. */
|
||||
final public 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, static::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler for unknown property mutator in Annotation class.
|
||||
*
|
||||
* @param string $name Unknown property name.
|
||||
* @param mixed $value Property value.
|
||||
*
|
||||
* @throws BadMethodCallException
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
throw new BadMethodCallException(
|
||||
sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class)
|
||||
);
|
||||
}
|
||||
}
|
||||
21
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php
vendored
Normal file
21
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation;
|
||||
|
||||
/**
|
||||
* Annotation that can be used to signal to the parser
|
||||
* to check the attribute type during the parsing process.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
final class Attribute
|
||||
{
|
||||
/** @var string */
|
||||
public $name;
|
||||
|
||||
/** @var string */
|
||||
public $type;
|
||||
|
||||
/** @var bool */
|
||||
public $required = false;
|
||||
}
|
||||
15
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php
vendored
Normal file
15
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
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.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
final class Attributes
|
||||
{
|
||||
/** @var array<Attribute> */
|
||||
public $value;
|
||||
}
|
||||
69
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php
vendored
Normal file
69
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
use function in_array;
|
||||
use function is_object;
|
||||
use function is_scalar;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Annotation that can be used to signal to the parser
|
||||
* to check the available values during the parsing process.
|
||||
*
|
||||
* @Annotation
|
||||
* @Attributes({
|
||||
* @Attribute("value", required = true, type = "array"),
|
||||
* @Attribute("literal", required = false, type = "array")
|
||||
* })
|
||||
*/
|
||||
final class Enum
|
||||
{
|
||||
/** @phpstan-var list<scalar> */
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Literal target declaration.
|
||||
*
|
||||
* @var mixed[]
|
||||
*/
|
||||
public $literal;
|
||||
|
||||
/**
|
||||
* @phpstan-param array{literal?: mixed[], value: list<scalar>} $values
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
if (! isset($values['literal'])) {
|
||||
$values['literal'] = [];
|
||||
}
|
||||
|
||||
foreach ($values['value'] as $var) {
|
||||
if (! is_scalar($var)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'@Enum supports only scalar values "%s" given.',
|
||||
is_object($var) ? get_class($var) : gettype($var)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($values['literal'] as $key => $var) {
|
||||
if (! in_array($key, $values['value'])) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Undefined enumerator value "%s" for literal "%s".',
|
||||
$key,
|
||||
$var
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$this->value = $values['value'];
|
||||
$this->literal = $values['literal'];
|
||||
}
|
||||
}
|
||||
43
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php
vendored
Normal file
43
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
use function json_encode;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Annotation that can be used to signal to the parser to ignore specific
|
||||
* annotations during the parsing process.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
final class IgnoreAnnotation
|
||||
{
|
||||
/** @phpstan-var list<string> */
|
||||
public $names;
|
||||
|
||||
/**
|
||||
* @phpstan-param array{value: string|list<string>} $values
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
if (is_string($values['value'])) {
|
||||
$values['value'] = [$values['value']];
|
||||
}
|
||||
|
||||
if (! is_array($values['value'])) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.',
|
||||
json_encode($values['value'])
|
||||
));
|
||||
}
|
||||
|
||||
$this->names = $values['value'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that the annotated class should be constructed with a named argument call.
|
||||
*
|
||||
* @Annotation
|
||||
* @Target("CLASS")
|
||||
*/
|
||||
final class NamedArgumentConstructor
|
||||
{
|
||||
}
|
||||
13
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Required.php
vendored
Normal file
13
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Required.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
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.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
final class Required
|
||||
{
|
||||
}
|
||||
101
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php
vendored
Normal file
101
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations\Annotation;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
use function array_keys;
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
use function implode;
|
||||
use function is_array;
|
||||
use function is_object;
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Annotation that can be used to signal to the parser
|
||||
* to check the annotation target during the parsing process.
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
final class Target
|
||||
{
|
||||
public const TARGET_CLASS = 1;
|
||||
public const TARGET_METHOD = 2;
|
||||
public const TARGET_PROPERTY = 4;
|
||||
public const TARGET_ANNOTATION = 8;
|
||||
public const TARGET_FUNCTION = 16;
|
||||
public const TARGET_ALL = 31;
|
||||
|
||||
/** @var array<string, int> */
|
||||
private static $map = [
|
||||
'ALL' => self::TARGET_ALL,
|
||||
'CLASS' => self::TARGET_CLASS,
|
||||
'METHOD' => self::TARGET_METHOD,
|
||||
'PROPERTY' => self::TARGET_PROPERTY,
|
||||
'FUNCTION' => self::TARGET_FUNCTION,
|
||||
'ANNOTATION' => self::TARGET_ANNOTATION,
|
||||
];
|
||||
|
||||
/** @phpstan-var list<string> */
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Targets as bitmask.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $targets;
|
||||
|
||||
/**
|
||||
* Literal target declaration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $literal;
|
||||
|
||||
/**
|
||||
* @phpstan-param array{value?: string|list<string>} $values
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
if (! isset($values['value'])) {
|
||||
$values['value'] = null;
|
||||
}
|
||||
|
||||
if (is_string($values['value'])) {
|
||||
$values['value'] = [$values['value']];
|
||||
}
|
||||
|
||||
if (! is_array($values['value'])) {
|
||||
throw new InvalidArgumentException(
|
||||
sprintf(
|
||||
'@Target expects either a string value, or an array of strings, "%s" given.',
|
||||
is_object($values['value']) ? get_class($values['value']) : gettype($values['value'])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$bitmask = 0;
|
||||
foreach ($values['value'] as $literal) {
|
||||
if (! isset(self::$map[$literal])) {
|
||||
throw new InvalidArgumentException(
|
||||
sprintf(
|
||||
'Invalid Target "%s". Available targets: [%s]',
|
||||
$literal,
|
||||
implode(', ', array_keys(self::$map))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$bitmask |= self::$map[$literal];
|
||||
}
|
||||
|
||||
$this->targets = $bitmask;
|
||||
$this->value = $values['value'];
|
||||
$this->literal = implode(', ', $this->value);
|
||||
}
|
||||
}
|
||||
167
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php
vendored
Normal file
167
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
use function implode;
|
||||
use function is_object;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Description of AnnotationException
|
||||
*/
|
||||
class AnnotationException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates a new AnnotationException describing a Syntax error.
|
||||
*
|
||||
* @param string $message Exception message
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function syntaxError($message)
|
||||
{
|
||||
return new self('[Syntax Error] ' . $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing a Semantical error.
|
||||
*
|
||||
* @param string $message Exception message
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function semanticalError($message)
|
||||
{
|
||||
return new self('[Semantical Error] ' . $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing an error which occurred during
|
||||
* the creation of the annotation.
|
||||
*
|
||||
* @param string $message
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function creationError($message, ?Throwable $previous = null)
|
||||
{
|
||||
return new self('[Creation Error] ' . $message, 0, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing a type error.
|
||||
*
|
||||
* @param string $message
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function typeError($message)
|
||||
{
|
||||
return new self('[Type Error] ' . $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing a constant semantical error.
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param string $context
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function semanticalErrorConstants($identifier, $context = null)
|
||||
{
|
||||
return self::semanticalError(sprintf(
|
||||
"Couldn't find constant %s%s.",
|
||||
$identifier,
|
||||
$context ? ', ' . $context : ''
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing an type error of an attribute.
|
||||
*
|
||||
* @param string $attributeName
|
||||
* @param string $annotationName
|
||||
* @param string $context
|
||||
* @param string $expected
|
||||
* @param mixed $actual
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function attributeTypeError($attributeName, $annotationName, $context, $expected, $actual)
|
||||
{
|
||||
return self::typeError(sprintf(
|
||||
'Attribute "%s" of @%s declared on %s expects %s, but got %s.',
|
||||
$attributeName,
|
||||
$annotationName,
|
||||
$context,
|
||||
$expected,
|
||||
is_object($actual) ? 'an instance of ' . get_class($actual) : gettype($actual)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing an required error of an attribute.
|
||||
*
|
||||
* @param string $attributeName
|
||||
* @param string $annotationName
|
||||
* @param string $context
|
||||
* @param string $expected
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function requiredError($attributeName, $annotationName, $context, $expected)
|
||||
{
|
||||
return self::typeError(sprintf(
|
||||
'Attribute "%s" of @%s declared on %s expects %s. This value should not be null.',
|
||||
$attributeName,
|
||||
$annotationName,
|
||||
$context,
|
||||
$expected
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationException describing a invalid enummerator.
|
||||
*
|
||||
* @param string $attributeName
|
||||
* @param string $annotationName
|
||||
* @param string $context
|
||||
* @param mixed $given
|
||||
* @phpstan-param list<string> $available
|
||||
*
|
||||
* @return AnnotationException
|
||||
*/
|
||||
public static function enumeratorError($attributeName, $annotationName, $context, $available, $given)
|
||||
{
|
||||
return new self(sprintf(
|
||||
'[Enum Error] Attribute "%s" of @%s declared on %s accepts only [%s], but got %s.',
|
||||
$attributeName,
|
||||
$annotationName,
|
||||
$context,
|
||||
implode(', ', $available),
|
||||
is_object($given) ? get_class($given) : $given
|
||||
));
|
||||
}
|
||||
|
||||
/** @return AnnotationException */
|
||||
public static function optimizerPlusSaveComments()
|
||||
{
|
||||
return new self(
|
||||
'You have to enable opcache.save_comments=1 or zend_optimizerplus.save_comments=1.'
|
||||
);
|
||||
}
|
||||
|
||||
/** @return AnnotationException */
|
||||
public static function optimizerPlusLoadComments()
|
||||
{
|
||||
return new self(
|
||||
'You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1.'
|
||||
);
|
||||
}
|
||||
}
|
||||
389
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php
vendored
Normal file
389
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php
vendored
Normal file
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
|
||||
use Doctrine\Common\Annotations\Annotation\Target;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function array_merge;
|
||||
use function class_exists;
|
||||
use function extension_loaded;
|
||||
use function ini_get;
|
||||
|
||||
/**
|
||||
* A reader for docblock annotations.
|
||||
*/
|
||||
class AnnotationReader implements Reader
|
||||
{
|
||||
/**
|
||||
* Global map for imports.
|
||||
*
|
||||
* @var array<string, class-string>
|
||||
*/
|
||||
private static $globalImports = [
|
||||
'ignoreannotation' => Annotation\IgnoreAnnotation::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* A list with annotations that are not causing exceptions when not resolved to an annotation class.
|
||||
*
|
||||
* The names are case sensitive.
|
||||
*
|
||||
* @var array<string, true>
|
||||
*/
|
||||
private static $globalIgnoredNames = ImplicitlyIgnoredAnnotationNames::LIST;
|
||||
|
||||
/**
|
||||
* A list with annotations that are not causing exceptions when not resolved to an annotation class.
|
||||
*
|
||||
* The names are case sensitive.
|
||||
*
|
||||
* @var array<string, true>
|
||||
*/
|
||||
private static $globalIgnoredNamespaces = [];
|
||||
|
||||
/**
|
||||
* Add a new annotation to the globally ignored annotation names with regard to exception handling.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public static function addGlobalIgnoredName($name)
|
||||
{
|
||||
self::$globalIgnoredNames[$name] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new annotation to the globally ignored annotation namespaces with regard to exception handling.
|
||||
*
|
||||
* @param string $namespace
|
||||
*/
|
||||
public static function addGlobalIgnoredNamespace($namespace)
|
||||
{
|
||||
self::$globalIgnoredNamespaces[$namespace] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Annotations parser.
|
||||
*
|
||||
* @var DocParser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* Annotations parser used to collect parsing metadata.
|
||||
*
|
||||
* @var DocParser
|
||||
*/
|
||||
private $preParser;
|
||||
|
||||
/**
|
||||
* PHP parser used to collect imports.
|
||||
*
|
||||
* @var PhpParser
|
||||
*/
|
||||
private $phpParser;
|
||||
|
||||
/**
|
||||
* In-memory cache mechanism to store imported annotations per class.
|
||||
*
|
||||
* @psalm-var array<'class'|'function', array<string, array<string, class-string>>>
|
||||
*/
|
||||
private $imports = [];
|
||||
|
||||
/**
|
||||
* In-memory cache mechanism to store ignored annotations per class.
|
||||
*
|
||||
* @psalm-var array<'class'|'function', array<string, array<string, true>>>
|
||||
*/
|
||||
private $ignoredAnnotationNames = [];
|
||||
|
||||
/**
|
||||
* Initializes a new AnnotationReader.
|
||||
*
|
||||
* @throws AnnotationException
|
||||
*/
|
||||
public function __construct(?DocParser $parser = null)
|
||||
{
|
||||
if (
|
||||
extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === '0' ||
|
||||
ini_get('opcache.save_comments') === '0')
|
||||
) {
|
||||
throw AnnotationException::optimizerPlusSaveComments();
|
||||
}
|
||||
|
||||
if (extension_loaded('Zend OPcache') && ini_get('opcache.save_comments') === 0) {
|
||||
throw AnnotationException::optimizerPlusSaveComments();
|
||||
}
|
||||
|
||||
// Make sure that the IgnoreAnnotation annotation is loaded
|
||||
class_exists(IgnoreAnnotation::class);
|
||||
|
||||
$this->parser = $parser ?: new DocParser();
|
||||
|
||||
$this->preParser = new DocParser();
|
||||
|
||||
$this->preParser->setImports(self::$globalImports);
|
||||
$this->preParser->setIgnoreNotImportedAnnotations(true);
|
||||
$this->preParser->setIgnoredAnnotationNames(self::$globalIgnoredNames);
|
||||
|
||||
$this->phpParser = new PhpParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class)
|
||||
{
|
||||
$this->parser->setTarget(Target::TARGET_CLASS);
|
||||
$this->parser->setImports($this->getImports($class));
|
||||
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
|
||||
$this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);
|
||||
|
||||
return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName)
|
||||
{
|
||||
$annotations = $this->getClassAnnotations($class);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if ($annotation instanceof $annotationName) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property)
|
||||
{
|
||||
$class = $property->getDeclaringClass();
|
||||
$context = 'property ' . $class->getName() . '::$' . $property->getName();
|
||||
|
||||
$this->parser->setTarget(Target::TARGET_PROPERTY);
|
||||
$this->parser->setImports($this->getPropertyImports($property));
|
||||
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
|
||||
$this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);
|
||||
|
||||
return $this->parser->parse($property->getDocComment(), $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
|
||||
{
|
||||
$annotations = $this->getPropertyAnnotations($property);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if ($annotation instanceof $annotationName) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method)
|
||||
{
|
||||
$class = $method->getDeclaringClass();
|
||||
$context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
|
||||
|
||||
$this->parser->setTarget(Target::TARGET_METHOD);
|
||||
$this->parser->setImports($this->getMethodImports($method));
|
||||
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
|
||||
$this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);
|
||||
|
||||
return $this->parser->parse($method->getDocComment(), $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
|
||||
{
|
||||
$annotations = $this->getMethodAnnotations($method);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if ($annotation instanceof $annotationName) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annotations applied to a function.
|
||||
*
|
||||
* @phpstan-return list<object> An array of Annotations.
|
||||
*/
|
||||
public function getFunctionAnnotations(ReflectionFunction $function): array
|
||||
{
|
||||
$context = 'function ' . $function->getName();
|
||||
|
||||
$this->parser->setTarget(Target::TARGET_FUNCTION);
|
||||
$this->parser->setImports($this->getImports($function));
|
||||
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($function));
|
||||
$this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);
|
||||
|
||||
return $this->parser->parse($function->getDocComment(), $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a function annotation.
|
||||
*
|
||||
* @return object|null The Annotation or NULL, if the requested annotation does not exist.
|
||||
*/
|
||||
public function getFunctionAnnotation(ReflectionFunction $function, string $annotationName)
|
||||
{
|
||||
$annotations = $this->getFunctionAnnotations($function);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if ($annotation instanceof $annotationName) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ignored annotations for the given class or function.
|
||||
*
|
||||
* @param ReflectionClass|ReflectionFunction $reflection
|
||||
*
|
||||
* @return array<string, true>
|
||||
*/
|
||||
private function getIgnoredAnnotationNames($reflection): array
|
||||
{
|
||||
$type = $reflection instanceof ReflectionClass ? 'class' : 'function';
|
||||
$name = $reflection->getName();
|
||||
|
||||
if (isset($this->ignoredAnnotationNames[$type][$name])) {
|
||||
return $this->ignoredAnnotationNames[$type][$name];
|
||||
}
|
||||
|
||||
$this->collectParsingMetadata($reflection);
|
||||
|
||||
return $this->ignoredAnnotationNames[$type][$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves imports for a class or a function.
|
||||
*
|
||||
* @param ReflectionClass|ReflectionFunction $reflection
|
||||
*
|
||||
* @return array<string, class-string>
|
||||
*/
|
||||
private function getImports($reflection): array
|
||||
{
|
||||
$type = $reflection instanceof ReflectionClass ? 'class' : 'function';
|
||||
$name = $reflection->getName();
|
||||
|
||||
if (isset($this->imports[$type][$name])) {
|
||||
return $this->imports[$type][$name];
|
||||
}
|
||||
|
||||
$this->collectParsingMetadata($reflection);
|
||||
|
||||
return $this->imports[$type][$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves imports for methods.
|
||||
*
|
||||
* @return array<string, class-string>
|
||||
*/
|
||||
private function getMethodImports(ReflectionMethod $method)
|
||||
{
|
||||
$class = $method->getDeclaringClass();
|
||||
$classImports = $this->getImports($class);
|
||||
|
||||
$traitImports = [];
|
||||
|
||||
foreach ($class->getTraits() as $trait) {
|
||||
if (
|
||||
! $trait->hasMethod($method->getName())
|
||||
|| $trait->getFileName() !== $method->getFileName()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$traitImports = array_merge($traitImports, $this->phpParser->parseUseStatements($trait));
|
||||
}
|
||||
|
||||
return array_merge($classImports, $traitImports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves imports for properties.
|
||||
*
|
||||
* @return array<string, class-string>
|
||||
*/
|
||||
private function getPropertyImports(ReflectionProperty $property)
|
||||
{
|
||||
$class = $property->getDeclaringClass();
|
||||
$classImports = $this->getImports($class);
|
||||
|
||||
$traitImports = [];
|
||||
|
||||
foreach ($class->getTraits() as $trait) {
|
||||
if (! $trait->hasProperty($property->getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$traitImports = array_merge($traitImports, $this->phpParser->parseUseStatements($trait));
|
||||
}
|
||||
|
||||
return array_merge($classImports, $traitImports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects parsing metadata for a given class or function.
|
||||
*
|
||||
* @param ReflectionClass|ReflectionFunction $reflection
|
||||
*/
|
||||
private function collectParsingMetadata($reflection): void
|
||||
{
|
||||
$type = $reflection instanceof ReflectionClass ? 'class' : 'function';
|
||||
$name = $reflection->getName();
|
||||
|
||||
$ignoredAnnotationNames = self::$globalIgnoredNames;
|
||||
$annotations = $this->preParser->parse($reflection->getDocComment(), $type . ' ' . $name);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if (! ($annotation instanceof IgnoreAnnotation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($annotation->names as $annot) {
|
||||
$ignoredAnnotationNames[$annot] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->imports[$type][$name] = array_merge(
|
||||
self::$globalImports,
|
||||
$this->phpParser->parseUseStatements($reflection),
|
||||
[
|
||||
'__NAMESPACE__' => $reflection->getNamespaceName(),
|
||||
'self' => $name,
|
||||
]
|
||||
);
|
||||
|
||||
$this->ignoredAnnotationNames[$type][$name] = $ignoredAnnotationNames;
|
||||
}
|
||||
}
|
||||
190
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php
vendored
Normal file
190
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use function array_key_exists;
|
||||
use function array_merge;
|
||||
use function class_exists;
|
||||
use function in_array;
|
||||
use function is_file;
|
||||
use function str_replace;
|
||||
use function stream_resolve_include_path;
|
||||
use function strpos;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
|
||||
final class AnnotationRegistry
|
||||
{
|
||||
/**
|
||||
* A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
|
||||
*
|
||||
* Contains the namespace as key and an array of directories as value. If the value is NULL
|
||||
* the include path is used for checking for the corresponding file.
|
||||
*
|
||||
* This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
|
||||
*
|
||||
* @var string[][]|string[]|null[]
|
||||
*/
|
||||
private static $autoloadNamespaces = [];
|
||||
|
||||
/**
|
||||
* A map of autoloader callables.
|
||||
*
|
||||
* @var callable[]
|
||||
*/
|
||||
private static $loaders = [];
|
||||
|
||||
/**
|
||||
* An array of classes which cannot be found
|
||||
*
|
||||
* @var null[] indexed by class name
|
||||
*/
|
||||
private static $failedToAutoload = [];
|
||||
|
||||
/**
|
||||
* Whenever registerFile() was used. Disables use of standard autoloader.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $registerFileUsed = false;
|
||||
|
||||
public static function reset(): void
|
||||
{
|
||||
self::$autoloadNamespaces = [];
|
||||
self::$loaders = [];
|
||||
self::$failedToAutoload = [];
|
||||
self::$registerFileUsed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers file.
|
||||
*
|
||||
* @deprecated This method is deprecated and will be removed in
|
||||
* doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
|
||||
*/
|
||||
public static function registerFile(string $file): void
|
||||
{
|
||||
self::$registerFileUsed = true;
|
||||
|
||||
require_once $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a namespace with one or many directories to look for files or null for the include path.
|
||||
*
|
||||
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
|
||||
*
|
||||
* @deprecated This method is deprecated and will be removed in
|
||||
* doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
|
||||
*
|
||||
* @phpstan-param string|list<string>|null $dirs
|
||||
*/
|
||||
public static function registerAutoloadNamespace(string $namespace, $dirs = null): void
|
||||
{
|
||||
self::$autoloadNamespaces[$namespace] = $dirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers multiple namespaces.
|
||||
*
|
||||
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
|
||||
*
|
||||
* @deprecated This method is deprecated and will be removed in
|
||||
* doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
|
||||
*
|
||||
* @param string[][]|string[]|null[] $namespaces indexed by namespace name
|
||||
*/
|
||||
public static function registerAutoloadNamespaces(array $namespaces): void
|
||||
{
|
||||
self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an autoloading callable for annotations, much like spl_autoload_register().
|
||||
*
|
||||
* NOTE: These class loaders HAVE to be silent when a class was not found!
|
||||
* IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
|
||||
*
|
||||
* @deprecated This method is deprecated and will be removed in
|
||||
* doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
|
||||
*/
|
||||
public static function registerLoader(callable $callable): void
|
||||
{
|
||||
// Reset our static cache now that we have a new loader to work with
|
||||
self::$failedToAutoload = [];
|
||||
self::$loaders[] = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an autoloading callable for annotations, if it is not already registered
|
||||
*
|
||||
* @deprecated This method is deprecated and will be removed in
|
||||
* doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
|
||||
*/
|
||||
public static function registerUniqueLoader(callable $callable): void
|
||||
{
|
||||
if (in_array($callable, self::$loaders, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::registerLoader($callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloads an annotation class silently.
|
||||
*/
|
||||
public static function loadAnnotationClass(string $class): bool
|
||||
{
|
||||
if (class_exists($class, false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (array_key_exists($class, self::$failedToAutoload)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (self::$autoloadNamespaces as $namespace => $dirs) {
|
||||
if (strpos($class, $namespace) !== 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
|
||||
|
||||
if ($dirs === null) {
|
||||
$path = stream_resolve_include_path($file);
|
||||
if ($path) {
|
||||
require $path;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
foreach ((array) $dirs as $dir) {
|
||||
if (is_file($dir . DIRECTORY_SEPARATOR . $file)) {
|
||||
require $dir . DIRECTORY_SEPARATOR . $file;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (self::$loaders as $loader) {
|
||||
if ($loader($class) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
self::$loaders === [] &&
|
||||
self::$autoloadNamespaces === [] &&
|
||||
self::$registerFileUsed === false &&
|
||||
class_exists($class)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
self::$failedToAutoload[$class] = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
266
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php
vendored
Normal file
266
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
use function assert;
|
||||
use function filemtime;
|
||||
use function max;
|
||||
use function time;
|
||||
|
||||
/**
|
||||
* A cache aware annotation reader.
|
||||
*
|
||||
* @deprecated the CachedReader is deprecated and will be removed
|
||||
* in version 2.0.0 of doctrine/annotations. Please use the
|
||||
* {@see \Doctrine\Common\Annotations\PsrCachedReader} instead.
|
||||
*/
|
||||
final class CachedReader implements Reader
|
||||
{
|
||||
/** @var Reader */
|
||||
private $delegate;
|
||||
|
||||
/** @var Cache */
|
||||
private $cache;
|
||||
|
||||
/** @var bool */
|
||||
private $debug;
|
||||
|
||||
/** @var array<string, array<object>> */
|
||||
private $loadedAnnotations = [];
|
||||
|
||||
/** @var int[] */
|
||||
private $loadedFilemtimes = [];
|
||||
|
||||
/** @param bool $debug */
|
||||
public function __construct(Reader $reader, Cache $cache, $debug = false)
|
||||
{
|
||||
$this->delegate = $reader;
|
||||
$this->cache = $cache;
|
||||
$this->debug = (bool) $debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class)
|
||||
{
|
||||
$cacheKey = $class->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) {
|
||||
return $this->loadedAnnotations[$cacheKey];
|
||||
}
|
||||
|
||||
$annots = $this->fetchFromCache($cacheKey, $class);
|
||||
if ($annots === false) {
|
||||
$annots = $this->delegate->getClassAnnotations($class);
|
||||
$this->saveToCache($cacheKey, $annots);
|
||||
}
|
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName)
|
||||
{
|
||||
foreach ($this->getClassAnnotations($class) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property)
|
||||
{
|
||||
$class = $property->getDeclaringClass();
|
||||
$cacheKey = $class->getName() . '$' . $property->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) {
|
||||
return $this->loadedAnnotations[$cacheKey];
|
||||
}
|
||||
|
||||
$annots = $this->fetchFromCache($cacheKey, $class);
|
||||
if ($annots === false) {
|
||||
$annots = $this->delegate->getPropertyAnnotations($property);
|
||||
$this->saveToCache($cacheKey, $annots);
|
||||
}
|
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
|
||||
{
|
||||
foreach ($this->getPropertyAnnotations($property) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method)
|
||||
{
|
||||
$class = $method->getDeclaringClass();
|
||||
$cacheKey = $class->getName() . '#' . $method->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) {
|
||||
return $this->loadedAnnotations[$cacheKey];
|
||||
}
|
||||
|
||||
$annots = $this->fetchFromCache($cacheKey, $class);
|
||||
if ($annots === false) {
|
||||
$annots = $this->delegate->getMethodAnnotations($method);
|
||||
$this->saveToCache($cacheKey, $annots);
|
||||
}
|
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
|
||||
{
|
||||
foreach ($this->getMethodAnnotations($method) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears loaded annotations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearLoadedAnnotations()
|
||||
{
|
||||
$this->loadedAnnotations = [];
|
||||
$this->loadedFilemtimes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a value from the cache.
|
||||
*
|
||||
* @param string $cacheKey The cache key.
|
||||
*
|
||||
* @return mixed The cached value or false when the value is not in cache.
|
||||
*/
|
||||
private function fetchFromCache($cacheKey, ReflectionClass $class)
|
||||
{
|
||||
$data = $this->cache->fetch($cacheKey);
|
||||
if ($data !== false) {
|
||||
if (! $this->debug || $this->isCacheFresh($cacheKey, $class)) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a value to the cache.
|
||||
*
|
||||
* @param string $cacheKey The cache key.
|
||||
* @param mixed $value The value.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function saveToCache($cacheKey, $value)
|
||||
{
|
||||
$this->cache->save($cacheKey, $value);
|
||||
if (! $this->debug) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cache->save('[C]' . $cacheKey, time());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the cache is fresh.
|
||||
*
|
||||
* @param string $cacheKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isCacheFresh($cacheKey, ReflectionClass $class)
|
||||
{
|
||||
$lastModification = $this->getLastModification($class);
|
||||
if ($lastModification === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->cache->fetch('[C]' . $cacheKey) >= $lastModification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time the class was last modified, testing traits and parents
|
||||
*/
|
||||
private function getLastModification(ReflectionClass $class): int
|
||||
{
|
||||
$filename = $class->getFileName();
|
||||
|
||||
if (isset($this->loadedFilemtimes[$filename])) {
|
||||
return $this->loadedFilemtimes[$filename];
|
||||
}
|
||||
|
||||
$parent = $class->getParentClass();
|
||||
|
||||
$lastModification = max(array_merge(
|
||||
[$filename ? filemtime($filename) : 0],
|
||||
array_map(function (ReflectionClass $reflectionTrait): int {
|
||||
return $this->getTraitLastModificationTime($reflectionTrait);
|
||||
}, $class->getTraits()),
|
||||
array_map(function (ReflectionClass $class): int {
|
||||
return $this->getLastModification($class);
|
||||
}, $class->getInterfaces()),
|
||||
$parent ? [$this->getLastModification($parent)] : []
|
||||
));
|
||||
|
||||
assert($lastModification !== false);
|
||||
|
||||
return $this->loadedFilemtimes[$filename] = $lastModification;
|
||||
}
|
||||
|
||||
private function getTraitLastModificationTime(ReflectionClass $reflectionTrait): int
|
||||
{
|
||||
$fileName = $reflectionTrait->getFileName();
|
||||
|
||||
if (isset($this->loadedFilemtimes[$fileName])) {
|
||||
return $this->loadedFilemtimes[$fileName];
|
||||
}
|
||||
|
||||
$lastModificationTime = max(array_merge(
|
||||
[$fileName ? filemtime($fileName) : 0],
|
||||
array_map(function (ReflectionClass $reflectionTrait): int {
|
||||
return $this->getTraitLastModificationTime($reflectionTrait);
|
||||
}, $reflectionTrait->getTraits())
|
||||
));
|
||||
|
||||
assert($lastModificationTime !== false);
|
||||
|
||||
return $this->loadedFilemtimes[$fileName] = $lastModificationTime;
|
||||
}
|
||||
}
|
||||
143
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php
vendored
Normal file
143
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Lexer\AbstractLexer;
|
||||
|
||||
use function ctype_alpha;
|
||||
use function is_numeric;
|
||||
use function str_replace;
|
||||
use function stripos;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
* Simple lexer for docblock annotations.
|
||||
*
|
||||
* @template-extends AbstractLexer<DocLexer::T_*, string>
|
||||
*/
|
||||
final class DocLexer extends AbstractLexer
|
||||
{
|
||||
public const T_NONE = 1;
|
||||
public const T_INTEGER = 2;
|
||||
public const T_STRING = 3;
|
||||
public const T_FLOAT = 4;
|
||||
|
||||
// All tokens that are also identifiers should be >= 100
|
||||
public const T_IDENTIFIER = 100;
|
||||
public const T_AT = 101;
|
||||
public const T_CLOSE_CURLY_BRACES = 102;
|
||||
public const T_CLOSE_PARENTHESIS = 103;
|
||||
public const T_COMMA = 104;
|
||||
public const T_EQUALS = 105;
|
||||
public const T_FALSE = 106;
|
||||
public const T_NAMESPACE_SEPARATOR = 107;
|
||||
public const T_OPEN_CURLY_BRACES = 108;
|
||||
public const T_OPEN_PARENTHESIS = 109;
|
||||
public const T_TRUE = 110;
|
||||
public const T_NULL = 111;
|
||||
public const T_COLON = 112;
|
||||
public const T_MINUS = 113;
|
||||
|
||||
/** @var array<string, self::T*> */
|
||||
protected $noCase = [
|
||||
'@' => self::T_AT,
|
||||
',' => self::T_COMMA,
|
||||
'(' => self::T_OPEN_PARENTHESIS,
|
||||
')' => self::T_CLOSE_PARENTHESIS,
|
||||
'{' => self::T_OPEN_CURLY_BRACES,
|
||||
'}' => self::T_CLOSE_CURLY_BRACES,
|
||||
'=' => self::T_EQUALS,
|
||||
':' => self::T_COLON,
|
||||
'-' => self::T_MINUS,
|
||||
'\\' => self::T_NAMESPACE_SEPARATOR,
|
||||
];
|
||||
|
||||
/** @var array<string, self::T*> */
|
||||
protected $withCase = [
|
||||
'true' => self::T_TRUE,
|
||||
'false' => self::T_FALSE,
|
||||
'null' => self::T_NULL,
|
||||
];
|
||||
|
||||
/**
|
||||
* Whether the next token starts immediately, or if there were
|
||||
* non-captured symbols before that
|
||||
*/
|
||||
public function nextTokenIsAdjacent(): bool
|
||||
{
|
||||
return $this->token === null
|
||||
|| ($this->lookahead !== null
|
||||
&& ($this->lookahead['position'] - $this->token['position']) === strlen($this->token['value']));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getCatchablePatterns()
|
||||
{
|
||||
return [
|
||||
'[a-z_\\\][a-z0-9_\:\\\]*[a-z_][a-z0-9_]*',
|
||||
'(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?',
|
||||
'"(?:""|[^"])*+"',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNonCatchablePatterns()
|
||||
{
|
||||
return ['\s+', '\*+', '(.)'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getType(&$value)
|
||||
{
|
||||
$type = self::T_NONE;
|
||||
|
||||
if ($value[0] === '"') {
|
||||
$value = str_replace('""', '"', substr($value, 1, strlen($value) - 2));
|
||||
|
||||
return self::T_STRING;
|
||||
}
|
||||
|
||||
if (isset($this->noCase[$value])) {
|
||||
return $this->noCase[$value];
|
||||
}
|
||||
|
||||
if ($value[0] === '_' || $value[0] === '\\' || ctype_alpha($value[0])) {
|
||||
return self::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
$lowerValue = strtolower($value);
|
||||
|
||||
if (isset($this->withCase[$lowerValue])) {
|
||||
return $this->withCase[$lowerValue];
|
||||
}
|
||||
|
||||
// Checking numeric value
|
||||
if (is_numeric($value)) {
|
||||
return strpos($value, '.') !== false || stripos($value, 'e') !== false
|
||||
? self::T_FLOAT : self::T_INTEGER;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/** @return array{value: int|string, type:self::T_*|null, position:int} */
|
||||
public function peek(): ?array
|
||||
{
|
||||
$token = parent::peek();
|
||||
|
||||
if ($token === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (array) $token;
|
||||
}
|
||||
}
|
||||
1506
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
vendored
Normal file
1506
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
315
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php
vendored
Normal file
315
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
use RuntimeException;
|
||||
|
||||
use function chmod;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function gettype;
|
||||
use function is_dir;
|
||||
use function is_file;
|
||||
use function is_int;
|
||||
use function is_writable;
|
||||
use function mkdir;
|
||||
use function rename;
|
||||
use function rtrim;
|
||||
use function serialize;
|
||||
use function sha1;
|
||||
use function sprintf;
|
||||
use function strtr;
|
||||
use function tempnam;
|
||||
use function uniqid;
|
||||
use function unlink;
|
||||
use function var_export;
|
||||
|
||||
/**
|
||||
* File cache reader for annotations.
|
||||
*
|
||||
* @deprecated the FileCacheReader is deprecated and will be removed
|
||||
* in version 2.0.0 of doctrine/annotations. Please use the
|
||||
* {@see \Doctrine\Common\Annotations\PsrCachedReader} instead.
|
||||
*/
|
||||
class FileCacheReader implements Reader
|
||||
{
|
||||
/** @var Reader */
|
||||
private $reader;
|
||||
|
||||
/** @var string */
|
||||
private $dir;
|
||||
|
||||
/** @var bool */
|
||||
private $debug;
|
||||
|
||||
/** @phpstan-var array<string, list<object>> */
|
||||
private $loadedAnnotations = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
private $classNameHashes = [];
|
||||
|
||||
/** @var int */
|
||||
private $umask;
|
||||
|
||||
/**
|
||||
* @param string $cacheDir
|
||||
* @param bool $debug
|
||||
* @param int $umask
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(Reader $reader, $cacheDir, $debug = false, $umask = 0002)
|
||||
{
|
||||
if (! is_int($umask)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The parameter umask must be an integer, was: %s',
|
||||
gettype($umask)
|
||||
));
|
||||
}
|
||||
|
||||
$this->reader = $reader;
|
||||
$this->umask = $umask;
|
||||
|
||||
if (! is_dir($cacheDir) && ! @mkdir($cacheDir, 0777 & (~$this->umask), true)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The directory "%s" does not exist and could not be created.',
|
||||
$cacheDir
|
||||
));
|
||||
}
|
||||
|
||||
$this->dir = rtrim($cacheDir, '\\/');
|
||||
$this->debug = $debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class)
|
||||
{
|
||||
if (! isset($this->classNameHashes[$class->name])) {
|
||||
$this->classNameHashes[$class->name] = sha1($class->name);
|
||||
}
|
||||
|
||||
$key = $this->classNameHashes[$class->name];
|
||||
|
||||
if (isset($this->loadedAnnotations[$key])) {
|
||||
return $this->loadedAnnotations[$key];
|
||||
}
|
||||
|
||||
$path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php';
|
||||
if (! is_file($path)) {
|
||||
$annot = $this->reader->getClassAnnotations($class);
|
||||
$this->saveCacheFile($path, $annot);
|
||||
|
||||
return $this->loadedAnnotations[$key] = $annot;
|
||||
}
|
||||
|
||||
$filename = $class->getFilename();
|
||||
if (
|
||||
$this->debug
|
||||
&& $filename !== false
|
||||
&& filemtime($path) < filemtime($filename)
|
||||
) {
|
||||
@unlink($path);
|
||||
|
||||
$annot = $this->reader->getClassAnnotations($class);
|
||||
$this->saveCacheFile($path, $annot);
|
||||
|
||||
return $this->loadedAnnotations[$key] = $annot;
|
||||
}
|
||||
|
||||
return $this->loadedAnnotations[$key] = include $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property)
|
||||
{
|
||||
$class = $property->getDeclaringClass();
|
||||
if (! isset($this->classNameHashes[$class->name])) {
|
||||
$this->classNameHashes[$class->name] = sha1($class->name);
|
||||
}
|
||||
|
||||
$key = $this->classNameHashes[$class->name] . '$' . $property->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$key])) {
|
||||
return $this->loadedAnnotations[$key];
|
||||
}
|
||||
|
||||
$path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php';
|
||||
if (! is_file($path)) {
|
||||
$annot = $this->reader->getPropertyAnnotations($property);
|
||||
$this->saveCacheFile($path, $annot);
|
||||
|
||||
return $this->loadedAnnotations[$key] = $annot;
|
||||
}
|
||||
|
||||
$filename = $class->getFilename();
|
||||
if (
|
||||
$this->debug
|
||||
&& $filename !== false
|
||||
&& filemtime($path) < filemtime($filename)
|
||||
) {
|
||||
@unlink($path);
|
||||
|
||||
$annot = $this->reader->getPropertyAnnotations($property);
|
||||
$this->saveCacheFile($path, $annot);
|
||||
|
||||
return $this->loadedAnnotations[$key] = $annot;
|
||||
}
|
||||
|
||||
return $this->loadedAnnotations[$key] = include $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method)
|
||||
{
|
||||
$class = $method->getDeclaringClass();
|
||||
if (! isset($this->classNameHashes[$class->name])) {
|
||||
$this->classNameHashes[$class->name] = sha1($class->name);
|
||||
}
|
||||
|
||||
$key = $this->classNameHashes[$class->name] . '#' . $method->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$key])) {
|
||||
return $this->loadedAnnotations[$key];
|
||||
}
|
||||
|
||||
$path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php';
|
||||
if (! is_file($path)) {
|
||||
$annot = $this->reader->getMethodAnnotations($method);
|
||||
$this->saveCacheFile($path, $annot);
|
||||
|
||||
return $this->loadedAnnotations[$key] = $annot;
|
||||
}
|
||||
|
||||
$filename = $class->getFilename();
|
||||
if (
|
||||
$this->debug
|
||||
&& $filename !== false
|
||||
&& filemtime($path) < filemtime($filename)
|
||||
) {
|
||||
@unlink($path);
|
||||
|
||||
$annot = $this->reader->getMethodAnnotations($method);
|
||||
$this->saveCacheFile($path, $annot);
|
||||
|
||||
return $this->loadedAnnotations[$key] = $annot;
|
||||
}
|
||||
|
||||
return $this->loadedAnnotations[$key] = include $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the cache file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function saveCacheFile($path, $data)
|
||||
{
|
||||
if (! is_writable($this->dir)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
<<<'EXCEPTION'
|
||||
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.,
|
||||
EXCEPTION
|
||||
,
|
||||
$this->dir
|
||||
));
|
||||
}
|
||||
|
||||
$tempfile = tempnam($this->dir, uniqid('', true));
|
||||
|
||||
if ($tempfile === false) {
|
||||
throw new RuntimeException(sprintf('Unable to create tempfile in directory: %s', $this->dir));
|
||||
}
|
||||
|
||||
@chmod($tempfile, 0666 & (~$this->umask));
|
||||
|
||||
$written = file_put_contents(
|
||||
$tempfile,
|
||||
'<?php return unserialize(' . var_export(serialize($data), true) . ');'
|
||||
);
|
||||
|
||||
if ($written === false) {
|
||||
throw new RuntimeException(sprintf('Unable to write cached file to: %s', $tempfile));
|
||||
}
|
||||
|
||||
@chmod($tempfile, 0666 & (~$this->umask));
|
||||
|
||||
if (rename($tempfile, $path) === false) {
|
||||
@unlink($tempfile);
|
||||
|
||||
throw new RuntimeException(sprintf('Unable to rename %s to %s', $tempfile, $path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName)
|
||||
{
|
||||
$annotations = $this->getClassAnnotations($class);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if ($annotation instanceof $annotationName) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
|
||||
{
|
||||
$annotations = $this->getMethodAnnotations($method);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if ($annotation instanceof $annotationName) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
|
||||
{
|
||||
$annotations = $this->getPropertyAnnotations($property);
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
if ($annotation instanceof $annotationName) {
|
||||
return $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears loaded annotations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearLoadedAnnotations()
|
||||
{
|
||||
$this->loadedAnnotations = [];
|
||||
}
|
||||
}
|
||||
178
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/ImplicitlyIgnoredAnnotationNames.php
vendored
Normal file
178
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/ImplicitlyIgnoredAnnotationNames.php
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
/**
|
||||
* A list of annotations that are implicitly ignored during the parsing process.
|
||||
*
|
||||
* All names are case sensitive.
|
||||
*/
|
||||
final class ImplicitlyIgnoredAnnotationNames
|
||||
{
|
||||
private const Reserved = [
|
||||
'Annotation' => true,
|
||||
'Attribute' => true,
|
||||
'Attributes' => true,
|
||||
/* Can we enable this? 'Enum' => true, */
|
||||
'Required' => true,
|
||||
'Target' => true,
|
||||
'NamedArgumentConstructor' => true,
|
||||
];
|
||||
|
||||
private const WidelyUsedNonStandard = [
|
||||
'fix' => true,
|
||||
'fixme' => true,
|
||||
'override' => true,
|
||||
];
|
||||
|
||||
private const PhpDocumentor1 = [
|
||||
'abstract' => true,
|
||||
'access' => true,
|
||||
'code' => true,
|
||||
'deprec' => true,
|
||||
'endcode' => true,
|
||||
'exception' => true,
|
||||
'final' => true,
|
||||
'ingroup' => true,
|
||||
'inheritdoc' => true,
|
||||
'inheritDoc' => true,
|
||||
'magic' => true,
|
||||
'name' => true,
|
||||
'private' => true,
|
||||
'static' => true,
|
||||
'staticvar' => true,
|
||||
'staticVar' => true,
|
||||
'toc' => true,
|
||||
'tutorial' => true,
|
||||
'throw' => true,
|
||||
];
|
||||
|
||||
private const PhpDocumentor2 = [
|
||||
'api' => true,
|
||||
'author' => true,
|
||||
'category' => true,
|
||||
'copyright' => true,
|
||||
'deprecated' => true,
|
||||
'example' => true,
|
||||
'filesource' => true,
|
||||
'global' => true,
|
||||
'ignore' => true,
|
||||
/* Can we enable this? 'index' => true, */
|
||||
'internal' => true,
|
||||
'license' => true,
|
||||
'link' => true,
|
||||
'method' => true,
|
||||
'package' => true,
|
||||
'param' => true,
|
||||
'property' => true,
|
||||
'property-read' => true,
|
||||
'property-write' => true,
|
||||
'return' => true,
|
||||
'see' => true,
|
||||
'since' => true,
|
||||
'source' => true,
|
||||
'subpackage' => true,
|
||||
'throws' => true,
|
||||
'todo' => true,
|
||||
'TODO' => true,
|
||||
'usedby' => true,
|
||||
'uses' => true,
|
||||
'var' => true,
|
||||
'version' => true,
|
||||
];
|
||||
|
||||
private const PHPUnit = [
|
||||
'author' => true,
|
||||
'after' => true,
|
||||
'afterClass' => true,
|
||||
'backupGlobals' => true,
|
||||
'backupStaticAttributes' => true,
|
||||
'before' => true,
|
||||
'beforeClass' => true,
|
||||
'codeCoverageIgnore' => true,
|
||||
'codeCoverageIgnoreStart' => true,
|
||||
'codeCoverageIgnoreEnd' => true,
|
||||
'covers' => true,
|
||||
'coversDefaultClass' => true,
|
||||
'coversNothing' => true,
|
||||
'dataProvider' => true,
|
||||
'depends' => true,
|
||||
'doesNotPerformAssertions' => true,
|
||||
'expectedException' => true,
|
||||
'expectedExceptionCode' => true,
|
||||
'expectedExceptionMessage' => true,
|
||||
'expectedExceptionMessageRegExp' => true,
|
||||
'group' => true,
|
||||
'large' => true,
|
||||
'medium' => true,
|
||||
'preserveGlobalState' => true,
|
||||
'requires' => true,
|
||||
'runTestsInSeparateProcesses' => true,
|
||||
'runInSeparateProcess' => true,
|
||||
'small' => true,
|
||||
'test' => true,
|
||||
'testdox' => true,
|
||||
'testWith' => true,
|
||||
'ticket' => true,
|
||||
'uses' => true,
|
||||
];
|
||||
|
||||
private const PhpCheckStyle = ['SuppressWarnings' => true];
|
||||
|
||||
private const PhpStorm = ['noinspection' => true];
|
||||
|
||||
private const PEAR = ['package_version' => true];
|
||||
|
||||
private const PlainUML = [
|
||||
'startuml' => true,
|
||||
'enduml' => true,
|
||||
];
|
||||
|
||||
private const Symfony = ['experimental' => true];
|
||||
|
||||
private const PhpCodeSniffer = [
|
||||
'codingStandardsIgnoreStart' => true,
|
||||
'codingStandardsIgnoreEnd' => true,
|
||||
];
|
||||
|
||||
private const SlevomatCodingStandard = ['phpcsSuppress' => true];
|
||||
|
||||
private const Phan = ['suppress' => true];
|
||||
|
||||
private const Rector = ['noRector' => true];
|
||||
|
||||
private const StaticAnalysis = [
|
||||
// PHPStan, Psalm
|
||||
'extends' => true,
|
||||
'implements' => true,
|
||||
'readonly' => true,
|
||||
'template' => true,
|
||||
'use' => true,
|
||||
|
||||
// Psalm
|
||||
'pure' => true,
|
||||
'immutable' => true,
|
||||
];
|
||||
|
||||
public const LIST = self::Reserved
|
||||
+ self::WidelyUsedNonStandard
|
||||
+ self::PhpDocumentor1
|
||||
+ self::PhpDocumentor2
|
||||
+ self::PHPUnit
|
||||
+ self::PhpCheckStyle
|
||||
+ self::PhpStorm
|
||||
+ self::PEAR
|
||||
+ self::PlainUML
|
||||
+ self::Symfony
|
||||
+ self::SlevomatCodingStandard
|
||||
+ self::PhpCodeSniffer
|
||||
+ self::Phan
|
||||
+ self::Rector
|
||||
+ self::StaticAnalysis;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
100
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php
vendored
Normal file
100
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function call_user_func_array;
|
||||
use function get_class;
|
||||
|
||||
/**
|
||||
* Allows the reader to be used in-place of Doctrine's reader.
|
||||
*/
|
||||
class IndexedReader implements Reader
|
||||
{
|
||||
/** @var Reader */
|
||||
private $delegate;
|
||||
|
||||
public function __construct(Reader $reader)
|
||||
{
|
||||
$this->delegate = $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class)
|
||||
{
|
||||
$annotations = [];
|
||||
foreach ($this->delegate->getClassAnnotations($class) as $annot) {
|
||||
$annotations[get_class($annot)] = $annot;
|
||||
}
|
||||
|
||||
return $annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName)
|
||||
{
|
||||
return $this->delegate->getClassAnnotation($class, $annotationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method)
|
||||
{
|
||||
$annotations = [];
|
||||
foreach ($this->delegate->getMethodAnnotations($method) as $annot) {
|
||||
$annotations[get_class($annot)] = $annot;
|
||||
}
|
||||
|
||||
return $annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
|
||||
{
|
||||
return $this->delegate->getMethodAnnotation($method, $annotationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property)
|
||||
{
|
||||
$annotations = [];
|
||||
foreach ($this->delegate->getPropertyAnnotations($property) as $annot) {
|
||||
$annotations[get_class($annot)] = $annot;
|
||||
}
|
||||
|
||||
return $annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
|
||||
{
|
||||
return $this->delegate->getPropertyAnnotation($property, $annotationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxies all methods to the delegate.
|
||||
*
|
||||
* @param string $method
|
||||
* @param mixed[] $args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
return call_user_func_array([$this->delegate, $method], $args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
/**
|
||||
* Marker interface for PHP7/PHP8 compatible support
|
||||
* for named arguments (and constructor property promotion).
|
||||
*
|
||||
* @deprecated Implementing this interface is deprecated
|
||||
* Use the Annotation @NamedArgumentConstructor instead
|
||||
*/
|
||||
interface NamedArgumentConstructorAnnotation
|
||||
{
|
||||
}
|
||||
92
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PhpParser.php
vendored
Normal file
92
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PhpParser.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use SplFileObject;
|
||||
|
||||
use function is_file;
|
||||
use function method_exists;
|
||||
use function preg_quote;
|
||||
use function preg_replace;
|
||||
|
||||
/**
|
||||
* Parses a file for namespaces/use/class declarations.
|
||||
*/
|
||||
final class PhpParser
|
||||
{
|
||||
/**
|
||||
* Parses a class.
|
||||
*
|
||||
* @deprecated use parseUseStatements instead
|
||||
*
|
||||
* @param ReflectionClass $class A <code>ReflectionClass</code> object.
|
||||
*
|
||||
* @return array<string, class-string> A list with use statements in the form (Alias => FQN).
|
||||
*/
|
||||
public function parseClass(ReflectionClass $class)
|
||||
{
|
||||
return $this->parseUseStatements($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a class or function for use statements.
|
||||
*
|
||||
* @param ReflectionClass|ReflectionFunction $reflection
|
||||
*
|
||||
* @psalm-return array<string, string> a list with use statements in the form (Alias => FQN).
|
||||
*/
|
||||
public function parseUseStatements($reflection): array
|
||||
{
|
||||
if (method_exists($reflection, 'getUseStatements')) {
|
||||
return $reflection->getUseStatements();
|
||||
}
|
||||
|
||||
$filename = $reflection->getFileName();
|
||||
|
||||
if ($filename === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$content = $this->getFileContent($filename, $reflection->getStartLine());
|
||||
|
||||
if ($content === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$namespace = preg_quote($reflection->getNamespaceName());
|
||||
$content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
|
||||
$tokenizer = new TokenParser('<?php ' . $content);
|
||||
|
||||
return $tokenizer->parseUseStatements($reflection->getNamespaceName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets 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|null The content of the file or null if the file does not exist.
|
||||
*/
|
||||
private function getFileContent($filename, $lineNumber)
|
||||
{
|
||||
if (! is_file($filename)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$lineCnt = 0;
|
||||
$file = new SplFileObject($filename);
|
||||
while (! $file->eof()) {
|
||||
if ($lineCnt++ === $lineNumber) {
|
||||
break;
|
||||
}
|
||||
|
||||
$content .= $file->fgets();
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
232
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php
vendored
Normal file
232
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
use Reflector;
|
||||
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
use function assert;
|
||||
use function filemtime;
|
||||
use function max;
|
||||
use function rawurlencode;
|
||||
use function time;
|
||||
|
||||
/**
|
||||
* A cache aware annotation reader.
|
||||
*/
|
||||
final class PsrCachedReader implements Reader
|
||||
{
|
||||
/** @var Reader */
|
||||
private $delegate;
|
||||
|
||||
/** @var CacheItemPoolInterface */
|
||||
private $cache;
|
||||
|
||||
/** @var bool */
|
||||
private $debug;
|
||||
|
||||
/** @var array<string, array<object>> */
|
||||
private $loadedAnnotations = [];
|
||||
|
||||
/** @var int[] */
|
||||
private $loadedFilemtimes = [];
|
||||
|
||||
public function __construct(Reader $reader, CacheItemPoolInterface $cache, bool $debug = false)
|
||||
{
|
||||
$this->delegate = $reader;
|
||||
$this->cache = $cache;
|
||||
$this->debug = (bool) $debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class)
|
||||
{
|
||||
$cacheKey = $class->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) {
|
||||
return $this->loadedAnnotations[$cacheKey];
|
||||
}
|
||||
|
||||
$annots = $this->fetchFromCache($cacheKey, $class, 'getClassAnnotations', $class);
|
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName)
|
||||
{
|
||||
foreach ($this->getClassAnnotations($class) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property)
|
||||
{
|
||||
$class = $property->getDeclaringClass();
|
||||
$cacheKey = $class->getName() . '$' . $property->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) {
|
||||
return $this->loadedAnnotations[$cacheKey];
|
||||
}
|
||||
|
||||
$annots = $this->fetchFromCache($cacheKey, $class, 'getPropertyAnnotations', $property);
|
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
|
||||
{
|
||||
foreach ($this->getPropertyAnnotations($property) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method)
|
||||
{
|
||||
$class = $method->getDeclaringClass();
|
||||
$cacheKey = $class->getName() . '#' . $method->getName();
|
||||
|
||||
if (isset($this->loadedAnnotations[$cacheKey])) {
|
||||
return $this->loadedAnnotations[$cacheKey];
|
||||
}
|
||||
|
||||
$annots = $this->fetchFromCache($cacheKey, $class, 'getMethodAnnotations', $method);
|
||||
|
||||
return $this->loadedAnnotations[$cacheKey] = $annots;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
|
||||
{
|
||||
foreach ($this->getMethodAnnotations($method) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function clearLoadedAnnotations(): void
|
||||
{
|
||||
$this->loadedAnnotations = [];
|
||||
$this->loadedFilemtimes = [];
|
||||
}
|
||||
|
||||
/** @return mixed[] */
|
||||
private function fetchFromCache(
|
||||
string $cacheKey,
|
||||
ReflectionClass $class,
|
||||
string $method,
|
||||
Reflector $reflector
|
||||
): array {
|
||||
$cacheKey = rawurlencode($cacheKey);
|
||||
|
||||
$item = $this->cache->getItem($cacheKey);
|
||||
if (($this->debug && ! $this->refresh($cacheKey, $class)) || ! $item->isHit()) {
|
||||
$this->cache->save($item->set($this->delegate->{$method}($reflector)));
|
||||
}
|
||||
|
||||
return $item->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in debug mode to check if the cache is fresh.
|
||||
*
|
||||
* @return bool Returns true if the cache was fresh, or false if the class
|
||||
* being read was modified since writing to the cache.
|
||||
*/
|
||||
private function refresh(string $cacheKey, ReflectionClass $class): bool
|
||||
{
|
||||
$lastModification = $this->getLastModification($class);
|
||||
if ($lastModification === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$item = $this->cache->getItem('[C]' . $cacheKey);
|
||||
if ($item->isHit() && $item->get() >= $lastModification) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->cache->save($item->set(time()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time the class was last modified, testing traits and parents
|
||||
*/
|
||||
private function getLastModification(ReflectionClass $class): int
|
||||
{
|
||||
$filename = $class->getFileName();
|
||||
|
||||
if (isset($this->loadedFilemtimes[$filename])) {
|
||||
return $this->loadedFilemtimes[$filename];
|
||||
}
|
||||
|
||||
$parent = $class->getParentClass();
|
||||
|
||||
$lastModification = max(array_merge(
|
||||
[$filename ? filemtime($filename) : 0],
|
||||
array_map(function (ReflectionClass $reflectionTrait): int {
|
||||
return $this->getTraitLastModificationTime($reflectionTrait);
|
||||
}, $class->getTraits()),
|
||||
array_map(function (ReflectionClass $class): int {
|
||||
return $this->getLastModification($class);
|
||||
}, $class->getInterfaces()),
|
||||
$parent ? [$this->getLastModification($parent)] : []
|
||||
));
|
||||
|
||||
assert($lastModification !== false);
|
||||
|
||||
return $this->loadedFilemtimes[$filename] = $lastModification;
|
||||
}
|
||||
|
||||
private function getTraitLastModificationTime(ReflectionClass $reflectionTrait): int
|
||||
{
|
||||
$fileName = $reflectionTrait->getFileName();
|
||||
|
||||
if (isset($this->loadedFilemtimes[$fileName])) {
|
||||
return $this->loadedFilemtimes[$fileName];
|
||||
}
|
||||
|
||||
$lastModificationTime = max(array_merge(
|
||||
[$fileName ? filemtime($fileName) : 0],
|
||||
array_map(function (ReflectionClass $reflectionTrait): int {
|
||||
return $this->getTraitLastModificationTime($reflectionTrait);
|
||||
}, $reflectionTrait->getTraits())
|
||||
));
|
||||
|
||||
assert($lastModificationTime !== false);
|
||||
|
||||
return $this->loadedFilemtimes[$fileName] = $lastModificationTime;
|
||||
}
|
||||
}
|
||||
80
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php
vendored
Normal file
80
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Interface for annotation readers.
|
||||
*/
|
||||
interface Reader
|
||||
{
|
||||
/**
|
||||
* Gets the annotations applied to a class.
|
||||
*
|
||||
* @param ReflectionClass $class The ReflectionClass of the class from which
|
||||
* the class annotations should be read.
|
||||
*
|
||||
* @return array<object> An array of Annotations.
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class);
|
||||
|
||||
/**
|
||||
* Gets a class annotation.
|
||||
*
|
||||
* @param ReflectionClass $class The ReflectionClass of the class from which
|
||||
* the class annotations should be read.
|
||||
* @param class-string<T> $annotationName The name of the annotation.
|
||||
*
|
||||
* @return T|null The Annotation or NULL, if the requested annotation does not exist.
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName);
|
||||
|
||||
/**
|
||||
* Gets the annotations applied to a method.
|
||||
*
|
||||
* @param ReflectionMethod $method The ReflectionMethod of the method from which
|
||||
* the annotations should be read.
|
||||
*
|
||||
* @return array<object> An array of Annotations.
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method);
|
||||
|
||||
/**
|
||||
* Gets a method annotation.
|
||||
*
|
||||
* @param ReflectionMethod $method The ReflectionMethod to read the annotations from.
|
||||
* @param class-string<T> $annotationName The name of the annotation.
|
||||
*
|
||||
* @return T|null The Annotation or NULL, if the requested annotation does not exist.
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName);
|
||||
|
||||
/**
|
||||
* Gets the annotations applied to a property.
|
||||
*
|
||||
* @param ReflectionProperty $property The ReflectionProperty of the property
|
||||
* from which the annotations should be read.
|
||||
*
|
||||
* @return array<object> An array of Annotations.
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property);
|
||||
|
||||
/**
|
||||
* Gets a property annotation.
|
||||
*
|
||||
* @param ReflectionProperty $property The ReflectionProperty to read the annotations from.
|
||||
* @param class-string<T> $annotationName The name of the annotation.
|
||||
*
|
||||
* @return T|null The Annotation or NULL, if the requested annotation does not exist.
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName);
|
||||
}
|
||||
114
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php
vendored
Normal file
114
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Simple Annotation Reader.
|
||||
*
|
||||
* This annotation reader is intended to be used in projects where you have
|
||||
* full-control over all annotations that are available.
|
||||
*
|
||||
* @deprecated Deprecated in favour of using AnnotationReader
|
||||
*/
|
||||
class SimpleAnnotationReader implements Reader
|
||||
{
|
||||
/** @var DocParser */
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* Initializes a new SimpleAnnotationReader.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->parser = new DocParser();
|
||||
$this->parser->setIgnoreNotImportedAnnotations(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a namespace in which we will look for annotations.
|
||||
*
|
||||
* @param string $namespace
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addNamespace($namespace)
|
||||
{
|
||||
$this->parser->addNamespace($namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotations(ReflectionClass $class)
|
||||
{
|
||||
return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotations(ReflectionMethod $method)
|
||||
{
|
||||
return $this->parser->parse(
|
||||
$method->getDocComment(),
|
||||
'method ' . $method->getDeclaringClass()->name . '::' . $method->getName() . '()'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotations(ReflectionProperty $property)
|
||||
{
|
||||
return $this->parser->parse(
|
||||
$property->getDocComment(),
|
||||
'property ' . $property->getDeclaringClass()->name . '::$' . $property->getName()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassAnnotation(ReflectionClass $class, $annotationName)
|
||||
{
|
||||
foreach ($this->getClassAnnotations($class) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
|
||||
{
|
||||
foreach ($this->getMethodAnnotations($method) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
|
||||
{
|
||||
foreach ($this->getPropertyAnnotations($property) as $annot) {
|
||||
if ($annot instanceof $annotationName) {
|
||||
return $annot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
206
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php
vendored
Normal file
206
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Common\Annotations;
|
||||
|
||||
use function array_merge;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function strtolower;
|
||||
use function token_get_all;
|
||||
|
||||
use const PHP_VERSION_ID;
|
||||
use const T_AS;
|
||||
use const T_COMMENT;
|
||||
use const T_DOC_COMMENT;
|
||||
use const T_NAME_FULLY_QUALIFIED;
|
||||
use const T_NAME_QUALIFIED;
|
||||
use const T_NAMESPACE;
|
||||
use const T_NS_SEPARATOR;
|
||||
use const T_STRING;
|
||||
use const T_USE;
|
||||
use const T_WHITESPACE;
|
||||
|
||||
/**
|
||||
* Parses a file for namespaces/use/class declarations.
|
||||
*/
|
||||
class TokenParser
|
||||
{
|
||||
/**
|
||||
* The token list.
|
||||
*
|
||||
* @phpstan-var list<mixed[]>
|
||||
*/
|
||||
private $tokens;
|
||||
|
||||
/**
|
||||
* The number of tokens.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $numTokens;
|
||||
|
||||
/**
|
||||
* The current array pointer.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $pointer = 0;
|
||||
|
||||
/** @param string $contents */
|
||||
public function __construct($contents)
|
||||
{
|
||||
$this->tokens = token_get_all($contents);
|
||||
|
||||
// The PHP parser sets internal compiler globals for certain things. Annoyingly, the last docblock comment it
|
||||
// saw gets stored in doc_comment. When it comes to compile the next thing to be include()d this stored
|
||||
// doc_comment becomes owned by the first thing the compiler sees in the file that it considers might have a
|
||||
// docblock. If the first thing in the file is a class without a doc block this would cause calls to
|
||||
// getDocBlock() on said class to return our long lost doc_comment. Argh.
|
||||
// To workaround, cause the parser to parse an empty docblock. Sure getDocBlock() will return this, but at least
|
||||
// it's harmless to us.
|
||||
token_get_all("<?php\n/**\n *\n */");
|
||||
|
||||
$this->numTokens = count($this->tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next non whitespace and non comment token.
|
||||
*
|
||||
* @param bool $docCommentIsComment If TRUE then a doc comment is considered a comment and skipped.
|
||||
* If FALSE then only whitespace and normal comments are skipped.
|
||||
*
|
||||
* @return mixed[]|string|null The token if exists, null otherwise.
|
||||
*/
|
||||
public function next($docCommentIsComment = true)
|
||||
{
|
||||
for ($i = $this->pointer; $i < $this->numTokens; $i++) {
|
||||
$this->pointer++;
|
||||
if (
|
||||
$this->tokens[$i][0] === T_WHITESPACE ||
|
||||
$this->tokens[$i][0] === T_COMMENT ||
|
||||
($docCommentIsComment && $this->tokens[$i][0] === T_DOC_COMMENT)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->tokens[$i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a single use statement.
|
||||
*
|
||||
* @return array<string, string> A list with all found class names for a use statement.
|
||||
*/
|
||||
public function parseUseStatement()
|
||||
{
|
||||
$groupRoot = '';
|
||||
$class = '';
|
||||
$alias = '';
|
||||
$statements = [];
|
||||
$explicitAlias = false;
|
||||
while (($token = $this->next())) {
|
||||
if (! $explicitAlias && $token[0] === T_STRING) {
|
||||
$class .= $token[1];
|
||||
$alias = $token[1];
|
||||
} elseif ($explicitAlias && $token[0] === T_STRING) {
|
||||
$alias = $token[1];
|
||||
} elseif (
|
||||
PHP_VERSION_ID >= 80000 &&
|
||||
($token[0] === T_NAME_QUALIFIED || $token[0] === T_NAME_FULLY_QUALIFIED)
|
||||
) {
|
||||
$class .= $token[1];
|
||||
|
||||
$classSplit = explode('\\', $token[1]);
|
||||
$alias = $classSplit[count($classSplit) - 1];
|
||||
} elseif ($token[0] === T_NS_SEPARATOR) {
|
||||
$class .= '\\';
|
||||
$alias = '';
|
||||
} elseif ($token[0] === T_AS) {
|
||||
$explicitAlias = true;
|
||||
$alias = '';
|
||||
} elseif ($token === ',') {
|
||||
$statements[strtolower($alias)] = $groupRoot . $class;
|
||||
$class = '';
|
||||
$alias = '';
|
||||
$explicitAlias = false;
|
||||
} elseif ($token === ';') {
|
||||
$statements[strtolower($alias)] = $groupRoot . $class;
|
||||
break;
|
||||
} elseif ($token === '{') {
|
||||
$groupRoot = $class;
|
||||
$class = '';
|
||||
} elseif ($token === '}') {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all use statements.
|
||||
*
|
||||
* @param string $namespaceName The namespace name of the reflected class.
|
||||
*
|
||||
* @return array<string, string> A list with all found use statements.
|
||||
*/
|
||||
public function parseUseStatements($namespaceName)
|
||||
{
|
||||
$statements = [];
|
||||
while (($token = $this->next())) {
|
||||
if ($token[0] === T_USE) {
|
||||
$statements = array_merge($statements, $this->parseUseStatement());
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($token[0] !== T_NAMESPACE || $this->parseNamespace() !== $namespaceName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get fresh array for new namespace. This is to prevent the parser to collect the use statements
|
||||
// for a previous namespace with the same name. This is the case if a namespace is defined twice
|
||||
// or if a namespace with the same name is commented out.
|
||||
$statements = [];
|
||||
}
|
||||
|
||||
return $statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the namespace.
|
||||
*
|
||||
* @return string The found namespace.
|
||||
*/
|
||||
public function parseNamespace()
|
||||
{
|
||||
$name = '';
|
||||
while (
|
||||
($token = $this->next()) && ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR || (
|
||||
PHP_VERSION_ID >= 80000 &&
|
||||
($token[0] === T_NAME_QUALIFIED || $token[0] === T_NAME_FULLY_QUALIFIED)
|
||||
))
|
||||
) {
|
||||
$name .= $token[1];
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class name.
|
||||
*
|
||||
* @return string The found class name.
|
||||
*/
|
||||
public function parseClass()
|
||||
{
|
||||
// Namespaces and class names are tokenized the same: T_STRINGs
|
||||
// separated by T_NS_SEPARATOR so we can use one function to provide
|
||||
// both.
|
||||
return $this->parseNamespace();
|
||||
}
|
||||
}
|
||||
4
vendor/doctrine/annotations/phpbench.json.dist
vendored
Normal file
4
vendor/doctrine/annotations/phpbench.json.dist
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"bootstrap": "tests/Doctrine/Performance/Common/bootstrap.php",
|
||||
"path": "tests/Doctrine/Performance/Common/Annotations"
|
||||
}
|
||||
156
vendor/doctrine/annotations/phpcs.xml.dist
vendored
Normal file
156
vendor/doctrine/annotations/phpcs.xml.dist
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd"
|
||||
>
|
||||
<arg name="basepath" value="."/>
|
||||
<arg name="extensions" value="php"/>
|
||||
<arg name="parallel" value="80"/>
|
||||
<arg name="cache" value=".phpcs-cache"/>
|
||||
<arg name="colors"/>
|
||||
|
||||
<!-- Show progress of the run and show sniff names -->
|
||||
<arg value="ps"/>
|
||||
|
||||
<config name="php_version" value="70100"/>
|
||||
|
||||
<file>lib</file>
|
||||
<file>tests</file>
|
||||
|
||||
<rule ref="Doctrine">
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint"/>
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint"/>
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.DeclareStrictTypes"/>
|
||||
<exclude name="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming"/>
|
||||
<exclude name="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming"/>
|
||||
<exclude name="SlevomatCodingStandard.Classes.SuperfluousTraitNaming.SuperfluousSuffix"/>
|
||||
<exclude name="SlevomatCodingStandard.Classes.DisallowLateStaticBindingForConstants.DisallowedLateStaticBindingForConstant"/>
|
||||
<exclude name="SlevomatCodingStandard.ControlStructures.ControlStructureSpacing.IncorrectLinesCountAfterLastControlStructure"/>
|
||||
|
||||
<exclude name="PSR2.Methods.MethodDeclaration.Underscore"/>
|
||||
<!-- https://github.com/slevomat/coding-standard/issues/867 -->
|
||||
<exclude name="SlevomatCodingStandard.ControlStructures.JumpStatementsSpacing.IncorrectLinesCountAfterLastControlStructure"/>
|
||||
<!-- See https://github.com/squizlabs/PHP_CodeSniffer/issues/2937 -->
|
||||
<exclude name="Squiz.Arrays.ArrayDeclaration.ValueNoNewline"/>
|
||||
<exclude name="Squiz.NamingConventions.ValidVariableName.PublicHasUnderscore"/>
|
||||
</rule>
|
||||
|
||||
<!-- Disable the rules that will require PHP 7.4 -->
|
||||
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint">
|
||||
<properties>
|
||||
<property name="enableNativeTypeHint" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
|
||||
<exclude-pattern>*/lib/Doctrine/Common/Annotations/DocParser.php</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.Classes.ValidClassName.NotCamelCaps">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassNoNamespaceNoComment.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Commenting.ForbiddenAnnotations.AnnotationForbidden">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/AbstractReaderTest.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.UseDoesNotStartWithBackslash.UseStartsWithBackslash">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="PSR12.Files.ImportStatement.LeadingSlash">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.TypeHints.LongTypeHints.UsedLongTypeHint">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.UseFromSameNamespace.UseFromSameNamespace">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.UseDoesNotStartWithBackslash.UseStartsWithBackslash">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.UseSpacing.IncorrectLinesCountBetweenSameTypeOfUse">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.MultipleUsesPerLine.MultipleUsesPerLine">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/*</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<!-- https://github.com/slevomat/coding-standard/issues/1066 -->
|
||||
<rule ref="SlevomatCodingStandard.PHP.UselessParentheses">
|
||||
<exclude-pattern>*/lib/Doctrine/Common/Annotations/DocParser.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/PhpParserTest.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<!-- It is easier to understand tests that involve annotations if you can
|
||||
declare several dummy classes with annotations in the same file -->
|
||||
<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
|
||||
<exclude-pattern>*/tests/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.Classes.ClassFileName.NoMatch">
|
||||
<exclude-pattern>*/tests/*</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="PSR1.Files.SideEffects.FoundWithSymbols">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Test.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/AbstractReaderTest.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/PhpParserTest.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/NamespaceWithClosureDeclaration.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithRequire.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<!-- these classes do not have a namespace on purpose -->
|
||||
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/SingleClassLOC1000.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/NonNamespacedClass.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Entity.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassNoNamespaceNoComment.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/TopLevelAnnotation.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingAnyTypeHint">
|
||||
<!-- there is a class property with an empty var annotation on purpose -->
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/AbstractReaderTest.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassWithValidAnnotationTarget.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.DisallowGroupUse.DisallowedGroupUse">
|
||||
<!-- The name of the file alone explains this -->
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/GroupUseStatement.php</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationWithVarType.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/EmptyInterface.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/InterfaceThatExtendsAnInterface.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousPrefix">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/InterfaceThatExtendsAnInterface.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/InterfaceWithConstants.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase">
|
||||
<!-- Usage of mixed case constants seems pretty deliberate here -->
|
||||
<exclude-pattern>*/lib/Doctrine/Common/Annotations/ImplicitlyIgnoredAnnotationNames.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<rule ref="Squiz.Functions.GlobalFunction.Found">
|
||||
<exclude-pattern>*/tests/Doctrine/Tests/Common/Annotations/Fixtures/functions.php</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<!-- Single-line PHPDoc blocks will confuse PHPUnit 7.5 -->
|
||||
<rule ref="SlevomatCodingStandard.Commenting.RequireOneLineDocComment.MultiLineDocComment">
|
||||
<exclude-pattern>*/tests</exclude-pattern>
|
||||
</rule>
|
||||
</ruleset>
|
||||
24
vendor/doctrine/annotations/phpstan.neon
vendored
Normal file
24
vendor/doctrine/annotations/phpstan.neon
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
parameters:
|
||||
level: 3
|
||||
paths:
|
||||
- lib
|
||||
- tests
|
||||
scanFiles:
|
||||
- tests/Doctrine/Tests/Common/Annotations/Fixtures/GlobalNamespacesPerFileWithClassAsFirst.php
|
||||
- tests/Doctrine/Tests/Common/Annotations/Fixtures/GlobalNamespacesPerFileWithClassAsLast.php
|
||||
- tests/Doctrine/Tests/Common/Annotations/Fixtures/NonNamespacedClass.php
|
||||
- tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Entity.php
|
||||
excludePaths:
|
||||
- tests/*/Fixtures/*
|
||||
- tests/Doctrine/Tests/Common/Annotations/ReservedKeywordsClasses.php
|
||||
- tests/Doctrine/Tests/Common/Annotations/Ticket/DCOM58Entity.php
|
||||
- tests/Doctrine/Tests/DoctrineTestCase.php
|
||||
- tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php
|
||||
polluteScopeWithLoopInitialAssignments: true
|
||||
ignoreErrors:
|
||||
- '#Instantiated class Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment not found#'
|
||||
- '#Property Doctrine\\Tests\\Common\\Annotations\\DummyClassNonAnnotationProblem::\$foo has unknown class#'
|
||||
- '#Call to an undefined static method PHPUnit\\Framework\\TestCase::expectExceptionMessageRegExp\(\)#'
|
||||
|
||||
# That tag is empty on purpose
|
||||
- '#PHPDoc tag @var has invalid value \(\)\: Unexpected token "\*/", expected type at offset 9#'
|
||||
26
vendor/doctrine/annotations/phpunit.xml.dist
vendored
Normal file
26
vendor/doctrine/annotations/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTodoAnnotatedTests="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
bootstrap="./tests/Doctrine/Tests/TestInit.php"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Doctrine Annotations Test Suite">
|
||||
<directory>./tests/Doctrine/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">./lib/Doctrine/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
15
vendor/doctrine/annotations/psalm.xml
vendored
Normal file
15
vendor/doctrine/annotations/psalm.xml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="7"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="lib/Doctrine/Common/Annotations" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
</psalm>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Performance\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\PsrCachedReader;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Controller;
|
||||
use ReflectionMethod;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
/**
|
||||
* @BeforeMethods({"initialize"})
|
||||
*/
|
||||
final class CachedReadPerformanceWithInMemoryBench
|
||||
{
|
||||
/** @var PsrCachedReader */
|
||||
private $reader;
|
||||
|
||||
/** @var ReflectionMethod */
|
||||
private $method;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
$this->reader = new PsrCachedReader(new AnnotationReader(), new ArrayAdapter());
|
||||
$this->method = new ReflectionMethod(Controller::class, 'helloAction');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(500)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function bench(): void
|
||||
{
|
||||
$this->reader->getMethodAnnotations($this->method);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Performance\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\DocLexer;
|
||||
|
||||
/**
|
||||
* @BeforeMethods({"initializeMethod", "initialize"})
|
||||
*/
|
||||
final class DocLexerPerformanceBench
|
||||
{
|
||||
use MethodInitializer;
|
||||
|
||||
/** @var DocLexer */
|
||||
private $lexer;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
$this->lexer = new DocLexer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(500)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function benchMethod(): void
|
||||
{
|
||||
$this->lexer->setInput($this->methodDocBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(500)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function benchClass(): void
|
||||
{
|
||||
$this->lexer->setInput($this->classDocBlock);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Performance\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\DocParser;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Template;
|
||||
|
||||
use function array_fill_keys;
|
||||
|
||||
/**
|
||||
* @BeforeMethods({"initializeMethod", "initialize"})
|
||||
*/
|
||||
final class DocParserPerformanceBench
|
||||
{
|
||||
use MethodInitializer;
|
||||
|
||||
private const IMPORTS = [
|
||||
'ignorephpdoc' => 'Annotations\Annotation\IgnorePhpDoc',
|
||||
'ignoreannotation' => 'Annotations\Annotation\IgnoreAnnotation',
|
||||
'route' => Route::class,
|
||||
'template' => Template::class,
|
||||
'__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations\Fixtures',
|
||||
];
|
||||
|
||||
private const IGNORED = [
|
||||
'access', 'author', 'copyright', 'deprecated', 'example', 'ignore',
|
||||
'internal', 'link', 'see', 'since', 'tutorial', 'version', 'package',
|
||||
'subpackage', 'name', 'global', 'param', 'return', 'staticvar',
|
||||
'static', 'var', 'throws', 'inheritdoc',
|
||||
];
|
||||
|
||||
/** @var DocParser */
|
||||
private $parser;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
$this->parser = new DocParser();
|
||||
|
||||
$this->parser->setImports(self::IMPORTS);
|
||||
$this->parser->setIgnoredAnnotationNames(array_fill_keys(self::IGNORED, true));
|
||||
$this->parser->setIgnoreNotImportedAnnotations(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(200)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function benchMethodParsing(): void
|
||||
{
|
||||
$this->parser->parse($this->methodDocBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(200)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function benchClassParsing(): void
|
||||
{
|
||||
$this->parser->parse($this->classDocBlock);
|
||||
}
|
||||
}
|
||||
27
vendor/doctrine/annotations/tests/Doctrine/Performance/Common/Annotations/MethodInitializer.php
vendored
Normal file
27
vendor/doctrine/annotations/tests/Doctrine/Performance/Common/Annotations/MethodInitializer.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Performance\Common\Annotations;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Controller;
|
||||
use ReflectionMethod;
|
||||
|
||||
trait MethodInitializer
|
||||
{
|
||||
/** @var ReflectionMethod */
|
||||
private $method;
|
||||
|
||||
/** @var string */
|
||||
private $methodDocBlock;
|
||||
|
||||
/** @var string */
|
||||
private $classDocBlock;
|
||||
|
||||
public function initializeMethod(): void
|
||||
{
|
||||
$this->method = new ReflectionMethod(Controller::class, 'helloAction');
|
||||
$this->methodDocBlock = $this->method->getDocComment();
|
||||
$this->classDocBlock = $this->method->getDeclaringClass()->getDocComment();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Performance\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\PhpParser;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\NamespacedSingleClassLOC1000;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* @BeforeMethods({"initialize"})
|
||||
*/
|
||||
final class PhpParserPerformanceWithShortCutBench
|
||||
{
|
||||
/** @var ReflectionClass */
|
||||
private $class;
|
||||
|
||||
/** @var PhpParser */
|
||||
private $parser;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
$this->class = new ReflectionClass(NamespacedSingleClassLOC1000::class);
|
||||
$this->parser = new PhpParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(500)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function bench(): void
|
||||
{
|
||||
$this->parser->parseClass($this->class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Performance\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\PhpParser;
|
||||
use ReflectionClass;
|
||||
use SingleClassLOC1000;
|
||||
|
||||
/**
|
||||
* @BeforeMethods({"initialize"})
|
||||
*/
|
||||
final class PhpParserPerformanceWithoutShortCutBench
|
||||
{
|
||||
/** @var ReflectionClass */
|
||||
private $class;
|
||||
|
||||
/** @var PhpParser */
|
||||
private $parser;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
$this->class = new ReflectionClass(SingleClassLOC1000::class);
|
||||
$this->parser = new PhpParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(500)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function bench(): void
|
||||
{
|
||||
$this->parser->parseClass($this->class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Performance\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
|
||||
/**
|
||||
* @BeforeMethods({"initializeMethod", "initialize"})
|
||||
*/
|
||||
final class ReadPerformanceBench
|
||||
{
|
||||
use MethodInitializer;
|
||||
|
||||
/** @var AnnotationReader */
|
||||
private $reader;
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
$this->reader = new AnnotationReader();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Revs(500)
|
||||
* @Iterations(5)
|
||||
*/
|
||||
public function bench(): void
|
||||
{
|
||||
$this->reader->getMethodAnnotations($this->method);
|
||||
}
|
||||
}
|
||||
8
vendor/doctrine/annotations/tests/Doctrine/Performance/Common/bootstrap.php
vendored
Normal file
8
vendor/doctrine/annotations/tests/Doctrine/Performance/Common/bootstrap.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../../../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../../Tests/Common/Annotations/Fixtures/Annotation/Route.php';
|
||||
require_once __DIR__ . '/../../Tests/Common/Annotations/Fixtures/Annotation/Secure.php';
|
||||
require_once __DIR__ . '/../../Tests/Common/Annotations/Fixtures/Annotation/Template.php';
|
||||
805
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AbstractReaderTest.php
vendored
Normal file
805
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AbstractReaderTest.php
vendored
Normal file
@@ -0,0 +1,805 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation;
|
||||
use Doctrine\Common\Annotations\AnnotationException;
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
use Test;
|
||||
use TopLevelAnnotation;
|
||||
|
||||
use function class_exists;
|
||||
use function reset;
|
||||
|
||||
require_once __DIR__ . '/TopLevelAnnotation.php';
|
||||
|
||||
abstract class AbstractReaderTest extends TestCase
|
||||
{
|
||||
/** @var bool */
|
||||
private $expectException = true;
|
||||
|
||||
final protected function ignoreIssues(): void
|
||||
{
|
||||
$this->expectException = false;
|
||||
}
|
||||
|
||||
public function getReflectionClass(): ReflectionClass
|
||||
{
|
||||
return new ReflectionClass(DummyClass::class);
|
||||
}
|
||||
|
||||
public function testAnnotations(): void
|
||||
{
|
||||
$class = $this->getReflectionClass();
|
||||
$reader = $this->getReader();
|
||||
|
||||
self::assertCount(1, $reader->getClassAnnotations($class));
|
||||
self::assertInstanceOf(
|
||||
$annotName = DummyAnnotation::class,
|
||||
$annot = $reader->getClassAnnotation($class, $annotName)
|
||||
);
|
||||
self::assertEquals('hello', $annot->dummyValue);
|
||||
|
||||
$field1Prop = $class->getProperty('field1');
|
||||
$propAnnots = $reader->getPropertyAnnotations($field1Prop);
|
||||
self::assertCount(1, $propAnnots);
|
||||
self::assertInstanceOf($annotName, $annot = $reader->getPropertyAnnotation($field1Prop, $annotName));
|
||||
self::assertEquals('fieldHello', $annot->dummyValue);
|
||||
|
||||
$getField1Method = $class->getMethod('getField1');
|
||||
$methodAnnots = $reader->getMethodAnnotations($getField1Method);
|
||||
self::assertCount(1, $methodAnnots);
|
||||
self::assertInstanceOf($annotName, $annot = $reader->getMethodAnnotation($getField1Method, $annotName));
|
||||
self::assertEquals([1, 2, 'three'], $annot->value);
|
||||
|
||||
$field2Prop = $class->getProperty('field2');
|
||||
$propAnnots = $reader->getPropertyAnnotations($field2Prop);
|
||||
self::assertCount(1, $propAnnots);
|
||||
self::assertInstanceOf(
|
||||
$annotName = DummyJoinTable::class,
|
||||
$joinTableAnnot = $reader->getPropertyAnnotation($field2Prop, $annotName)
|
||||
);
|
||||
self::assertCount(1, $joinTableAnnot->joinColumns);
|
||||
self::assertCount(1, $joinTableAnnot->inverseJoinColumns);
|
||||
self::assertInstanceOf(DummyJoinColumn::class, $joinTableAnnot->joinColumns[0]);
|
||||
self::assertInstanceOf(DummyJoinColumn::class, $joinTableAnnot->inverseJoinColumns[0]);
|
||||
self::assertEquals('col1', $joinTableAnnot->joinColumns[0]->name);
|
||||
self::assertEquals('col2', $joinTableAnnot->joinColumns[0]->referencedColumnName);
|
||||
self::assertEquals('col3', $joinTableAnnot->inverseJoinColumns[0]->name);
|
||||
self::assertEquals('col4', $joinTableAnnot->inverseJoinColumns[0]->referencedColumnName);
|
||||
|
||||
$dummyAnnot = $reader->getMethodAnnotation($class->getMethod('getField1'), DummyAnnotation::class);
|
||||
self::assertEquals('', $dummyAnnot->dummyValue);
|
||||
self::assertEquals([1, 2, 'three'], $dummyAnnot->value);
|
||||
|
||||
$dummyAnnot = $reader->getMethodAnnotation($class->getMethod('getField3'), DummyAnnotation::class);
|
||||
self::assertEquals('\d{4}-[01]\d-[0-3]\d [0-2]\d:[0-5]\d:[0-5]\d', $dummyAnnot->value);
|
||||
|
||||
$dummyAnnot = $reader->getPropertyAnnotation($class->getProperty('field1'), DummyAnnotation::class);
|
||||
self::assertEquals('fieldHello', $dummyAnnot->dummyValue);
|
||||
|
||||
$classAnnot = $reader->getClassAnnotation($class, DummyAnnotation::class);
|
||||
self::assertEquals('hello', $classAnnot->dummyValue);
|
||||
}
|
||||
|
||||
public function testAnnotationsWithValidTargets(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassWithValidAnnotationTarget::class);
|
||||
|
||||
self::assertCount(1, $reader->getClassAnnotations($class));
|
||||
self::assertCount(1, $reader->getPropertyAnnotations($class->getProperty('foo')));
|
||||
self::assertCount(1, $reader->getMethodAnnotations($class->getMethod('someFunction')));
|
||||
self::assertCount(1, $reader->getPropertyAnnotations($class->getProperty('nested')));
|
||||
}
|
||||
|
||||
public function testAnnotationsWithVarType(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassWithAnnotationWithVarType::class);
|
||||
|
||||
self::assertCount(1, $fooAnnot = $reader->getPropertyAnnotations($class->getProperty('foo')));
|
||||
self::assertCount(1, $barAnnot = $reader->getMethodAnnotations($class->getMethod('bar')));
|
||||
|
||||
self::assertIsString($fooAnnot[0]->string);
|
||||
self::assertInstanceOf(Fixtures\AnnotationTargetAll::class, $barAnnot[0]->annotation);
|
||||
}
|
||||
|
||||
public function testAtInDescription(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassWithAtInDescriptionAndAnnotation::class);
|
||||
|
||||
self::assertCount(1, $fooAnnot = $reader->getPropertyAnnotations($class->getProperty('foo')));
|
||||
self::assertCount(1, $barAnnot = $reader->getPropertyAnnotations($class->getProperty('bar')));
|
||||
|
||||
self::assertInstanceOf(Fixtures\AnnotationTargetPropertyMethod::class, $fooAnnot[0]);
|
||||
self::assertInstanceOf(Fixtures\AnnotationTargetPropertyMethod::class, $barAnnot[0]);
|
||||
}
|
||||
|
||||
public function testClassWithWithDanglingComma(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$annots = $reader->getClassAnnotations(new ReflectionClass(DummyClassWithDanglingComma::class));
|
||||
|
||||
self::assertCount(1, $annots);
|
||||
}
|
||||
|
||||
public function testClassWithInvalidAnnotationTargetAtClassDocBlock(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
if ($this->expectException) {
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'[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'
|
||||
);
|
||||
}
|
||||
|
||||
$reader->getClassAnnotations(new ReflectionClass(Fixtures\ClassWithInvalidAnnotationTargetAtClass::class));
|
||||
}
|
||||
|
||||
public function testClassWithWithInclude(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$annots = $reader->getClassAnnotations(new ReflectionClass(Fixtures\ClassWithRequire::class));
|
||||
self::assertCount(1, $annots);
|
||||
}
|
||||
|
||||
public function testClassWithInvalidAnnotationTargetAtPropertyDocBlock(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
if ($this->expectException) {
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'[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'
|
||||
);
|
||||
}
|
||||
|
||||
$reader->getPropertyAnnotations(new ReflectionProperty(
|
||||
Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class,
|
||||
'foo'
|
||||
));
|
||||
}
|
||||
|
||||
public function testClassWithInvalidNestedAnnotationTargetAtPropertyDocBlock(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
if ($this->expectException) {
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'[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'
|
||||
);
|
||||
}
|
||||
|
||||
$reader->getPropertyAnnotations(new ReflectionProperty(
|
||||
Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class,
|
||||
'bar'
|
||||
));
|
||||
}
|
||||
|
||||
public function testClassWithInvalidAnnotationTargetAtMethodDocBlock(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
if ($this->expectException) {
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'[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'
|
||||
);
|
||||
}
|
||||
|
||||
$reader->getMethodAnnotations(new ReflectionMethod(
|
||||
Fixtures\ClassWithInvalidAnnotationTargetAtMethod::class,
|
||||
'functionName'
|
||||
));
|
||||
}
|
||||
|
||||
public function testClassWithAnnotationWithTargetSyntaxErrorAtClassDocBlock(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
"Expected namespace separator or identifier, got ')' at position 24" .
|
||||
' in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError.'
|
||||
);
|
||||
$reader->getClassAnnotations(new ReflectionClass(
|
||||
Fixtures\ClassWithAnnotationWithTargetSyntaxError::class
|
||||
));
|
||||
}
|
||||
|
||||
public function testClassWithAnnotationWithTargetSyntaxErrorAtPropertyDocBlock(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
"Expected namespace separator or identifier, got ')' at position 24" .
|
||||
' in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError.'
|
||||
);
|
||||
$reader->getPropertyAnnotations(new ReflectionProperty(
|
||||
Fixtures\ClassWithAnnotationWithTargetSyntaxError::class,
|
||||
'foo'
|
||||
));
|
||||
}
|
||||
|
||||
public function testClassWithAnnotationWithTargetSyntaxErrorAtMethodDocBlock(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
"Expected namespace separator or identifier, got ')' at position 24" .
|
||||
' in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError.'
|
||||
);
|
||||
$reader->getMethodAnnotations(new ReflectionMethod(
|
||||
Fixtures\ClassWithAnnotationWithTargetSyntaxError::class,
|
||||
'bar'
|
||||
));
|
||||
}
|
||||
|
||||
public function testClassWithPropertyInvalidVarTypeError(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassWithAnnotationWithVarType::class);
|
||||
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'[Type Error] Attribute "string" of @AnnotationWithVarType declared on property' .
|
||||
' Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationWithVarType::$invalidProperty' .
|
||||
' expects a(n) string, but got integer.'
|
||||
);
|
||||
$reader->getPropertyAnnotations($class->getProperty('invalidProperty'));
|
||||
}
|
||||
|
||||
public function testClassWithMethodInvalidVarTypeError(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassWithAnnotationWithVarType::class);
|
||||
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'[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.'
|
||||
);
|
||||
$reader->getMethodAnnotations($class->getMethod('invalidMethod'));
|
||||
}
|
||||
|
||||
public function testClassSyntaxErrorContext(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
"Expected namespace separator or identifier, got ')' at position 18" .
|
||||
' in class Doctrine\Tests\Common\Annotations\DummyClassSyntaxError.'
|
||||
);
|
||||
$reader->getClassAnnotations(new ReflectionClass(DummyClassSyntaxError::class));
|
||||
}
|
||||
|
||||
public function testMethodSyntaxErrorContext(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
"Expected namespace separator or identifier, got ')' at position 18" .
|
||||
' in method Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError::foo().'
|
||||
);
|
||||
$reader->getMethodAnnotations(new ReflectionMethod(DummyClassMethodSyntaxError::class, 'foo'));
|
||||
}
|
||||
|
||||
public function testPropertySyntaxErrorContext(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
"Expected namespace separator or identifier, got ')'" .
|
||||
' at position 36 in property Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError::$foo.'
|
||||
);
|
||||
$reader->getPropertyAnnotations(new ReflectionProperty(DummyClassPropertySyntaxError::class, 'foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group regression
|
||||
*/
|
||||
public function testMultipleAnnotationsOnSameLine(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$annots = $reader->getPropertyAnnotations(new ReflectionProperty(DummyClass2::class, 'id'));
|
||||
self::assertCount(3, $annots);
|
||||
}
|
||||
|
||||
public function testNonAnnotationProblem(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
|
||||
self::assertNotNull($annot = $reader->getPropertyAnnotation(
|
||||
new ReflectionProperty(DummyClassNonAnnotationProblem::class, 'foo'),
|
||||
$name = DummyAnnotation::class
|
||||
));
|
||||
self::assertInstanceOf($name, $annot);
|
||||
}
|
||||
|
||||
public function testIncludeIgnoreAnnotation(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
|
||||
$reader->getPropertyAnnotations(new ReflectionProperty(Fixtures\ClassWithIgnoreAnnotation::class, 'foo'));
|
||||
self::assertFalse(class_exists(Fixtures\IgnoreAnnotationClass::class, false));
|
||||
}
|
||||
|
||||
public function testImportWithConcreteAnnotation(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$property = new ReflectionProperty(TestImportWithConcreteAnnotation::class, 'field');
|
||||
$annotations = $reader->getPropertyAnnotations($property);
|
||||
self::assertCount(1, $annotations);
|
||||
self::assertNotNull($reader->getPropertyAnnotation($property, DummyAnnotation::class));
|
||||
}
|
||||
|
||||
public function testImportWithInheritance(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
|
||||
$class = new TestParentClass();
|
||||
$ref = new ReflectionClass($class);
|
||||
|
||||
$childAnnotations = $reader->getPropertyAnnotations($ref->getProperty('child'));
|
||||
self::assertCount(1, $childAnnotations);
|
||||
self::assertInstanceOf(Foo\Name::class, reset($childAnnotations));
|
||||
|
||||
$parentAnnotations = $reader->getPropertyAnnotations($ref->getProperty('parent'));
|
||||
self::assertCount(1, $parentAnnotations);
|
||||
self::assertInstanceOf(Bar\Name::class, reset($parentAnnotations));
|
||||
}
|
||||
|
||||
public function testImportDetectsNotImportedAnnotation(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
if ($this->expectException) {
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'The annotation "@NameFoo" in property' .
|
||||
' Doctrine\Tests\Common\Annotations\TestAnnotationNotImportedClass::$field was never imported.'
|
||||
);
|
||||
}
|
||||
|
||||
$reader->getPropertyAnnotations(new ReflectionProperty(TestAnnotationNotImportedClass::class, 'field'));
|
||||
}
|
||||
|
||||
public function testImportDetectsNonExistentAnnotation(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
if ($this->expectException) {
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'The annotation "@Foo\Bar\Name" in property' .
|
||||
' Doctrine\Tests\Common\Annotations\TestNonExistentAnnotationClass::$field was never imported.'
|
||||
);
|
||||
}
|
||||
|
||||
$reader->getPropertyAnnotations(new ReflectionProperty(TestNonExistentAnnotationClass::class, 'field'));
|
||||
}
|
||||
|
||||
public function testTopLevelAnnotation(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$annotations = $reader->getPropertyAnnotations(new ReflectionProperty(
|
||||
TestTopLevelAnnotationClass::class,
|
||||
'field'
|
||||
));
|
||||
|
||||
self::assertCount(1, $annotations);
|
||||
self::assertInstanceOf(TopLevelAnnotation::class, reset($annotations));
|
||||
}
|
||||
|
||||
public function testIgnoresAnnotationsNotPrefixedWithWhitespace(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
|
||||
$annotation = $reader->getClassAnnotation(
|
||||
new ReflectionClass(new TestIgnoresNonAnnotationsClass()),
|
||||
NameBar::class
|
||||
);
|
||||
self::assertInstanceOf(NameBar::class, $annotation);
|
||||
}
|
||||
|
||||
private static $testResetsPhpParserAfterUseRun = false;
|
||||
|
||||
/**
|
||||
* When getUseStatements isn't available on ReflectionClass the PhpParser has to use token_get_all(). If that
|
||||
* happens various PHP compiler globals get set, and these can have seriously bad effects on the next file to be
|
||||
* parsed.
|
||||
* Notably the doc_comment compiler global can end up containing a docblock comment. The next file to be parsed
|
||||
* on an include() will have this docblock comment attached to the first thing in the file that the compiler
|
||||
* considers to own comments. If this is a class then any later calls to getDocComment() for that class will have
|
||||
* undesirable effects. *sigh*
|
||||
*/
|
||||
public function testResetsPhpParserAfterUse(): void
|
||||
{
|
||||
// If someone has already included our main test fixture this test is invalid. It's important that our require
|
||||
// causes this file to be parsed and compiled at a certain point.
|
||||
self::assertFalse(! self::$testResetsPhpParserAfterUseRun && class_exists(
|
||||
Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment::class
|
||||
), 'Test invalid if class has already been compiled');
|
||||
self::$testResetsPhpParserAfterUseRun = true;
|
||||
|
||||
$reader = $this->getReader();
|
||||
|
||||
// First make sure the annotation cache knows about the annotations we want to use.
|
||||
// If we don't do this then loading of annotations into the cache will cause the parser to get out of the bad
|
||||
// state we want to test.
|
||||
$class = new ReflectionClass(Fixtures\ClassWithValidAnnotationTarget::class);
|
||||
$reader->getClassAnnotations($class);
|
||||
|
||||
// Now import an incredibly dull class which makes use of the same
|
||||
// class level annotation that the previous class does.
|
||||
$class = new ReflectionClass(Fixtures\ClassWithClassAnnotationOnly::class);
|
||||
$annotations = $reader->getClassAnnotations($class);
|
||||
|
||||
// This include needs to be here since we need the PHP compiler to run over it as the next thing the PHP
|
||||
// parser sees since PhpParser called token_get_all() on the intro to ClassWithClassAnnotationOnly.
|
||||
// Our test class cannot be in a namespace (some versions of PHP reset the doc_comment compiler global when
|
||||
// you hit a namespace declaration), so cannot be autoloaded.
|
||||
require_once __DIR__ . '/Fixtures/ClassNoNamespaceNoComment.php';
|
||||
|
||||
// So, hopefully, if all has gone OK, our class with class annotations should actually have them.
|
||||
// If this fails then something is quite badly wrong elsewhere.
|
||||
// Note that if this happens before the require it can cause other PHP files to be included, resetting the
|
||||
// compiler global state, and invalidating this test case.
|
||||
self::assertNotEmpty($annotations);
|
||||
|
||||
$annotations = $reader->getClassAnnotations(new ReflectionClass(
|
||||
new Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment()
|
||||
));
|
||||
// And if our workaround for this bug is OK, our class with no doc
|
||||
// comment should not have any class annotations.
|
||||
self::assertEmpty($annotations);
|
||||
}
|
||||
|
||||
public function testErrorWhenInvalidAnnotationIsUsed(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\InvalidAnnotationUsageClass::class);
|
||||
if ($this->expectException) {
|
||||
$this->expectException(AnnotationException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'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.'
|
||||
);
|
||||
}
|
||||
|
||||
$reader->getClassAnnotations($ref);
|
||||
}
|
||||
|
||||
public function testInvalidAnnotationUsageButIgnoredClass(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\InvalidAnnotationUsageButIgnoredClass::class);
|
||||
$annots = $reader->getClassAnnotations($ref);
|
||||
|
||||
self::assertCount(2, $annots);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1660
|
||||
* @group regression
|
||||
*/
|
||||
public function testInvalidAnnotationButIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassDDC1660::class);
|
||||
|
||||
self::assertTrue(class_exists(Fixtures\Annotation\Version::class));
|
||||
self::assertEmpty($reader->getClassAnnotations($class));
|
||||
self::assertEmpty($reader->getMethodAnnotations($class->getMethod('bar')));
|
||||
self::assertEmpty($reader->getPropertyAnnotations($class->getProperty('foo')));
|
||||
}
|
||||
|
||||
public function testAnnotationEnumeratorException(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassWithAnnotationEnum::class);
|
||||
|
||||
self::assertCount(1, $bar = $reader->getMethodAnnotations($class->getMethod('bar')));
|
||||
self::assertCount(1, $foo = $reader->getPropertyAnnotations($class->getProperty('foo')));
|
||||
|
||||
self::assertInstanceOf(Fixtures\AnnotationEnum::class, $bar[0]);
|
||||
self::assertInstanceOf(Fixtures\AnnotationEnum::class, $foo[0]);
|
||||
|
||||
try {
|
||||
$reader->getPropertyAnnotations($class->getProperty('invalidProperty'));
|
||||
$this->fail();
|
||||
} catch (AnnotationException $exc) {
|
||||
self::assertEquals(
|
||||
'[Enum Error] Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum' .
|
||||
' declared on property Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum' .
|
||||
'::$invalidProperty accepts only [ONE, TWO, THREE], but got FOUR.',
|
||||
$exc->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$reader->getMethodAnnotations($class->getMethod('invalidMethod'));
|
||||
$this->fail();
|
||||
} catch (AnnotationException $exc) {
|
||||
self::assertEquals(
|
||||
'[Enum Error] Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum' .
|
||||
' declared on method Doctrine\Tests\Common\Annotations\Fixtures\ClassWithAnnotationEnum' .
|
||||
'::invalidMethod() accepts only [ONE, TWO, THREE], but got 5.',
|
||||
$exc->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DCOM-106
|
||||
*/
|
||||
public function testIgnoreFixMeAndUpperCaseToDo(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(DCOM106::class);
|
||||
|
||||
self::assertEmpty($reader->getClassAnnotations($ref));
|
||||
}
|
||||
|
||||
public function testWillSkipAnnotationsContainingDashes(): void
|
||||
{
|
||||
self::assertEmpty(
|
||||
$this
|
||||
->getReader()
|
||||
->getClassAnnotations(new ReflectionClass(
|
||||
Fixtures\ClassWithInvalidAnnotationContainingDashes::class
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
public function testWillFailOnAnnotationConstantReferenceContainingDashes(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$reflection = new ReflectionClass(Fixtures\ClassWithAnnotationConstantReferenceWithDashes::class);
|
||||
|
||||
$this->expectExceptionMessage(
|
||||
'[Syntax Error] Expected Doctrine\Common\Annotations\DocLexer::T_CLOSE_PARENTHESIS, got \'-\' at'
|
||||
. ' position 14 in class ' . Fixtures\ClassWithAnnotationConstantReferenceWithDashes::class . '.'
|
||||
);
|
||||
|
||||
$reader->getClassAnnotations($reflection);
|
||||
}
|
||||
|
||||
abstract protected function getReader(): Reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @parseAnnotation("var")
|
||||
*/
|
||||
class TestParseAnnotationClass
|
||||
{
|
||||
/** @var */
|
||||
public $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NameBar
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class TestIgnoresNonAnnotationsClass
|
||||
{
|
||||
}
|
||||
|
||||
class TestTopLevelAnnotationClass
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @\TopLevelAnnotation
|
||||
*/
|
||||
public $field;
|
||||
}
|
||||
|
||||
class TestNonExistentAnnotationClass
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @Foo\Bar\Name
|
||||
*/
|
||||
public $field;
|
||||
}
|
||||
|
||||
class TestAnnotationNotImportedClass
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @NameFoo
|
||||
*/
|
||||
public $field;
|
||||
}
|
||||
|
||||
class TestChildClass
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @\Doctrine\Tests\Common\Annotations\Foo\Name(name = "foo")
|
||||
*/
|
||||
protected $child;
|
||||
}
|
||||
|
||||
class TestParentClass extends TestChildClass
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @\Doctrine\Tests\Common\Annotations\Bar\Name(name = "bar")
|
||||
*/
|
||||
public $parent;
|
||||
}
|
||||
|
||||
class TestImportWithConcreteAnnotation
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @DummyAnnotation(dummyValue = "bar")
|
||||
*/
|
||||
public $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignoreAnnotation("var")
|
||||
*/
|
||||
class DummyClass2
|
||||
{
|
||||
/**
|
||||
* @DummyId @DummyColumn(type="integer") @DummyGeneratedValue
|
||||
* @var int
|
||||
*/
|
||||
public $id;
|
||||
}
|
||||
|
||||
/** @Annotation */
|
||||
class NameBar extends Annotation
|
||||
{
|
||||
}
|
||||
/** @Annotation */
|
||||
class DummyId extends Annotation
|
||||
{
|
||||
}
|
||||
/** @Annotation */
|
||||
class DummyColumn extends Annotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $type;
|
||||
}
|
||||
/** @Annotation */
|
||||
class DummyGeneratedValue extends Annotation
|
||||
{
|
||||
}
|
||||
/** @Annotation */
|
||||
class DummyAnnotation extends Annotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $dummyValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class DummyAnnotationWithIgnoredAnnotation extends Annotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $dummyValue;
|
||||
}
|
||||
|
||||
/** @Annotation */
|
||||
class DummyJoinColumn extends Annotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
/** @var mixed */
|
||||
public $referencedColumnName;
|
||||
}
|
||||
/** @Annotation */
|
||||
class DummyJoinTable extends Annotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
/** @var mixed */
|
||||
public $joinColumns;
|
||||
/** @var mixed */
|
||||
public $inverseJoinColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @DummyAnnotation(dummyValue = "bar",)
|
||||
*/
|
||||
class DummyClassWithDanglingComma
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @DummyAnnotation(@)
|
||||
*/
|
||||
class DummyClassSyntaxError
|
||||
{
|
||||
}
|
||||
|
||||
class DummyClassMethodSyntaxError
|
||||
{
|
||||
/**
|
||||
* @DummyAnnotation(@)
|
||||
*/
|
||||
public function foo(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class DummyClassPropertySyntaxError
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @DummyAnnotation(@)
|
||||
*/
|
||||
public $foo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignoreAnnotation({"since", "var"})
|
||||
*/
|
||||
class DummyClassNonAnnotationProblem
|
||||
{
|
||||
/**
|
||||
* @DummyAnnotation
|
||||
* @var Test
|
||||
*/
|
||||
public $foo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @DummyAnnotation Foo bar <foobar@1domain.com>
|
||||
*/
|
||||
class DummyClassWithEmail
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fixme public
|
||||
* @TODO
|
||||
*/
|
||||
class DCOM106
|
||||
{
|
||||
}
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Foo;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation;
|
||||
|
||||
/** @Annotation */
|
||||
class Name extends Annotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
}
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Bar;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation;
|
||||
|
||||
/** @Annotation */
|
||||
class Name extends Annotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
}
|
||||
30
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Annotation/TargetTest.php
vendored
Normal file
30
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Annotation/TargetTest.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Annotation;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation\Target;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@see \Doctrine\Common\Annotations\Annotation\Target}
|
||||
*
|
||||
* @covers \Doctrine\Common\Annotations\Annotation\Target
|
||||
*/
|
||||
class TargetTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @group DDC-3006
|
||||
*/
|
||||
public function testValidMixedTargets(): void
|
||||
{
|
||||
$target = new Target(['value' => ['ALL']]);
|
||||
self::assertEquals(Target::TARGET_ALL, $target->targets);
|
||||
|
||||
$target = new Target(['value' => ['METHOD', 'METHOD']]);
|
||||
self::assertEquals(Target::TARGET_METHOD, $target->targets);
|
||||
self::assertNotEquals(Target::TARGET_PROPERTY, $target->targets);
|
||||
|
||||
$target = new Target(['value' => ['PROPERTY', 'METHOD']]);
|
||||
self::assertEquals(Target::TARGET_METHOD | Target::TARGET_PROPERTY, $target->targets);
|
||||
}
|
||||
}
|
||||
332
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php
vendored
Normal file
332
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AnnotationReaderTest.php
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\DocParser;
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\SingleUseAnnotation;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithEnumProperty;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\ClassWithEnumAnnotations;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\ClassWithFullPathUseStatement;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\ClassWithImportedIgnoredAnnotation;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\ClassWithPHPCodeSnifferAnnotation;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\ClassWithPhpCsSuppressAnnotation;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\ClassWithPHPStanGenericsAnnotations;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\IgnoredNamespaces\AnnotatedAtClassLevel;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\IgnoredNamespaces\AnnotatedAtMethodLevel;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\IgnoredNamespaces\AnnotatedAtPropertyLevel;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\IgnoredNamespaces\AnnotatedWithAlias;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Suit;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
|
||||
use function class_exists;
|
||||
use function spl_autoload_register;
|
||||
use function spl_autoload_unregister;
|
||||
|
||||
use const PHP_VERSION_ID;
|
||||
|
||||
class AnnotationReaderTest extends AbstractReaderTest
|
||||
{
|
||||
/**
|
||||
* @return AnnotationReader
|
||||
*/
|
||||
protected function getReader(?DocParser $parser = null): Reader
|
||||
{
|
||||
return new AnnotationReader($parser);
|
||||
}
|
||||
|
||||
public function testMethodAnnotationFromTrait(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\ClassUsesTrait::class);
|
||||
|
||||
$annotations = $reader->getMethodAnnotations($ref->getMethod('someMethod'));
|
||||
self::assertInstanceOf(Bar\Autoload::class, $annotations[0]);
|
||||
|
||||
$annotations = $reader->getMethodAnnotations($ref->getMethod('traitMethod'));
|
||||
self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotations[0]);
|
||||
}
|
||||
|
||||
public function testMethodAnnotationFromOverwrittenTrait(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\ClassOverwritesTrait::class);
|
||||
|
||||
$annotations = $reader->getMethodAnnotations($ref->getMethod('traitMethod'));
|
||||
self::assertInstanceOf(Bar2\Autoload::class, $annotations[0]);
|
||||
}
|
||||
|
||||
public function testPropertyAnnotationFromTrait(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\ClassUsesTrait::class);
|
||||
|
||||
$annotations = $reader->getPropertyAnnotations($ref->getProperty('aProperty'));
|
||||
self::assertInstanceOf(Bar\Autoload::class, $annotations[0]);
|
||||
|
||||
$annotations = $reader->getPropertyAnnotations($ref->getProperty('traitProperty'));
|
||||
self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotations[0]);
|
||||
}
|
||||
|
||||
public function testOmitNotRegisteredAnnotation(): void
|
||||
{
|
||||
$parser = new DocParser();
|
||||
$parser->setIgnoreNotImportedAnnotations(true);
|
||||
|
||||
$reader = $this->getReader($parser);
|
||||
$ref = new ReflectionClass(Fixtures\ClassWithNotRegisteredAnnotationUsed::class);
|
||||
|
||||
$annotations = $reader->getMethodAnnotations($ref->getMethod('methodWithNotRegisteredAnnotation'));
|
||||
self::assertEquals([], $annotations);
|
||||
}
|
||||
|
||||
public function testClassAnnotationSupportsSelfAccessorForConstants(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\ClassWithAnnotationWithSelfConstantReference::class);
|
||||
|
||||
$annotations = $reader->getClassAnnotations($ref);
|
||||
|
||||
self::assertCount(1, $annotations);
|
||||
|
||||
$annotation = $annotations[0];
|
||||
self::assertInstanceOf(Fixtures\AnnotationWithConstants::class, $annotation);
|
||||
self::assertEquals(
|
||||
$annotation->value,
|
||||
Fixtures\ClassWithAnnotationWithSelfConstantReference::VALUE_FOR_CLASS
|
||||
);
|
||||
}
|
||||
|
||||
public function testPropertyAnnotationSupportsSelfAccessorForConstants(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\ClassWithAnnotationWithSelfConstantReference::class);
|
||||
|
||||
$classProperty = $ref->getProperty('classProperty');
|
||||
$classAnnotation = $reader->getPropertyAnnotation($classProperty, Fixtures\AnnotationWithConstants::class);
|
||||
self::assertNotNull($classAnnotation);
|
||||
self::assertEquals(
|
||||
$classAnnotation->value,
|
||||
Fixtures\ClassWithAnnotationWithSelfConstantReference::VALUE_FOR_CLASS
|
||||
);
|
||||
|
||||
$traitProperty = $ref->getProperty('traitProperty');
|
||||
$traitAnnotation = $reader->getPropertyAnnotation($traitProperty, Fixtures\AnnotationWithConstants::class);
|
||||
self::assertNotNull($traitAnnotation);
|
||||
self::assertEquals(
|
||||
$traitAnnotation->value,
|
||||
Fixtures\ClassWithAnnotationWithSelfConstantReference::VALUE_FOR_TRAIT
|
||||
);
|
||||
}
|
||||
|
||||
public function testMethodAnnotationSupportsSelfAccessorForConstants(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(Fixtures\ClassWithAnnotationWithSelfConstantReference::class);
|
||||
|
||||
$classMethod = $ref->getMethod('classMethod');
|
||||
$classAnnotation = $reader->getMethodAnnotation($classMethod, Fixtures\AnnotationWithConstants::class);
|
||||
self::assertNotNull($classAnnotation);
|
||||
self::assertEquals(
|
||||
$classAnnotation->value,
|
||||
Fixtures\ClassWithAnnotationWithSelfConstantReference::VALUE_FOR_CLASS
|
||||
);
|
||||
|
||||
$traitMethod = $ref->getMethod('traitMethod');
|
||||
$traitAnnotation = $reader->getMethodAnnotation($traitMethod, Fixtures\AnnotationWithConstants::class);
|
||||
self::assertNotNull($traitAnnotation);
|
||||
self::assertEquals(
|
||||
$traitAnnotation->value,
|
||||
Fixtures\ClassWithAnnotationWithSelfConstantReference::VALUE_FOR_TRAIT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 45
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testClassAnnotationIsIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(AnnotatedAtClassLevel::class);
|
||||
|
||||
$reader::addGlobalIgnoredNamespace('SomeClassAnnotationNamespace');
|
||||
|
||||
self::assertEmpty($reader->getClassAnnotations($ref));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 45
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testMethodAnnotationIsIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(AnnotatedAtMethodLevel::class);
|
||||
|
||||
$reader::addGlobalIgnoredNamespace('SomeMethodAnnotationNamespace');
|
||||
|
||||
self::assertEmpty($reader->getMethodAnnotations($ref->getMethod('test')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 45
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testPropertyAnnotationIsIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(AnnotatedAtPropertyLevel::class);
|
||||
|
||||
$reader::addGlobalIgnoredNamespace('SomePropertyAnnotationNamespace');
|
||||
|
||||
self::assertEmpty($reader->getPropertyAnnotations($ref->getProperty('property')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 244
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testAnnotationWithAliasIsIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(AnnotatedWithAlias::class);
|
||||
|
||||
$reader::addGlobalIgnoredNamespace('SomePropertyAnnotationNamespace');
|
||||
|
||||
self::assertEmpty($reader->getPropertyAnnotations($ref->getProperty('property')));
|
||||
}
|
||||
|
||||
public function testClassWithFullPathUseStatement(): void
|
||||
{
|
||||
if (class_exists(SingleUseAnnotation::class, false)) {
|
||||
throw new LogicException(
|
||||
'The SingleUseAnnotation must not be used in other tests for this test to be useful.' .
|
||||
'If the class is already loaded then the code path that finds the class to load is not used and ' .
|
||||
'this test becomes useless.'
|
||||
);
|
||||
}
|
||||
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(ClassWithFullPathUseStatement::class);
|
||||
|
||||
$annotations = $reader->getClassAnnotations($ref);
|
||||
|
||||
self::assertInstanceOf(SingleUseAnnotation::class, $annotations[0]);
|
||||
}
|
||||
|
||||
public function testPhpCsSuppressAnnotationIsIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(ClassWithPhpCsSuppressAnnotation::class);
|
||||
|
||||
self::assertEmpty($reader->getMethodAnnotations($ref->getMethod('foo')));
|
||||
}
|
||||
|
||||
public function testGloballyIgnoredAnnotationNotIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$class = new ReflectionClass(Fixtures\ClassDDC1660::class);
|
||||
$testLoader = static function (string $className): bool {
|
||||
if ($className === 'since') {
|
||||
throw new InvalidArgumentException(
|
||||
'Globally ignored annotation names should never be passed to an autoloader.'
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
spl_autoload_register($testLoader, true, true);
|
||||
try {
|
||||
self::assertEmpty($reader->getClassAnnotations($class));
|
||||
} finally {
|
||||
spl_autoload_unregister($testLoader);
|
||||
}
|
||||
}
|
||||
|
||||
public function testPHPCodeSnifferAnnotationsAreIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(ClassWithPHPCodeSnifferAnnotation::class);
|
||||
|
||||
self::assertEmpty($reader->getClassAnnotations($ref));
|
||||
}
|
||||
|
||||
public function testPHPStanGenericsAnnotationsAreIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(ClassWithPHPStanGenericsAnnotations::class);
|
||||
|
||||
self::assertEmpty($reader->getClassAnnotations($ref));
|
||||
self::assertEmpty($reader->getPropertyAnnotations($ref->getProperty('bar')));
|
||||
self::assertEmpty($reader->getMethodAnnotations($ref->getMethod('foo')));
|
||||
|
||||
$this->expectException('\Doctrine\Common\Annotations\AnnotationException');
|
||||
$this->expectExceptionMessage(
|
||||
'[Semantical Error] The annotation "@Template" in method' .
|
||||
' Doctrine\Tests\Common\Annotations\Fixtures\ClassWithPHPStanGenericsAnnotations' .
|
||||
'::twigTemplateFunctionName() was never imported.'
|
||||
);
|
||||
self::assertEmpty($reader->getMethodAnnotations($ref->getMethod('twigTemplateFunctionName')));
|
||||
}
|
||||
|
||||
public function testImportedIgnoredAnnotationIsStillIgnored(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(ClassWithImportedIgnoredAnnotation::class);
|
||||
|
||||
self::assertEmpty($reader->getMethodAnnotations($ref->getMethod('something')));
|
||||
}
|
||||
|
||||
public function testFunctionsAnnotation(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionFunction('Doctrine\Tests\Common\Annotations\Fixtures\foo');
|
||||
|
||||
$annotations = $reader->getFunctionAnnotations($ref);
|
||||
self::assertCount(1, $annotations);
|
||||
self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotations[0]);
|
||||
}
|
||||
|
||||
public function testFunctionAnnotation(): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionFunction('Doctrine\Tests\Common\Annotations\Fixtures\foo');
|
||||
|
||||
$annotation = $reader->getFunctionAnnotation($ref, Fixtures\Annotation\Autoload::class);
|
||||
self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8.1
|
||||
* @dataProvider provideEnumProperties
|
||||
*/
|
||||
public function testAnnotationWithEnum(string $property, Suit $expectedValue): void
|
||||
{
|
||||
$reader = $this->getReader();
|
||||
$ref = new ReflectionClass(ClassWithEnumAnnotations::class);
|
||||
|
||||
$annotation = $reader->getPropertyAnnotation($ref->getProperty($property), AnnotationWithEnumProperty::class);
|
||||
|
||||
self::assertSame($expectedValue, $annotation->suit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array{string, Suit}>
|
||||
*/
|
||||
public function provideEnumProperties(): array
|
||||
{
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'annotationWithDefaults' => ['annotationWithDefaults', Suit::Hearts],
|
||||
'annotationWithSpades' => ['annotationWithSpades', Suit::Spades],
|
||||
];
|
||||
}
|
||||
}
|
||||
231
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AnnotationRegistryTest.php
vendored
Normal file
231
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AnnotationRegistryTest.php
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\CanBeAutoLoaded;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\LoadedUsingRegisterFile;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\ShouldNeverBeLoaded;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionProperty;
|
||||
use TypeError;
|
||||
|
||||
use function random_int;
|
||||
|
||||
class AnnotationRegistryTest extends TestCase
|
||||
{
|
||||
/** @var string */
|
||||
protected $class = AnnotationRegistry::class;
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testReset(): void
|
||||
{
|
||||
$data = ['foo' => 'bar'];
|
||||
|
||||
$this->setStaticField($this->class, 'autoloadNamespaces', $data);
|
||||
$this->setStaticField($this->class, 'loaders', $data);
|
||||
|
||||
self::assertSame($data, $this->getStaticField($this->class, 'autoloadNamespaces'));
|
||||
self::assertSame($data, $this->getStaticField($this->class, 'loaders'));
|
||||
|
||||
AnnotationRegistry::reset();
|
||||
|
||||
self::assertEmpty($this->getStaticField($this->class, 'autoloadNamespaces'));
|
||||
self::assertEmpty($this->getStaticField($this->class, 'loaders'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testRegisterAutoloadNamespaces(): void
|
||||
{
|
||||
$this->setStaticField($this->class, 'autoloadNamespaces', ['foo' => 'bar']);
|
||||
|
||||
AnnotationRegistry::registerAutoloadNamespaces(['test' => 'bar']);
|
||||
self::assertSame(['foo' => 'bar', 'test' => 'bar'], $this->getStaticField($this->class, 'autoloadNamespaces'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testRegisterLoaderNoCallable(): void
|
||||
{
|
||||
$this->expectException(TypeError::class);
|
||||
|
||||
AnnotationRegistry::registerLoader('test' . random_int(10, 10000));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $value
|
||||
*/
|
||||
protected function setStaticField(string $class, string $field, array $value): void
|
||||
{
|
||||
$reflection = new ReflectionProperty($class, $field);
|
||||
|
||||
$reflection->setAccessible(true);
|
||||
$reflection->setValue(null, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getStaticField(string $class, string $field)
|
||||
{
|
||||
$reflection = new ReflectionProperty($class, $field);
|
||||
|
||||
$reflection->setAccessible(true);
|
||||
|
||||
return $reflection->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testStopCallingLoadersIfClassIsNotFound(): void
|
||||
{
|
||||
AnnotationRegistry::reset();
|
||||
$i = 0;
|
||||
$autoLoader = static function () use (&$i): bool {
|
||||
$i += 1;
|
||||
|
||||
return false;
|
||||
};
|
||||
AnnotationRegistry::registerLoader($autoLoader);
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
self::assertSame(1, $i, 'Autoloader should only be called once');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testStopCallingLoadersAfterClassIsFound(): void
|
||||
{
|
||||
$className = 'autoloadedClass' . random_int(10, 100000);
|
||||
AnnotationRegistry::reset();
|
||||
$i = 0;
|
||||
$autoLoader = static function () use (&$i, $className): bool {
|
||||
eval('class ' . $className . ' {}');
|
||||
$i += 1;
|
||||
|
||||
return true;
|
||||
};
|
||||
AnnotationRegistry::registerLoader($autoLoader);
|
||||
AnnotationRegistry::loadAnnotationClass($className);
|
||||
AnnotationRegistry::loadAnnotationClass($className);
|
||||
AnnotationRegistry::loadAnnotationClass($className);
|
||||
self::assertSame(1, $i, 'Autoloader should only be called once');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testAddingANewLoaderClearsTheCache(): void
|
||||
{
|
||||
$failures = 0;
|
||||
$failingLoader = static function () use (&$failures): bool {
|
||||
$failures += 1;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
AnnotationRegistry::reset();
|
||||
AnnotationRegistry::registerLoader($failingLoader);
|
||||
|
||||
self::assertSame(0, $failures);
|
||||
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
|
||||
self::assertSame(1, $failures);
|
||||
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
|
||||
self::assertSame(1, $failures);
|
||||
|
||||
AnnotationRegistry::registerLoader(static function (): bool {
|
||||
return false;
|
||||
});
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
|
||||
self::assertSame(2, $failures);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testResetClearsRegisteredAutoloaderFailures(): void
|
||||
{
|
||||
$failures = 0;
|
||||
$failingLoader = static function () use (&$failures): bool {
|
||||
$failures += 1;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
AnnotationRegistry::reset();
|
||||
AnnotationRegistry::registerLoader($failingLoader);
|
||||
|
||||
self::assertSame(0, $failures);
|
||||
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
|
||||
self::assertSame(1, $failures);
|
||||
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
|
||||
self::assertSame(1, $failures);
|
||||
|
||||
AnnotationRegistry::reset();
|
||||
AnnotationRegistry::registerLoader($failingLoader);
|
||||
AnnotationRegistry::loadAnnotationClass('unloadableClass');
|
||||
|
||||
self::assertSame(2, $failures);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testRegisterLoaderIfNotExistsOnlyRegisteresSameLoaderOnce(): void
|
||||
{
|
||||
$className = 'autoloadedClassThatDoesNotExist';
|
||||
AnnotationRegistry::reset();
|
||||
$autoLoader = self::createPartialMock(Autoloader::class, ['__invoke']);
|
||||
$autoLoader->expects($this->once())->method('__invoke');
|
||||
AnnotationRegistry::registerUniqueLoader($autoLoader);
|
||||
AnnotationRegistry::registerUniqueLoader($autoLoader);
|
||||
AnnotationRegistry::loadAnnotationClass($className);
|
||||
AnnotationRegistry::loadAnnotationClass($className);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testClassExistsFallback(): void
|
||||
{
|
||||
AnnotationRegistry::reset();
|
||||
|
||||
self::assertTrue(AnnotationRegistry::loadAnnotationClass(CanBeAutoLoaded::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testClassExistsFallbackNotUsedWhenRegisterFileUsed(): void
|
||||
{
|
||||
AnnotationRegistry::reset();
|
||||
AnnotationRegistry::registerFile(__DIR__ . '/Fixtures/Annotation/LoadedUsingRegisterFile.php');
|
||||
|
||||
self::assertTrue(AnnotationRegistry::loadAnnotationClass(LoadedUsingRegisterFile::class));
|
||||
self::assertFalse(AnnotationRegistry::loadAnnotationClass(ShouldNeverBeLoaded::class));
|
||||
}
|
||||
}
|
||||
|
||||
class Autoloader
|
||||
{
|
||||
public function __invoke(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
46
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AnnotationTest.php
vendored
Normal file
46
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/AnnotationTest.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Doctrine\Common\Annotations\Annotation;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
final class AnnotationTest extends TestCase
|
||||
{
|
||||
public function testMagicGetThrowsBadMethodCallException(): void
|
||||
{
|
||||
$name = 'foo';
|
||||
|
||||
$annotation = new Annotation([]);
|
||||
|
||||
$this->expectException(BadMethodCallException::class);
|
||||
$this->expectExceptionMessage(sprintf(
|
||||
"Unknown property '%s' on annotation '%s'.",
|
||||
$name,
|
||||
Annotation::class
|
||||
));
|
||||
|
||||
// @phpstan-ignore-next-line This is expected not to exist
|
||||
$annotation->{$name};
|
||||
}
|
||||
|
||||
public function testMagicSetThrowsBadMethodCallException(): void
|
||||
{
|
||||
$name = 'foo';
|
||||
|
||||
$annotation = new Annotation([]);
|
||||
|
||||
$this->expectException(BadMethodCallException::class);
|
||||
$this->expectExceptionMessage(sprintf(
|
||||
"Unknown property '%s' on annotation '%s'.",
|
||||
$name,
|
||||
Annotation::class
|
||||
));
|
||||
|
||||
// @phpstan-ignore-next-line This is expected not to exist
|
||||
$annotation->{$name} = 9001;
|
||||
}
|
||||
}
|
||||
292
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php
vendored
Normal file
292
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\CachedReader;
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\ClassThatUsesTraitThatUsesAnotherTraitWithMethods;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
|
||||
use function assert;
|
||||
use function class_exists;
|
||||
use function time;
|
||||
use function touch;
|
||||
|
||||
class CachedReaderTest extends AbstractReaderTest
|
||||
{
|
||||
/** @var int|ArrayCache */
|
||||
private $cache;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
if (! class_exists(ArrayCache::class)) {
|
||||
$this->markTestSkipped('Cannot test deprecated cached reader without doctrine/cache 1.x');
|
||||
}
|
||||
|
||||
parent::setup();
|
||||
}
|
||||
|
||||
public function testIgnoresStaleCache(): void
|
||||
{
|
||||
$cache = time() - 10;
|
||||
touch(__DIR__ . '/Fixtures/Controller.php', $cache + 10);
|
||||
|
||||
$this->doTestCacheStale(Fixtures\Controller::class, $cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 62
|
||||
*/
|
||||
public function testIgnoresStaleCacheWithParentClass(): void
|
||||
{
|
||||
$cache = time() - 10;
|
||||
touch(__DIR__ . '/Fixtures/ControllerWithParentClass.php', $cache - 10);
|
||||
touch(__DIR__ . '/Fixtures/AbstractController.php', $cache + 10);
|
||||
|
||||
$this->doTestCacheStale(Fixtures\ControllerWithParentClass::class, $cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 62
|
||||
*/
|
||||
public function testIgnoresStaleCacheWithTraits(): void
|
||||
{
|
||||
$cache = time() - 10;
|
||||
touch(__DIR__ . '/Fixtures/ControllerWithTrait.php', $cache - 10);
|
||||
touch(__DIR__ . '/Fixtures/Traits/SecretRouteTrait.php', $cache + 10);
|
||||
|
||||
$this->doTestCacheStale(Fixtures\ControllerWithTrait::class, $cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 62
|
||||
*/
|
||||
public function testIgnoresStaleCacheWithTraitsThatUseOtherTraits(): void
|
||||
{
|
||||
$cache = time() - 10;
|
||||
|
||||
touch(__DIR__ . '/Fixtures/ClassThatUsesTraitThatUsesAnotherTrait.php', $cache - 10);
|
||||
touch(__DIR__ . '/Fixtures/Traits/EmptyTrait.php', $cache + 10);
|
||||
|
||||
$this->doTestCacheStale(
|
||||
Fixtures\ClassThatUsesTraitThatUsesAnotherTrait::class,
|
||||
$cache
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 62
|
||||
*/
|
||||
public function testIgnoresStaleCacheWithInterfacesThatExtendOtherInterfaces(): void
|
||||
{
|
||||
$cache = time() - 10;
|
||||
|
||||
touch(__DIR__ . '/Fixtures/InterfaceThatExtendsAnInterface.php', $cache - 10);
|
||||
touch(__DIR__ . '/Fixtures/EmptyInterface.php', $cache + 10);
|
||||
|
||||
$this->doTestCacheStale(
|
||||
Fixtures\InterfaceThatExtendsAnInterface::class,
|
||||
$cache
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 62
|
||||
* @group 105
|
||||
*/
|
||||
public function testUsesFreshCacheWithTraitsThatUseOtherTraits(): void
|
||||
{
|
||||
$cacheTime = time();
|
||||
|
||||
touch(__DIR__ . '/Fixtures/ClassThatUsesTraitThatUsesAnotherTrait.php', $cacheTime - 10);
|
||||
touch(__DIR__ . '/Fixtures/Traits/EmptyTrait.php', $cacheTime - 10);
|
||||
|
||||
$this->doTestCacheFresh(
|
||||
'Doctrine\Tests\Common\Annotations\Fixtures\ClassThatUsesTraitThatUsesAnotherTrait',
|
||||
$cacheTime
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 62
|
||||
*/
|
||||
public function testPurgeLoadedAnnotations(): void
|
||||
{
|
||||
$cache = time() - 10;
|
||||
|
||||
touch(__DIR__ . '/Fixtures/ClassThatUsesTraitThatUsesAnotherTrait.php', $cache - 10);
|
||||
touch(__DIR__ . '/Fixtures/Traits/EmptyTrait.php', $cache + 10);
|
||||
|
||||
$reader = $this->doTestCacheStale(
|
||||
Fixtures\ClassThatUsesTraitThatUsesAnotherTrait::class,
|
||||
$cache
|
||||
);
|
||||
|
||||
$classReader = new ReflectionClass(CachedReader::class);
|
||||
|
||||
$loadedAnnotationsProperty = $classReader->getProperty('loadedAnnotations');
|
||||
$loadedAnnotationsProperty->setAccessible(true);
|
||||
$this->assertCount(1, $loadedAnnotationsProperty->getValue($reader));
|
||||
|
||||
$loadedFilemtimesProperty = $classReader->getProperty('loadedFilemtimes');
|
||||
$loadedFilemtimesProperty->setAccessible(true);
|
||||
$this->assertCount(3, $loadedFilemtimesProperty->getValue($reader));
|
||||
|
||||
$reader->clearLoadedAnnotations();
|
||||
|
||||
$this->assertCount(0, $loadedAnnotationsProperty->getValue($reader));
|
||||
$this->assertCount(0, $loadedFilemtimesProperty->getValue($reader));
|
||||
}
|
||||
|
||||
/**
|
||||
* As there is a cache on loadedAnnotations, we need to test two different
|
||||
* method's annotations of the same file
|
||||
*
|
||||
* We test four things
|
||||
* 1. we load the file (and its filemtime) for method1 annotation with fresh cache
|
||||
* 2. we load the file for method2 with stale cache => but still no save, because seen as fresh
|
||||
* 3. we purge loaded annotations and filemtime
|
||||
* 4. same as 2, but this time without filemtime cache, so file seen as stale and new cache is saved
|
||||
*
|
||||
* @group 62
|
||||
* @group 105
|
||||
*/
|
||||
public function testAvoidCallingFilemtimeTooMuch(): void
|
||||
{
|
||||
$this->markTestSkipped('Skipped until further investigation');
|
||||
|
||||
$className = ClassThatUsesTraitThatUsesAnotherTraitWithMethods::class;
|
||||
$cacheKey = $className;
|
||||
$cacheTime = time() - 10;
|
||||
|
||||
$cacheKeyMethod1 = $cacheKey . '#method1';
|
||||
$cacheKeyMethod2 = $cacheKey . '#method2';
|
||||
|
||||
$route1 = new Route();
|
||||
$route1->pattern = '/someprefix';
|
||||
$route2 = new Route();
|
||||
$route2->pattern = '/someotherprefix';
|
||||
|
||||
$cache = $this->createMock('Doctrine\Common\Cache\Cache');
|
||||
assert($cache instanceof Cache && $cache instanceof MockObject);
|
||||
|
||||
$cache
|
||||
->expects($this->exactly(6))
|
||||
->method('fetch')
|
||||
->withConsecutive(
|
||||
// first pass => cache ok for method 1
|
||||
// we load annotations AND filemtimes for this file
|
||||
[$this->equalTo($cacheKeyMethod1)],
|
||||
[$this->equalTo('[C]' . $cacheKeyMethod1)],
|
||||
// second pass => cache ok for method 2
|
||||
// filemtime is seen as fresh even if it's not
|
||||
[$this->equalTo($cacheKeyMethod2)],
|
||||
[$this->equalTo('[C]' . $cacheKeyMethod2)],
|
||||
// third pass => cache stale for method 2
|
||||
// filemtime is seen as not fresh => we save
|
||||
[$this->equalTo($cacheKeyMethod2)],
|
||||
[$this->equalTo('[C]' . $cacheKeyMethod2)]
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(
|
||||
[$route1], // Result was cached, but there was an annotation;
|
||||
$cacheTime,
|
||||
[$route2], // Result was cached, but there was an annotation;
|
||||
$cacheTime,
|
||||
[$route2], // Result was cached, but there was an annotation;
|
||||
$cacheTime
|
||||
);
|
||||
|
||||
$cache
|
||||
->expects($this->exactly(2))
|
||||
->method('save')
|
||||
->withConsecutive(
|
||||
[$this->equalTo($cacheKeyMethod2)],
|
||||
[$this->equalTo('[C]' . $cacheKeyMethod2)]
|
||||
);
|
||||
|
||||
$reader = new CachedReader(new AnnotationReader(), $cache, true);
|
||||
|
||||
touch(__DIR__ . '/Fixtures/ClassThatUsesTraitThatUsesAnotherTraitWithMethods.php', $cacheTime - 20);
|
||||
touch(__DIR__ . '/Fixtures/Traits/EmptyTrait.php', $cacheTime - 20);
|
||||
$this->assertEquals([$route1], $reader->getMethodAnnotations(new ReflectionMethod($className, 'method1')));
|
||||
|
||||
// only filemtime changes, but not cleared => no change
|
||||
touch(__DIR__ . '/Fixtures/ClassThatUsesTraitThatUsesAnotherTrait.php', $cacheTime + 5);
|
||||
touch(__DIR__ . '/Fixtures/Traits/EmptyTrait.php', $cacheTime + 5);
|
||||
$this->assertEquals([$route2], $reader->getMethodAnnotations(new ReflectionMethod($className, 'method2')));
|
||||
|
||||
$reader->clearLoadedAnnotations();
|
||||
$this->assertEquals([$route2], $reader->getMethodAnnotations(new ReflectionMethod($className, 'method2')));
|
||||
}
|
||||
|
||||
protected function doTestCacheStale(string $className, int $lastCacheModification): CachedReader
|
||||
{
|
||||
$cacheKey = $className;
|
||||
|
||||
$cache = $this->createMock(Cache::class);
|
||||
$cache
|
||||
->expects($this->exactly(2))
|
||||
->method('fetch')
|
||||
->withConsecutive(
|
||||
[$this->equalTo($cacheKey)],
|
||||
[$this->equalTo('[C]' . $cacheKey)]
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(
|
||||
[], // Result was cached, but there was no annotation
|
||||
$lastCacheModification
|
||||
);
|
||||
$cache
|
||||
->expects($this->exactly(2))
|
||||
->method('save')
|
||||
->withConsecutive(
|
||||
[$this->equalTo($cacheKey)],
|
||||
[$this->equalTo('[C]' . $cacheKey)]
|
||||
);
|
||||
|
||||
$reader = new CachedReader(new AnnotationReader(), $cache, true);
|
||||
$route = new Route();
|
||||
$route->pattern = '/someprefix';
|
||||
|
||||
self::assertEquals([$route], $reader->getClassAnnotations(new ReflectionClass($className)));
|
||||
|
||||
return $reader;
|
||||
}
|
||||
|
||||
protected function doTestCacheFresh(string $className, int $lastCacheModification): void
|
||||
{
|
||||
$cacheKey = $className;
|
||||
$route = new Route();
|
||||
$route->pattern = '/someprefix';
|
||||
|
||||
$cache = $this->createMock('Doctrine\Common\Cache\Cache');
|
||||
$cache
|
||||
->expects($this->exactly(2))
|
||||
->method('fetch')
|
||||
->withConsecutive(
|
||||
[$this->equalTo($cacheKey)],
|
||||
[$this->equalTo('[C]' . $cacheKey)]
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(
|
||||
[$route],
|
||||
$lastCacheModification
|
||||
);
|
||||
$cache->expects(self::never())->method('save');
|
||||
|
||||
$reader = new CachedReader(new AnnotationReader(), $cache, true);
|
||||
|
||||
$this->assertEquals([$route], $reader->getClassAnnotations(new ReflectionClass($className)));
|
||||
}
|
||||
|
||||
protected function getReader(): Reader
|
||||
{
|
||||
$this->cache = new ArrayCache();
|
||||
|
||||
return new CachedReader(new AnnotationReader(), $this->cache);
|
||||
}
|
||||
}
|
||||
328
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DocLexerTest.php
vendored
Normal file
328
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DocLexerTest.php
vendored
Normal file
@@ -0,0 +1,328 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\DocLexer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use function str_repeat;
|
||||
|
||||
class DocLexerTest extends TestCase
|
||||
{
|
||||
public function testMarkerAnnotation(): void
|
||||
{
|
||||
$lexer = new DocLexer();
|
||||
|
||||
$lexer->setInput('@Name');
|
||||
self::assertNull($lexer->token);
|
||||
self::assertNull($lexer->lookahead);
|
||||
|
||||
self::assertTrue($lexer->moveNext());
|
||||
self::assertNull($lexer->token);
|
||||
self::assertNotNull($lexer->lookahead);
|
||||
self::assertEquals('@', $lexer->lookahead['value']);
|
||||
|
||||
self::assertTrue($lexer->moveNext());
|
||||
self::assertNotNull($lexer->token);
|
||||
self::assertEquals('@', $lexer->token['value']);
|
||||
self::assertEquals('Name', $lexer->lookahead['value']);
|
||||
|
||||
self::assertFalse($lexer->moveNext());
|
||||
}
|
||||
|
||||
public function testScannerTokenizesDocBlockWhitConstants(): void
|
||||
{
|
||||
$lexer = new DocLexer();
|
||||
$docblock = '@AnnotationWithConstants(
|
||||
PHP_EOL,
|
||||
ClassWithConstants::SOME_VALUE,
|
||||
ClassWithConstants::CONSTANT_,
|
||||
ClassWithConstants::CONST_ANT3,
|
||||
\Doctrine\Tests\Common\Annotations\Fixtures\InterfaceWithConstants::SOME_VALUE
|
||||
)';
|
||||
|
||||
$tokens = [
|
||||
[
|
||||
'value' => '@',
|
||||
'position' => 0,
|
||||
'type' => DocLexer::T_AT,
|
||||
],
|
||||
[
|
||||
'value' => 'AnnotationWithConstants',
|
||||
'position' => 1,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => '(',
|
||||
'position' => 24,
|
||||
'type' => DocLexer::T_OPEN_PARENTHESIS,
|
||||
],
|
||||
[
|
||||
'value' => 'PHP_EOL',
|
||||
'position' => 38,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => ',',
|
||||
'position' => 45,
|
||||
'type' => DocLexer::T_COMMA,
|
||||
],
|
||||
[
|
||||
'value' => 'ClassWithConstants::SOME_VALUE',
|
||||
'position' => 59,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => ',',
|
||||
'position' => 89,
|
||||
'type' => DocLexer::T_COMMA,
|
||||
],
|
||||
[
|
||||
'value' => 'ClassWithConstants::CONSTANT_',
|
||||
'position' => 103,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => ',',
|
||||
'position' => 132,
|
||||
'type' => DocLexer::T_COMMA,
|
||||
],
|
||||
[
|
||||
'value' => 'ClassWithConstants::CONST_ANT3',
|
||||
'position' => 146,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => ',',
|
||||
'position' => 176,
|
||||
'type' => DocLexer::T_COMMA,
|
||||
],
|
||||
[
|
||||
'value' => '\\Doctrine\\Tests\\Common\\Annotations\\Fixtures\\InterfaceWithConstants::SOME_VALUE',
|
||||
'position' => 190,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => ')',
|
||||
'position' => 277,
|
||||
'type' => DocLexer::T_CLOSE_PARENTHESIS,
|
||||
],
|
||||
];
|
||||
|
||||
$lexer->setInput($docblock);
|
||||
|
||||
foreach ($tokens as $expected) {
|
||||
$lexer->moveNext();
|
||||
$lookahead = $lexer->lookahead;
|
||||
self::assertEquals($expected['value'], $lookahead['value']);
|
||||
self::assertEquals($expected['type'], $lookahead['type']);
|
||||
self::assertEquals($expected['position'], $lookahead['position']);
|
||||
}
|
||||
|
||||
self::assertFalse($lexer->moveNext());
|
||||
}
|
||||
|
||||
public function testScannerTokenizesDocBlockWhitInvalidIdentifier(): void
|
||||
{
|
||||
$lexer = new DocLexer();
|
||||
$docblock = '@Foo\3.42';
|
||||
|
||||
$tokens = [
|
||||
[
|
||||
'value' => '@',
|
||||
'position' => 0,
|
||||
'type' => DocLexer::T_AT,
|
||||
],
|
||||
[
|
||||
'value' => 'Foo',
|
||||
'position' => 1,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => '\\',
|
||||
'position' => 4,
|
||||
'type' => DocLexer::T_NAMESPACE_SEPARATOR,
|
||||
],
|
||||
[
|
||||
'value' => 3.42,
|
||||
'position' => 5,
|
||||
'type' => DocLexer::T_FLOAT,
|
||||
],
|
||||
];
|
||||
|
||||
$lexer->setInput($docblock);
|
||||
|
||||
foreach ($tokens as $expected) {
|
||||
$lexer->moveNext();
|
||||
$lookahead = $lexer->lookahead;
|
||||
self::assertEquals($expected['value'], $lookahead['value']);
|
||||
self::assertEquals($expected['type'], $lookahead['type']);
|
||||
self::assertEquals($expected['position'], $lookahead['position']);
|
||||
}
|
||||
|
||||
self::assertFalse($lexer->moveNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 44
|
||||
*/
|
||||
public function testWithinDoubleQuotesVeryVeryLongStringWillNotOverflowPregSplitStackLimit(): void
|
||||
{
|
||||
$lexer = new DocLexer();
|
||||
|
||||
$lexer->setInput('"' . str_repeat('.', 20240) . '"');
|
||||
|
||||
self::assertIsArray($lexer->glimpse());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 44
|
||||
*/
|
||||
public function testRecognizesDoubleQuotesEscapeSequence(): void
|
||||
{
|
||||
$lexer = new DocLexer();
|
||||
$docblock = '@Foo("""' . "\n" . '""")';
|
||||
|
||||
$tokens = [
|
||||
[
|
||||
'value' => '@',
|
||||
'position' => 0,
|
||||
'type' => DocLexer::T_AT,
|
||||
],
|
||||
[
|
||||
'value' => 'Foo',
|
||||
'position' => 1,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => '(',
|
||||
'position' => 4,
|
||||
'type' => DocLexer::T_OPEN_PARENTHESIS,
|
||||
],
|
||||
[
|
||||
'value' => "\"\n\"",
|
||||
'position' => 5,
|
||||
'type' => DocLexer::T_STRING,
|
||||
],
|
||||
[
|
||||
'value' => ')',
|
||||
'position' => 12,
|
||||
'type' => DocLexer::T_CLOSE_PARENTHESIS,
|
||||
],
|
||||
];
|
||||
|
||||
$lexer->setInput($docblock);
|
||||
|
||||
foreach ($tokens as $expected) {
|
||||
$lexer->moveNext();
|
||||
$lookahead = $lexer->lookahead;
|
||||
self::assertEquals($expected['value'], $lookahead['value']);
|
||||
self::assertEquals($expected['type'], $lookahead['type']);
|
||||
self::assertEquals($expected['position'], $lookahead['position']);
|
||||
}
|
||||
|
||||
self::assertFalse($lexer->moveNext());
|
||||
}
|
||||
|
||||
public function testDoesNotRecognizeFullAnnotationWithDashInIt(): void
|
||||
{
|
||||
$this->expectDocblockTokens(
|
||||
'@foo-bar--',
|
||||
[
|
||||
[
|
||||
'value' => '@',
|
||||
'position' => 0,
|
||||
'type' => DocLexer::T_AT,
|
||||
],
|
||||
[
|
||||
'value' => 'foo',
|
||||
'position' => 1,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => '-',
|
||||
'position' => 4,
|
||||
'type' => DocLexer::T_MINUS,
|
||||
],
|
||||
[
|
||||
'value' => 'bar',
|
||||
'position' => 5,
|
||||
'type' => DocLexer::T_IDENTIFIER,
|
||||
],
|
||||
[
|
||||
'value' => '-',
|
||||
'position' => 8,
|
||||
'type' => DocLexer::T_MINUS,
|
||||
],
|
||||
[
|
||||
'value' => '-',
|
||||
'position' => 9,
|
||||
'type' => DocLexer::T_MINUS,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testRecognizesNegativeNumbers(): void
|
||||
{
|
||||
$this->expectDocblockTokens(
|
||||
'-12.34 -56',
|
||||
[
|
||||
[
|
||||
'value' => '-12.34',
|
||||
'position' => 0,
|
||||
'type' => DocLexer::T_FLOAT,
|
||||
],
|
||||
[
|
||||
'value' => '-56',
|
||||
'position' => 7,
|
||||
'type' => DocLexer::T_INTEGER,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param list<array{value: mixed, position: int, type:int}> $expectedTokens
|
||||
*/
|
||||
private function expectDocblockTokens(string $docBlock, array $expectedTokens): void
|
||||
{
|
||||
$lexer = new DocLexer();
|
||||
$lexer->setInput($docBlock);
|
||||
|
||||
$actualTokens = [];
|
||||
|
||||
while ($lexer->moveNext()) {
|
||||
$lookahead = $lexer->lookahead;
|
||||
|
||||
$actualTokens[] = [
|
||||
'value' => $lookahead['value'],
|
||||
'type' => $lookahead['type'],
|
||||
'position' => $lookahead['position'],
|
||||
];
|
||||
}
|
||||
|
||||
self::assertEquals($expectedTokens, $actualTokens);
|
||||
}
|
||||
|
||||
public function testTokenAdjacency(): void
|
||||
{
|
||||
$lexer = new DocLexer();
|
||||
|
||||
$lexer->setInput('-- -');
|
||||
|
||||
self::assertTrue($lexer->nextTokenIsAdjacent());
|
||||
self::assertTrue($lexer->moveNext());
|
||||
self::assertTrue($lexer->nextTokenIsAdjacent());
|
||||
self::assertTrue($lexer->moveNext());
|
||||
self::assertTrue($lexer->nextTokenIsAdjacent());
|
||||
self::assertTrue($lexer->moveNext());
|
||||
self::assertFalse($lexer->nextTokenIsAdjacent());
|
||||
self::assertFalse($lexer->moveNext());
|
||||
}
|
||||
|
||||
public function testItReturnsNullWhenThereIsNothingToParse(): void
|
||||
{
|
||||
self::assertNull((new DocLexer())->peek());
|
||||
}
|
||||
}
|
||||
2092
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DocParserTest.php
vendored
Normal file
2092
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DocParserTest.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DummyClass.php
vendored
Normal file
52
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/DummyClass.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
/**
|
||||
* 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".
|
||||
*
|
||||
* @DummyAnnotation(dummyValue="hello")
|
||||
*/
|
||||
class DummyClass
|
||||
{
|
||||
/**
|
||||
* A nice property.
|
||||
*
|
||||
* @var mixed
|
||||
* @DummyAnnotation(dummyValue="fieldHello")
|
||||
*/
|
||||
public $field1;
|
||||
|
||||
/**
|
||||
* @var mixed;
|
||||
* @DummyJoinTable(name="join_table",
|
||||
* joinColumns={@DummyJoinColumn(name="col1", referencedColumnName="col2")},
|
||||
* inverseJoinColumns={
|
||||
* @DummyJoinColumn(name="col3", referencedColumnName="col4")
|
||||
* })
|
||||
*/
|
||||
public $field2;
|
||||
|
||||
/**
|
||||
* Gets the value of field1.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @DummyAnnotation({1,2,"three"})
|
||||
*/
|
||||
public function getField1()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A parameter value with a space in it.
|
||||
*
|
||||
* @DummyAnnotation("\d{4}-[01]\d-[0-3]\d [0-2]\d:[0-5]\d:[0-5]\d")
|
||||
*/
|
||||
public function getField3(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
56
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/FileCacheReaderTest.php
vendored
Normal file
56
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/FileCacheReaderTest.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Doctrine\Common\Annotations\FileCacheReader;
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
|
||||
use function glob;
|
||||
use function method_exists;
|
||||
use function mkdir;
|
||||
use function rmdir;
|
||||
use function sys_get_temp_dir;
|
||||
use function uniqid;
|
||||
use function unlink;
|
||||
|
||||
class FileCacheReaderTest extends AbstractReaderTest
|
||||
{
|
||||
/** @var string */
|
||||
private $cacheDir;
|
||||
|
||||
protected function getReader(): Reader
|
||||
{
|
||||
$this->cacheDir = sys_get_temp_dir() . '/annotations_' . uniqid('', true);
|
||||
@mkdir($this->cacheDir);
|
||||
|
||||
return new FileCacheReader(new AnnotationReader(), $this->cacheDir);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
foreach (glob($this->cacheDir . '/*.php') as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
rmdir($this->cacheDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DCOM-81
|
||||
*/
|
||||
public function testAttemptToCreateAnnotationCacheDir(): void
|
||||
{
|
||||
$this->cacheDir = sys_get_temp_dir() . '/not_existed_dir_' . uniqid('', true);
|
||||
|
||||
if (method_exists($this, 'assertDirectoryDoesNotExist')) {
|
||||
self::assertDirectoryDoesNotExist($this->cacheDir);
|
||||
} else {
|
||||
self::assertDirectoryNotExists($this->cacheDir);
|
||||
}
|
||||
|
||||
new FileCacheReader(new AnnotationReader(), $this->cacheDir);
|
||||
|
||||
self::assertDirectoryExists($this->cacheDir);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
abstract class AbstractController
|
||||
{
|
||||
}
|
||||
@@ -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,8 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
/** @Annotation */
|
||||
class CanBeAutoLoaded
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
/** @Annotation */
|
||||
class LoadedUsingRegisterFile
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
class Param
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
/** @Annotation */
|
||||
class Route
|
||||
{
|
||||
/** @var string @Required */
|
||||
public $pattern;
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
use function is_string;
|
||||
|
||||
/** @Annotation */
|
||||
class Secure
|
||||
{
|
||||
/** @var mixed */
|
||||
public $roles;
|
||||
|
||||
/**
|
||||
* @param mixed[] $values
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
if (is_string($values['value'])) {
|
||||
$values['value'] = [$values['value']];
|
||||
}
|
||||
|
||||
$this->roles = $values['value'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
/** @Annotation */
|
||||
class ShouldNeverBeLoaded
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class SingleUseAnnotation
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
/** @Annotation */
|
||||
class Template
|
||||
{
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @param mixed[] $values
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
$this->name = $values['value'] ?? null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures\Annotation;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("PROPERTY")
|
||||
*/
|
||||
final class Version
|
||||
{
|
||||
}
|
||||
20
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationEnum.php
vendored
Normal file
20
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/AnnotationEnum.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
final class AnnotationEnum
|
||||
{
|
||||
public const ONE = 'ONE';
|
||||
public const TWO = 'TWO';
|
||||
public const THREE = 'THREE';
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
* @Enum({"ONE","TWO","THREE"})
|
||||
*/
|
||||
public $value;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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,33 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnumLiteral as SelfEnum;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
final class AnnotationEnumLiteral
|
||||
{
|
||||
public const ONE = 1;
|
||||
public const TWO = 2;
|
||||
public 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,30 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
final class AnnotationEnumLiteralInvalid
|
||||
{
|
||||
public const ONE = 1;
|
||||
public const TWO = 2;
|
||||
public const THREE = 3;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
* @Enum(
|
||||
* value = {
|
||||
* 1,
|
||||
* 2
|
||||
* },
|
||||
* literal = {
|
||||
* 1 : "AnnotationEnumLiteral::ONE",
|
||||
* 2 : "AnnotationEnumLiteral::TWO",
|
||||
* 3 : "AnnotationEnumLiteral::THREE"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
public $value;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
class AnnotationTargetAll
|
||||
{
|
||||
/** @var mixed */
|
||||
public $data;
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
/** @var mixed */
|
||||
public $target;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({ "ANNOTATION" })
|
||||
*/
|
||||
final class AnnotationTargetAnnotation
|
||||
{
|
||||
/** @var mixed */
|
||||
public $data;
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
/** @var mixed */
|
||||
public $target;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("CLASS")
|
||||
*/
|
||||
final class AnnotationTargetClass
|
||||
{
|
||||
/** @var mixed */
|
||||
public $data;
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
/** @var mixed */
|
||||
public $target;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("METHOD")
|
||||
*/
|
||||
final class AnnotationTargetMethod
|
||||
{
|
||||
/** @var mixed */
|
||||
public $data;
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
/** @var mixed */
|
||||
public $target;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({ "METHOD", "PROPERTY" })
|
||||
*/
|
||||
final class AnnotationTargetPropertyMethod
|
||||
{
|
||||
/** @var mixed */
|
||||
public $data;
|
||||
/** @var mixed */
|
||||
public $name;
|
||||
/** @var mixed */
|
||||
public $target;
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll;
|
||||
|
||||
/**
|
||||
* @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("arrayOfStrings", type = "string[]"),
|
||||
@Attribute("annotation", type = "Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll"),
|
||||
@Attribute("arrayOfAnnotations", type = "array<Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll>"),
|
||||
})
|
||||
*/
|
||||
final class AnnotationWithAttributes
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var mixed */
|
||||
private $mixed;
|
||||
/** @var bool */
|
||||
private $boolean;
|
||||
/** @var bool */
|
||||
private $bool;
|
||||
/** @var float */
|
||||
private $float;
|
||||
/** @var string */
|
||||
private $string;
|
||||
/** @var integer */
|
||||
private $integer;
|
||||
/** @var mixed[] */
|
||||
private $array;
|
||||
/** @var object */
|
||||
private $annotation;
|
||||
/** @var int[] */
|
||||
private $arrayOfIntegers;
|
||||
/** @var string[] */
|
||||
private $arrayOfStrings;
|
||||
/** @var object[] */
|
||||
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(): int
|
||||
{
|
||||
return $this->integer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getArray()
|
||||
{
|
||||
return $this->array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AnnotationTargetAll
|
||||
*/
|
||||
public function getAnnotation()
|
||||
{
|
||||
return $this->annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getArrayOfStrings()
|
||||
{
|
||||
return $this->arrayOfStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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,17 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
final class AnnotationWithConstants
|
||||
{
|
||||
public const INTEGER = 1;
|
||||
public const FLOAT = 1.2;
|
||||
public const STRING = '1.2.3';
|
||||
|
||||
/** @var mixed */
|
||||
public $value;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
* @NamedArgumentConstructor
|
||||
*/
|
||||
final class AnnotationWithEnumProperty
|
||||
{
|
||||
public function __construct(
|
||||
public readonly Suit $suit = Suit::Hearts,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
* @Attributes({
|
||||
@Attribute("value", required = true , type = "string"),
|
||||
@Attribute(
|
||||
"annot",
|
||||
required = true ,
|
||||
type = "Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation"
|
||||
),
|
||||
})
|
||||
*/
|
||||
final class AnnotationWithRequiredAttributes
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
private $value;
|
||||
|
||||
/** @var AnnotationTargetAnnotation */
|
||||
private $annot;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AnnotationTargetAnnotation
|
||||
*/
|
||||
public function getAnnot()
|
||||
{
|
||||
return $this->annot;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target("ALL")
|
||||
*/
|
||||
final class AnnotationWithRequiredAttributesWithoutConstructor
|
||||
{
|
||||
/**
|
||||
* @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,43 @@
|
||||
<?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 string[] */
|
||||
public $arrayOfStrings;
|
||||
|
||||
/** @var \Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll[] */
|
||||
public $arrayOfAnnotations;
|
||||
}
|
||||
11
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Api.php
vendored
Normal file
11
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/Api.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
/**
|
||||
* This class is not an annotation
|
||||
* It's a class build to test ClassWithInclude
|
||||
*/
|
||||
class Api
|
||||
{
|
||||
}
|
||||
30
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassDDC1660.php
vendored
Normal file
30
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassDDC1660.php
vendored
Normal file
@@ -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 $param
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 2.0
|
||||
* @version 1
|
||||
*/
|
||||
public function bar($param)
|
||||
{
|
||||
return $param;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass;
|
||||
|
||||
class Doctrine_Tests_Common_Annotations_Fixtures_ClassNoNamespaceNoComment
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Bar2\Autoload;
|
||||
|
||||
class ClassOverwritesTrait
|
||||
{
|
||||
use TraitWithAnnotatedMethod;
|
||||
|
||||
/**
|
||||
* @Autoload
|
||||
*/
|
||||
public function traitMethod(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Bar2;
|
||||
|
||||
/** @Annotation */
|
||||
class Autoload
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Traits\TraitThatUsesAnotherTrait;
|
||||
|
||||
/**
|
||||
* @Route("/someprefix")
|
||||
*/
|
||||
class ClassThatUsesTraitThatUsesAnotherTrait
|
||||
{
|
||||
use TraitThatUsesAnotherTrait;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Traits\TraitThatUsesAnotherTrait;
|
||||
|
||||
class ClassThatUsesTraitThatUsesAnotherTraitWithMethods
|
||||
{
|
||||
use TraitThatUsesAnotherTrait;
|
||||
|
||||
/**
|
||||
* @Route("/someprefix")
|
||||
*/
|
||||
public function method1(): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/someotherprefix")
|
||||
*/
|
||||
public function method2(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
30
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassUsesTrait.php
vendored
Normal file
30
vendor/doctrine/annotations/tests/Doctrine/Tests/Common/Annotations/Fixtures/ClassUsesTrait.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Bar\Autoload;
|
||||
|
||||
class ClassUsesTrait
|
||||
{
|
||||
use TraitWithAnnotatedMethod;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
* @Autoload
|
||||
*/
|
||||
public $aProperty;
|
||||
|
||||
/**
|
||||
* @Autoload
|
||||
*/
|
||||
public function someMethod(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Bar;
|
||||
|
||||
/** @Annotation */
|
||||
class Autoload
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route;
|
||||
|
||||
/** @Route(@AValid-constant::REFERENCE) */
|
||||
class ClassWithAnnotationConstantReferenceWithDashes
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationEnum;
|
||||
|
||||
class ClassWithAnnotationEnum
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @AnnotationEnum(AnnotationEnum::ONE)
|
||||
*/
|
||||
public $foo;
|
||||
|
||||
/**
|
||||
* @AnnotationEnum("TWO")
|
||||
*/
|
||||
public function bar(): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
* @AnnotationEnum("FOUR")
|
||||
*/
|
||||
public $invalidProperty;
|
||||
|
||||
/**
|
||||
* @AnnotationEnum(5)
|
||||
*/
|
||||
public function invalidMethod(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\Traits\TraitWithSelfConstantReferenceTrait;
|
||||
|
||||
/** @AnnotationWithConstants(self::VALUE_FOR_CLASS) */
|
||||
class ClassWithAnnotationWithSelfConstantReference
|
||||
{
|
||||
use TraitWithSelfConstantReferenceTrait;
|
||||
|
||||
public const VALUE_FOR_CLASS = 'ClassWithAnnotationWithSelfConstantReference.VALUE_FROM_CLASS';
|
||||
public const VALUE_FOR_TRAIT = 'ClassWithAnnotationWithSelfConstantReference.VALUE_FOR_TRAIT';
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
* @AnnotationWithConstants(self::VALUE_FOR_CLASS)
|
||||
*/
|
||||
private $classProperty;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*
|
||||
* @AnnotationWithConstants(self::VALUE_FOR_CLASS)
|
||||
*/
|
||||
public function classMethod()
|
||||
{
|
||||
return $this->classProperty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Annotations\Fixtures;
|
||||
|
||||
use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError;
|
||||
|
||||
/**
|
||||
* @AnnotationWithTargetSyntaxError()
|
||||
*/
|
||||
class ClassWithAnnotationWithTargetSyntaxError
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
* @AnnotationWithTargetSyntaxError()
|
||||
*/
|
||||
public $foo;
|
||||
|
||||
/**
|
||||
* @AnnotationWithTargetSyntaxError()
|
||||
*/
|
||||
public function bar(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user