diff --git a/Annotations/AnnotationGenerator.php b/Annotations/AnnotationGenerator.php
index f4e8f89..4e045e4 100644
--- a/Annotations/AnnotationGenerator.php
+++ b/Annotations/AnnotationGenerator.php
@@ -11,6 +11,9 @@
namespace Piwik\Plugins\OpenApiDocs\Annotations;
+use Matomo\Dependencies\OpenApiDocs\phpDocumentor\Reflection\DocBlock\Tags\Param;
+use Matomo\Dependencies\OpenApiDocs\phpDocumentor\Reflection\DocBlock\Tags\TagWithType;
+use Matomo\Dependencies\OpenApiDocs\phpDocumentor\Reflection\DocBlockFactory;
use Piwik\API\DocumentationGenerator;
use Piwik\API\NoDefaultValue;
use Piwik\API\Proxy;
@@ -24,11 +27,6 @@
use Piwik\UrlHelper;
use Piwik\Validators\BaseValidator;
use Piwik\Validators\NotEmpty;
-use PHPStan\PhpDocParser\Lexer\Lexer;
-use PHPStan\PhpDocParser\Parser\PhpDocParser;
-use PHPStan\PhpDocParser\Parser\TypeParser;
-use PHPStan\PhpDocParser\Parser\ConstExprParser;
-use PHPStan\PhpDocParser\Parser\TokenIterator;
class AnnotationGenerator
{
@@ -282,21 +280,21 @@ protected function buildAnnotationForMethod(array $rules, string $pluginName, \R
*/
public function getParamInfoFromDocBlock(string $docBlock): array
{
- $lexer = new Lexer();
- $tokens = $lexer->tokenize($docBlock);
- $expressionParser = new ConstExprParser();
- $parser = new PhpDocParser(new TypeParser($expressionParser), $expressionParser);
- $node = $parser->parse(new TokenIterator($tokens));
+ $factory = DocBlockFactory::createInstance();
+ $docBlockObject = $factory->create($docBlock);
$params = [];
- foreach ($node->getParamTagValues() as $param) {
- $name = ltrim($param->parameterName, '$');
+ foreach ($docBlockObject->getTagsByName('param') as $param) {
+ if (!($param instanceof Param)) {
+ continue;
+ }
+ $name = ltrim($param->getVariableName(), '$');
$params[$name] = [
- 'type' => (string)$param->type,
+ 'type' => (string) $param->getType(),
// Normalise the description. E.g. remove linebreaks and indentation
- 'description' => trim(preg_replace(['/^\h+/m', '/\R+/u',], ['', ' '], $param->description)),
- 'byRef' => $param->isReference,
- 'variadic' => $param->isVariadic,
+ 'description' => trim(preg_replace(['/^\h+/m', '/\R+/u',], ['', ' '], (string) $param->getDescription())),
+ 'byRef' => $param->isReference(),
+ 'variadic' => $param->isVariadic(),
];
}
return $params;
@@ -313,27 +311,24 @@ public function getParamInfoFromDocBlock(string $docBlock): array
*/
public function getResponseInfoFromDocBlock(string $docBlock): array
{
- $lexer = new Lexer();
- $tokens = $lexer->tokenize($docBlock);
- $expressionParser = new ConstExprParser();
- $parser = new PhpDocParser(new TypeParser($expressionParser), $expressionParser);
- $node = $parser->parse(new TokenIterator($tokens));
+ $factory = DocBlockFactory::createInstance();
+ $docBlockObject = $factory->create($docBlock);
$responseInfo = ['type' => null];
- $returnTags = $node->getReturnTagValues();
- if (empty($returnTags)) {
+ $returnTags = $docBlockObject->getTagsByName('return');
+ if (empty($returnTags) || !($returnTags[0] instanceof TagWithType)) {
return $responseInfo;
}
$returnTag = $returnTags[0];
- $tagValue = strval($returnTag->type);
+ $tagValue = strval($returnTag->getType());
$responseInfo['type'] = $this->getOpenApiTypeFromPhpType($tagValue);
if ($responseInfo['type'] === 'string' && !empty($tagValue) && strtolower($tagValue) !== 'string') {
$responseInfo['type'] = '';
$responseInfo['description'] = 'Response of unknown type';
}
- if (!empty($returnTag->description)) {
- $responseInfo['description'] = $returnTag->description;
+ if (!empty($returnTag->getDescription())) {
+ $responseInfo['description'] = $returnTag->getDescription();
}
return $responseInfo;
diff --git a/Commands/GenerateAnnotations.php b/Commands/GenerateAnnotations.php
index 1c147df..d5faa45 100644
--- a/Commands/GenerateAnnotations.php
+++ b/Commands/GenerateAnnotations.php
@@ -72,11 +72,6 @@ protected function doExecute(): int
$input = $this->getInput();
$output = $this->getOutput();
- if (!class_exists('PHPStan\PhpDocParser\Parser\PhpDocParser')) {
- $output->writeln("This command requires phpstan/phpdoc-parser. It should be available while running Matomo in development mode.");
- return self::FAILURE;
- }
-
$plugin = $input->getOption('plugin');
if (empty($plugin)) {
throw new \RuntimeException('Please specify a plugin name.');
diff --git a/composer.json b/composer.json
index c36ed8c..bf84190 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,8 @@
{
"require": {
"zircote/swagger-php": "^5.4",
- "doctrine/annotations": "^2.0"
+ "doctrine/annotations": "^2.0",
+ "phpdocumentor/reflection-docblock": "^5.6"
},
"replace": {
"monolog/monolog": "*",
diff --git a/composer.lock b/composer.lock
index 96d7444..bdaa0d8 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "c02410b41ab976b8400bb73dedbf07dc",
+ "content-hash": "453a28cb96a34b8b4d977dc6f929ec57",
"packages": [
{
"name": "doctrine/annotations",
@@ -82,6 +82,54 @@
},
"time": "2024-09-05T10:17:24+00:00"
},
+ {
+ "name": "doctrine/deprecations",
+ "version": "1.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+ "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<=7.5 || >=13"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9 || ^12 || ^13",
+ "phpstan/phpstan": "1.4.10 || 2.1.11",
+ "phpstan/phpstan-phpunit": "^1.0 || ^2",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12",
+ "psr/log": "^1 || ^2 || ^3"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.5"
+ },
+ "time": "2025-04-07T20:06:18+00:00"
+ },
{
"name": "doctrine/lexer",
"version": "3.0.1",
@@ -217,6 +265,228 @@
},
"time": "2025-08-13T20:13:15+00:00"
},
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-2.x": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ },
+ "time": "2020-06-27T09:03:43+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "5.6.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9",
+ "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1.1",
+ "ext-filter": "*",
+ "php": "^7.4 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.2",
+ "phpdocumentor/type-resolver": "^1.7",
+ "phpstan/phpdoc-parser": "^1.7|^2.0",
+ "webmozart/assert": "^1.9.1"
+ },
+ "require-dev": {
+ "mockery/mockery": "~1.3.5 || ~1.6.0",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-mockery": "^1.1",
+ "phpstan/phpstan-webmozart-assert": "^1.2",
+ "phpunit/phpunit": "^9.5",
+ "psalm/phar": "^5.26"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ },
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.3"
+ },
+ "time": "2025-08-01T19:43:32+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "1.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
+ "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.3 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.0",
+ "phpstan/phpdoc-parser": "^1.18|^2.0"
+ },
+ "require-dev": {
+ "ext-tokenizer": "*",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpunit/phpunit": "^9.5",
+ "rector/rector": "^0.13.9",
+ "vimeo/psalm": "^4.25"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-1.x": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0"
+ },
+ "time": "2024-11-09T15:12:26+00:00"
+ },
+ {
+ "name": "phpstan/phpdoc-parser",
+ "version": "2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
+ "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^2.0",
+ "nikic/php-parser": "^5.3.0",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpunit/phpunit": "^9.6",
+ "symfony/process": "^5.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\PhpDocParser\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPDoc parser with support for nullable, intersection and generic types",
+ "support": {
+ "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
+ },
+ "time": "2025-08-30T15:50:23+00:00"
+ },
{
"name": "psr/cache",
"version": "3.0.0",
@@ -560,6 +830,64 @@
],
"time": "2025-08-27T11:34:33+00:00"
},
+ {
+ "name": "webmozart/assert",
+ "version": "1.11.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozarts/assert.git",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan": "<0.12.20",
+ "vimeo/psalm": "<4.6.1 || 4.6.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5.13"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.11.0"
+ },
+ "time": "2022-06-03T18:03:27+00:00"
+ },
{
"name": "zircote/swagger-php",
"version": "5.4.0",
diff --git a/phpstan-bootstrap.php b/phpstan-bootstrap.php
new file mode 100644
index 0000000..bdf349e
--- /dev/null
+++ b/phpstan-bootstrap.php
@@ -0,0 +1,4 @@
+ 'array',
+ 'description' => 'Some test description for the return annotation.',
];
$this->assertEquals($expected, $this->annotationGenerator->getResponseInfoFromDocBlock(self::EXAMPLE_API_METHOD_DOC_BLOCK1));
}
diff --git a/vendor/autoload_original.php b/vendor/autoload_original.php
index 8349aed..1baee05 100644
--- a/vendor/autoload_original.php
+++ b/vendor/autoload_original.php
@@ -22,4 +22,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
-return ComposerAutoloaderInitc02410b41ab976b8400bb73dedbf07dc::getLoader();
+return ComposerAutoloaderInit1e9ddc6b3f094bbece3e6bb946077640::getLoader();
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
index 6050e83..c16cefd 100644
--- a/vendor/composer/autoload_psr4.php
+++ b/vendor/composer/autoload_psr4.php
@@ -6,12 +6,16 @@
$baseDir = dirname($vendorDir);
return array(
+ 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
+ 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
+ 'PHPStan\\PhpDocParser\\' => array($vendorDir . '/phpstan/phpdoc-parser/src'),
'OpenApi\\' => array($vendorDir . '/zircote/swagger-php/src'),
+ 'Doctrine\\Deprecations\\' => array($vendorDir . '/doctrine/deprecations/src'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/src'),
'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations'),
);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index b6f351c..91515b8 100644
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInitc02410b41ab976b8400bb73dedbf07dc
+class ComposerAutoloaderInit1e9ddc6b3f094bbece3e6bb946077640
{
private static $loader;
@@ -22,16 +22,16 @@ public static function getLoader()
return self::$loader;
}
- spl_autoload_register(array('ComposerAutoloaderInitc02410b41ab976b8400bb73dedbf07dc', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInit1e9ddc6b3f094bbece3e6bb946077640', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
- spl_autoload_unregister(array('ComposerAutoloaderInitc02410b41ab976b8400bb73dedbf07dc', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInit1e9ddc6b3f094bbece3e6bb946077640', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
- call_user_func(\Composer\Autoload\ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc::getInitializer($loader));
+ call_user_func(\Composer\Autoload\ComposerStaticInit1e9ddc6b3f094bbece3e6bb946077640::getInitializer($loader));
$loader->register(true);
- $filesToLoad = \Composer\Autoload\ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc::$files;
+ $filesToLoad = \Composer\Autoload\ComposerStaticInit1e9ddc6b3f094bbece3e6bb946077640::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index 66659ed..5081b9f 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -4,13 +4,21 @@
namespace Composer\Autoload;
-class ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc
+class ComposerStaticInit1e9ddc6b3f094bbece3e6bb946077640
{
public static $files = array(
);
public static $prefixLengthsPsr4 = array (
+ 'p' =>
+ array (
+ 'phpDocumentor\\Reflection\\' => 25,
+ ),
+ 'W' =>
+ array (
+ 'Webmozart\\Assert\\' => 17,
+ ),
'S' =>
array (
'Symfony\\Polyfill\\Ctype\\' => 23,
@@ -21,6 +29,7 @@ class ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc
array (
'Psr\\Cache\\' => 10,
'PhpParser\\' => 10,
+ 'PHPStan\\PhpDocParser\\' => 21,
),
'O' =>
array (
@@ -28,12 +37,23 @@ class ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc
),
'D' =>
array (
+ 'Doctrine\\Deprecations\\' => 22,
'Doctrine\\Common\\Lexer\\' => 22,
'Doctrine\\Common\\Annotations\\' => 28,
),
);
public static $prefixDirsPsr4 = array (
+ 'phpDocumentor\\Reflection\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
+ 1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
+ 2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
+ ),
+ 'Webmozart\\Assert\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/webmozart/assert/src',
+ ),
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
@@ -54,10 +74,18 @@ class ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc
array (
0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
),
+ 'PHPStan\\PhpDocParser\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src',
+ ),
'OpenApi\\' =>
array (
0 => __DIR__ . '/..' . '/zircote/swagger-php/src',
),
+ 'Doctrine\\Deprecations\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/doctrine/deprecations/src',
+ ),
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/src',
@@ -75,9 +103,9 @@ class ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc::$prefixDirsPsr4;
- $loader->classMap = ComposerStaticInitc02410b41ab976b8400bb73dedbf07dc::$classMap;
+ $loader->prefixLengthsPsr4 = ComposerStaticInit1e9ddc6b3f094bbece3e6bb946077640::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit1e9ddc6b3f094bbece3e6bb946077640::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInit1e9ddc6b3f094bbece3e6bb946077640::$classMap;
}, null, ClassLoader::class);
}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 3575ed6..acf0d66 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -79,6 +79,57 @@
},
"install-path": "../doctrine/annotations"
},
+ {
+ "name": "doctrine/deprecations",
+ "version": "1.1.5",
+ "version_normalized": "1.1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+ "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<=7.5 || >=13"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9 || ^12 || ^13",
+ "phpstan/phpstan": "1.4.10 || 2.1.11",
+ "phpstan/phpstan-phpunit": "^1.0 || ^2",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12",
+ "psr/log": "^1 || ^2 || ^3"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "time": "2025-04-07T20:06:18+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.5"
+ },
+ "install-path": "../doctrine/deprecations"
+ },
{
"name": "doctrine/lexer",
"version": "3.0.1",
@@ -220,6 +271,240 @@
},
"install-path": "../nikic/php-parser"
},
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "2.2.0",
+ "version_normalized": "2.2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "time": "2020-06-27T09:03:43+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-2.x": "2.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ },
+ "install-path": "../phpdocumentor/reflection-common"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "5.6.3",
+ "version_normalized": "5.6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9",
+ "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1.1",
+ "ext-filter": "*",
+ "php": "^7.4 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.2",
+ "phpdocumentor/type-resolver": "^1.7",
+ "phpstan/phpdoc-parser": "^1.7|^2.0",
+ "webmozart/assert": "^1.9.1"
+ },
+ "require-dev": {
+ "mockery/mockery": "~1.3.5 || ~1.6.0",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-mockery": "^1.1",
+ "phpstan/phpstan-webmozart-assert": "^1.2",
+ "phpunit/phpunit": "^9.5",
+ "psalm/phar": "^5.26"
+ },
+ "time": "2025-08-01T19:43:32+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ },
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.3"
+ },
+ "install-path": "../phpdocumentor/reflection-docblock"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "1.10.0",
+ "version_normalized": "1.10.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
+ "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.3 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.0",
+ "phpstan/phpdoc-parser": "^1.18|^2.0"
+ },
+ "require-dev": {
+ "ext-tokenizer": "*",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpunit/phpunit": "^9.5",
+ "rector/rector": "^0.13.9",
+ "vimeo/psalm": "^4.25"
+ },
+ "time": "2024-11-09T15:12:26+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-1.x": "1.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0"
+ },
+ "install-path": "../phpdocumentor/type-resolver"
+ },
+ {
+ "name": "phpstan/phpdoc-parser",
+ "version": "2.3.0",
+ "version_normalized": "2.3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
+ "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^2.0",
+ "nikic/php-parser": "^5.3.0",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpunit/phpunit": "^9.6",
+ "symfony/process": "^5.2"
+ },
+ "time": "2025-08-30T15:50:23+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\PhpDocParser\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPDoc parser with support for nullable, intersection and generic types",
+ "support": {
+ "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
+ },
+ "install-path": "../phpstan/phpdoc-parser"
+ },
{
"name": "psr/cache",
"version": "3.0.0",
@@ -578,6 +863,67 @@
],
"install-path": "../symfony/yaml"
},
+ {
+ "name": "webmozart/assert",
+ "version": "1.11.0",
+ "version_normalized": "1.11.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozarts/assert.git",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan": "<0.12.20",
+ "vimeo/psalm": "<4.6.1 || 4.6.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5.13"
+ },
+ "time": "2022-06-03T18:03:27+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.11.0"
+ },
+ "install-path": "../webmozart/assert"
+ },
{
"name": "zircote/swagger-php",
"version": "5.4.0",
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index 08b6452..a4447cc 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => '__root__',
'pretty_version' => 'dev-5.x-dev',
'version' => 'dev-5.x-dev',
- 'reference' => '7773ba7c581833d8cfe2eb522cb7516d132720af',
+ 'reference' => 'b5ecf24dbc489a212c869ea6953193928bdb8d36',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'__root__' => array(
'pretty_version' => 'dev-5.x-dev',
'version' => 'dev-5.x-dev',
- 'reference' => '7773ba7c581833d8cfe2eb522cb7516d132720af',
+ 'reference' => 'b5ecf24dbc489a212c869ea6953193928bdb8d36',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -28,6 +28,15 @@
'aliases' => array(),
'dev_requirement' => false,
),
+ 'doctrine/deprecations' => array(
+ 'pretty_version' => '1.1.5',
+ 'version' => '1.1.5.0',
+ 'reference' => '459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../doctrine/deprecations',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
'doctrine/lexer' => array(
'pretty_version' => '3.0.1',
'version' => '3.0.1.0',
@@ -52,6 +61,42 @@
'aliases' => array(),
'dev_requirement' => false,
),
+ 'phpdocumentor/reflection-common' => array(
+ 'pretty_version' => '2.2.0',
+ 'version' => '2.2.0.0',
+ 'reference' => '1d01c49d4ed62f25aa84a747ad35d5a16924662b',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../phpdocumentor/reflection-common',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ 'phpdocumentor/reflection-docblock' => array(
+ 'pretty_version' => '5.6.3',
+ 'version' => '5.6.3.0',
+ 'reference' => '94f8051919d1b0369a6bcc7931d679a511c03fe9',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../phpdocumentor/reflection-docblock',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ 'phpdocumentor/type-resolver' => array(
+ 'pretty_version' => '1.10.0',
+ 'version' => '1.10.0.0',
+ 'reference' => '679e3ce485b99e84c775d28e2e96fade9a7fb50a',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../phpdocumentor/type-resolver',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ 'phpstan/phpdoc-parser' => array(
+ 'pretty_version' => '2.3.0',
+ 'version' => '2.3.0.0',
+ 'reference' => '1e0cd5370df5dd2e556a36b9c62f62e555870495',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../phpstan/phpdoc-parser',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
'psr/cache' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
@@ -103,6 +148,15 @@
'aliases' => array(),
'dev_requirement' => false,
),
+ 'webmozart/assert' => array(
+ 'pretty_version' => '1.11.0',
+ 'version' => '1.11.0.0',
+ 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../webmozart/assert',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
'zircote/swagger-php' => array(
'pretty_version' => '5.4.0',
'version' => '5.4.0.0',
diff --git a/vendor/prefixed/doctrine/deprecations/LICENSE b/vendor/prefixed/doctrine/deprecations/LICENSE
new file mode 100644
index 0000000..156905c
--- /dev/null
+++ b/vendor/prefixed/doctrine/deprecations/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020-2021 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.
diff --git a/vendor/prefixed/doctrine/deprecations/src/Deprecation.php b/vendor/prefixed/doctrine/deprecations/src/Deprecation.php
new file mode 100644
index 0000000..2402264
--- /dev/null
+++ b/vendor/prefixed/doctrine/deprecations/src/Deprecation.php
@@ -0,0 +1,241 @@
+|null */
+ private static $type;
+ /** @var LoggerInterface|null */
+ private static $logger;
+ /** @var array */
+ private static $ignoredPackages = [];
+ /** @var array */
+ private static $triggeredDeprecations = [];
+ /** @var array */
+ private static $ignoredLinks = [];
+ /** @var bool */
+ private static $deduplication = \true;
+ /**
+ * Trigger a deprecation for the given package and identfier.
+ *
+ * The link should point to a Github issue or Wiki entry detailing the
+ * deprecation. It is additionally used to de-duplicate the trigger of the
+ * same deprecation during a request.
+ *
+ * @param float|int|string $args
+ */
+ public static function trigger(string $package, string $link, string $message, ...$args) : void
+ {
+ $type = self::$type ?? self::getTypeFromEnv();
+ if ($type === self::TYPE_NONE) {
+ return;
+ }
+ if (isset(self::$ignoredLinks[$link])) {
+ return;
+ }
+ if (array_key_exists($link, self::$triggeredDeprecations)) {
+ self::$triggeredDeprecations[$link]++;
+ } else {
+ self::$triggeredDeprecations[$link] = 1;
+ }
+ if (self::$deduplication === \true && self::$triggeredDeprecations[$link] > 1) {
+ return;
+ }
+ if (isset(self::$ignoredPackages[$package])) {
+ return;
+ }
+ $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+ $message = sprintf($message, ...$args);
+ self::delegateTriggerToBackend($message, $backtrace, $link, $package);
+ }
+ /**
+ * Trigger a deprecation for the given package and identifier when called from outside.
+ *
+ * "Outside" means we assume that $package is currently installed as a
+ * dependency and the caller is not a file in that package. When $package
+ * is installed as a root package then deprecations triggered from the
+ * tests folder are also considered "outside".
+ *
+ * This deprecation method assumes that you are using Composer to install
+ * the dependency and are using the default /vendor/ folder and not a
+ * Composer plugin to change the install location. The assumption is also
+ * that $package is the exact composer packge name.
+ *
+ * Compared to {@link trigger()} this method causes some overhead when
+ * deprecation tracking is enabled even during deduplication, because it
+ * needs to call {@link debug_backtrace()}
+ *
+ * @param float|int|string $args
+ */
+ public static function triggerIfCalledFromOutside(string $package, string $link, string $message, ...$args) : void
+ {
+ $type = self::$type ?? self::getTypeFromEnv();
+ if ($type === self::TYPE_NONE) {
+ return;
+ }
+ $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+ // first check that the caller is not from a tests folder, in which case we always let deprecations pass
+ if (isset($backtrace[1]['file'], $backtrace[0]['file']) && strpos($backtrace[1]['file'], DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR) === \false) {
+ $path = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $package) . DIRECTORY_SEPARATOR;
+ if (strpos($backtrace[0]['file'], $path) === \false) {
+ return;
+ }
+ if (strpos($backtrace[1]['file'], $path) !== \false) {
+ return;
+ }
+ }
+ if (isset(self::$ignoredLinks[$link])) {
+ return;
+ }
+ if (array_key_exists($link, self::$triggeredDeprecations)) {
+ self::$triggeredDeprecations[$link]++;
+ } else {
+ self::$triggeredDeprecations[$link] = 1;
+ }
+ if (self::$deduplication === \true && self::$triggeredDeprecations[$link] > 1) {
+ return;
+ }
+ if (isset(self::$ignoredPackages[$package])) {
+ return;
+ }
+ $message = sprintf($message, ...$args);
+ self::delegateTriggerToBackend($message, $backtrace, $link, $package);
+ }
+ /** @param list $backtrace */
+ private static function delegateTriggerToBackend(string $message, array $backtrace, string $link, string $package) : void
+ {
+ $type = self::$type ?? self::getTypeFromEnv();
+ if (($type & self::TYPE_PSR_LOGGER) > 0) {
+ $context = ['file' => $backtrace[0]['file'] ?? null, 'line' => $backtrace[0]['line'] ?? null, 'package' => $package, 'link' => $link];
+ assert(self::$logger !== null);
+ self::$logger->notice($message, $context);
+ }
+ if (!(($type & self::TYPE_TRIGGER_ERROR) > 0)) {
+ return;
+ }
+ $message .= sprintf(' (%s:%d called by %s:%d, %s, package %s)', self::basename($backtrace[0]['file'] ?? 'native code'), $backtrace[0]['line'] ?? 0, self::basename($backtrace[1]['file'] ?? 'native code'), $backtrace[1]['line'] ?? 0, $link, $package);
+ @trigger_error($message, E_USER_DEPRECATED);
+ }
+ /**
+ * A non-local-aware version of PHPs basename function.
+ */
+ private static function basename(string $filename) : string
+ {
+ $pos = strrpos($filename, DIRECTORY_SEPARATOR);
+ if ($pos === \false) {
+ return $filename;
+ }
+ return substr($filename, $pos + 1);
+ }
+ public static function enableTrackingDeprecations() : void
+ {
+ self::$type = self::$type ?? self::getTypeFromEnv();
+ self::$type |= self::TYPE_TRACK_DEPRECATIONS;
+ }
+ public static function enableWithTriggerError() : void
+ {
+ self::$type = self::$type ?? self::getTypeFromEnv();
+ self::$type |= self::TYPE_TRIGGER_ERROR;
+ }
+ public static function enableWithPsrLogger(LoggerInterface $logger) : void
+ {
+ self::$type = self::$type ?? self::getTypeFromEnv();
+ self::$type |= self::TYPE_PSR_LOGGER;
+ self::$logger = $logger;
+ }
+ public static function withoutDeduplication() : void
+ {
+ self::$deduplication = \false;
+ }
+ public static function disable() : void
+ {
+ self::$type = self::TYPE_NONE;
+ self::$logger = null;
+ self::$deduplication = \true;
+ self::$ignoredLinks = [];
+ foreach (self::$triggeredDeprecations as $link => $count) {
+ self::$triggeredDeprecations[$link] = 0;
+ }
+ }
+ public static function ignorePackage(string $packageName) : void
+ {
+ self::$ignoredPackages[$packageName] = \true;
+ }
+ public static function ignoreDeprecations(string ...$links) : void
+ {
+ foreach ($links as $link) {
+ self::$ignoredLinks[$link] = \true;
+ }
+ }
+ public static function getUniqueTriggeredDeprecationsCount() : int
+ {
+ return array_reduce(self::$triggeredDeprecations, static function (int $carry, int $count) {
+ return $carry + $count;
+ }, 0);
+ }
+ /**
+ * Returns each triggered deprecation link identifier and the amount of occurrences.
+ *
+ * @return array
+ */
+ public static function getTriggeredDeprecations() : array
+ {
+ return self::$triggeredDeprecations;
+ }
+ /** @return int-mask-of */
+ private static function getTypeFromEnv() : int
+ {
+ switch ($_SERVER['DOCTRINE_DEPRECATIONS'] ?? $_ENV['DOCTRINE_DEPRECATIONS'] ?? null) {
+ case 'trigger':
+ self::$type = self::TYPE_TRIGGER_ERROR;
+ break;
+ case 'track':
+ self::$type = self::TYPE_TRACK_DEPRECATIONS;
+ break;
+ default:
+ self::$type = self::TYPE_NONE;
+ break;
+ }
+ return self::$type;
+ }
+}
diff --git a/vendor/prefixed/doctrine/deprecations/src/PHPUnit/VerifyDeprecations.php b/vendor/prefixed/doctrine/deprecations/src/PHPUnit/VerifyDeprecations.php
new file mode 100644
index 0000000..4ae78f3
--- /dev/null
+++ b/vendor/prefixed/doctrine/deprecations/src/PHPUnit/VerifyDeprecations.php
@@ -0,0 +1,43 @@
+ */
+ private $doctrineDeprecationsExpectations = [];
+ /** @var array */
+ private $doctrineNoDeprecationsExpectations = [];
+ public function expectDeprecationWithIdentifier(string $identifier) : void
+ {
+ $this->doctrineDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+ }
+ public function expectNoDeprecationWithIdentifier(string $identifier) : void
+ {
+ $this->doctrineNoDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+ }
+ /** @before */
+ #[Before]
+ public function enableDeprecationTracking() : void
+ {
+ Deprecation::enableTrackingDeprecations();
+ }
+ /** @after */
+ #[After]
+ public function verifyDeprecationsAreTriggered() : void
+ {
+ foreach ($this->doctrineDeprecationsExpectations as $identifier => $expectation) {
+ $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+ $this->assertTrue($actualCount > $expectation, sprintf("Expected deprecation with identifier '%s' was not triggered by code executed in test.", $identifier));
+ }
+ foreach ($this->doctrineNoDeprecationsExpectations as $identifier => $expectation) {
+ $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+ $this->assertTrue($actualCount === $expectation, sprintf("Expected deprecation with identifier '%s' was triggered by code executed in test, but expected not to.", $identifier));
+ }
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-common/LICENSE b/vendor/prefixed/phpdocumentor/reflection-common/LICENSE
new file mode 100644
index 0000000..ed6926c
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-common/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 phpDocumentor
+
+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.
+
diff --git a/vendor/prefixed/phpdocumentor/reflection-common/src/Element.php b/vendor/prefixed/phpdocumentor/reflection-common/src/Element.php
new file mode 100644
index 0000000..d97d473
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-common/src/Element.php
@@ -0,0 +1,27 @@
+fqsen = $fqsen;
+ if (isset($matches[2])) {
+ $this->name = $matches[2];
+ } else {
+ $matches = explode('\\', $fqsen);
+ $name = end($matches);
+ assert(is_string($name));
+ $this->name = trim($name, '()');
+ }
+ }
+ /**
+ * converts this class to string.
+ */
+ public function __toString() : string
+ {
+ return $this->fqsen;
+ }
+ /**
+ * Returns the name of the element without path.
+ */
+ public function getName() : string
+ {
+ return $this->name;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-common/src/Location.php b/vendor/prefixed/phpdocumentor/reflection-common/src/Location.php
new file mode 100644
index 0000000..6e43386
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-common/src/Location.php
@@ -0,0 +1,47 @@
+lineNumber = $lineNumber;
+ $this->columnNumber = $columnNumber;
+ }
+ /**
+ * Returns the line number that is covered by this location.
+ */
+ public function getLineNumber() : int
+ {
+ return $this->lineNumber;
+ }
+ /**
+ * Returns the column number (character position on a line) for this location object.
+ */
+ public function getColumnNumber() : int
+ {
+ return $this->columnNumber;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-common/src/Project.php b/vendor/prefixed/phpdocumentor/reflection-common/src/Project.php
new file mode 100644
index 0000000..c3e8aa7
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-common/src/Project.php
@@ -0,0 +1,23 @@
+summary = $summary;
+ $this->description = $description ?: new DocBlock\Description('');
+ foreach ($tags as $tag) {
+ $this->addTag($tag);
+ }
+ $this->context = $context;
+ $this->location = $location;
+ $this->isTemplateEnd = $isTemplateEnd;
+ $this->isTemplateStart = $isTemplateStart;
+ }
+ public function getSummary() : string
+ {
+ return $this->summary;
+ }
+ public function getDescription() : DocBlock\Description
+ {
+ return $this->description;
+ }
+ /**
+ * Returns the current context.
+ */
+ public function getContext() : ?Types\Context
+ {
+ return $this->context;
+ }
+ /**
+ * Returns the current location.
+ */
+ public function getLocation() : ?Location
+ {
+ return $this->location;
+ }
+ /**
+ * Returns whether this DocBlock is the start of a Template section.
+ *
+ * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker
+ * (`#@+`) that is appended directly after the opening `/**` of a DocBlock.
+ *
+ * An example of such an opening is:
+ *
+ * ```
+ * /**#@+
+ * * My DocBlock
+ * * /
+ * ```
+ *
+ * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all
+ * elements that follow until another DocBlock is found that contains the closing marker (`#@-`).
+ *
+ * @see self::isTemplateEnd() for the check whether a closing marker was provided.
+ */
+ public function isTemplateStart() : bool
+ {
+ return $this->isTemplateStart;
+ }
+ /**
+ * Returns whether this DocBlock is the end of a Template section.
+ *
+ * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality.
+ */
+ public function isTemplateEnd() : bool
+ {
+ return $this->isTemplateEnd;
+ }
+ /**
+ * Returns the tags for this DocBlock.
+ *
+ * @return Tag[]
+ */
+ public function getTags() : array
+ {
+ return $this->tags;
+ }
+ /**
+ * Returns an array of tags matching the given name. If no tags are found
+ * an empty array is returned.
+ *
+ * @param string $name String to search by.
+ *
+ * @return Tag[]
+ */
+ public function getTagsByName(string $name) : array
+ {
+ $result = [];
+ foreach ($this->getTags() as $tag) {
+ if ($tag->getName() !== $name) {
+ continue;
+ }
+ $result[] = $tag;
+ }
+ return $result;
+ }
+ /**
+ * Returns an array of tags with type matching the given name. If no tags are found
+ * an empty array is returned.
+ *
+ * @param string $name String to search by.
+ *
+ * @return TagWithType[]
+ */
+ public function getTagsWithTypeByName(string $name) : array
+ {
+ $result = [];
+ foreach ($this->getTagsByName($name) as $tag) {
+ if (!$tag instanceof TagWithType) {
+ continue;
+ }
+ $result[] = $tag;
+ }
+ return $result;
+ }
+ /**
+ * Checks if a tag of a certain type is present in this DocBlock.
+ *
+ * @param string $name Tag name to check for.
+ */
+ public function hasTag(string $name) : bool
+ {
+ foreach ($this->getTags() as $tag) {
+ if ($tag->getName() === $name) {
+ return \true;
+ }
+ }
+ return \false;
+ }
+ /**
+ * Remove a tag from this DocBlock.
+ *
+ * @param Tag $tagToRemove The tag to remove.
+ */
+ public function removeTag(Tag $tagToRemove) : void
+ {
+ foreach ($this->tags as $key => $tag) {
+ if ($tag === $tagToRemove) {
+ unset($this->tags[$key]);
+ break;
+ }
+ }
+ }
+ /**
+ * Adds a tag to this DocBlock.
+ *
+ * @param Tag $tag The tag to add.
+ */
+ private function addTag(Tag $tag) : void
+ {
+ $this->tags[] = $tag;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Description.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Description.php
new file mode 100644
index 0000000..dc2721d
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Description.php
@@ -0,0 +1,108 @@
+create('This is a {@see Description}', $context);
+ *
+ * The description factory will interpret the given body and create a body template and list of tags from them, and pass
+ * that onto the constructor if this class.
+ *
+ * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace
+ * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial
+ * > type names and FQSENs.
+ *
+ * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this:
+ *
+ * $description = new Description(
+ * 'This is a %1$s',
+ * [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ]
+ * );
+ *
+ * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object
+ * is mainly responsible for rendering.
+ *
+ * @see DescriptionFactory to create a new Description.
+ * @see Tags\Formatter for the formatting of the body and tags.
+ */
+class Description
+{
+ /**
+ * @var string
+ */
+ private $bodyTemplate;
+ /** @var Tag[] */
+ private $tags;
+ /**
+ * Initializes a Description with its body (template) and a listing of the tags used in the body template.
+ *
+ * @param Tag[] $tags
+ */
+ public function __construct(string $bodyTemplate, array $tags = [])
+ {
+ $this->bodyTemplate = $bodyTemplate;
+ $this->tags = $tags;
+ }
+ /**
+ * Returns the body template.
+ */
+ public function getBodyTemplate() : string
+ {
+ return $this->bodyTemplate;
+ }
+ /**
+ * Returns the tags for this DocBlock.
+ *
+ * @return Tag[]
+ */
+ public function getTags() : array
+ {
+ return $this->tags;
+ }
+ /**
+ * Renders this description as a string where the provided formatter will format the tags in the expected string
+ * format.
+ */
+ public function render(?Formatter $formatter = null) : string
+ {
+ if ($this->tags === []) {
+ return vsprintf($this->bodyTemplate, []);
+ }
+ if ($formatter === null) {
+ $formatter = new PassthroughFormatter();
+ }
+ $tags = [];
+ foreach ($this->tags as $tag) {
+ $tags[] = '{' . $formatter->format($tag) . '}';
+ }
+ return vsprintf($this->bodyTemplate, $tags);
+ }
+ /**
+ * Returns a plain string representation of this description.
+ */
+ public function __toString() : string
+ {
+ return $this->render();
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php
new file mode 100644
index 0000000..fc7dd64
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php
@@ -0,0 +1,157 @@
+tagFactory = $tagFactory;
+ }
+ /**
+ * Returns the parsed text of this description.
+ */
+ public function create(string $contents, ?TypeContext $context = null) : Description
+ {
+ $tokens = $this->lex($contents);
+ $count = count($tokens);
+ $tagCount = 0;
+ $tags = [];
+ for ($i = 1; $i < $count; $i += 2) {
+ $tags[] = $this->tagFactory->create($tokens[$i], $context);
+ $tokens[$i] = '%' . ++$tagCount . '$s';
+ }
+ //In order to allow "literal" inline tags, the otherwise invalid
+ //sequence "{@}" is changed to "@", and "{}" is changed to "}".
+ //"%" is escaped to "%%" because of vsprintf.
+ //See unit tests for examples.
+ for ($i = 0; $i < $count; $i += 2) {
+ $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);
+ }
+ return new Description(implode('', $tokens), $tags);
+ }
+ /**
+ * Strips the contents from superfluous whitespace and splits the description into a series of tokens.
+ *
+ * @return string[] A series of tokens of which the description text is composed.
+ */
+ private function lex(string $contents) : array
+ {
+ $contents = $this->removeSuperfluousStartingWhitespace($contents);
+ // performance optimalization; if there is no inline tag, don't bother splitting it up.
+ if (strpos($contents, '{@') === \false) {
+ return [$contents];
+ }
+ return Utils::pregSplit('/\\{
+ # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally.
+ (?!@\\})
+ # We want to capture the whole tag line, but without the inline tag delimiters.
+ (\\@
+ # Match everything up to the next delimiter.
+ [^{}]*
+ # Nested inline tag content should not be captured, or it will appear in the result separately.
+ (?:
+ # Match nested inline tags.
+ (?:
+ # Because we did not catch the tag delimiters earlier, we must be explicit with them here.
+ # Notice that this also matches "{}", as a way to later introduce it as an escape sequence.
+ \\{(?1)?\\}
+ |
+ # Make sure we match hanging "{".
+ \\{
+ )
+ # Match content after the nested inline tag.
+ [^{}]*
+ )* # If there are more inline tags, match them as well. We use "*" since there may not be any
+ # nested inline tags.
+ )
+ \\}/Sux', $contents, 0, PREG_SPLIT_DELIM_CAPTURE);
+ }
+ /**
+ * Removes the superfluous from a multi-line description.
+ *
+ * When a description has more than one line then it can happen that the second and subsequent lines have an
+ * additional indentation. This is commonly in use with tags like this:
+ *
+ * {@}since 1.1.0 This is an example
+ * description where we have an
+ * indentation in the second and
+ * subsequent lines.
+ *
+ * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent
+ * lines and this may cause rendering issues when, for example, using a Markdown converter.
+ */
+ private function removeSuperfluousStartingWhitespace(string $contents) : string
+ {
+ $lines = Utils::pregSplit("/\r\n?|\n/", $contents);
+ // if there is only one line then we don't have lines with superfluous whitespace and
+ // can use the contents as-is
+ if (count($lines) <= 1) {
+ return $contents;
+ }
+ // determine how many whitespace characters need to be stripped
+ $startingSpaceCount = 9999999;
+ for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) {
+ // lines with a no length do not count as they are not indented at all
+ if (trim($lines[$i]) === '') {
+ continue;
+ }
+ // determine the number of prefixing spaces by checking the difference in line length before and after
+ // an ltrim
+ $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i])));
+ }
+ // strip the number of spaces from each line
+ if ($startingSpaceCount > 0) {
+ for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) {
+ $lines[$i] = substr($lines[$i], $startingSpaceCount);
+ }
+ }
+ return implode("\n", $lines);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php
new file mode 100644
index 0000000..18605a3
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php
@@ -0,0 +1,135 @@
+getFilePath();
+ $file = $this->getExampleFileContents($filename);
+ if ($file === null) {
+ return sprintf('** File not found : %s **', $filename);
+ }
+ return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount()));
+ }
+ /**
+ * Registers the project's root directory where an 'examples' folder can be expected.
+ */
+ public function setSourceDirectory(string $directory = '') : void
+ {
+ $this->sourceDirectory = $directory;
+ }
+ /**
+ * Returns the project's root directory where an 'examples' folder can be expected.
+ */
+ public function getSourceDirectory() : string
+ {
+ return $this->sourceDirectory;
+ }
+ /**
+ * Registers a series of directories that may contain examples.
+ *
+ * @param string[] $directories
+ */
+ public function setExampleDirectories(array $directories) : void
+ {
+ $this->exampleDirectories = $directories;
+ }
+ /**
+ * Returns a series of directories that may contain examples.
+ *
+ * @return string[]
+ */
+ public function getExampleDirectories() : array
+ {
+ return $this->exampleDirectories;
+ }
+ /**
+ * Attempts to find the requested example file and returns its contents or null if no file was found.
+ *
+ * This method will try several methods in search of the given example file, the first one it encounters is
+ * returned:
+ *
+ * 1. Iterates through all examples folders for the given filename
+ * 2. Checks the source folder for the given filename
+ * 3. Checks the 'examples' folder in the current working directory for examples
+ * 4. Checks the path relative to the current working directory for the given filename
+ *
+ * @return string[] all lines of the example file
+ */
+ private function getExampleFileContents(string $filename) : ?array
+ {
+ $normalizedPath = null;
+ foreach ($this->exampleDirectories as $directory) {
+ $exampleFileFromConfig = $this->constructExamplePath($directory, $filename);
+ if (is_readable($exampleFileFromConfig)) {
+ $normalizedPath = $exampleFileFromConfig;
+ break;
+ }
+ }
+ if ($normalizedPath === null) {
+ if (is_readable($this->getExamplePathFromSource($filename))) {
+ $normalizedPath = $this->getExamplePathFromSource($filename);
+ } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) {
+ $normalizedPath = $this->getExamplePathFromExampleDirectory($filename);
+ } elseif (is_readable($filename)) {
+ $normalizedPath = $filename;
+ }
+ }
+ $lines = $normalizedPath !== null && is_readable($normalizedPath) ? file($normalizedPath) : \false;
+ return $lines !== \false ? $lines : null;
+ }
+ /**
+ * Get example filepath based on the example directory inside your project.
+ */
+ private function getExamplePathFromExampleDirectory(string $file) : string
+ {
+ return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file;
+ }
+ /**
+ * Returns a path to the example file in the given directory..
+ */
+ private function constructExamplePath(string $directory, string $file) : string
+ {
+ return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file;
+ }
+ /**
+ * Get example filepath based on sourcecode.
+ */
+ private function getExamplePathFromSource(string $file) : string
+ {
+ return sprintf('%s%s%s', trim($this->getSourceDirectory(), '\\/'), DIRECTORY_SEPARATOR, trim($file, '"'));
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php
new file mode 100644
index 0000000..40d2990
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php
@@ -0,0 +1,111 @@
+indent = $indent;
+ $this->indentString = $indentString;
+ $this->isFirstLineIndented = $indentFirstLine;
+ $this->lineLength = $lineLength;
+ $this->tagFormatter = $tagFormatter ?: new PassthroughFormatter();
+ $this->lineEnding = $lineEnding;
+ }
+ /**
+ * Generate a DocBlock comment.
+ *
+ * @param DocBlock $docblock The DocBlock to serialize.
+ *
+ * @return string The serialized doc block.
+ */
+ public function getDocComment(DocBlock $docblock) : string
+ {
+ $indent = str_repeat($this->indentString, $this->indent);
+ $firstIndent = $this->isFirstLineIndented ? $indent : '';
+ // 3 === strlen(' * ')
+ $wrapLength = $this->lineLength !== null ? $this->lineLength - strlen($indent) - 3 : null;
+ $text = $this->removeTrailingSpaces($indent, $this->addAsterisksForEachLine($indent, $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength)));
+ $comment = $firstIndent . "/**\n";
+ if ($text) {
+ $comment .= $indent . ' * ' . $text . "\n";
+ $comment .= $indent . " *\n";
+ }
+ $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment);
+ return str_replace("\n", $this->lineEnding, $comment . $indent . ' */');
+ }
+ private function removeTrailingSpaces(string $indent, string $text) : string
+ {
+ return str_replace(sprintf("\n%s * \n", $indent), sprintf("\n%s *\n", $indent), $text);
+ }
+ private function addAsterisksForEachLine(string $indent, string $text) : string
+ {
+ return str_replace("\n", sprintf("\n%s * ", $indent), $text);
+ }
+ private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, ?int $wrapLength) : string
+ {
+ $text = $docblock->getSummary() . ((string) $docblock->getDescription() ? "\n\n" . $docblock->getDescription() : '');
+ if ($wrapLength !== null) {
+ $text = wordwrap($text, $wrapLength);
+ return $text;
+ }
+ return $text;
+ }
+ private function addTagBlock(DocBlock $docblock, ?int $wrapLength, string $indent, string $comment) : string
+ {
+ foreach ($docblock->getTags() as $tag) {
+ $tagText = $this->tagFormatter->format($tag);
+ if ($wrapLength !== null) {
+ $tagText = wordwrap($tagText, $wrapLength);
+ }
+ $tagText = str_replace("\n", sprintf("\n%s * ", $indent), $tagText);
+ $comment .= sprintf("%s * %s\n", $indent, $tagText);
+ }
+ return $comment;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php
new file mode 100644
index 0000000..f2cd41a
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php
@@ -0,0 +1,310 @@
+ Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise
+ * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to
+ * > verify that a dependency is actually passed.
+ *
+ * This Factory also features a Service Locator component that is used to pass the right dependencies to the
+ * `create` method of a tag; each dependency should be registered as a service or as a parameter.
+ *
+ * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass
+ * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface.
+ */
+final class StandardTagFactory implements TagFactory
+{
+ /** PCRE regular expression matching a tag name. */
+ public const REGEX_TAGNAME = '[\\w\\-\\_\\\\:]+';
+ /**
+ * @var array|Factory> An array with a tag as a key, and an
+ * FQCN to a class that handles it as an array value.
+ */
+ private $tagHandlerMappings = [
+ 'author' => Author::class,
+ 'covers' => Covers::class,
+ 'deprecated' => Deprecated::class,
+ // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example',
+ 'link' => LinkTag::class,
+ 'mixin' => Mixin::class,
+ 'method' => Method::class,
+ 'param' => Param::class,
+ 'property-read' => PropertyRead::class,
+ 'property' => Property::class,
+ 'property-write' => PropertyWrite::class,
+ 'return' => Return_::class,
+ 'see' => SeeTag::class,
+ 'since' => Since::class,
+ 'source' => Source::class,
+ 'template-covariant' => TemplateCovariant::class,
+ 'throw' => Throws::class,
+ 'throws' => Throws::class,
+ 'uses' => Uses::class,
+ 'var' => Var_::class,
+ 'version' => Version::class,
+ ];
+ /**
+ * @var array> An array with an annotation as a key, and an
+ * FQCN to a class that handles it as an array value.
+ */
+ private $annotationMappings = [];
+ /**
+ * @var ReflectionParameter[][] a lazy-loading cache containing parameters
+ * for each tagHandler that has been used.
+ */
+ private $tagHandlerParameterCache = [];
+ /**
+ * @var \Matomo\Dependencies\OpenApiDocs\phpDocumentor\Reflection\FqsenResolver
+ */
+ private $fqsenResolver;
+ /**
+ * @var mixed[] an array representing a simple Service Locator where we can store parameters and
+ * services that can be inserted into the Factory Methods of Tag Handlers.
+ */
+ private $serviceLocator = [];
+ /**
+ * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers.
+ *
+ * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property
+ * is used.
+ *
+ * @see self::registerTagHandler() to add a new tag handler to the existing default list.
+ *
+ * @param array> $tagHandlers
+ */
+ public function __construct(FqsenResolver $fqsenResolver, ?array $tagHandlers = null)
+ {
+ $this->fqsenResolver = $fqsenResolver;
+ if ($tagHandlers !== null) {
+ $this->tagHandlerMappings = $tagHandlers;
+ }
+ $this->addService($fqsenResolver, FqsenResolver::class);
+ }
+ public function create(string $tagLine, ?TypeContext $context = null) : Tag
+ {
+ if (!$context) {
+ $context = new TypeContext('');
+ }
+ [$tagName, $tagBody] = $this->extractTagParts($tagLine);
+ return $this->createTag(trim($tagBody), $tagName, $context);
+ }
+ /**
+ * @param mixed $value
+ */
+ public function addParameter(string $name, $value) : void
+ {
+ $this->serviceLocator[$name] = $value;
+ }
+ public function addService(object $service, ?string $alias = null) : void
+ {
+ $this->serviceLocator[$alias ?? get_class($service)] = $service;
+ }
+ /** {@inheritDoc} */
+ public function registerTagHandler(string $tagName, $handler) : void
+ {
+ Assert::stringNotEmpty($tagName);
+ if (strpos($tagName, '\\') !== \false && $tagName[0] !== '\\') {
+ throw new InvalidArgumentException('A namespaced tag must have a leading backslash as it must be fully qualified');
+ }
+ if (is_object($handler)) {
+ Assert::isInstanceOf($handler, Factory::class);
+ $this->tagHandlerMappings[$tagName] = $handler;
+ return;
+ }
+ Assert::classExists($handler);
+ Assert::implementsInterface($handler, Tag::class);
+ $this->tagHandlerMappings[$tagName] = $handler;
+ }
+ /**
+ * Extracts all components for a tag.
+ *
+ * @return string[]
+ */
+ private function extractTagParts(string $tagLine) : array
+ {
+ $matches = [];
+ if (!preg_match('/^@(' . self::REGEX_TAGNAME . ')((?:[\\s\\(\\{])\\s*([^\\s].*)|$)/us', $tagLine, $matches)) {
+ throw new InvalidArgumentException('The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors');
+ }
+ return array_slice($matches, 1);
+ }
+ /**
+ * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the
+ * body was invalid.
+ */
+ private function createTag(string $body, string $name, TypeContext $context) : Tag
+ {
+ $handlerClassName = $this->findHandlerClassName($name, $context);
+ $arguments = $this->getArgumentsForParametersFromWiring($this->fetchParametersForHandlerFactoryMethod($handlerClassName), $this->getServiceLocatorWithDynamicParameters($context, $name, $body));
+ if (array_key_exists('tagLine', $arguments)) {
+ $arguments['tagLine'] = sprintf('@%s %s', $name, $body);
+ }
+ try {
+ $callable = [$handlerClassName, 'create'];
+ Assert::isCallable($callable);
+ /** @phpstan-var callable(string): ?Tag $callable */
+ $tag = call_user_func_array($callable, $arguments);
+ return $tag ?? InvalidTag::create($body, $name);
+ } catch (InvalidArgumentException $e) {
+ return InvalidTag::create($body, $name)->withError($e);
+ }
+ }
+ /**
+ * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).
+ *
+ * @return class-string|Factory
+ */
+ private function findHandlerClassName(string $tagName, TypeContext $context)
+ {
+ $handlerClassName = Generic::class;
+ if (isset($this->tagHandlerMappings[$tagName])) {
+ $handlerClassName = $this->tagHandlerMappings[$tagName];
+ } elseif ($this->isAnnotation($tagName)) {
+ // TODO: Annotation support is planned for a later stage and as such is disabled for now
+ $tagName = (string) $this->fqsenResolver->resolve($tagName, $context);
+ if (isset($this->annotationMappings[$tagName])) {
+ $handlerClassName = $this->annotationMappings[$tagName];
+ }
+ }
+ return $handlerClassName;
+ }
+ /**
+ * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters.
+ *
+ * @param ReflectionParameter[] $parameters
+ * @param mixed[] $locator
+ *
+ * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters
+ * is provided with this method.
+ */
+ private function getArgumentsForParametersFromWiring(array $parameters, array $locator) : array
+ {
+ $arguments = [];
+ foreach ($parameters as $parameter) {
+ $type = $parameter->getType();
+ $typeHint = null;
+ if ($type instanceof ReflectionNamedType) {
+ $typeHint = $type->getName();
+ if ($typeHint === 'self') {
+ $declaringClass = $parameter->getDeclaringClass();
+ if ($declaringClass !== null) {
+ $typeHint = $declaringClass->getName();
+ }
+ }
+ }
+ $parameterName = $parameter->getName();
+ if (isset($locator[$typeHint])) {
+ $arguments[$parameterName] = $locator[$typeHint];
+ continue;
+ }
+ if (isset($locator[$parameterName])) {
+ $arguments[$parameterName] = $locator[$parameterName];
+ continue;
+ }
+ $arguments[$parameterName] = null;
+ }
+ return $arguments;
+ }
+ /**
+ * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given
+ * tag handler class name.
+ *
+ * @param class-string|Factory $handler
+ *
+ * @return ReflectionParameter[]
+ */
+ private function fetchParametersForHandlerFactoryMethod($handler) : array
+ {
+ $handlerClassName = is_object($handler) ? get_class($handler) : $handler;
+ if (!isset($this->tagHandlerParameterCache[$handlerClassName])) {
+ $methodReflection = new ReflectionMethod($handlerClassName, 'create');
+ $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters();
+ }
+ return $this->tagHandlerParameterCache[$handlerClassName];
+ }
+ /**
+ * Returns a copy of this class' Service Locator with added dynamic parameters,
+ * such as the tag's name, body and Context.
+ *
+ * @param TypeContext $context The Context (namespace and aliases) that may be
+ * passed and is used to resolve FQSENs.
+ * @param string $tagName The name of the tag that may be
+ * passed onto the factory method of the Tag class.
+ * @param string $tagBody The body of the tag that may be
+ * passed onto the factory method of the Tag class.
+ *
+ * @return mixed[]
+ */
+ private function getServiceLocatorWithDynamicParameters(TypeContext $context, string $tagName, string $tagBody) : array
+ {
+ return array_merge($this->serviceLocator, ['name' => $tagName, 'body' => $tagBody, TypeContext::class => $context]);
+ }
+ /**
+ * Returns whether the given tag belongs to an annotation.
+ *
+ * @todo this method should be populated once we implement Annotation notation support.
+ */
+ private function isAnnotation(string $tagContent) : bool
+ {
+ // 1. Contains a namespace separator
+ // 2. Contains parenthesis
+ // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part
+ // of the annotation class name matches the found tag name
+ return \false;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php
new file mode 100644
index 0000000..e8adf64
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php
@@ -0,0 +1,25 @@
+|Factory $handler FQCN of handler.
+ *
+ * @throws InvalidArgumentException If the tag name is not a string.
+ * @throws InvalidArgumentException If the tag name is namespaced (contains backslashes) but
+ * does not start with a backslash.
+ * @throws InvalidArgumentException If the handler is not a string.
+ * @throws InvalidArgumentException If the handler is not an existing class.
+ * @throws InvalidArgumentException If the handler does not implement the {@see Tag} interface.
+ */
+ public function registerTagHandler(string $tagName, $handler) : void;
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php
new file mode 100644
index 0000000..d082638
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php
@@ -0,0 +1,85 @@
+authorName = $authorName;
+ $this->authorEmail = $authorEmail;
+ }
+ /**
+ * Gets the author's name.
+ *
+ * @return string The author's name.
+ */
+ public function getAuthorName() : string
+ {
+ return $this->authorName;
+ }
+ /**
+ * Returns the author's email.
+ *
+ * @return string The author's email.
+ */
+ public function getEmail() : string
+ {
+ return $this->authorEmail;
+ }
+ /**
+ * Returns this tag in string form.
+ */
+ public function __toString() : string
+ {
+ if ($this->authorEmail) {
+ $authorEmail = '<' . $this->authorEmail . '>';
+ } else {
+ $authorEmail = '';
+ }
+ $authorName = $this->authorName;
+ return $authorName . ($authorEmail !== '' ? ($authorName !== '' ? ' ' : '') . $authorEmail : '');
+ }
+ /**
+ * Attempts to create a new Author object based on the tag body.
+ */
+ public static function create(string $body) : ?self
+ {
+ $splitTagContent = preg_match('/^([^\\<]*)(?:\\<([^\\>]*)\\>)?$/u', $body, $matches);
+ if (!$splitTagContent) {
+ return null;
+ }
+ $authorName = trim($matches[1]);
+ $email = isset($matches[2]) ? trim($matches[2]) : '';
+ return new static($authorName, $email);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php
new file mode 100644
index 0000000..0c88bc2
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php
@@ -0,0 +1,45 @@
+name;
+ }
+ public function getDescription() : ?Description
+ {
+ return $this->description;
+ }
+ public function render(?Formatter $formatter = null) : string
+ {
+ if ($formatter === null) {
+ $formatter = new Formatter\PassthroughFormatter();
+ }
+ return $formatter->format($this);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php
new file mode 100644
index 0000000..e779e11
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php
@@ -0,0 +1,82 @@
+refers = $refers;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?DescriptionFactory $descriptionFactory = null, ?FqsenResolver $resolver = null, ?TypeContext $context = null) : self
+ {
+ Assert::stringNotEmpty($body);
+ Assert::notNull($descriptionFactory);
+ Assert::notNull($resolver);
+ $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
+ return new static(self::resolveFqsen($parts[0], $resolver, $context), $descriptionFactory->create($parts[1] ?? '', $context));
+ }
+ private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
+ {
+ Assert::notNull($fqsenResolver);
+ $fqsenParts = explode('::', $parts);
+ $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
+ if (!array_key_exists(1, $fqsenParts)) {
+ return $resolved;
+ }
+ return new Fqsen($resolved . '::' . $fqsenParts[1]);
+ }
+ /**
+ * Returns the structural element this tag refers to.
+ */
+ public function getReference() : Fqsen
+ {
+ return $this->refers;
+ }
+ /**
+ * Returns a string representation of this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $refers = (string) $this->refers;
+ return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php
new file mode 100644
index 0000000..cbba1d6
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php
@@ -0,0 +1,86 @@
+version = $version;
+ $this->description = $description;
+ }
+ /**
+ * @return static
+ */
+ public static function create(?string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ if ($body === null || $body === '') {
+ return new static();
+ }
+ $matches = [];
+ if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {
+ return new static(null, $descriptionFactory !== null ? $descriptionFactory->create($body, $context) : null);
+ }
+ Assert::notNull($descriptionFactory);
+ return new static($matches[1], $descriptionFactory->create($matches[2] ?? '', $context));
+ }
+ /**
+ * Gets the version section of the tag.
+ */
+ public function getVersion() : ?string
+ {
+ return $this->version;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $version = (string) $this->version;
+ return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php
new file mode 100644
index 0000000..abed618
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php
@@ -0,0 +1,153 @@
+filePath = $filePath;
+ $this->startingLine = $startingLine;
+ $this->lineCount = $lineCount;
+ if ($content !== null) {
+ $this->content = trim($content);
+ }
+ $this->isURI = $isURI;
+ }
+ public function getContent() : string
+ {
+ if ($this->content === null || $this->content === '') {
+ $filePath = $this->filePath;
+ if ($this->isURI) {
+ $filePath = $this->isUriRelative($this->filePath) ? str_replace('%2F', '/', rawurlencode($this->filePath)) : $this->filePath;
+ }
+ return trim($filePath);
+ }
+ return $this->content;
+ }
+ public function getDescription() : ?string
+ {
+ return $this->content;
+ }
+ public static function create(string $body) : ?Tag
+ {
+ // File component: File path in quotes or File URI / Source information
+ if (!preg_match('/^\\s*(?:(\\"[^\\"]+\\")|(\\S+))(?:\\s+(.*))?$/sux', $body, $matches)) {
+ return null;
+ }
+ $filePath = null;
+ $fileUri = null;
+ if (array_key_exists(1, $matches) && $matches[1] !== '') {
+ $filePath = $matches[1];
+ } else {
+ $fileUri = array_key_exists(2, $matches) ? $matches[2] : '';
+ }
+ $startingLine = 1;
+ $lineCount = 0;
+ $description = null;
+ if (array_key_exists(3, $matches)) {
+ $description = $matches[3];
+ // Starting line / Number of lines / Description
+ if (preg_match('/^([1-9]\\d*)(?:\\s+((?1))\\s*)?(.*)$/sux', $matches[3], $contentMatches)) {
+ $startingLine = (int) $contentMatches[1];
+ if (isset($contentMatches[2])) {
+ $lineCount = (int) $contentMatches[2];
+ }
+ if (array_key_exists(3, $contentMatches)) {
+ $description = $contentMatches[3];
+ }
+ }
+ }
+ return new static($filePath ?? $fileUri ?? '', $fileUri !== null, $startingLine, $lineCount, $description);
+ }
+ /**
+ * Returns the file path.
+ *
+ * @return string Path to a file to use as an example.
+ * May also be an absolute URI.
+ */
+ public function getFilePath() : string
+ {
+ return trim($this->filePath, '"');
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ $filePath = $this->filePath;
+ $isDefaultLine = $this->startingLine === 1 && $this->lineCount === 0;
+ $startingLine = !$isDefaultLine ? (string) $this->startingLine : '';
+ $lineCount = !$isDefaultLine ? (string) $this->lineCount : '';
+ $content = (string) $this->content;
+ return $filePath . ($startingLine !== '' ? ($filePath !== '' ? ' ' : '') . $startingLine : '') . ($lineCount !== '' ? ($filePath !== '' || $startingLine !== '' ? ' ' : '') . $lineCount : '') . ($content !== '' ? ($filePath !== '' || $startingLine !== '' || $lineCount !== '' ? ' ' : '') . $content : '');
+ }
+ /**
+ * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute).
+ */
+ private function isUriRelative(string $uri) : bool
+ {
+ return strpos($uri, ':') === \false;
+ }
+ public function getStartingLine() : int
+ {
+ return $this->startingLine;
+ }
+ public function getLineCount() : int
+ {
+ return $this->lineCount;
+ }
+ public function getName() : string
+ {
+ return 'example';
+ }
+ public function render(?Formatter $formatter = null) : string
+ {
+ if ($formatter === null) {
+ $formatter = new Formatter\PassthroughFormatter();
+ }
+ return $formatter->format($this);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Extends_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Extends_.php
new file mode 100644
index 0000000..546ebd4
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Extends_.php
@@ -0,0 +1,39 @@
+name = 'extends';
+ $this->type = $type;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body) : ?Tag
+ {
+ Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ return null;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php
new file mode 100644
index 0000000..06f459b
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php
@@ -0,0 +1,105 @@
+ \true, 'lines' => \true]);
+ $this->lexer = new Lexer($config);
+ $constParser = new ConstExprParser($config);
+ $this->parser = new PhpDocParser($config, new TypeParser($config, $constParser), $constParser);
+ } else {
+ $this->lexer = new Lexer(\true);
+ $constParser = new ConstExprParser(\true, \true, ['lines' => \true, 'indexes' => \true]);
+ $this->parser = new PhpDocParser(new TypeParser($constParser, \true, ['lines' => \true, 'indexes' => \true]), $constParser, \true, \true, ['lines' => \true, 'indexes' => \true], \true);
+ }
+ $this->factories = $factories;
+ }
+ public function create(string $tagLine, ?TypeContext $context = null) : Tag
+ {
+ $tokens = $this->tokenizeLine($tagLine . "\n");
+ $ast = $this->parser->parseTag($tokens);
+ if (property_exists($ast->value, 'description') === \true) {
+ $ast->value->setAttribute('description', rtrim($ast->value->description . $tokens->joinUntil(Lexer::TOKEN_END), "\n"));
+ }
+ if ($context === null) {
+ $context = new TypeContext('');
+ }
+ try {
+ foreach ($this->factories as $factory) {
+ if ($factory->supports($ast, $context)) {
+ return $factory->create($ast, $context);
+ }
+ }
+ } catch (RuntimeException $e) {
+ return InvalidTag::create((string) $ast->value, 'method')->withError($e);
+ }
+ return InvalidTag::create((string) $ast->value, $ast->name);
+ }
+ /**
+ * Solve the issue with the lexer not tokenizing the line correctly
+ *
+ * This method is a workaround for the lexer that includes newline tokens with spaces. For
+ * phpstan this isn't an issue, as it doesn't do a lot of things with the indentation of descriptions.
+ * But for us is important to keep the indentation of the descriptions, so we need to fix the lexer output.
+ */
+ private function tokenizeLine(string $tagLine) : TokenIterator
+ {
+ $tokens = $this->lexer->tokenize($tagLine);
+ $fixed = [];
+ foreach ($tokens as $token) {
+ if ($token[1] === Lexer::TOKEN_PHPDOC_EOL && rtrim($token[0], " \t") !== $token[0]) {
+ $fixed[] = [rtrim($token[Lexer::VALUE_OFFSET], " \t"), Lexer::TOKEN_PHPDOC_EOL, $token[2] ?? 0];
+ $fixed[] = [ltrim($token[Lexer::VALUE_OFFSET], "\n\r"), Lexer::TOKEN_HORIZONTAL_WS, ($token[2] ?? 0) + 1];
+ continue;
+ }
+ $fixed[] = $token;
+ }
+ return new TokenIterator($fixed);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ExtendsFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ExtendsFactory.php
new file mode 100644
index 0000000..5030658
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ExtendsFactory.php
@@ -0,0 +1,47 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof ExtendsTagValueNode && $node->name === '@extends';
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, ExtendsTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new Extends_($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Factory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Factory.php
new file mode 100644
index 0000000..3430320
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Factory.php
@@ -0,0 +1,38 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof ImplementsTagValueNode && $node->name === '@implements';
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, ImplementsTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new Implements_($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php
new file mode 100644
index 0000000..99fc96e
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php
@@ -0,0 +1,58 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, MethodTagValueNode::class);
+ return new Method($tagValue->methodName, [], $this->createReturnType($tagValue, $context), $tagValue->isStatic, $this->descriptionFactory->create($tagValue->description, $context), \false, array_map(function (MethodTagValueParameterNode $param) use($context) {
+ return new MethodParameter(trim($param->parameterName, '$'), $param->type === null ? new Mixed_() : $this->typeResolver->createType($param->type, $context), $param->isReference, $param->isVariadic, $param->defaultValue === null ? MethodParameter::NO_DEFAULT_VALUE : (string) $param->defaultValue);
+ }, $tagValue->parameters));
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof MethodTagValueNode;
+ }
+ private function createReturnType(MethodTagValueNode $tagValue, Context $context) : Type
+ {
+ if ($tagValue->returnType === null) {
+ return new Void_();
+ }
+ return $this->typeResolver->createType($tagValue->returnType, $context);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php
new file mode 100644
index 0000000..91c7388
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php
@@ -0,0 +1,84 @@
+{$method}($defaultValue);
+ }
+ return '';
+ }
+ private function formatDouble(float $defaultValue) : string
+ {
+ return var_export($defaultValue, \true);
+ }
+ /**
+ * @param mixed $defaultValue
+ */
+ private function formatNull($defaultValue) : string
+ {
+ return 'null';
+ }
+ private function formatInteger(int $defaultValue) : string
+ {
+ return var_export($defaultValue, \true);
+ }
+ private function formatString(string $defaultValue) : string
+ {
+ return var_export($defaultValue, \true);
+ }
+ private function formatBoolean(bool $defaultValue) : string
+ {
+ return var_export($defaultValue, \true);
+ }
+ /**
+ * @param array<(array|int|float|bool|string|object|null)> $defaultValue
+ */
+ private function formatArray(array $defaultValue) : string
+ {
+ $formatedValue = '[';
+ foreach ($defaultValue as $key => $value) {
+ $method = 'format' . ucfirst(gettype($value));
+ if (!method_exists($this, $method)) {
+ continue;
+ }
+ $formatedValue .= $this->{$method}($value);
+ if ($key === array_key_last($defaultValue)) {
+ continue;
+ }
+ $formatedValue .= ',';
+ }
+ return $formatedValue . ']';
+ }
+ private function formatObject(object $defaultValue) : string
+ {
+ return 'new ' . get_class($defaultValue) . '()';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PHPStanFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PHPStanFactory.php
new file mode 100644
index 0000000..ffb0336
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PHPStanFactory.php
@@ -0,0 +1,13 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ if ($tagValue instanceof InvalidTagValueNode) {
+ Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/362', sprintf('Param tag value "%s" is invalid, falling back to legacy parsing. Please update your docblocks.', $tagValue->value));
+ return Param::create($tagValue->value, $this->typeResolver, $this->descriptionFactory, $context);
+ }
+ Assert::isInstanceOfAny($tagValue, [ParamTagValueNode::class, TypelessParamTagValueNode::class]);
+ if (($tagValue->type ?? null) instanceof OffsetAccessTypeNode) {
+ return InvalidTag::create((string) $tagValue, 'param');
+ }
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new Param(trim($tagValue->parameterName, '$'), $this->typeResolver->createType($tagValue->type ?? new IdentifierTypeNode('mixed'), $context), $tagValue->isVariadic, $this->descriptionFactory->create($description, $context), $tagValue->isReference);
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof ParamTagValueNode || $node->value instanceof TypelessParamTagValueNode || $node->name === '@param';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyFactory.php
new file mode 100644
index 0000000..24cd813
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyFactory.php
@@ -0,0 +1,48 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new Property(trim($tagValue->propertyName, '$'), $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof PropertyTagValueNode && $node->name === '@property';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyReadFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyReadFactory.php
new file mode 100644
index 0000000..8636d38
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyReadFactory.php
@@ -0,0 +1,48 @@
+typeResolver = $typeResolver;
+ $this->descriptionFactory = $descriptionFactory;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new PropertyRead(trim($tagValue->propertyName, '$'), $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof PropertyTagValueNode && $node->name === '@property-read';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyWriteFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyWriteFactory.php
new file mode 100644
index 0000000..a7b7b06
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyWriteFactory.php
@@ -0,0 +1,48 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new PropertyWrite(trim($tagValue->propertyName, '$'), $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof PropertyTagValueNode && $node->name === '@property-write';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ReturnFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ReturnFactory.php
new file mode 100644
index 0000000..46003dc
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ReturnFactory.php
@@ -0,0 +1,47 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, ReturnTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new Return_($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof ReturnTagValueNode;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php
new file mode 100644
index 0000000..3ae3ebb
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php
@@ -0,0 +1,23 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof ExtendsTagValueNode && $node->name === '@template-extends';
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, ExtendsTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new TemplateExtends($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateFactory.php
new file mode 100644
index 0000000..9b79403
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateFactory.php
@@ -0,0 +1,48 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, TemplateTagValueNode::class);
+ $name = $tagValue->name;
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new Template($name, $this->typeResolver->createType($tagValue->bound, $context), $this->typeResolver->createType($tagValue->default, $context), $this->descriptionFactory->create($description, $context));
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof TemplateTagValueNode && $node->name === '@template';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php
new file mode 100644
index 0000000..025bf32
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php
@@ -0,0 +1,47 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof ImplementsTagValueNode && $node->name === '@template-implements';
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, ImplementsTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new TemplateImplements($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/VarFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/VarFactory.php
new file mode 100644
index 0000000..bac9713
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/VarFactory.php
@@ -0,0 +1,48 @@
+descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+ public function create(PhpDocTagNode $node, Context $context) : Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, VarTagValueNode::class);
+ $description = $tagValue->getAttribute('description');
+ if (is_string($description) === \false) {
+ $description = $tagValue->description;
+ }
+ return new Var_(trim($tagValue->variableName, '$'), $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context));
+ }
+ public function supports(PhpDocTagNode $node, Context $context) : bool
+ {
+ return $node->value instanceof VarTagValueNode;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php
new file mode 100644
index 0000000..890828f
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php
@@ -0,0 +1,21 @@
+maxLen = max($this->maxLen, strlen($tag->getName()));
+ }
+ }
+ /**
+ * Formats the given tag to return a simple plain text version.
+ */
+ public function format(Tag $tag) : string
+ {
+ return '@' . $tag->getName() . str_repeat(' ', $this->maxLen - strlen($tag->getName()) + 1) . $tag;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php
new file mode 100644
index 0000000..7a4eeea
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php
@@ -0,0 +1,26 @@
+getName() . ' ' . $tag);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php
new file mode 100644
index 0000000..2ee5f40
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php
@@ -0,0 +1,71 @@
+validateTagName($name);
+ $this->name = $name;
+ $this->description = $description;
+ }
+ /**
+ * Creates a new tag that represents any unknown tag type.
+ *
+ * @return static
+ */
+ public static function create(string $body, string $name = '', ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::stringNotEmpty($name);
+ Assert::notNull($descriptionFactory);
+ $description = $body !== '' ? $descriptionFactory->create($body, $context) : null;
+ return new static($name, $description);
+ }
+ /**
+ * Returns the tag as a serialized string
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ return $description;
+ }
+ /**
+ * Validates if the tag name matches the expected format, otherwise throws an exception.
+ */
+ private function validateTagName(string $name) : void
+ {
+ if (!preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) {
+ throw new InvalidArgumentException('The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, ' . 'hyphens and backslashes.');
+ }
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Implements_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Implements_.php
new file mode 100644
index 0000000..a746e6b
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Implements_.php
@@ -0,0 +1,39 @@
+name = 'implements';
+ $this->type = $type;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body) : ?Tag
+ {
+ Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ return null;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php
new file mode 100644
index 0000000..79f2977
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php
@@ -0,0 +1,127 @@
+name = $name;
+ $this->body = $body;
+ }
+ public function getException() : ?Throwable
+ {
+ return $this->throwable;
+ }
+ public function getName() : string
+ {
+ return $this->name;
+ }
+ public static function create(string $body, string $name = '') : self
+ {
+ return new self($name, $body);
+ }
+ public function withError(Throwable $exception) : self
+ {
+ $this->flattenExceptionBacktrace($exception);
+ $tag = new self($this->name, $this->body);
+ $tag->throwable = $exception;
+ return $tag;
+ }
+ /**
+ * Removes all complex types from backtrace
+ *
+ * Not all objects are serializable. So we need to remove them from the
+ * stored exception to be sure that we do not break existing library usage.
+ */
+ private function flattenExceptionBacktrace(Throwable $exception) : void
+ {
+ $traceProperty = (new ReflectionClass(Exception::class))->getProperty('trace');
+ if (\PHP_VERSION_ID < 80100) {
+ $traceProperty->setAccessible(\true);
+ }
+ do {
+ $trace = $exception->getTrace();
+ if (isset($trace[0]['args'])) {
+ $trace = array_map(function (array $call) : array {
+ $call['args'] = array_map([$this, 'flattenArguments'], $call['args'] ?? []);
+ return $call;
+ }, $trace);
+ }
+ $traceProperty->setValue($exception, $trace);
+ $exception = $exception->getPrevious();
+ } while ($exception !== null);
+ if (\PHP_VERSION_ID < 80100) {
+ $traceProperty->setAccessible(\false);
+ }
+ }
+ /**
+ * @param mixed $value
+ *
+ * @return mixed
+ *
+ * @throws ReflectionException
+ */
+ private function flattenArguments($value)
+ {
+ if ($value instanceof Closure) {
+ $closureReflection = new ReflectionFunction($value);
+ $value = sprintf('(Closure at %s:%s)', $closureReflection->getFileName(), $closureReflection->getStartLine());
+ } elseif (is_object($value)) {
+ $value = sprintf('object(%s)', get_class($value));
+ } elseif (is_resource($value)) {
+ $value = sprintf('resource(%s)', get_resource_type($value));
+ } elseif (is_array($value)) {
+ $value = array_map([$this, 'flattenArguments'], $value);
+ }
+ return $value;
+ }
+ public function render(?Formatter $formatter = null) : string
+ {
+ if ($formatter === null) {
+ $formatter = new Formatter\PassthroughFormatter();
+ }
+ return $formatter->format($this);
+ }
+ public function __toString() : string
+ {
+ return $this->body;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php
new file mode 100644
index 0000000..fc66297
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php
@@ -0,0 +1,67 @@
+link = $link;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::notNull($descriptionFactory);
+ $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
+ $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
+ return new static($parts[0], $description);
+ }
+ /**
+ * Gets the link
+ */
+ public function getLink() : string
+ {
+ return $this->link;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $link = $this->link;
+ return $link . ($description !== '' ? ($link !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php
new file mode 100644
index 0000000..04a4308
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php
@@ -0,0 +1,277 @@
+> $arguments
+ * @param MethodParameter[] $parameters
+ * @phpstan-param array $arguments
+ */
+ public function __construct(string $methodName, array $arguments = [], ?Type $returnType = null, bool $static = \false, ?Description $description = null, bool $returnsReference = \false, ?array $parameters = null)
+ {
+ Assert::stringNotEmpty($methodName);
+ if ($returnType === null) {
+ $returnType = new Void_();
+ }
+ $arguments = $this->filterArguments($arguments);
+ $this->methodName = $methodName;
+ $this->returnType = $returnType;
+ $this->isStatic = $static;
+ $this->description = $description;
+ $this->returnsReference = $returnsReference;
+ $this->parameters = $parameters ?? $this->fromLegacyArguments($arguments);
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : ?self
+ {
+ trigger_error('Create using static factory is deprecated, this method should not be called directly
+ by library consumers', E_USER_DEPRECATED);
+ Assert::stringNotEmpty($body);
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ // 1. none or more whitespace
+ // 2. optionally the keyword "static" followed by whitespace
+ // 3. optionally a word with underscores followed by whitespace : as
+ // type for the return value
+ // 4. optionally an ampersand followed or not by whitespace : as
+ // a reference
+ // 5. then optionally a word with underscores followed by () and
+ // whitespace : as method name as used by phpDocumentor
+ // 6. then a word with underscores, followed by ( and any character
+ // until a ) and whitespace : as method name with signature
+ // 7. any remaining text : as description
+ if (!preg_match('/^
+ # Static keyword
+ # Declares a static method ONLY if type is also present
+ (?:
+ (static)
+ \\s+
+ )?
+ # Return type
+ (?:
+ (
+ (?:[\\w\\|_\\\\]*\\$this[\\w\\|_\\\\]*)
+ |
+ (?:
+ (?:[\\w\\|_\\\\]+)
+ # array notation
+ (?:\\[\\])*
+ )*+
+ )
+ \\s+
+ )?
+ # Returns reference
+ (?:
+ (&)
+ \\s*
+ )?
+ # Method name
+ ([\\w_]+)
+ # Arguments
+ (?:
+ \\(([^\\)]*)\\)
+ )?
+ \\s*
+ # Description
+ (.*)
+ $/sux', $body, $matches)) {
+ return null;
+ }
+ [, $static, $returnType, $returnsReference, $methodName, $argumentLines, $description] = $matches;
+ $static = $static === 'static';
+ if ($returnType === '') {
+ $returnType = 'void';
+ }
+ $returnsReference = $returnsReference === '&';
+ $returnType = $typeResolver->resolve($returnType, $context);
+ $description = $descriptionFactory->create($description, $context);
+ /** @phpstan-var array $arguments */
+ $arguments = [];
+ if ($argumentLines !== '') {
+ $argumentsExploded = explode(',', $argumentLines);
+ foreach ($argumentsExploded as $argument) {
+ $argument = explode(' ', self::stripRestArg(trim($argument)), 2);
+ if (strpos($argument[0], '$') === 0) {
+ $argumentName = substr($argument[0], 1);
+ $argumentType = new Mixed_();
+ } else {
+ $argumentType = $typeResolver->resolve($argument[0], $context);
+ $argumentName = '';
+ if (isset($argument[1])) {
+ $argument[1] = self::stripRestArg($argument[1]);
+ $argumentName = substr($argument[1], 1);
+ }
+ }
+ $arguments[] = ['name' => $argumentName, 'type' => $argumentType];
+ }
+ }
+ return new static($methodName, $arguments, $returnType, $static, $description, $returnsReference);
+ }
+ /**
+ * Retrieves the method name.
+ */
+ public function getMethodName() : string
+ {
+ return $this->methodName;
+ }
+ /**
+ * @deprecated Method deprecated, use {@see self::getParameters()}
+ *
+ * @return array>
+ * @phpstan-return array
+ */
+ public function getArguments() : array
+ {
+ trigger_error('Method deprecated, use ::getParameters()', E_USER_DEPRECATED);
+ return array_map(static function (MethodParameter $methodParameter) {
+ return ['name' => $methodParameter->getName(), 'type' => $methodParameter->getType()];
+ }, $this->parameters);
+ }
+ /** @return MethodParameter[] */
+ public function getParameters() : array
+ {
+ return $this->parameters;
+ }
+ /**
+ * Checks whether the method tag describes a static method or not.
+ *
+ * @return bool TRUE if the method declaration is for a static method, FALSE otherwise.
+ */
+ public function isStatic() : bool
+ {
+ return $this->isStatic;
+ }
+ public function getReturnType() : Type
+ {
+ return $this->returnType;
+ }
+ public function returnsReference() : bool
+ {
+ return $this->returnsReference;
+ }
+ public function __toString() : string
+ {
+ $arguments = [];
+ foreach ($this->parameters as $parameter) {
+ $arguments[] = (string) $parameter;
+ }
+ $argumentStr = '(' . implode(', ', $arguments) . ')';
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $static = $this->isStatic ? 'static' : '';
+ $returnType = (string) $this->returnType;
+ $methodName = $this->methodName;
+ $reference = $this->returnsReference ? '&' : '';
+ return $static . ($returnType !== '' ? ($static !== '' ? ' ' : '') . $returnType : '') . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $reference . $methodName : '') . $argumentStr . ($description !== '' ? ' ' . $description : '');
+ }
+ /**
+ * @param mixed[][]|string[] $arguments
+ * @phpstan-param array $arguments
+ *
+ * @return mixed[][]
+ * @phpstan-return array
+ */
+ private function filterArguments(array $arguments = []) : array
+ {
+ $result = [];
+ foreach ($arguments as $argument) {
+ if (is_string($argument)) {
+ $argument = ['name' => $argument];
+ }
+ if (!isset($argument['type'])) {
+ $argument['type'] = new Mixed_();
+ }
+ $keys = array_keys($argument);
+ sort($keys);
+ if ($keys !== ['name', 'type']) {
+ throw new InvalidArgumentException('Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, \true));
+ }
+ $result[] = $argument;
+ }
+ return $result;
+ }
+ private static function stripRestArg(string $argument) : string
+ {
+ if (strpos($argument, '...') === 0) {
+ $argument = trim(substr($argument, 3));
+ }
+ return $argument;
+ }
+ /**
+ * @param array{name: string, type: Type} $arguments
+ * @phpstan-param array $arguments
+ *
+ * @return MethodParameter[]
+ */
+ private function fromLegacyArguments(array $arguments) : array
+ {
+ trigger_error('Create method parameters via legacy format is deprecated add parameters via the constructor', E_USER_DEPRECATED);
+ return array_map(static function ($arg) {
+ return new MethodParameter($arg['name'], $arg['type']);
+ }, $arguments);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/MethodParameter.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/MethodParameter.php
new file mode 100644
index 0000000..1b2ef29
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/MethodParameter.php
@@ -0,0 +1,75 @@
+type = $type;
+ $this->isReference = $isReference;
+ $this->isVariadic = $isVariadic;
+ $this->name = $name;
+ $this->defaultValue = $defaultValue;
+ }
+ public function getName() : string
+ {
+ return $this->name;
+ }
+ public function getType() : Type
+ {
+ return $this->type;
+ }
+ public function isReference() : bool
+ {
+ return $this->isReference;
+ }
+ public function isVariadic() : bool
+ {
+ return $this->isVariadic;
+ }
+ public function getDefaultValue() : ?string
+ {
+ if ($this->defaultValue === self::NO_DEFAULT_VALUE) {
+ return null;
+ }
+ return (new MethodParameterFactory())->format($this->defaultValue);
+ }
+ public function __toString() : string
+ {
+ return $this->getType() . ' ' . ($this->isReference() ? '&' : '') . ($this->isVariadic() ? '...' : '') . '$' . $this->getName() . ($this->defaultValue !== self::NO_DEFAULT_VALUE ? (new MethodParameterFactory())->format($this->defaultValue) : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Mixin.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Mixin.php
new file mode 100644
index 0000000..be31adc
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Mixin.php
@@ -0,0 +1,40 @@
+name = 'mixin';
+ $this->type = $type;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$type, $description] = self::extractTypeFromBody($body);
+ $type = $typeResolver->resolve($type, $context);
+ $description = $descriptionFactory->create($description, $context);
+ return new static($type, $description);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php
new file mode 100644
index 0000000..f65026d
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php
@@ -0,0 +1,141 @@
+name = 'param';
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->isVariadic = $isVariadic;
+ $this->description = $description;
+ $this->isReference = $isReference;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ Assert::stringNotEmpty($body);
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$firstPart, $body] = self::extractTypeFromBody($body);
+ $type = null;
+ $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $variableName = '';
+ $isVariadic = \false;
+ $isReference = \false;
+ // if the first item that is encountered is not a variable; it is a type
+ if ($firstPart && !self::strStartsWithVariable($firstPart)) {
+ $type = $typeResolver->resolve($firstPart, $context);
+ } else {
+ // first part is not a type; we should prepend it to the parts array for further processing
+ array_unshift($parts, $firstPart);
+ }
+ // if the next item starts with a $ or ...$ or &$ or &...$ it must be the variable name
+ if (isset($parts[0]) && self::strStartsWithVariable($parts[0])) {
+ $variableName = array_shift($parts);
+ if ($type) {
+ array_shift($parts);
+ }
+ Assert::notNull($variableName);
+ if (strpos($variableName, '$') === 0) {
+ $variableName = substr($variableName, 1);
+ } elseif (strpos($variableName, '&$') === 0) {
+ $isReference = \true;
+ $variableName = substr($variableName, 2);
+ } elseif (strpos($variableName, '...$') === 0) {
+ $isVariadic = \true;
+ $variableName = substr($variableName, 4);
+ } elseif (strpos($variableName, '&...$') === 0) {
+ $isVariadic = \true;
+ $isReference = \true;
+ $variableName = substr($variableName, 5);
+ }
+ }
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+ return new static($variableName, $type, $isVariadic, $description, $isReference);
+ }
+ /**
+ * Returns the variable's name.
+ */
+ public function getVariableName() : ?string
+ {
+ return $this->variableName;
+ }
+ /**
+ * Returns whether this tag is variadic.
+ */
+ public function isVariadic() : bool
+ {
+ return $this->isVariadic;
+ }
+ /**
+ * Returns whether this tag is passed by reference.
+ */
+ public function isReference() : bool
+ {
+ return $this->isReference;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $variableName = '';
+ if ($this->variableName !== null && $this->variableName !== '') {
+ $variableName .= ($this->isReference ? '&' : '') . ($this->isVariadic ? '...' : '');
+ $variableName .= '$' . $this->variableName;
+ }
+ $type = (string) $this->type;
+ return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
+ }
+ private static function strStartsWithVariable(string $str) : bool
+ {
+ return strpos($str, '$') === 0 || strpos($str, '...$') === 0 || strpos($str, '&$') === 0 || strpos($str, '&...$') === 0;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php
new file mode 100644
index 0000000..465ddcd
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php
@@ -0,0 +1,104 @@
+name = 'property';
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ Assert::stringNotEmpty($body);
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$firstPart, $body] = self::extractTypeFromBody($body);
+ $type = null;
+ $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $variableName = '';
+ // if the first item that is encountered is not a variable; it is a type
+ if ($firstPart && $firstPart[0] !== '$') {
+ $type = $typeResolver->resolve($firstPart, $context);
+ } else {
+ // first part is not a type; we should prepend it to the parts array for further processing
+ array_unshift($parts, $firstPart);
+ }
+ // if the next item starts with a $ it must be the variable name
+ if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
+ $variableName = array_shift($parts);
+ if ($type) {
+ array_shift($parts);
+ }
+ Assert::notNull($variableName);
+ $variableName = substr($variableName, 1);
+ }
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+ return new static($variableName, $type, $description);
+ }
+ /**
+ * Returns the variable's name.
+ */
+ public function getVariableName() : ?string
+ {
+ return $this->variableName;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description !== null) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ if ($this->variableName !== null && $this->variableName !== '') {
+ $variableName = '$' . $this->variableName;
+ } else {
+ $variableName = '';
+ }
+ $type = (string) $this->type;
+ return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php
new file mode 100644
index 0000000..5588764
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php
@@ -0,0 +1,104 @@
+name = 'property-read';
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ Assert::stringNotEmpty($body);
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$firstPart, $body] = self::extractTypeFromBody($body);
+ $type = null;
+ $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $variableName = '';
+ // if the first item that is encountered is not a variable; it is a type
+ if ($firstPart && $firstPart[0] !== '$') {
+ $type = $typeResolver->resolve($firstPart, $context);
+ } else {
+ // first part is not a type; we should prepend it to the parts array for further processing
+ array_unshift($parts, $firstPart);
+ }
+ // if the next item starts with a $ it must be the variable name
+ if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
+ $variableName = array_shift($parts);
+ if ($type) {
+ array_shift($parts);
+ }
+ Assert::notNull($variableName);
+ $variableName = substr($variableName, 1);
+ }
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+ return new static($variableName, $type, $description);
+ }
+ /**
+ * Returns the variable's name.
+ */
+ public function getVariableName() : ?string
+ {
+ return $this->variableName;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description !== null) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ if ($this->variableName !== null && $this->variableName !== '') {
+ $variableName = '$' . $this->variableName;
+ } else {
+ $variableName = '';
+ }
+ $type = (string) $this->type;
+ return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php
new file mode 100644
index 0000000..5023751
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php
@@ -0,0 +1,104 @@
+name = 'property-write';
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ Assert::stringNotEmpty($body);
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$firstPart, $body] = self::extractTypeFromBody($body);
+ $type = null;
+ $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $variableName = '';
+ // if the first item that is encountered is not a variable; it is a type
+ if ($firstPart && $firstPart[0] !== '$') {
+ $type = $typeResolver->resolve($firstPart, $context);
+ } else {
+ // first part is not a type; we should prepend it to the parts array for further processing
+ array_unshift($parts, $firstPart);
+ }
+ // if the next item starts with a $ it must be the variable name
+ if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
+ $variableName = array_shift($parts);
+ if ($type) {
+ array_shift($parts);
+ }
+ Assert::notNull($variableName);
+ $variableName = substr($variableName, 1);
+ }
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+ return new static($variableName, $type, $description);
+ }
+ /**
+ * Returns the variable's name.
+ */
+ public function getVariableName() : ?string
+ {
+ return $this->variableName;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ if ($this->variableName) {
+ $variableName = '$' . $this->variableName;
+ } else {
+ $variableName = '';
+ }
+ $type = (string) $this->type;
+ return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php
new file mode 100644
index 0000000..a888149
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php
@@ -0,0 +1,35 @@
+fqsen = $fqsen;
+ }
+ /**
+ * @return string string representation of the referenced fqsen
+ */
+ public function __toString() : string
+ {
+ return (string) $this->fqsen;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php
new file mode 100644
index 0000000..dcf6d3b
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php
@@ -0,0 +1,20 @@
+uri = $uri;
+ }
+ public function __toString() : string
+ {
+ return $this->uri;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php
new file mode 100644
index 0000000..87e0ca9
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php
@@ -0,0 +1,47 @@
+name = 'return';
+ $this->type = $type;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$type, $description] = self::extractTypeFromBody($body);
+ $type = $typeResolver->resolve($type, $context);
+ $description = $descriptionFactory->create($description, $context);
+ return new static($type, $description);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php
new file mode 100644
index 0000000..cd808a5
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php
@@ -0,0 +1,89 @@
+refers = $refers;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?FqsenResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::notNull($descriptionFactory);
+ $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
+ $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
+ // https://tools.ietf.org/html/rfc2396#section-3
+ if (preg_match('#\\w://\\w#', $parts[0])) {
+ return new static(new Url($parts[0]), $description);
+ }
+ return new static(new FqsenRef(self::resolveFqsen($parts[0], $typeResolver, $context)), $description);
+ }
+ private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
+ {
+ Assert::notNull($fqsenResolver);
+ $fqsenParts = explode('::', $parts);
+ $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
+ if (!array_key_exists(1, $fqsenParts)) {
+ return $resolved;
+ }
+ return new Fqsen($resolved . '::' . $fqsenParts[1]);
+ }
+ /**
+ * Returns the ref of this tag.
+ */
+ public function getReference() : Reference
+ {
+ return $this->refers;
+ }
+ /**
+ * Returns a string representation of this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $refers = (string) $this->refers;
+ return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php
new file mode 100644
index 0000000..e1f74c7
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php
@@ -0,0 +1,83 @@
+version = $version;
+ $this->description = $description;
+ }
+ public static function create(?string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : ?self
+ {
+ if ($body === null || $body === '') {
+ return new static();
+ }
+ $matches = [];
+ if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {
+ return null;
+ }
+ Assert::notNull($descriptionFactory);
+ return new static($matches[1], $descriptionFactory->create($matches[2] ?? '', $context));
+ }
+ /**
+ * Gets the version section of the tag.
+ */
+ public function getVersion() : ?string
+ {
+ return $this->version;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description !== null) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $version = (string) $this->version;
+ return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php
new file mode 100644
index 0000000..18ca2d7
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php
@@ -0,0 +1,92 @@
+startingLine = (int) $startingLine;
+ $this->lineCount = $lineCount !== null ? (int) $lineCount : null;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::stringNotEmpty($body);
+ Assert::notNull($descriptionFactory);
+ $startingLine = 1;
+ $lineCount = null;
+ $description = null;
+ // Starting line / Number of lines / Description
+ if (preg_match('/^([1-9]\\d*)\\s*(?:((?1))\\s+)?(.*)$/sux', $body, $matches)) {
+ $startingLine = (int) $matches[1];
+ if (isset($matches[2]) && $matches[2] !== '') {
+ $lineCount = (int) $matches[2];
+ }
+ $description = $matches[3];
+ }
+ return new static($startingLine, $lineCount, $descriptionFactory->create($description ?? '', $context));
+ }
+ /**
+ * Gets the starting line.
+ *
+ * @return int The starting line, relative to the structural element's
+ * location.
+ */
+ public function getStartingLine() : int
+ {
+ return $this->startingLine;
+ }
+ /**
+ * Returns the number of lines.
+ *
+ * @return int|null The number of lines, relative to the starting line. NULL
+ * means "to the end".
+ */
+ public function getLineCount() : ?int
+ {
+ return $this->lineCount;
+ }
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $startingLine = (string) $this->startingLine;
+ $lineCount = $this->lineCount !== null ? ' ' . $this->lineCount : '';
+ return $startingLine . $lineCount . ($description !== '' ? ' ' . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php
new file mode 100644
index 0000000..1918a28
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php
@@ -0,0 +1,70 @@
+type;
+ }
+ /**
+ * @return string[]
+ */
+ protected static function extractTypeFromBody(string $body) : array
+ {
+ $type = '';
+ $nestingLevel = 0;
+ for ($i = 0, $iMax = strlen($body); $i < $iMax; $i++) {
+ $character = $body[$i];
+ if ($nestingLevel === 0 && trim($character) === '') {
+ break;
+ }
+ $type .= $character;
+ if (in_array($character, ['<', '(', '[', '{'])) {
+ $nestingLevel++;
+ continue;
+ }
+ if (in_array($character, ['>', ')', ']', '}'])) {
+ $nestingLevel--;
+ continue;
+ }
+ }
+ if ($nestingLevel < 0 || $nestingLevel > 0) {
+ throw new InvalidArgumentException(sprintf('Could not find type in %s, please check for malformed notations', $body));
+ }
+ $description = trim(substr($body, strlen($type)));
+ return [$type, $description];
+ }
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $type = (string) $this->type;
+ return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Template.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Template.php
new file mode 100644
index 0000000..7f4d516
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Template.php
@@ -0,0 +1,73 @@
+name = 'template';
+ $this->templateName = $templateName;
+ $this->bound = $bound;
+ $this->default = $default;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body) : ?Tag
+ {
+ Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ return null;
+ }
+ public function getTemplateName() : string
+ {
+ return $this->templateName;
+ }
+ public function getBound() : ?Type
+ {
+ return $this->bound;
+ }
+ public function getDefault() : ?Type
+ {
+ return $this->default;
+ }
+ public function __toString() : string
+ {
+ $bound = $this->bound !== null ? ' of ' . $this->bound : '';
+ $default = $this->default !== null ? ' = ' . $this->default : '';
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ return $this->templateName . $bound . $default . ($description !== '' ? ' ' . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateCovariant.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateCovariant.php
new file mode 100644
index 0000000..4db5074
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateCovariant.php
@@ -0,0 +1,40 @@
+name = 'template-covariant';
+ $this->type = $type;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$type, $description] = self::extractTypeFromBody($body);
+ $type = $typeResolver->resolve($type, $context);
+ $description = $descriptionFactory->create($description, $context);
+ return new static($type, $description);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateExtends.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateExtends.php
new file mode 100644
index 0000000..0c839e9
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateExtends.php
@@ -0,0 +1,26 @@
+name = 'template-extends';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateImplements.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateImplements.php
new file mode 100644
index 0000000..865228a
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateImplements.php
@@ -0,0 +1,26 @@
+name = 'template-implements';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php
new file mode 100644
index 0000000..5b3e17d
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php
@@ -0,0 +1,40 @@
+name = 'throws';
+ $this->type = $type;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$type, $description] = self::extractTypeFromBody($body);
+ $type = $typeResolver->resolve($type, $context);
+ $description = $descriptionFactory->create($description, $context);
+ return new static($type, $description);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php
new file mode 100644
index 0000000..599cb34
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php
@@ -0,0 +1,81 @@
+refers = $refers;
+ $this->description = $description;
+ }
+ public static function create(string $body, ?FqsenResolver $resolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Assert::notNull($resolver);
+ Assert::notNull($descriptionFactory);
+ $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
+ return new static(self::resolveFqsen($parts[0], $resolver, $context), $descriptionFactory->create($parts[1] ?? '', $context));
+ }
+ private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
+ {
+ Assert::notNull($fqsenResolver);
+ $fqsenParts = explode('::', $parts);
+ $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
+ if (!array_key_exists(1, $fqsenParts)) {
+ return $resolved;
+ }
+ return new Fqsen($resolved . '::' . $fqsenParts[1]);
+ }
+ /**
+ * Returns the structural element this tag refers to.
+ */
+ public function getReference() : Fqsen
+ {
+ return $this->refers;
+ }
+ /**
+ * Returns a string representation of this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $refers = (string) $this->refers;
+ return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php
new file mode 100644
index 0000000..1fd6c08
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php
@@ -0,0 +1,104 @@
+name = 'var';
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
+ public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
+ {
+ Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers');
+ Assert::stringNotEmpty($body);
+ Assert::notNull($typeResolver);
+ Assert::notNull($descriptionFactory);
+ [$firstPart, $body] = self::extractTypeFromBody($body);
+ $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+ // if the first item that is encountered is not a variable; it is a type
+ if ($firstPart && $firstPart[0] !== '$') {
+ $type = $typeResolver->resolve($firstPart, $context);
+ } else {
+ // first part is not a type; we should prepend it to the parts array for further processing
+ array_unshift($parts, $firstPart);
+ }
+ // if the next item starts with a $ it must be the variable name
+ if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
+ $variableName = array_shift($parts);
+ if ($type) {
+ array_shift($parts);
+ }
+ Assert::notNull($variableName);
+ $variableName = substr($variableName, 1);
+ }
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+ return new static($variableName, $type, $description);
+ }
+ /**
+ * Returns the variable's name.
+ */
+ public function getVariableName() : ?string
+ {
+ return $this->variableName;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description !== null) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ if ($this->variableName !== null && $this->variableName !== '') {
+ $variableName = '$' . $this->variableName;
+ } else {
+ $variableName = '';
+ }
+ $type = (string) $this->type;
+ return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php
new file mode 100644
index 0000000..978fa8a
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php
@@ -0,0 +1,86 @@
+version = $version;
+ $this->description = $description;
+ }
+ public static function create(?string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : ?self
+ {
+ if ($body === null || $body === '') {
+ return new static();
+ }
+ $matches = [];
+ if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {
+ return null;
+ }
+ $description = null;
+ if ($descriptionFactory !== null) {
+ $description = $descriptionFactory->create($matches[2] ?? '', $context);
+ }
+ return new static($matches[1], $description);
+ }
+ /**
+ * Gets the version section of the tag.
+ */
+ public function getVersion() : ?string
+ {
+ return $this->version;
+ }
+ /**
+ * Returns a string representation for this tag.
+ */
+ public function __toString() : string
+ {
+ if ($this->description) {
+ $description = $this->description->render();
+ } else {
+ $description = '';
+ }
+ $version = (string) $this->version;
+ return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactory.php
new file mode 100644
index 0000000..18af241
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactory.php
@@ -0,0 +1,271 @@
+descriptionFactory = $descriptionFactory;
+ $this->tagFactory = $tagFactory;
+ }
+ /**
+ * Factory method for easy instantiation.
+ *
+ * @param array|Factory> $additionalTags
+ */
+ public static function createInstance(array $additionalTags = []) : DocBlockFactoryInterface
+ {
+ $fqsenResolver = new FqsenResolver();
+ $tagFactory = new StandardTagFactory($fqsenResolver);
+ $descriptionFactory = new DescriptionFactory($tagFactory);
+ $typeResolver = new TypeResolver($fqsenResolver);
+ $phpstanTagFactory = new AbstractPHPStanFactory(new ParamFactory($typeResolver, $descriptionFactory), new VarFactory($typeResolver, $descriptionFactory), new ReturnFactory($typeResolver, $descriptionFactory), new PropertyFactory($typeResolver, $descriptionFactory), new PropertyReadFactory($typeResolver, $descriptionFactory), new PropertyWriteFactory($typeResolver, $descriptionFactory), new MethodFactory($typeResolver, $descriptionFactory), new ImplementsFactory($typeResolver, $descriptionFactory), new ExtendsFactory($typeResolver, $descriptionFactory), new TemplateFactory($typeResolver, $descriptionFactory), new TemplateImplementsFactory($typeResolver, $descriptionFactory), new TemplateExtendsFactory($typeResolver, $descriptionFactory));
+ $tagFactory->addService($descriptionFactory);
+ $tagFactory->addService($typeResolver);
+ $tagFactory->registerTagHandler('param', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('var', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('return', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('property', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('property-read', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('property-write', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('method', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('extends', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('implements', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('template', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('template-extends', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('template-implements', $phpstanTagFactory);
+ $docBlockFactory = new self($descriptionFactory, $tagFactory);
+ foreach ($additionalTags as $tagName => $tagHandler) {
+ $docBlockFactory->registerTagHandler($tagName, $tagHandler);
+ }
+ return $docBlockFactory;
+ }
+ /**
+ * @param object|string $docblock A string containing the DocBlock to parse or an object supporting the
+ * getDocComment method (such as a ReflectionClass object).
+ */
+ public function create($docblock, ?Types\Context $context = null, ?Location $location = null) : DocBlock
+ {
+ if (is_object($docblock)) {
+ if (!method_exists($docblock, 'getDocComment')) {
+ $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method';
+ throw new InvalidArgumentException($exceptionMessage);
+ }
+ $docblock = $docblock->getDocComment();
+ Assert::string($docblock);
+ }
+ Assert::stringNotEmpty($docblock);
+ if ($context === null) {
+ $context = new Types\Context('');
+ }
+ $parts = $this->splitDocBlock($this->stripDocComment($docblock));
+ [$templateMarker, $summary, $description, $tags] = $parts;
+ return new DocBlock($summary, $description ? $this->descriptionFactory->create($description, $context) : null, $this->parseTagBlock($tags, $context), $context, $location, $templateMarker === '#@+', $templateMarker === '#@-');
+ }
+ /**
+ * @param class-string|Factory $handler
+ */
+ public function registerTagHandler(string $tagName, $handler) : void
+ {
+ $this->tagFactory->registerTagHandler($tagName, $handler);
+ }
+ /**
+ * Strips the asterisks from the DocBlock comment.
+ *
+ * @param string $comment String containing the comment text.
+ */
+ private function stripDocComment(string $comment) : string
+ {
+ $comment = preg_replace('#[ \\t]*(?:\\/\\*\\*|\\*\\/|\\*)?[ \\t]?(.*)?#u', '$1', $comment);
+ Assert::string($comment);
+ $comment = trim($comment);
+ // reg ex above is not able to remove */ from a single line docblock
+ if (substr($comment, -2) === '*/') {
+ $comment = trim(substr($comment, 0, -2));
+ }
+ return str_replace(["\r\n", "\r"], "\n", $comment);
+ }
+ // phpcs:disable
+ /**
+ * Splits the DocBlock into a template marker, summary, description and block of tags.
+ *
+ * @param string $comment Comment to split into the sub-parts.
+ *
+ * @return string[] containing the template marker (if any), summary, description and a string containing the tags.
+ *
+ * @author Mike van Riel for extending the regex with template marker support.
+ *
+ * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
+ */
+ private function splitDocBlock(string $comment) : array
+ {
+ // phpcs:enable
+ // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
+ // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the
+ // performance impact of running a regular expression
+ if (strpos($comment, '@') === 0) {
+ return ['', '', '', $comment];
+ }
+ // clears all extra horizontal whitespace from the line endings to prevent parsing issues
+ $comment = preg_replace('/\\h*$/Sum', '', $comment);
+ Assert::string($comment);
+ /*
+ * Splits the docblock into a template marker, summary, description and tags section.
+ *
+ * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may
+ * occur after it and will be stripped).
+ * - The short description is started from the first character until a dot is encountered followed by a
+ * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing
+ * errors). This is optional.
+ * - The long description, any character until a new line is encountered followed by an @ and word
+ * characters (a tag). This is optional.
+ * - Tags; the remaining characters
+ *
+ * Big thanks to RichardJ for contributing this Regular Expression
+ */
+ preg_match('/
+ \\A
+ # 1. Extract the template marker
+ (?:(\\#\\@\\+|\\#\\@\\-)\\n?)?
+
+ # 2. Extract the summary
+ (?:
+ (?! @\\pL ) # The summary may not start with an @
+ (
+ [^\\n.]+
+ (?:
+ (?! \\. \\n | \\n{2} ) # End summary upon a dot followed by newline or two newlines
+ [\\n.]* (?! [ \\t]* @\\pL ) # End summary when an @ is found as first character on a new line
+ [^\\n.]+ # Include anything else
+ )*
+ \\.?
+ )?
+ )
+
+ # 3. Extract the description
+ (?:
+ \\s* # Some form of whitespace _must_ precede a description because a summary must be there
+ (?! @\\pL ) # The description may not start with an @
+ (
+ [^\\n]+
+ (?: \\n+
+ (?! [ \\t]* @\\pL ) # End description when an @ is found as first character on a new line
+ [^\\n]+ # Include anything else
+ )*
+ )
+ )?
+
+ # 4. Extract the tags (anything that follows)
+ (\\s+ [\\s\\S]*)? # everything that follows
+ /ux', $comment, $matches);
+ array_shift($matches);
+ while (count($matches) < 4) {
+ $matches[] = '';
+ }
+ return $matches;
+ }
+ /**
+ * Creates the tag objects.
+ *
+ * @param string $tags Tag block to parse.
+ * @param Types\Context $context Context of the parsed Tag
+ *
+ * @return DocBlock\Tag[]
+ */
+ private function parseTagBlock(string $tags, Types\Context $context) : array
+ {
+ $tags = $this->filterTagBlock($tags);
+ if ($tags === null) {
+ return [];
+ }
+ $result = [];
+ $lines = $this->splitTagBlockIntoTagLines($tags);
+ foreach ($lines as $key => $tagLine) {
+ $result[$key] = $this->tagFactory->create(trim($tagLine), $context);
+ }
+ return $result;
+ }
+ /**
+ * @return string[]
+ */
+ private function splitTagBlockIntoTagLines(string $tags) : array
+ {
+ $result = [];
+ foreach (explode("\n", $tags) as $tagLine) {
+ if ($tagLine !== '' && strpos($tagLine, '@') === 0) {
+ $result[] = $tagLine;
+ } else {
+ $result[count($result) - 1] .= "\n" . $tagLine;
+ }
+ }
+ return $result;
+ }
+ private function filterTagBlock(string $tags) : ?string
+ {
+ $tags = trim($tags);
+ if (!$tags) {
+ return null;
+ }
+ if ($tags[0] !== '@') {
+ // @codeCoverageIgnoreStart
+ // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that
+ // we didn't foresee.
+ throw new LogicException('A tag block started with text instead of an at-sign(@): ' . $tags);
+ // @codeCoverageIgnoreEnd
+ }
+ return $tags;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php
new file mode 100644
index 0000000..ee53578
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php
@@ -0,0 +1,20 @@
+> $additionalTags
+ */
+ public static function createInstance(array $additionalTags = []) : self;
+ /**
+ * @param string|object $docblock
+ */
+ public function create($docblock, ?Types\Context $context = null, ?Location $location = null) : DocBlock;
+}
diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/PcreException.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/PcreException.php
new file mode 100644
index 0000000..01896aa
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/PcreException.php
@@ -0,0 +1,35 @@
+resolve('string');
+ echo get_class($type); // phpDocumentor\Reflection\Types\String_
+
+The real power of this resolver is in its capability to expand partial class names into fully qualified class names;
+but in order to do that we need an additional :php:class:`\phpDocumentor\Reflection\Types\Context` class that
+will inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply.
+
+Read more about the Context class in the next section.
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/docs/index.rst b/vendor/prefixed/phpdocumentor/type-resolver/docs/index.rst
new file mode 100644
index 0000000..0ff9a8b
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/docs/index.rst
@@ -0,0 +1,17 @@
+=============
+Type resolver
+=============
+
+This project part of the phpDocumentor project. It is capable of creating an object structure of the type
+specifications found in the PHPDoc blocks of a project. This can be useful for static analysis of a project
+or other behavior that requires knowledge of the types used in a project like automatically build forms.
+
+This project aims to cover all types that are available in PHPDoc and PHP itself. And is open for extension by
+third party developers.
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+
+ index
+ getting-started
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/phpdoc.dist.xml b/vendor/prefixed/phpdocumentor/type-resolver/phpdoc.dist.xml
new file mode 100644
index 0000000..6c98991
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/phpdoc.dist.xml
@@ -0,0 +1,46 @@
+
+
+ Type Resolver
+
+
+
+
+ latest
+
+
+ src/
+
+
+
+ tests/**/*
+ build/**/*
+ var/**/*
+ vendor/**/*
+
+
+ php
+
+
+ template
+ template-extends
+ template-implements
+ extends
+ implements
+
+ phpDocumentor
+
+
+
+ docs
+
+
+
+
+
+
+
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/FqsenResolver.php b/vendor/prefixed/phpdocumentor/type-resolver/src/FqsenResolver.php
new file mode 100644
index 0000000..8cb644b
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/FqsenResolver.php
@@ -0,0 +1,66 @@
+isFqsen($fqsen)) {
+ return new Fqsen($fqsen);
+ }
+ return $this->resolvePartialStructuralElementName($fqsen, $context);
+ }
+ /**
+ * Tests whether the given type is a Fully Qualified Structural Element Name.
+ */
+ private function isFqsen(string $type) : bool
+ {
+ return strpos($type, self::OPERATOR_NAMESPACE) === 0;
+ }
+ /**
+ * Resolves a partial Structural Element Name (i.e. `Reflection\DocBlock`) to its FQSEN representation
+ * (i.e. `\phpDocumentor\Reflection\DocBlock`) based on the Namespace and aliases mentioned in the Context.
+ *
+ * @throws InvalidArgumentException When type is not a valid FQSEN.
+ */
+ private function resolvePartialStructuralElementName(string $type, Context $context) : Fqsen
+ {
+ $typeParts = explode(self::OPERATOR_NAMESPACE, $type, 2);
+ $namespaceAliases = $context->getNamespaceAliases();
+ // if the first segment is not an alias; prepend namespace name and return
+ if (!isset($namespaceAliases[$typeParts[0]])) {
+ $namespace = $context->getNamespace();
+ if ($namespace !== '') {
+ $namespace .= self::OPERATOR_NAMESPACE;
+ }
+ return new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type);
+ }
+ $typeParts[0] = $namespaceAliases[$typeParts[0]];
+ return new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts));
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoType.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoType.php
new file mode 100644
index 0000000..edf2bf7
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoType.php
@@ -0,0 +1,17 @@
+items = $items;
+ }
+ /**
+ * @return ArrayShapeItem[]
+ */
+ public function getItems() : array
+ {
+ return $this->items;
+ }
+ public function underlyingType() : Type
+ {
+ return new Array_(new Mixed_(), new ArrayKey());
+ }
+ public function __toString() : string
+ {
+ return 'array{' . implode(', ', $this->items) . '}';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShapeItem.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShapeItem.php
new file mode 100644
index 0000000..6469639
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShapeItem.php
@@ -0,0 +1,17 @@
+owner = $owner;
+ $this->expression = $expression;
+ }
+ public function getOwner() : Type
+ {
+ return $this->owner;
+ }
+ public function getExpression() : string
+ {
+ return $this->expression;
+ }
+ public function underlyingType() : Type
+ {
+ return new Mixed_();
+ }
+ public function __toString() : string
+ {
+ return sprintf('%s::%s', (string) $this->owner, $this->expression);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/False_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/False_.php
new file mode 100644
index 0000000..083646c
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/False_.php
@@ -0,0 +1,34 @@
+value = $value;
+ }
+ public function getValue() : float
+ {
+ return $this->value;
+ }
+ public function underlyingType() : Type
+ {
+ return new Float_();
+ }
+ public function __toString() : string
+ {
+ return (string) $this->value;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php
new file mode 100644
index 0000000..82f1437
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php
@@ -0,0 +1,35 @@
+minValue = $minValue;
+ $this->maxValue = $maxValue;
+ }
+ public function underlyingType() : Type
+ {
+ return new Integer();
+ }
+ public function getMinValue() : string
+ {
+ return $this->minValue;
+ }
+ public function getMaxValue() : string
+ {
+ return $this->maxValue;
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ return 'int<' . $this->minValue . ', ' . $this->maxValue . '>';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php
new file mode 100644
index 0000000..513c78f
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php
@@ -0,0 +1,39 @@
+value = $value;
+ }
+ public function getValue() : int
+ {
+ return $this->value;
+ }
+ public function underlyingType() : Type
+ {
+ return new Integer();
+ }
+ public function __toString() : string
+ {
+ return (string) $this->value;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ListShape.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ListShape.php
new file mode 100644
index 0000000..834122a
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ListShape.php
@@ -0,0 +1,14 @@
+getItems()) . '}';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ListShapeItem.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ListShapeItem.php
new file mode 100644
index 0000000..d6b767f
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ListShapeItem.php
@@ -0,0 +1,8 @@
+valueType instanceof Mixed_) {
+ return 'list';
+ }
+ return 'list<' . $this->valueType . '>';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php
new file mode 100644
index 0000000..ee11a6e
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php
@@ -0,0 +1,35 @@
+valueType, $this->keyType);
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ if ($this->keyType) {
+ return 'non-empty-array<' . $this->keyType . ',' . $this->valueType . '>';
+ }
+ if ($this->valueType instanceof Mixed_) {
+ return 'non-empty-array';
+ }
+ return 'non-empty-array<' . $this->valueType . '>';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php
new file mode 100644
index 0000000..03828eb
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php
@@ -0,0 +1,44 @@
+valueType, $this->keyType);
+ }
+ public function __construct(?Type $valueType = null)
+ {
+ parent::__construct($valueType, new Integer());
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ if ($this->valueType instanceof Mixed_) {
+ return 'non-empty-list';
+ }
+ return 'non-empty-list<' . $this->valueType . '>';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php
new file mode 100644
index 0000000..9248331
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php
@@ -0,0 +1,35 @@
+items = $items;
+ }
+ /**
+ * @return ObjectShapeItem[]
+ */
+ public function getItems() : array
+ {
+ return $this->items;
+ }
+ public function underlyingType() : Type
+ {
+ return new Object_();
+ }
+ public function __toString() : string
+ {
+ return 'object{' . implode(', ', $this->items) . '}';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ObjectShapeItem.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ObjectShapeItem.php
new file mode 100644
index 0000000..5e9cb70
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ObjectShapeItem.php
@@ -0,0 +1,8 @@
+key = $key;
+ $this->value = $value ?? new Mixed_();
+ $this->optional = $optional;
+ }
+ public function getKey() : ?string
+ {
+ return $this->key;
+ }
+ public function getValue() : Type
+ {
+ return $this->value;
+ }
+ public function isOptional() : bool
+ {
+ return $this->optional;
+ }
+ public function __toString() : string
+ {
+ if ($this->key !== null) {
+ return sprintf('%s%s: %s', $this->key, $this->optional ? '?' : '', (string) $this->value);
+ }
+ return (string) $this->value;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/StringValue.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/StringValue.php
new file mode 100644
index 0000000..f90ecfd
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/StringValue.php
@@ -0,0 +1,40 @@
+value = $value;
+ }
+ public function getValue() : string
+ {
+ return $this->value;
+ }
+ public function underlyingType() : Type
+ {
+ return new String_();
+ }
+ public function __toString() : string
+ {
+ return sprintf('"%s"', $this->value);
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php
new file mode 100644
index 0000000..71bdac7
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php
@@ -0,0 +1,35 @@
+ List of recognized keywords and unto which Value Object they map
+ * @psalm-var array>
+ */
+ private $keywords = ['string' => String_::class, 'class-string' => ClassString::class, 'interface-string' => InterfaceString::class, 'html-escaped-string' => HtmlEscapedString::class, 'lowercase-string' => LowercaseString::class, 'non-empty-lowercase-string' => NonEmptyLowercaseString::class, 'non-empty-string' => NonEmptyString::class, 'numeric-string' => NumericString::class, 'numeric' => Numeric_::class, 'trait-string' => TraitString::class, 'int' => Integer::class, 'integer' => Integer::class, 'positive-int' => PositiveInteger::class, 'negative-int' => NegativeInteger::class, 'bool' => Boolean::class, 'boolean' => Boolean::class, 'real' => Float_::class, 'float' => Float_::class, 'double' => Float_::class, 'object' => Object_::class, 'mixed' => Mixed_::class, 'array' => Array_::class, 'array-key' => ArrayKey::class, 'non-empty-array' => NonEmptyArray::class, 'resource' => Resource_::class, 'void' => Void_::class, 'null' => Null_::class, 'scalar' => Scalar::class, 'callback' => Callable_::class, 'callable' => Callable_::class, 'callable-string' => CallableString::class, 'false' => False_::class, 'true' => True_::class, 'literal-string' => LiteralString::class, 'self' => Self_::class, '$this' => This::class, 'static' => Static_::class, 'parent' => Parent_::class, 'iterable' => Iterable_::class, 'never' => Never_::class, 'list' => List_::class, 'non-empty-list' => NonEmptyList::class];
+ /**
+ * @psalm-readonly
+ * @var FqsenResolver
+ */
+ private $fqsenResolver;
+ /**
+ * @psalm-readonly
+ * @var TypeParser
+ */
+ private $typeParser;
+ /**
+ * @psalm-readonly
+ * @var Lexer
+ */
+ private $lexer;
+ /**
+ * Initializes this TypeResolver with the means to create and resolve Fqsen objects.
+ */
+ public function __construct(?FqsenResolver $fqsenResolver = null)
+ {
+ $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver();
+ if (class_exists(ParserConfig::class)) {
+ $this->typeParser = new TypeParser(new ParserConfig([]), new ConstExprParser(new ParserConfig([])));
+ $this->lexer = new Lexer(new ParserConfig([]));
+ } else {
+ $this->typeParser = new TypeParser(new ConstExprParser());
+ $this->lexer = new Lexer();
+ }
+ }
+ /**
+ * Analyzes the given type and returns the FQCN variant.
+ *
+ * When a type is provided this method checks whether it is not a keyword or
+ * Fully Qualified Class Name. If so it will use the given namespace and
+ * aliases to expand the type to a FQCN representation.
+ *
+ * This method only works as expected if the namespace and aliases are set;
+ * no dynamic reflection is being performed here.
+ *
+ * @uses Context::getNamespace() to determine with what to prefix the type name.
+ * @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be
+ * replaced with another namespace.
+ *
+ * @param string $type The relative or absolute type.
+ */
+ public function resolve(string $type, ?Context $context = null) : Type
+ {
+ $type = trim($type);
+ if (!$type) {
+ throw new InvalidArgumentException('Attempted to resolve "' . $type . '" but it appears to be empty');
+ }
+ if ($context === null) {
+ $context = new Context('');
+ }
+ $tokens = $this->lexer->tokenize($type);
+ $tokenIterator = new TokenIterator($tokens);
+ $ast = $this->parse($tokenIterator);
+ $type = $this->createType($ast, $context);
+ return $this->tryParseRemainingCompoundTypes($tokenIterator, $context, $type);
+ }
+ public function createType(?TypeNode $type, Context $context) : Type
+ {
+ if ($type === null) {
+ return new Mixed_();
+ }
+ switch (get_class($type)) {
+ case ArrayTypeNode::class:
+ return new Array_($this->createType($type->type, $context));
+ case ArrayShapeNode::class:
+ switch ($type->kind) {
+ case ArrayShapeNode::KIND_ARRAY:
+ return new ArrayShape(...array_map(function (ArrayShapeItemNode $item) use($context) : ArrayShapeItem {
+ return new ArrayShapeItem((string) $item->keyName, $this->createType($item->valueType, $context), $item->optional);
+ }, $type->items));
+ case ArrayShapeNode::KIND_LIST:
+ return new ListShape(...array_map(function (ArrayShapeItemNode $item) use($context) : ListShapeItem {
+ return new ListShapeItem(null, $this->createType($item->valueType, $context), $item->optional);
+ }, $type->items));
+ default:
+ throw new RuntimeException('Unsupported array shape kind');
+ }
+ case ObjectShapeNode::class:
+ return new ObjectShape(...array_map(function (ObjectShapeItemNode $item) use($context) : ObjectShapeItem {
+ return new ObjectShapeItem((string) $item->keyName, $this->createType($item->valueType, $context), $item->optional);
+ }, $type->items));
+ case CallableTypeNode::class:
+ return $this->createFromCallable($type, $context);
+ case ConstTypeNode::class:
+ return $this->createFromConst($type, $context);
+ case GenericTypeNode::class:
+ return $this->createFromGeneric($type, $context);
+ case IdentifierTypeNode::class:
+ return $this->resolveSingleType($type->name, $context);
+ case IntersectionTypeNode::class:
+ return new Intersection(array_filter(array_map(function (TypeNode $nestedType) use($context) : Type {
+ $type = $this->createType($nestedType, $context);
+ if ($type instanceof AggregatedType) {
+ return new Expression($type);
+ }
+ return $type;
+ }, $type->types)));
+ case NullableTypeNode::class:
+ $nestedType = $this->createType($type->type, $context);
+ return new Nullable($nestedType);
+ case UnionTypeNode::class:
+ return new Compound(array_filter(array_map(function (TypeNode $nestedType) use($context) : Type {
+ $type = $this->createType($nestedType, $context);
+ if ($type instanceof AggregatedType) {
+ return new Expression($type);
+ }
+ return $type;
+ }, $type->types)));
+ case ThisTypeNode::class:
+ return new This();
+ case ConditionalTypeNode::class:
+ case ConditionalTypeForParameterNode::class:
+ case OffsetAccessTypeNode::class:
+ default:
+ return new Mixed_();
+ }
+ }
+ private function createFromGeneric(GenericTypeNode $type, Context $context) : Type
+ {
+ switch (strtolower($type->type->name)) {
+ case 'array':
+ return $this->createArray($type->genericTypes, $context);
+ case 'class-string':
+ $subType = $this->createType($type->genericTypes[0], $context);
+ if (!$subType instanceof Object_ || $subType->getFqsen() === null) {
+ throw new RuntimeException($subType . ' is not a class string');
+ }
+ return new ClassString($subType->getFqsen());
+ case 'interface-string':
+ $subType = $this->createType($type->genericTypes[0], $context);
+ if (!$subType instanceof Object_ || $subType->getFqsen() === null) {
+ throw new RuntimeException($subType . ' is not a class string');
+ }
+ return new InterfaceString($subType->getFqsen());
+ case 'list':
+ return new List_($this->createType($type->genericTypes[0], $context));
+ case 'non-empty-list':
+ return new NonEmptyList($this->createType($type->genericTypes[0], $context));
+ case 'int':
+ if (isset($type->genericTypes[1]) === \false) {
+ throw new RuntimeException('int has not the correct format');
+ }
+ return new IntegerRange((string) $type->genericTypes[0], (string) $type->genericTypes[1]);
+ case 'iterable':
+ return new Iterable_(...array_reverse(array_map(function (TypeNode $genericType) use($context) : Type {
+ return $this->createType($genericType, $context);
+ }, $type->genericTypes)));
+ default:
+ $collectionType = $this->createType($type->type, $context);
+ if ($collectionType instanceof Object_ === \false) {
+ throw new RuntimeException(sprintf('%s is not a collection', (string) $collectionType));
+ }
+ return new Collection($collectionType->getFqsen(), ...array_reverse(array_map(function (TypeNode $genericType) use($context) : Type {
+ return $this->createType($genericType, $context);
+ }, $type->genericTypes)));
+ }
+ }
+ private function createFromCallable(CallableTypeNode $type, Context $context) : Callable_
+ {
+ return new Callable_(array_map(function (CallableTypeParameterNode $param) use($context) : CallableParameter {
+ return new CallableParameter($this->createType($param->type, $context), $param->parameterName !== '' ? trim($param->parameterName, '$') : null, $param->isReference, $param->isVariadic, $param->isOptional);
+ }, $type->parameters), $this->createType($type->returnType, $context));
+ }
+ private function createFromConst(ConstTypeNode $type, Context $context) : Type
+ {
+ switch (\true) {
+ case $type->constExpr instanceof ConstExprIntegerNode:
+ return new IntegerValue((int) $type->constExpr->value);
+ case $type->constExpr instanceof ConstExprFloatNode:
+ return new FloatValue((float) $type->constExpr->value);
+ case $type->constExpr instanceof ConstExprStringNode:
+ return new StringValue($type->constExpr->value);
+ case $type->constExpr instanceof ConstFetchNode:
+ return new ConstExpression($this->resolve($type->constExpr->className, $context), $type->constExpr->name);
+ default:
+ throw new RuntimeException(sprintf('Unsupported constant type %s', get_class($type)));
+ }
+ }
+ /**
+ * resolve the given type into a type object
+ *
+ * @param string $type the type string, representing a single type
+ *
+ * @return Type|Array_|Object_
+ *
+ * @psalm-mutation-free
+ */
+ private function resolveSingleType(string $type, Context $context) : object
+ {
+ switch (\true) {
+ case $this->isKeyword($type):
+ return $this->resolveKeyword($type);
+ case $this->isFqsen($type):
+ return $this->resolveTypedObject($type);
+ case $this->isPartialStructuralElementName($type):
+ return $this->resolveTypedObject($type, $context);
+ // @codeCoverageIgnoreStart
+ default:
+ // I haven't got the foggiest how the logic would come here but added this as a defense.
+ throw new RuntimeException('Unable to resolve type "' . $type . '", there is no known method to resolve it');
+ }
+ // @codeCoverageIgnoreEnd
+ }
+ /**
+ * Adds a keyword to the list of Keywords and associates it with a specific Value Object.
+ *
+ * @psalm-param class-string $typeClassName
+ */
+ public function addKeyword(string $keyword, string $typeClassName) : void
+ {
+ if (!class_exists($typeClassName)) {
+ throw new InvalidArgumentException('The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class' . ' but we could not find the class ' . $typeClassName);
+ }
+ $interfaces = class_implements($typeClassName);
+ if ($interfaces === \false) {
+ throw new InvalidArgumentException('The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class' . ' but we could not find the class ' . $typeClassName);
+ }
+ if (!in_array(Type::class, $interfaces, \true)) {
+ throw new InvalidArgumentException('The class "' . $typeClassName . '" must implement the interface "phpDocumentor\\Reflection\\Type"');
+ }
+ $this->keywords[$keyword] = $typeClassName;
+ }
+ /**
+ * Detects whether the given type represents a PHPDoc keyword.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @psalm-mutation-free
+ */
+ private function isKeyword(string $type) : bool
+ {
+ return array_key_exists(strtolower($type), $this->keywords);
+ }
+ /**
+ * Detects whether the given type represents a relative structural element name.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @psalm-mutation-free
+ */
+ private function isPartialStructuralElementName(string $type) : bool
+ {
+ return isset($type[0]) && $type[0] !== self::OPERATOR_NAMESPACE && !$this->isKeyword($type);
+ }
+ /**
+ * Tests whether the given type is a Fully Qualified Structural Element Name.
+ *
+ * @psalm-mutation-free
+ */
+ private function isFqsen(string $type) : bool
+ {
+ return strpos($type, self::OPERATOR_NAMESPACE) === 0;
+ }
+ /**
+ * Resolves the given keyword (such as `string`) into a Type object representing that keyword.
+ *
+ * @psalm-mutation-free
+ */
+ private function resolveKeyword(string $type) : Type
+ {
+ $className = $this->keywords[strtolower($type)];
+ return new $className();
+ }
+ /**
+ * Resolves the given FQSEN string into an FQSEN object.
+ *
+ * @psalm-mutation-free
+ */
+ private function resolveTypedObject(string $type, ?Context $context = null) : Object_
+ {
+ return new Object_($this->fqsenResolver->resolve($type, $context));
+ }
+ /** @param TypeNode[] $typeNodes */
+ private function createArray(array $typeNodes, Context $context) : Array_
+ {
+ $types = array_reverse(array_map(function (TypeNode $node) use($context) : Type {
+ return $this->createType($node, $context);
+ }, $typeNodes));
+ if (isset($types[1]) === \false) {
+ return new Array_(...$types);
+ }
+ if ($this->validArrayKeyType($types[1]) || $types[1] instanceof ArrayKey) {
+ return new Array_(...$types);
+ }
+ if ($types[1] instanceof Compound && $types[1]->getIterator()->count() === 2) {
+ if ($this->validArrayKeyType($types[1]->get(0)) && $this->validArrayKeyType($types[1]->get(1))) {
+ return new Array_(...$types);
+ }
+ }
+ throw new RuntimeException('An array can have only integers or strings as keys');
+ }
+ private function validArrayKeyType(?Type $type) : bool
+ {
+ return $type instanceof String_ || $type instanceof Integer;
+ }
+ private function parse(TokenIterator $tokenIterator) : TypeNode
+ {
+ try {
+ $ast = $this->typeParser->parse($tokenIterator);
+ } catch (ParserException $e) {
+ throw new RuntimeException($e->getMessage(), 0, $e);
+ }
+ return $ast;
+ }
+ /**
+ * Will try to parse unsupported type notations by phpstan
+ *
+ * The phpstan parser doesn't support the illegal nullable combinations like this library does.
+ * This method will warn the user about those notations but for bc purposes we will still have it here.
+ */
+ private function tryParseRemainingCompoundTypes(TokenIterator $tokenIterator, Context $context, Type $type) : Type
+ {
+ if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_UNION) || $tokenIterator->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) {
+ Deprecation::trigger('phpdocumentor/type-resolver', 'https://github.com/phpDocumentor/TypeResolver/issues/184', 'Legacy nullable type detected, please update your code as
+ you are using nullable types in a docblock. support will be removed in v2.0.0');
+ }
+ $continue = \true;
+ while ($continue) {
+ $continue = \false;
+ while ($tokenIterator->tryConsumeTokenType(Lexer::TOKEN_UNION)) {
+ $ast = $this->parse($tokenIterator);
+ $type2 = $this->createType($ast, $context);
+ $type = new Compound([$type, $type2]);
+ $continue = \true;
+ }
+ while ($tokenIterator->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) {
+ $ast = $this->typeParser->parse($tokenIterator);
+ $type2 = $this->createType($ast, $context);
+ $type = new Intersection([$type, $type2]);
+ $continue = \true;
+ }
+ }
+ return $type;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AbstractList.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AbstractList.php
new file mode 100644
index 0000000..4435ff5
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AbstractList.php
@@ -0,0 +1,70 @@
+valueType = $valueType;
+ $this->defaultKeyType = new Compound([new String_(), new Integer()]);
+ $this->keyType = $keyType;
+ }
+ /**
+ * Returns the type for the keys of this array.
+ */
+ public function getKeyType() : Type
+ {
+ return $this->keyType ?? $this->defaultKeyType;
+ }
+ /**
+ * Returns the type for the values of this array.
+ */
+ public function getValueType() : Type
+ {
+ return $this->valueType;
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ if ($this->keyType) {
+ return 'array<' . $this->keyType . ',' . $this->valueType . '>';
+ }
+ if ($this->valueType instanceof Mixed_) {
+ return 'array';
+ }
+ if ($this->valueType instanceof Compound) {
+ return '(' . $this->valueType . ')[]';
+ }
+ return $this->valueType . '[]';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AggregatedType.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AggregatedType.php
new file mode 100644
index 0000000..4c2394b
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AggregatedType.php
@@ -0,0 +1,108 @@
+
+ */
+abstract class AggregatedType implements Type, IteratorAggregate
+{
+ /**
+ * @psalm-allow-private-mutation
+ * @var array
+ */
+ private $types = [];
+ /** @var string */
+ private $token;
+ /**
+ * @param array $types
+ */
+ public function __construct(array $types, string $token)
+ {
+ foreach ($types as $type) {
+ $this->add($type);
+ }
+ $this->token = $token;
+ }
+ /**
+ * Returns the type at the given index.
+ */
+ public function get(int $index) : ?Type
+ {
+ if (!$this->has($index)) {
+ return null;
+ }
+ return $this->types[$index];
+ }
+ /**
+ * Tests if this compound type has a type with the given index.
+ */
+ public function has(int $index) : bool
+ {
+ return array_key_exists($index, $this->types);
+ }
+ /**
+ * Tests if this compound type contains the given type.
+ */
+ public function contains(Type $type) : bool
+ {
+ foreach ($this->types as $typePart) {
+ // if the type is duplicate; do not add it
+ if ((string) $typePart === (string) $type) {
+ return \true;
+ }
+ }
+ return \false;
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ return implode($this->token, $this->types);
+ }
+ /**
+ * @return ArrayIterator
+ */
+ public function getIterator() : ArrayIterator
+ {
+ return new ArrayIterator($this->types);
+ }
+ /**
+ * @psalm-suppress ImpureMethodCall
+ */
+ private function add(Type $type) : void
+ {
+ if ($type instanceof static) {
+ foreach ($type->getIterator() as $subType) {
+ $this->add($subType);
+ }
+ return;
+ }
+ // if the type is duplicate; do not add it
+ if ($this->contains($type)) {
+ return;
+ }
+ $this->types[] = $type;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ArrayKey.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ArrayKey.php
new file mode 100644
index 0000000..4174317
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ArrayKey.php
@@ -0,0 +1,37 @@
+type = $type;
+ $this->isReference = $isReference;
+ $this->isVariadic = $isVariadic;
+ $this->isOptional = $isOptional;
+ $this->name = $name;
+ }
+ public function getName() : ?string
+ {
+ return $this->name;
+ }
+ public function getType() : Type
+ {
+ return $this->type;
+ }
+ public function isReference() : bool
+ {
+ return $this->isReference;
+ }
+ public function isVariadic() : bool
+ {
+ return $this->isVariadic;
+ }
+ public function isOptional() : bool
+ {
+ return $this->isOptional;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Callable_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Callable_.php
new file mode 100644
index 0000000..c1d6d12
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Callable_.php
@@ -0,0 +1,50 @@
+parameters = $parameters;
+ $this->returnType = $returnType;
+ }
+ /** @return CallableParameter[] */
+ public function getParameters() : array
+ {
+ return $this->parameters;
+ }
+ public function getReturnType() : ?Type
+ {
+ return $this->returnType;
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ return 'callable';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ClassString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ClassString.php
new file mode 100644
index 0000000..62384c0
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ClassString.php
@@ -0,0 +1,54 @@
+fqsen = $fqsen;
+ }
+ public function underlyingType() : Type
+ {
+ return new String_();
+ }
+ /**
+ * Returns the FQSEN associated with this object.
+ */
+ public function getFqsen() : ?Fqsen
+ {
+ return $this->fqsen;
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ if ($this->fqsen === null) {
+ return 'class-string';
+ }
+ return 'class-string<' . (string) $this->fqsen . '>';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Collection.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Collection.php
new file mode 100644
index 0000000..4779cf9
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Collection.php
@@ -0,0 +1,59 @@
+`
+ * 2. `ACollectionObject`
+ *
+ * - ACollectionObject can be 'array' or an object that can act as an array
+ * - aValueType and aKeyType can be any type expression
+ *
+ * @psalm-immutable
+ */
+final class Collection extends AbstractList
+{
+ /** @var Fqsen|null */
+ private $fqsen;
+ /**
+ * Initializes this representation of an array with the given Type or Fqsen.
+ */
+ public function __construct(?Fqsen $fqsen, Type $valueType, ?Type $keyType = null)
+ {
+ parent::__construct($valueType, $keyType);
+ $this->fqsen = $fqsen;
+ }
+ /**
+ * Returns the FQSEN associated with this object.
+ */
+ public function getFqsen() : ?Fqsen
+ {
+ return $this->fqsen;
+ }
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ */
+ public function __toString() : string
+ {
+ $objectType = (string) ($this->fqsen ?? 'object');
+ if ($this->keyType === null) {
+ return $objectType . '<' . $this->valueType . '>';
+ }
+ return $objectType . '<' . $this->keyType . ',' . $this->valueType . '>';
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Compound.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Compound.php
new file mode 100644
index 0000000..08295bd
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Compound.php
@@ -0,0 +1,35 @@
+ $types
+ */
+ public function __construct(array $types)
+ {
+ parent::__construct($types, '|');
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Context.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Context.php
new file mode 100644
index 0000000..207d1da
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Context.php
@@ -0,0 +1,82 @@
+ Fully Qualified Namespace.
+ * @psalm-var array
+ */
+ private $namespaceAliases;
+ /**
+ * Initializes the new context and normalizes all passed namespaces to be in Qualified Namespace Name (QNN)
+ * format (without a preceding `\`).
+ *
+ * @param string $namespace The namespace where this DocBlock resides in.
+ * @param string[] $namespaceAliases List of namespace aliases => Fully Qualified Namespace.
+ * @psalm-param array $namespaceAliases
+ */
+ public function __construct(string $namespace, array $namespaceAliases = [])
+ {
+ $this->namespace = $namespace !== 'global' && $namespace !== 'default' ? trim($namespace, '\\') : '';
+ foreach ($namespaceAliases as $alias => $fqnn) {
+ if ($fqnn[0] === '\\') {
+ $fqnn = substr($fqnn, 1);
+ }
+ if ($fqnn[strlen($fqnn) - 1] === '\\') {
+ $fqnn = substr($fqnn, 0, -1);
+ }
+ $namespaceAliases[$alias] = $fqnn;
+ }
+ $this->namespaceAliases = $namespaceAliases;
+ }
+ /**
+ * Returns the Qualified Namespace Name (thus without `\` in front) where the associated element is in.
+ */
+ public function getNamespace() : string
+ {
+ return $this->namespace;
+ }
+ /**
+ * Returns a list of Qualified Namespace Names (thus without `\` in front) that are imported, the keys represent
+ * the alias for the imported Namespace.
+ *
+ * @return string[]
+ * @psalm-return array
+ */
+ public function getNamespaceAliases() : array
+ {
+ return $this->namespaceAliases;
+ }
+}
diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ContextFactory.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ContextFactory.php
new file mode 100644
index 0000000..3c7fa79
--- /dev/null
+++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ContextFactory.php
@@ -0,0 +1,360 @@
+ $reflector */
+ return $this->createFromReflectionClass($reflector);
+ }
+ if ($reflector instanceof ReflectionParameter) {
+ return $this->createFromReflectionParameter($reflector);
+ }
+ if ($reflector instanceof ReflectionMethod) {
+ return $this->createFromReflectionMethod($reflector);
+ }
+ if ($reflector instanceof ReflectionProperty) {
+ return $this->createFromReflectionProperty($reflector);
+ }
+ if ($reflector instanceof ReflectionClassConstant) {
+ return $this->createFromReflectionClassConstant($reflector);
+ }
+ throw new UnexpectedValueException('Unhandled \\Reflector instance given: ' . get_class($reflector));
+ }
+ private function createFromReflectionParameter(ReflectionParameter $parameter) : Context
+ {
+ $class = $parameter->getDeclaringClass();
+ if (!$class) {
+ throw new InvalidArgumentException('Unable to get class of ' . $parameter->getName());
+ }
+ return $this->createFromReflectionClass($class);
+ }
+ private function createFromReflectionMethod(ReflectionMethod $method) : Context
+ {
+ $class = $method->getDeclaringClass();
+ return $this->createFromReflectionClass($class);
+ }
+ private function createFromReflectionProperty(ReflectionProperty $property) : Context
+ {
+ $class = $property->getDeclaringClass();
+ return $this->createFromReflectionClass($class);
+ }
+ private function createFromReflectionClassConstant(ReflectionClassConstant $constant) : Context
+ {
+ //phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable
+ /** @phpstan-var ReflectionClass