관리-도구
편집 파일: phpdocumentor.tar
reflection-common/README.md 0000604 00000002472 15224653673 0011461 0 ustar 00 [](https://opensource.org/licenses/MIT) [](https://travis-ci.org/phpDocumentor/ReflectionCommon) [](https://ci.appveyor.com/project/phpDocumentor/ReflectionCommon/branch/master) [](https://coveralls.io/github/phpDocumentor/ReflectionCommon?branch=master) [](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionCommon/?branch=master) [](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionCommon/?branch=master) [](https://packagist.org/packages/phpDocumentor/Reflection-Common) [](https://packagist.org/packages/phpDocumentor/Reflection-Common) ReflectionCommon ================ reflection-common/LICENSE 0000604 00000002071 15224653673 0011202 0 ustar 00 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. reflection-common/composer.json 0000604 00000001330 15224653673 0012714 0 ustar 00 { "name": "phpdocumentor/reflection-common", "keywords": ["phpdoc", "phpDocumentor", "reflection", "static analysis", "FQSEN"], "homepage": "http://www.phpdoc.org", "description": "Common reflection classes used by phpdocumentor to reflect the code structure", "license": "MIT", "authors": [ { "name": "Jaap van Otterdijk", "email": "opensource@ijaap.nl" } ], "require": { "php": ">=7.1" }, "autoload" : { "psr-4" : { "phpDocumentor\\Reflection\\": "src/" } }, "require-dev": { "phpunit/phpunit": "~6" }, "extra": { "branch-alias": { "dev-master": "2.x-dev" } } } reflection-common/.github/workflows/push.yml 0000604 00000014654 15224653673 0015306 0 ustar 00 on: push: branches: - 2.x pull_request: name: Qa workflow jobs: setup: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Restore/cache vendor folder uses: actions/cache@v1 with: path: vendor key: all-build-${{ hashFiles('**/composer.lock') }} restore-keys: | all-build-${{ hashFiles('**/composer.lock') }} all-build- - name: Restore/cache tools folder uses: actions/cache@v1 with: path: tools key: all-tools-${{ github.sha }} restore-keys: | all-tools-${{ github.sha }}- all-tools- - name: composer uses: docker://composer env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: install --no-interaction --prefer-dist --optimize-autoloader - name: Install phive run: make install-phive - name: Install PHAR dependencies run: tools/phive.phar --no-progress install --copy --trust-gpg-keys 4AA394086372C20A,8A03EA3B385DBAA1 --force-accept-unsigned phpunit-with-coverage: runs-on: ubuntu-latest name: Unit tests needs: setup steps: - uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: 7.2 ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 coverage: pcov - name: Restore/cache tools folder uses: actions/cache@v1 with: path: tools key: all-tools-${{ github.sha }} restore-keys: | all-tools-${{ github.sha }}- all-tools- - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies uses: actions/cache@v1 with: path: ${{ steps.composer-cache.outputs.dir }} key: ubuntu-latest-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ubuntu-latest-composer- - name: Install Composer dependencies run: | composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader - name: Run PHPUnit run: php tools/phpunit phpunit: runs-on: ${{ matrix.operating-system }} strategy: matrix: operating-system: - ubuntu-latest - windows-latest - macOS-latest php-versions: ['7.2', '7.3', '7.4', '8.0'] name: Unit tests for PHP version ${{ matrix.php-versions }} on ${{ matrix.operating-system }} needs: - setup - phpunit-with-coverage steps: - uses: actions/checkout@v2 - name: Restore/cache tools folder uses: actions/cache@v1 with: path: tools key: all-tools-${{ github.sha }} restore-keys: | all-tools-${{ github.sha }}- all-tools- - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 coverage: none - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies uses: actions/cache@v1 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install Composer dependencies run: | composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader - name: Run PHPUnit continue-on-error: true run: php tools/phpunit codestyle: runs-on: ubuntu-latest needs: [setup, phpunit] steps: - uses: actions/checkout@v2 - name: Restore/cache vendor folder uses: actions/cache@v1 with: path: vendor key: all-build-${{ hashFiles('**/composer.lock') }} restore-keys: | all-build-${{ hashFiles('**/composer.lock') }} all-build- - name: Code style check uses: phpDocumentor/coding-standard@latest with: args: -s phpstan: runs-on: ubuntu-latest needs: [setup, phpunit] steps: - uses: actions/checkout@v2 - name: Restore/cache vendor folder uses: actions/cache@v1 with: path: vendor key: all-build-${{ hashFiles('**/composer.lock') }} restore-keys: | all-build-${{ hashFiles('**/composer.lock') }} all-build- - name: PHPStan uses: phpDocumentor/phpstan-ga@latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: analyse src --configuration phpstan.neon psalm: runs-on: ubuntu-latest needs: [setup, phpunit] steps: - uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: 7.2 ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 tools: psalm coverage: none - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies uses: actions/cache@v1 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install Composer dependencies run: | composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader - name: Psalm run: psalm --output-format=github bc_check: name: BC Check runs-on: ubuntu-latest needs: [setup, phpunit] steps: - uses: actions/checkout@v2 - name: fetch tags run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - name: Restore/cache vendor folder uses: actions/cache@v1 with: path: vendor key: all-build-${{ hashFiles('**/composer.lock') }} restore-keys: | all-build-${{ hashFiles('**/composer.lock') }} all-build- - name: Roave BC Check uses: docker://nyholm/roave-bc-check-ga reflection-common/.github/dependabot.yml 0000604 00000000202 15224653673 0014357 0 ustar 00 version: 2 updates: - package-ecosystem: composer directory: "/" schedule: interval: daily open-pull-requests-limit: 10 reflection-common/src/Project.php 0000604 00000001206 15224653673 0013102 0 ustar 00 <?php declare(strict_types=1); /** * phpDocumentor * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; /** * Interface for project. Since the definition of a project can be different per factory this interface will be small. */ interface Project { /** * Returns the name of the project. */ public function getName(): string; } reflection-common/src/Location.php 0000604 00000002360 15224653673 0013246 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2018 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; /** * The location where an element occurs within a file. */ final class Location { /** @var int */ private $lineNumber = 0; /** @var int */ private $columnNumber = 0; /** * Initializes the location for an element using its line number in the file and optionally the column number. */ public function __construct(int $lineNumber, int $columnNumber = 0) { $this->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; } } reflection-common/src/Fqsen.php 0000604 00000003534 15224653673 0012556 0 ustar 00 <?php declare(strict_types=1); /** * phpDocumentor * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; use InvalidArgumentException; /** * Value Object for Fqsen. * * @link https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc-meta.md */ final class Fqsen { /** * @var string full quallified class name */ private $fqsen; /** * @var string name of the element without path. */ private $name; /** * Initializes the object. * * @throws InvalidArgumentException when $fqsen is not matching the format. */ public function __construct(string $fqsen) { $matches = []; $result = preg_match( '/^\\\\([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\\\]*)?(?:[:]{2}\\$?([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*))?(?:\\(\\))?$/', $fqsen, $matches ); if ($result === 0) { throw new InvalidArgumentException( sprintf('"%s" is not a valid Fqsen.', $fqsen) ); } $this->fqsen = $fqsen; if (isset($matches[2])) { $this->name = $matches[2]; } else { $matches = explode('\\', $fqsen); $this->name = trim(end($matches), '()'); } } /** * 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; } } reflection-common/src/Element.php 0000604 00000001216 15224653673 0013066 0 ustar 00 <?php declare(strict_types=1); /** * phpDocumentor * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; /** * Interface for Api Elements */ interface Element { /** * Returns the Fqsen of the element. */ public function getFqsen(): Fqsen; /** * Returns the name of the element. */ public function getName(): string; } reflection-common/src/File.php 0000604 00000001422 15224653673 0012353 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2018 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; /** * Interface for files processed by the ProjectFactory */ interface File { /** * Returns the content of the file as a string. */ public function getContents(): string; /** * Returns md5 hash of the file. */ public function md5(): string; /** * Returns an relative path to the file. */ public function path(): string; } reflection-common/src/ProjectFactory.php 0000604 00000001417 15224653673 0014436 0 ustar 00 <?php declare(strict_types=1); /** * phpDocumentor * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; /** * Interface for project factories. A project factory shall convert a set of files * into an object implementing the Project interface. */ interface ProjectFactory { /** * Creates a project from the set of files. * * @param string $name * @param File[] $files * @return Project */ public function create($name, array $files): Project; } reflection-docblock/LICENSE 0000604 00000002070 15224653673 0011471 0 ustar 00 The MIT License (MIT) Copyright (c) 2010 Mike van Riel 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. reflection-docblock/composer.json 0000604 00000001761 15224653673 0013214 0 ustar 00 { "name": "phpdocumentor/reflection-docblock", "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "type": "library", "license": "MIT", "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "require": { "php": "^7.0", "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "autoload": { "psr-4": {"phpDocumentor\\Reflection\\": ["src/"]} }, "autoload-dev": { "psr-4": {"phpDocumentor\\Reflection\\": ["tests/unit"]} }, "require-dev": { "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4", "doctrine/instantiator": "^1.0.5" }, "extra": { "branch-alias": { "dev-master": "4.x-dev" } } } reflection-docblock/README.md 0000604 00000004165 15224653673 0011752 0 ustar 00 The ReflectionDocBlock Component [](https://travis-ci.org/phpDocumentor/ReflectionDocBlock) ================================ Introduction ------------ The ReflectionDocBlock component of phpDocumentor provides a DocBlock parser that is 100% compatible with the [PHPDoc standard](http://phpdoc.org/docs/latest). With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock. Installation ------------ ```bash composer require phpdocumentor/reflection-docblock ``` Usage ----- In order to parse the DocBlock one needs a DocBlockFactory that can be instantiated using its `createInstance` factory method like this: ```php $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); ``` Then we can use the `create` method of the factory to interpret the DocBlock. Please note that it is also possible to provide a class that has the `getDocComment()` method, such as an object of type `ReflectionClass`, the create method will read that if it exists. ```php $docComment = <<<DOCCOMMENT /** * This is an example of a summary. * * This is a Description. A Summary and Description are separated by either * two subsequent newlines (thus a whiteline in between as can be seen in this * example), or when the Summary ends with a dot (`.`) and some form of * whitespace. */ DOCCOMMENT; $docblock = $factory->create($docComment); ``` The `create` method will yield an object of type `\phpDocumentor\Reflection\DocBlock` whose methods can be queried: ```php // Contains the summary for this DocBlock $summary = $docblock->getSummary(); // Contains \phpDocumentor\Reflection\DocBlock\Description object $description = $docblock->getDescription(); // You can either cast it to string $description = (string) $docblock->getDescription(); // Or use the render method to get a string representation of the Description. $description = $docblock->getDescription()->render(); ``` > For more examples it would be best to review the scripts in the [`/examples` folder](/examples). reflection-docblock/src/DocBlockFactory.php 0000604 00000022206 15224653673 0014777 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\StandardTagFactory; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\TagFactory; use Webmozart\Assert\Assert; final class DocBlockFactory implements DocBlockFactoryInterface { /** @var DocBlock\DescriptionFactory */ private $descriptionFactory; /** @var DocBlock\TagFactory */ private $tagFactory; /** * Initializes this factory with the required subcontractors. * * @param DescriptionFactory $descriptionFactory * @param TagFactory $tagFactory */ public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory) { $this->descriptionFactory = $descriptionFactory; $this->tagFactory = $tagFactory; } /** * Factory method for easy instantiation. * * @param string[] $additionalTags * * @return DocBlockFactory */ public static function createInstance(array $additionalTags = []) { $fqsenResolver = new FqsenResolver(); $tagFactory = new StandardTagFactory($fqsenResolver); $descriptionFactory = new DescriptionFactory($tagFactory); $tagFactory->addService($descriptionFactory); $tagFactory->addService(new TypeResolver($fqsenResolver)); $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). * @param Types\Context $context * @param Location $location * * @return DocBlock */ public function create($docblock, Types\Context $context = null, Location $location = null) { 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::stringNotEmpty($docblock); if ($context === null) { $context = new Types\Context(''); } $parts = $this->splitDocBlock($this->stripDocComment($docblock)); list($templateMarker, $summary, $description, $tags) = $parts; return new DocBlock( $summary, $description ? $this->descriptionFactory->create($description, $context) : null, array_filter($this->parseTagBlock($tags, $context), function ($tag) { return $tag instanceof Tag; }), $context, $location, $templateMarker === '#@+', $templateMarker === '#@-' ); } public function registerTagHandler($tagName, $handler) { $this->tagFactory->registerTagHandler($tagName, $handler); } /** * Strips the asterisks from the DocBlock comment. * * @param string $comment String containing the comment text. * * @return string */ private function stripDocComment($comment) { $comment = trim(preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u', '$1', $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); } /** * Splits the DocBlock into a template marker, summary, description and block of tags. * * @param string $comment Comment to split into the sub-parts. * * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split. * @author Mike van Riel <me@mikevanriel.com> for extending the regex with template marker support. * * @return string[] containing the template marker (if any), summary, description and a string containing the tags. */ private function splitDocBlock($comment) { // 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); /* * 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($tags, Types\Context $context) { $tags = $this->filterTagBlock($tags); if (!$tags) { return []; } $result = $this->splitTagBlockIntoTagLines($tags); foreach ($result as $key => $tagLine) { $result[$key] = $this->tagFactory->create(trim($tagLine), $context); } return $result; } /** * @param string $tags * * @return string[] */ private function splitTagBlockIntoTagLines($tags) { $result = []; foreach (explode("\n", $tags) as $tag_line) { if (isset($tag_line[0]) && ($tag_line[0] === '@')) { $result[] = $tag_line; } else { $result[count($result) - 1] .= "\n" . $tag_line; } } return $result; } /** * @param $tags * @return string */ private function filterTagBlock($tags) { $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; } } reflection-docblock/src/DocBlock.php 0000604 00000013401 15224653673 0013444 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; use phpDocumentor\Reflection\DocBlock\Tag; use Webmozart\Assert\Assert; final class DocBlock { /** @var string The opening line for this docblock. */ private $summary = ''; /** @var DocBlock\Description The actual description for this docblock. */ private $description = null; /** @var Tag[] An array containing all the tags in this docblock; except inline. */ private $tags = []; /** @var Types\Context Information about the context of this DocBlock. */ private $context = null; /** @var Location Information about the location of this DocBlock. */ private $location = null; /** @var bool Is this DocBlock (the start of) a template? */ private $isTemplateStart = false; /** @var bool Does this DocBlock signify the end of a DocBlock template? */ private $isTemplateEnd = false; /** * @param string $summary * @param DocBlock\Description $description * @param DocBlock\Tag[] $tags * @param Types\Context $context The context in which the DocBlock occurs. * @param Location $location The location within the file that this DocBlock occurs in. * @param bool $isTemplateStart * @param bool $isTemplateEnd */ public function __construct( $summary = '', DocBlock\Description $description = null, array $tags = [], Types\Context $context = null, Location $location = null, $isTemplateStart = false, $isTemplateEnd = false ) { Assert::string($summary); Assert::boolean($isTemplateStart); Assert::boolean($isTemplateEnd); Assert::allIsInstanceOf($tags, Tag::class); $this->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; } /** * @return string */ public function getSummary() { return $this->summary; } /** * @return DocBlock\Description */ public function getDescription() { return $this->description; } /** * Returns the current context. * * @return Types\Context */ public function getContext() { return $this->context; } /** * Returns the current location. * * @return Location */ public function getLocation() { 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. * * @return boolean */ public function isTemplateStart() { 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. * * @return boolean */ public function isTemplateEnd() { return $this->isTemplateEnd; } /** * Returns the tags for this DocBlock. * * @return Tag[] */ public function getTags() { 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($name) { Assert::string($name); $result = []; /** @var Tag $tag */ foreach ($this->getTags() as $tag) { if ($tag->getName() !== $name) { 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. * * @return bool */ public function hasTag($name) { Assert::string($name); /** @var Tag $tag */ foreach ($this->getTags() as $tag) { if ($tag->getName() === $name) { return true; } } return false; } /** * Remove a tag from this DocBlock. * * @param Tag $tag The tag to remove. * * @return void */ public function removeTag(Tag $tagToRemove) { 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. * * @return void */ private function addTag(Tag $tag) { $this->tags[] = $tag; } } reflection-docblock/src/DocBlockFactoryInterface.php 0000604 00000001041 15224653673 0016612 0 ustar 00 <?php namespace phpDocumentor\Reflection; interface DocBlockFactoryInterface { /** * Factory method for easy instantiation. * * @param string[] $additionalTags * * @return DocBlockFactory */ public static function createInstance(array $additionalTags = []); /** * @param string $docblock * @param Types\Context $context * @param Location $location * * @return DocBlock */ public function create($docblock, Types\Context $context = null, Location $location = null); } reflection-docblock/src/Exception/PcreException.php 0000604 00000002223 15224653673 0016472 0 ustar 00 <?php declare(strict_types=1); namespace phpDocumentor\Reflection\Exception; use InvalidArgumentException; use const PREG_BACKTRACK_LIMIT_ERROR; use const PREG_BAD_UTF8_ERROR; use const PREG_BAD_UTF8_OFFSET_ERROR; use const PREG_INTERNAL_ERROR; use const PREG_JIT_STACKLIMIT_ERROR; use const PREG_NO_ERROR; use const PREG_RECURSION_LIMIT_ERROR; final class PcreException extends InvalidArgumentException { public static function createFromPhpError(int $errorCode) : self { switch ($errorCode) { case PREG_BACKTRACK_LIMIT_ERROR: return new self('Backtrack limit error'); case PREG_RECURSION_LIMIT_ERROR: return new self('Recursion limit error'); case PREG_BAD_UTF8_ERROR: return new self('Bad UTF8 error'); case PREG_BAD_UTF8_OFFSET_ERROR: return new self('Bad UTF8 offset error'); case PREG_JIT_STACKLIMIT_ERROR: return new self('Jit stacklimit error'); case PREG_NO_ERROR: case PREG_INTERNAL_ERROR: default: } return new self('Unknown Pcre error'); } } reflection-docblock/src/DocBlock/TagFactory.php 0000604 00000007407 15224653673 0015520 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\Types\Context as TypeContext; interface TagFactory { /** * Adds a parameter to the service locator that can be injected in a tag's factory method. * * When calling a tag's "create" method we always check the signature for dependencies to inject. One way is to * typehint a parameter in the signature so that we can use that interface or class name to inject a dependency * (see {@see addService()} for more information on that). * * Another way is to check the name of the argument against the names in the Service Locator. With this method * you can add a variable that will be inserted when a tag's create method is not typehinted and has a matching * name. * * Be aware that there are two reserved names: * * - name, representing the name of the tag. * - body, representing the complete body of the tag. * * These parameters are injected at the last moment and will override any existing parameter with those names. * * @param string $name * @param mixed $value * * @return void */ public function addParameter($name, $value); /** * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided. * * When calling a tag's "create" method we always check the signature for dependencies to inject. If a parameter * has a typehint then the ServiceLocator is queried to see if a Service is registered for that typehint. * * Because interfaces are regularly used as type-hints this method provides an alias parameter; if the FQCN of the * interface is passed as alias then every time that interface is requested the provided service will be returned. * * @param object $service * @param string $alias * * @return void */ public function addService($service); /** * Factory method responsible for instantiating the correct sub type. * * @param string $tagLine The text for this tag, including description. * @param TypeContext $context * * @throws \InvalidArgumentException if an invalid tag line was presented. * * @return Tag A new tag object. */ public function create($tagLine, TypeContext $context = null); /** * Registers a handler for tags. * * If you want to use your own tags then you can use this method to instruct the TagFactory to register the name * of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement the {@see Tag} interface (and thus * the create method). * * @param string $tagName Name of tag to register a handler for. When registering a namespaced tag, the full * name, along with a prefixing slash MUST be provided. * @param string $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 * * @return void */ public function registerTagHandler($tagName, $handler); } reflection-docblock/src/DocBlock/DescriptionFactory.php 0000604 00000015560 15224653673 0017267 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\Types\Context as TypeContext; /** * Creates a new Description object given a body of text. * * Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their * body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the * Description object's `render` method. * * In addition to the above does a Description support two types of escape sequences: * * 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}` * 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description * of an inline tag. * * If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning * of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping * over unexpected spaces as can be observed with tag descriptions. */ class DescriptionFactory { /** @var TagFactory */ private $tagFactory; /** * Initializes this factory with the means to construct (inline) tags. * * @param TagFactory $tagFactory */ public function __construct(TagFactory $tagFactory) { $this->tagFactory = $tagFactory; } /** * Returns the parsed text of this description. * * @param string $contents * @param TypeContext $context * * @return Description */ public function create($contents, TypeContext $context = null) { list($text, $tags) = $this->parse($this->lex($contents), $context); return new Description($text, $tags); } /** * Strips the contents from superfluous whitespace and splits the description into a series of tokens. * * @param string $contents * * @return string[] A series of tokens of which the description text is composed. */ private function lex($contents) { $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 preg_split( '/\{ # "{@}" 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, null, PREG_SPLIT_DELIM_CAPTURE ); } /** * Parses the stream of tokens in to a new set of tokens containing Tags. * * @param string[] $tokens * @param TypeContext $context * * @return string[]|Tag[] */ private function parse($tokens, TypeContext $context) { $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 [implode('', $tokens), $tags]; } /** * 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. * * @param string $contents * * @return string */ private function removeSuperfluousStartingWhitespace($contents) { $lines = explode("\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; $i < count($lines); $i++) { // lines with a no length do not count as they are not indented at all if (strlen(trim($lines[$i])) === 0) { 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; $i < count($lines); $i++) { $lines[$i] = substr($lines[$i], $startingSpaceCount); } } return implode("\n", $lines); } } reflection-docblock/src/DocBlock/Serializer.php 0000604 00000011376 15224653673 0015566 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock; use Webmozart\Assert\Assert; /** * Converts a DocBlock back from an object to a complete DocComment including Asterisks. */ class Serializer { /** @var string The string to indent the comment with. */ protected $indentString = ' '; /** @var int The number of times the indent string is repeated. */ protected $indent = 0; /** @var bool Whether to indent the first line with the given indent amount and string. */ protected $isFirstLineIndented = true; /** @var int|null The max length of a line. */ protected $lineLength = null; /** @var DocBlock\Tags\Formatter A custom tag formatter. */ protected $tagFormatter = null; /** * Create a Serializer instance. * * @param int $indent The number of times the indent string is repeated. * @param string $indentString The string to indent the comment with. * @param bool $indentFirstLine Whether to indent the first line. * @param int|null $lineLength The max length of a line or NULL to disable line wrapping. * @param DocBlock\Tags\Formatter $tagFormatter A custom tag formatter, defaults to PassthroughFormatter. */ public function __construct($indent = 0, $indentString = ' ', $indentFirstLine = true, $lineLength = null, $tagFormatter = null) { Assert::integer($indent); Assert::string($indentString); Assert::boolean($indentFirstLine); Assert::nullOrInteger($lineLength); Assert::nullOrIsInstanceOf($tagFormatter, 'phpDocumentor\Reflection\DocBlock\Tags\Formatter'); $this->indent = $indent; $this->indentString = $indentString; $this->isFirstLineIndented = $indentFirstLine; $this->lineLength = $lineLength; $this->tagFormatter = $tagFormatter ?: new DocBlock\Tags\Formatter\PassthroughFormatter(); } /** * Generate a DocBlock comment. * * @param DocBlock $docblock The DocBlock to serialize. * * @return string The serialized doc block. */ public function getDocComment(DocBlock $docblock) { $indent = str_repeat($this->indentString, $this->indent); $firstIndent = $this->isFirstLineIndented ? $indent : ''; // 3 === strlen(' * ') $wrapLength = $this->lineLength ? $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); $comment .= $indent . ' */'; return $comment; } /** * @param $indent * @param $text * @return mixed */ private function removeTrailingSpaces($indent, $text) { return str_replace("\n{$indent} * \n", "\n{$indent} *\n", $text); } /** * @param $indent * @param $text * @return mixed */ private function addAsterisksForEachLine($indent, $text) { return str_replace("\n", "\n{$indent} * ", $text); } /** * @param DocBlock $docblock * @param $wrapLength * @return string */ private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, $wrapLength) { $text = $docblock->getSummary() . ((string)$docblock->getDescription() ? "\n\n" . $docblock->getDescription() : ''); if ($wrapLength !== null) { $text = wordwrap($text, $wrapLength); return $text; } return $text; } /** * @param DocBlock $docblock * @param $wrapLength * @param $indent * @param $comment * @return string */ private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment) { foreach ($docblock->getTags() as $tag) { $tagText = $this->tagFormatter->format($tag); if ($wrapLength !== null) { $tagText = wordwrap($tagText, $wrapLength); } $tagText = str_replace("\n", "\n{$indent} * ", $tagText); $comment .= "{$indent} * {$tagText}\n"; } return $comment; } } reflection-docblock/src/DocBlock/Description.php 0000604 00000007057 15224653673 0015741 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Tags\Formatter; use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter; use Webmozart\Assert\Assert; /** * Object representing to description for a DocBlock. * * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete * description text using the format that you would prefer. * * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is * thus recommended to use that to create a Description object, like this: * * $description = $descriptionFactory->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 Description\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 string $bodyTemplate * @param Tag[] $tags */ public function __construct($bodyTemplate, array $tags = []) { Assert::string($bodyTemplate); $this->bodyTemplate = $bodyTemplate; $this->tags = $tags; } /** * Returns the tags for this DocBlock. * * @return Tag[] */ public function getTags() { return $this->tags; } /** * Renders this description as a string where the provided formatter will format the tags in the expected string * format. * * @param Formatter|null $formatter * * @return string */ public function render(Formatter $formatter = null) { 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. * * @return string */ public function __toString() { return $this->render(); } } reflection-docblock/src/DocBlock/StandardTagFactory.php 0000604 00000027122 15224653673 0017175 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod; use phpDocumentor\Reflection\DocBlock\Tags\Generic; use phpDocumentor\Reflection\FqsenResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Creates a Tag object given the contents of a tag. * * This Factory is capable of determining the appropriate class for a tag and instantiate it using its `create` * factory method. The `create` factory method of a Tag can have a variable number of arguments; this way you can * pass the dependencies that you need to construct a tag object. * * > 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. */ const REGEX_TAGNAME = '[\w\-\_\\\\]+'; /** * @var string[] An array with a tag as a key, and an FQCN to a class that handles it as an array value. */ private $tagHandlerMappings = [ 'author' => '\phpDocumentor\Reflection\DocBlock\Tags\Author', 'covers' => '\phpDocumentor\Reflection\DocBlock\Tags\Covers', 'deprecated' => '\phpDocumentor\Reflection\DocBlock\Tags\Deprecated', // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', 'link' => '\phpDocumentor\Reflection\DocBlock\Tags\Link', 'method' => '\phpDocumentor\Reflection\DocBlock\Tags\Method', 'param' => '\phpDocumentor\Reflection\DocBlock\Tags\Param', 'property-read' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead', 'property' => '\phpDocumentor\Reflection\DocBlock\Tags\Property', 'property-write' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite', 'return' => '\phpDocumentor\Reflection\DocBlock\Tags\Return_', 'see' => '\phpDocumentor\Reflection\DocBlock\Tags\See', 'since' => '\phpDocumentor\Reflection\DocBlock\Tags\Since', 'source' => '\phpDocumentor\Reflection\DocBlock\Tags\Source', 'throw' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws', 'throws' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws', 'uses' => '\phpDocumentor\Reflection\DocBlock\Tags\Uses', 'var' => '\phpDocumentor\Reflection\DocBlock\Tags\Var_', 'version' => '\phpDocumentor\Reflection\DocBlock\Tags\Version' ]; /** * @var \ReflectionParameter[][] a lazy-loading cache containing parameters for each tagHandler that has been used. */ private $tagHandlerParameterCache = []; /** * @var 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. * * @param FqsenResolver $fqsenResolver * @param string[] $tagHandlers * * @see self::registerTagHandler() to add a new tag handler to the existing default list. */ public function __construct(FqsenResolver $fqsenResolver, array $tagHandlers = null) { $this->fqsenResolver = $fqsenResolver; if ($tagHandlers !== null) { $this->tagHandlerMappings = $tagHandlers; } $this->addService($fqsenResolver, FqsenResolver::class); } /** * {@inheritDoc} */ public function create($tagLine, TypeContext $context = null) { if (! $context) { $context = new TypeContext(''); } list($tagName, $tagBody) = $this->extractTagParts($tagLine); if ($tagBody !== '' && $tagBody[0] === '[') { throw new \InvalidArgumentException( 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors' ); } return $this->createTag($tagBody, $tagName, $context); } /** * {@inheritDoc} */ public function addParameter($name, $value) { $this->serviceLocator[$name] = $value; } /** * {@inheritDoc} */ public function addService($service, $alias = null) { $this->serviceLocator[$alias ?: get_class($service)] = $service; } /** * {@inheritDoc} */ public function registerTagHandler($tagName, $handler) { Assert::stringNotEmpty($tagName); Assert::stringNotEmpty($handler); Assert::classExists($handler); Assert::implementsInterface($handler, StaticMethod::class); if (strpos($tagName, '\\') && $tagName[0] !== '\\') { throw new \InvalidArgumentException( 'A namespaced tag must have a leading backslash as it must be fully qualified' ); } $this->tagHandlerMappings[$tagName] = $handler; } /** * Extracts all components for a tag. * * @param string $tagLine * * @return string[] */ private function extractTagParts($tagLine) { $matches = []; if (! preg_match('/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)/us', $tagLine, $matches)) { throw new \InvalidArgumentException( 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors' ); } if (count($matches) < 3) { $matches[] = ''; } 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. * * @param string $body * @param string $name * @param TypeContext $context * * @return Tag|null */ private function createTag($body, $name, TypeContext $context) { $handlerClassName = $this->findHandlerClassName($name, $context); $arguments = $this->getArgumentsForParametersFromWiring( $this->fetchParametersForHandlerFactoryMethod($handlerClassName), $this->getServiceLocatorWithDynamicParameters($context, $name, $body) ); return call_user_func_array([$handlerClassName, 'create'], $arguments); } /** * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`). * * @param string $tagName * @param TypeContext $context * * @return string */ private function findHandlerClassName($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($parameters, $locator) { $arguments = []; foreach ($parameters as $index => $parameter) { $typeHint = $parameter->getClass() ? $parameter->getClass()->getName() : null; if (isset($locator[$typeHint])) { $arguments[] = $locator[$typeHint]; continue; } $parameterName = $parameter->getName(); if (isset($locator[$parameterName])) { $arguments[] = $locator[$parameterName]; continue; } $arguments[] = null; } return $arguments; } /** * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given * tag handler class name. * * @param string $handlerClassName * * @return \ReflectionParameter[] */ private function fetchParametersForHandlerFactoryMethod($handlerClassName) { 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 aliasses) 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, $tagName, $tagBody) { $locator = array_merge( $this->serviceLocator, [ 'name' => $tagName, 'body' => $tagBody, TypeContext::class => $context ] ); return $locator; } /** * Returns whether the given tag belongs to an annotation. * * @param string $tagContent * * @todo this method should be populated once we implement Annotation notation support. * * @return bool */ private function isAnnotation($tagContent) { // 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; } } reflection-docblock/src/DocBlock/Tag.php 0000604 00000001165 15224653673 0014163 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Tags\Formatter; interface Tag { public function getName(); public static function create($body); public function render(Formatter $formatter = null); public function __toString(); } reflection-docblock/src/DocBlock/ExampleFinder.php 0000604 00000011315 15224653673 0016171 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Tags\Example; /** * Class used to find an example file's location based on a given ExampleDescriptor. */ class ExampleFinder { /** @var string */ private $sourceDirectory = ''; /** @var string[] */ private $exampleDirectories = []; /** * Attempts to find the example contents for the given descriptor. * * @param Example $example * * @return string */ public function find(Example $example) { $filename = $example->getFilePath(); $file = $this->getExampleFileContents($filename); if (!$file) { return "** File not found : {$filename} **"; } return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount())); } /** * Registers the project's root directory where an 'examples' folder can be expected. * * @param string $directory * * @return void */ public function setSourceDirectory($directory = '') { $this->sourceDirectory = $directory; } /** * Returns the project's root directory where an 'examples' folder can be expected. * * @return string */ public function getSourceDirectory() { return $this->sourceDirectory; } /** * Registers a series of directories that may contain examples. * * @param string[] $directories */ public function setExampleDirectories(array $directories) { $this->exampleDirectories = $directories; } /** * Returns a series of directories that may contain examples. * * @return string[] */ public function getExampleDirectories() { 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 * * @param string $filename * * @return string|null */ private function getExampleFileContents($filename) { $normalizedPath = null; foreach ($this->exampleDirectories as $directory) { $exampleFileFromConfig = $this->constructExamplePath($directory, $filename); if (is_readable($exampleFileFromConfig)) { $normalizedPath = $exampleFileFromConfig; break; } } if (!$normalizedPath) { 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; } } return $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : null; } /** * Get example filepath based on the example directory inside your project. * * @param string $file * * @return string */ private function getExamplePathFromExampleDirectory($file) { return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file; } /** * Returns a path to the example file in the given directory.. * * @param string $directory * @param string $file * * @return string */ private function constructExamplePath($directory, $file) { return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file; } /** * Get example filepath based on sourcecode. * * @param string $file * * @return string */ private function getExamplePathFromSource($file) { return sprintf( '%s%s%s', trim($this->getSourceDirectory(), '\\/'), DIRECTORY_SEPARATOR, trim($file, '"') ); } } reflection-docblock/src/DocBlock/Tags/Since.php 0000604 00000004777 15224653673 0015423 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}since tag in a Docblock. */ final class Since extends BaseTag implements Factory\StaticMethod { protected $name = 'since'; /** * PCRE regular expression matching a version vector. * Assumes the "x" modifier. */ const REGEX_VECTOR = '(?: # Normal release vectors. \d\S* | # VCS version vectors. Per PHPCS, they are expected to # follow the form of the VCS name, followed by ":", followed # by the version vector itself. # By convention, popular VCSes like CVS, SVN and GIT use "$" # around the actual version vector. [^\s\:]+\:\s*\$[^\$]+\$ )'; /** @var string The version vector. */ private $version = ''; public function __construct($version = null, Description $description = null) { Assert::nullOrStringNotEmpty($version); $this->version = $version; $this->description = $description; } /** * @return static */ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) { Assert::nullOrString($body); if (empty($body)) { return new static(); } $matches = []; if (! preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { return null; } return new static( $matches[1], $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) ); } /** * Gets the version section of the tag. * * @return string */ public function getVersion() { return $this->version; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return $this->version . ($this->description ? ' ' . $this->description->render() : ''); } } reflection-docblock/src/DocBlock/Tags/Uses.php 0000604 00000004120 15224653673 0015257 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\FqsenResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}uses tag in a Docblock. */ final class Uses extends BaseTag implements Factory\StaticMethod { protected $name = 'uses'; /** @var Fqsen */ protected $refers = null; /** * Initializes this tag. * * @param Fqsen $refers * @param Description $description */ public function __construct(Fqsen $refers, Description $description = null) { $this->refers = $refers; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, FqsenResolver $resolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::string($body); Assert::allNotNull([$resolver, $descriptionFactory]); $parts = preg_split('/\s+/Su', $body, 2); return new static( $resolver->resolve($parts[0], $context), $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context) ); } /** * Returns the structural element this tag refers to. * * @return Fqsen */ public function getReference() { return $this->refers; } /** * Returns a string representation of this tag. * * @return string */ public function __toString() { return $this->refers . ' ' . $this->description->render(); } } reflection-docblock/src/DocBlock/Tags/Param.php 0000604 00000007574 15224653673 0015420 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for the {@}param tag in a Docblock. */ final class Param extends BaseTag implements Factory\StaticMethod { /** @var string */ protected $name = 'param'; /** @var Type */ private $type; /** @var string */ private $variableName = ''; /** @var bool determines whether this is a variadic argument */ private $isVariadic = false; /** * @param string $variableName * @param Type $type * @param bool $isVariadic * @param Description $description */ public function __construct($variableName, Type $type = null, $isVariadic = false, Description $description = null) { Assert::string($variableName); Assert::boolean($isVariadic); $this->variableName = $variableName; $this->type = $type; $this->isVariadic = $isVariadic; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::stringNotEmpty($body); Assert::allNotNull([$typeResolver, $descriptionFactory]); $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); $type = null; $variableName = ''; $isVariadic = false; // if the first item that is encountered is not a variable; it is a type if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { $type = $typeResolver->resolve(array_shift($parts), $context); array_shift($parts); } // if the next item starts with a $ or ...$ it must be the variable name if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$' || substr($parts[0], 0, 4) === '...$')) { $variableName = array_shift($parts); array_shift($parts); if (substr($variableName, 0, 3) === '...') { $isVariadic = true; $variableName = substr($variableName, 3); } if (substr($variableName, 0, 1) === '$') { $variableName = substr($variableName, 1); } } $description = $descriptionFactory->create(implode('', $parts), $context); return new static($variableName, $type, $isVariadic, $description); } /** * Returns the variable's name. * * @return string */ public function getVariableName() { return $this->variableName; } /** * Returns the variable's type or null if unknown. * * @return Type|null */ public function getType() { return $this->type; } /** * Returns whether this tag is variadic. * * @return boolean */ public function isVariadic() { return $this->isVariadic; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return ($this->type ? $this->type . ' ' : '') . ($this->isVariadic() ? '...' : '') . '$' . $this->variableName . ($this->description ? ' ' . $this->description : ''); } } reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php 0000604 00000002372 15224653673 0021230 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @author Jan Schneider <jan@horde.org> * @copyright 2017 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\Formatter; class AlignFormatter implements Formatter { /** @var int The maximum tag name length. */ protected $maxLen = 0; /** * Constructor. * * @param Tag[] $tags All tags that should later be aligned with the formatter. */ public function __construct(array $tags) { foreach ($tags as $tag) { $this->maxLen = max($this->maxLen, strlen($tag->getName())); } } /** * Formats the given tag to return a simple plain text version. * * @param Tag $tag * * @return string */ public function format(Tag $tag) { return '@' . $tag->getName() . str_repeat(' ', $this->maxLen - strlen($tag->getName()) + 1) . (string)$tag; } } reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php 0000604 00000001453 15224653673 0022504 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\Formatter; class PassthroughFormatter implements Formatter { /** * Formats the given tag to return a simple plain text version. * * @param Tag $tag * * @return string */ public function format(Tag $tag) { return trim('@' . $tag->getName() . ' ' . (string)$tag); } } reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php 0000604 00000001664 15224653673 0017324 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; use phpDocumentor\Reflection\Fqsen as RealFqsen; /** * Fqsen reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See} */ final class Fqsen implements Reference { /** * @var RealFqsen */ private $fqsen; /** * Fqsen constructor. */ public function __construct(RealFqsen $fqsen) { $this->fqsen = $fqsen; } /** * @return string string representation of the referenced fqsen */ public function __toString() { return (string)$this->fqsen; } } reflection-docblock/src/DocBlock/Tags/Reference/Reference.php 0000604 00000001054 15224653673 0020137 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; /** * Interface for references in {@see phpDocumentor\Reflection\DocBlock\Tags\See} */ interface Reference { public function __toString(); } reflection-docblock/src/DocBlock/Tags/Reference/Url.php 0000604 00000001515 15224653673 0017005 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; use Webmozart\Assert\Assert; /** * Url reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See} */ final class Url implements Reference { /** * @var string */ private $uri; /** * Url constructor. */ public function __construct($uri) { Assert::stringNotEmpty($uri); $this->uri = $uri; } public function __toString() { return $this->uri; } } reflection-docblock/src/DocBlock/Tags/PropertyRead.php 0000604 00000006342 15224653673 0016770 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}property-read tag in a Docblock. */ class PropertyRead extends BaseTag implements Factory\StaticMethod { /** @var string */ protected $name = 'property-read'; /** @var Type */ private $type; /** @var string */ protected $variableName = ''; /** * @param string $variableName * @param Type $type * @param Description $description */ public function __construct($variableName, Type $type = null, Description $description = null) { Assert::string($variableName); $this->variableName = $variableName; $this->type = $type; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::stringNotEmpty($body); Assert::allNotNull([$typeResolver, $descriptionFactory]); $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); $type = null; $variableName = ''; // if the first item that is encountered is not a variable; it is a type if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { $type = $typeResolver->resolve(array_shift($parts), $context); array_shift($parts); } // if the next item starts with a $ or ...$ it must be the variable name if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { $variableName = array_shift($parts); array_shift($parts); if (substr($variableName, 0, 1) === '$') { $variableName = substr($variableName, 1); } } $description = $descriptionFactory->create(implode('', $parts), $context); return new static($variableName, $type, $description); } /** * Returns the variable's name. * * @return string */ public function getVariableName() { return $this->variableName; } /** * Returns the variable's type or null if unknown. * * @return Type|null */ public function getType() { return $this->type; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return ($this->type ? $this->type . ' ' : '') . '$' . $this->variableName . ($this->description ? ' ' . $this->description : ''); } } reflection-docblock/src/DocBlock/Tags/Version.php 0000604 00000004704 15224653673 0015775 0 ustar 00 <?php /** * phpDocumentor * * PHP Version 5.3 * * @author Vasil Rangelov <boen.robot@gmail.com> * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}version tag in a Docblock. */ final class Version extends BaseTag implements Factory\StaticMethod { protected $name = 'version'; /** * PCRE regular expression matching a version vector. * Assumes the "x" modifier. */ const REGEX_VECTOR = '(?: # Normal release vectors. \d\S* | # VCS version vectors. Per PHPCS, they are expected to # follow the form of the VCS name, followed by ":", followed # by the version vector itself. # By convention, popular VCSes like CVS, SVN and GIT use "$" # around the actual version vector. [^\s\:]+\:\s*\$[^\$]+\$ )'; /** @var string The version vector. */ private $version = ''; public function __construct($version = null, Description $description = null) { Assert::nullOrStringNotEmpty($version); $this->version = $version; $this->description = $description; } /** * @return static */ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) { Assert::nullOrString($body); if (empty($body)) { return new static(); } $matches = []; if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { return null; } return new static( $matches[1], $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) ); } /** * Gets the version section of the tag. * * @return string */ public function getVersion() { return $this->version; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return $this->version . ($this->description ? ' ' . $this->description->render() : ''); } } reflection-docblock/src/DocBlock/Tags/Generic.php 0000604 00000005137 15224653673 0015725 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\StandardTagFactory; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Parses a tag definition for a DocBlock. */ class Generic extends BaseTag implements Factory\StaticMethod { /** * Parses a tag and populates the member variables. * * @param string $name Name of the tag. * @param Description $description The contents of the given tag. */ public function __construct($name, Description $description = null) { $this->validateTagName($name); $this->name = $name; $this->description = $description; } /** * Creates a new tag that represents any unknown tag type. * * @param string $body * @param string $name * @param DescriptionFactory $descriptionFactory * @param TypeContext $context * * @return static */ public static function create( $body, $name = '', DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::string($body); Assert::stringNotEmpty($name); Assert::notNull($descriptionFactory); $description = $descriptionFactory && $body !== "" ? $descriptionFactory->create($body, $context) : null; return new static($name, $description); } /** * Returns the tag as a serialized string * * @return string */ public function __toString() { return ($this->description ? $this->description->render() : ''); } /** * Validates if the tag name matches the expected format, otherwise throws an exception. * * @param string $name * * @return void */ private function validateTagName($name) { 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.' ); } } } reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php 0000604 00000000727 15224653673 0020350 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; interface StaticMethod { public static function create($body); } reflection-docblock/src/DocBlock/Tags/BaseTag.php 0000604 00000002277 15224653673 0015661 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Description; /** * Parses a tag definition for a DocBlock. */ abstract class BaseTag implements DocBlock\Tag { /** @var string Name of the tag */ protected $name = ''; /** @var Description|null Description of the tag. */ protected $description; /** * Gets the name of this tag. * * @return string The name of this tag. */ public function getName() { return $this->name; } public function getDescription() { return $this->description; } public function render(Formatter $formatter = null) { if ($formatter === null) { $formatter = new Formatter\PassthroughFormatter(); } return $formatter->format($this); } } reflection-docblock/src/DocBlock/Tags/Formatter.php 0000604 00000001243 15224653673 0016306 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Tag; interface Formatter { /** * Formats a tag into a string representation according to a specific format, such as Markdown. * * @param Tag $tag * * @return string */ public function format(Tag $tag); } reflection-docblock/src/DocBlock/Tags/Property.php 0000604 00000006324 15224653673 0016174 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}property tag in a Docblock. */ class Property extends BaseTag implements Factory\StaticMethod { /** @var string */ protected $name = 'property'; /** @var Type */ private $type; /** @var string */ protected $variableName = ''; /** * @param string $variableName * @param Type $type * @param Description $description */ public function __construct($variableName, Type $type = null, Description $description = null) { Assert::string($variableName); $this->variableName = $variableName; $this->type = $type; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::stringNotEmpty($body); Assert::allNotNull([$typeResolver, $descriptionFactory]); $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); $type = null; $variableName = ''; // if the first item that is encountered is not a variable; it is a type if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { $type = $typeResolver->resolve(array_shift($parts), $context); array_shift($parts); } // if the next item starts with a $ or ...$ it must be the variable name if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { $variableName = array_shift($parts); array_shift($parts); if (substr($variableName, 0, 1) === '$') { $variableName = substr($variableName, 1); } } $description = $descriptionFactory->create(implode('', $parts), $context); return new static($variableName, $type, $description); } /** * Returns the variable's name. * * @return string */ public function getVariableName() { return $this->variableName; } /** * Returns the variable's type or null if unknown. * * @return Type|null */ public function getType() { return $this->type; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return ($this->type ? $this->type . ' ' : '') . '$' . $this->variableName . ($this->description ? ' ' . $this->description : ''); } } reflection-docblock/src/DocBlock/Tags/TagWithType.php 0000604 00000002651 15224653673 0016560 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\Type; use function in_array; use function strlen; use function substr; use function trim; abstract class TagWithType extends BaseTag { /** @var ?Type */ protected $type; /** * Returns the type section of the variable. */ public function getType() : ?Type { return $this->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; } } $description = trim(substr($body, strlen($type))); return [$type, $description]; } } reflection-docblock/src/DocBlock/Tags/Var_.php 0000604 00000006416 15224653673 0015241 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}var tag in a Docblock. */ class Var_ extends BaseTag implements Factory\StaticMethod { /** @var string */ protected $name = 'var'; /** @var Type */ private $type; /** @var string */ protected $variableName = ''; /** * @param string $variableName * @param Type $type * @param Description $description */ public function __construct($variableName, Type $type = null, Description $description = null) { Assert::string($variableName); $this->variableName = $variableName; $this->type = $type; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::stringNotEmpty($body); Assert::allNotNull([$typeResolver, $descriptionFactory]); $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); $type = null; $variableName = ''; // if the first item that is encountered is not a variable; it is a type if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { $type = $typeResolver->resolve(array_shift($parts), $context); array_shift($parts); } // if the next item starts with a $ or ...$ it must be the variable name if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { $variableName = array_shift($parts); array_shift($parts); if (substr($variableName, 0, 1) === '$') { $variableName = substr($variableName, 1); } } $description = $descriptionFactory->create(implode('', $parts), $context); return new static($variableName, $type, $description); } /** * Returns the variable's name. * * @return string */ public function getVariableName() { return $this->variableName; } /** * Returns the variable's type or null if unknown. * * @return Type|null */ public function getType() { return $this->type; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return ($this->type ? $this->type . ' ' : '') . (empty($this->variableName) ? null : ('$' . $this->variableName)) . ($this->description ? ' ' . $this->description : ''); } } reflection-docblock/src/DocBlock/Tags/Deprecated.php 0000604 00000005227 15224653673 0016411 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}deprecated tag in a Docblock. */ final class Deprecated extends BaseTag implements Factory\StaticMethod { protected $name = 'deprecated'; /** * PCRE regular expression matching a version vector. * Assumes the "x" modifier. */ const REGEX_VECTOR = '(?: # Normal release vectors. \d\S* | # VCS version vectors. Per PHPCS, they are expected to # follow the form of the VCS name, followed by ":", followed # by the version vector itself. # By convention, popular VCSes like CVS, SVN and GIT use "$" # around the actual version vector. [^\s\:]+\:\s*\$[^\$]+\$ )'; /** @var string The version vector. */ private $version = ''; public function __construct($version = null, Description $description = null) { Assert::nullOrStringNotEmpty($version); $this->version = $version; $this->description = $description; } /** * @return static */ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) { Assert::nullOrString($body); if (empty($body)) { return new static(); } $matches = []; if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { return new static( null, null !== $descriptionFactory ? $descriptionFactory->create($body, $context) : null ); } return new static( $matches[1], $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) ); } /** * Gets the version section of the tag. * * @return string */ public function getVersion() { return $this->version; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return $this->version . ($this->description ? ' ' . $this->description->render() : ''); } } reflection-docblock/src/DocBlock/Tags/Throws.php 0000604 00000003615 15224653673 0015636 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}throws tag in a Docblock. */ final class Throws extends BaseTag implements Factory\StaticMethod { protected $name = 'throws'; /** @var Type */ private $type; public function __construct(Type $type, Description $description = null) { $this->type = $type; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::string($body); Assert::allNotNull([$typeResolver, $descriptionFactory]); $parts = preg_split('/\s+/Su', $body, 2); $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context); $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context); return new static($type, $description); } /** * Returns the type section of the variable. * * @return Type */ public function getType() { return $this->type; } public function __toString() { return $this->type . ' ' . $this->description; } } reflection-docblock/src/DocBlock/Tags/See.php 0000604 00000004704 15224653673 0015064 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef; use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference; use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url; use phpDocumentor\Reflection\FqsenResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for an {@}see tag in a Docblock. */ class See extends BaseTag implements Factory\StaticMethod { protected $name = 'see'; /** @var Reference */ protected $refers = null; /** * Initializes this tag. * * @param Reference $refers * @param Description $description */ public function __construct(Reference $refers, Description $description = null) { $this->refers = $refers; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, FqsenResolver $resolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::string($body); Assert::allNotNull([$resolver, $descriptionFactory]); $parts = preg_split('/\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/i', $parts[0])) { return new static(new Url($parts[0]), $description); } return new static(new FqsenRef($resolver->resolve($parts[0], $context)), $description); } /** * Returns the ref of this tag. * * @return Reference */ public function getReference() { return $this->refers; } /** * Returns a string representation of this tag. * * @return string */ public function __toString() { return $this->refers . ($this->description ? ' ' . $this->description->render() : ''); } } reflection-docblock/src/DocBlock/Tags/Author.php 0000604 00000004735 15224653673 0015616 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use Webmozart\Assert\Assert; /** * Reflection class for an {@}author tag in a Docblock. */ final class Author extends BaseTag implements Factory\StaticMethod { /** @var string register that this is the author tag. */ protected $name = 'author'; /** @var string The name of the author */ private $authorName = ''; /** @var string The email of the author */ private $authorEmail = ''; /** * Initializes this tag with the author name and e-mail. * * @param string $authorName * @param string $authorEmail */ public function __construct($authorName, $authorEmail) { Assert::string($authorName); Assert::string($authorEmail); if ($authorEmail && !filter_var($authorEmail, FILTER_VALIDATE_EMAIL)) { throw new \InvalidArgumentException('The author tag does not have a valid e-mail address'); } $this->authorName = $authorName; $this->authorEmail = $authorEmail; } /** * Gets the author's name. * * @return string The author's name. */ public function getAuthorName() { return $this->authorName; } /** * Returns the author's email. * * @return string The author's email. */ public function getEmail() { return $this->authorEmail; } /** * Returns this tag in string form. * * @return string */ public function __toString() { return $this->authorName . (strlen($this->authorEmail) ? ' <' . $this->authorEmail . '>' : ''); } /** * Attempts to create a new Author object based on †he tag body. * * @param string $body * * @return static */ public static function create($body) { Assert::string($body); $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); } } reflection-docblock/src/DocBlock/Tags/Link.php 0000604 00000003516 15224653673 0015245 0 ustar 00 <?php /** * phpDocumentor * * PHP Version 5.3 * * @author Ben Selby <benmatselby@gmail.com> * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a @link tag in a Docblock. */ final class Link extends BaseTag implements Factory\StaticMethod { protected $name = 'link'; /** @var string */ private $link = ''; /** * Initializes a link to a URL. * * @param string $link * @param Description $description */ public function __construct($link, Description $description = null) { Assert::string($link); $this->link = $link; $this->description = $description; } /** * {@inheritdoc} */ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) { Assert::string($body); Assert::notNull($descriptionFactory); $parts = preg_split('/\s+/Su', $body, 2); $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; return new static($parts[0], $description); } /** * Gets the link * * @return string */ public function getLink() { return $this->link; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return $this->link . ($this->description ? ' ' . $this->description->render() : ''); } } reflection-docblock/src/DocBlock/Tags/Method.php 0000604 00000015666 15224653673 0015601 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use phpDocumentor\Reflection\Types\Void_; use Webmozart\Assert\Assert; /** * Reflection class for an {@}method in a Docblock. */ final class Method extends BaseTag implements Factory\StaticMethod { protected $name = 'method'; /** @var string */ private $methodName = ''; /** @var string[] */ private $arguments = []; /** @var bool */ private $isStatic = false; /** @var Type */ private $returnType; public function __construct( $methodName, array $arguments = [], Type $returnType = null, $static = false, Description $description = null ) { Assert::stringNotEmpty($methodName); Assert::boolean($static); if ($returnType === null) { $returnType = new Void_(); } $this->methodName = $methodName; $this->arguments = $this->filterArguments($arguments); $this->returnType = $returnType; $this->isStatic = $static; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::stringNotEmpty($body); Assert::allNotNull([ $typeResolver, $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. then optionally a word with underscores followed by () and // whitespace : as method name as used by phpDocumentor // 5. then a word with underscores, followed by ( and any character // until a ) and whitespace : as method name with signature // 6. 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+ )? # Legacy method name (not captured) (?: [\w_]+\(\)\s+ )? # Method name ([\w\|_\\\\]+) # Arguments (?: \(([^\)]*)\) )? \s* # Description (.*) $/sux', $body, $matches )) { return null; } list(, $static, $returnType, $methodName, $arguments, $description) = $matches; $static = $static === 'static'; if ($returnType === '') { $returnType = 'void'; } $returnType = $typeResolver->resolve($returnType, $context); $description = $descriptionFactory->create($description, $context); if (is_string($arguments) && strlen($arguments) > 0) { $arguments = explode(',', $arguments); foreach ($arguments as &$argument) { $argument = explode(' ', self::stripRestArg(trim($argument)), 2); if ($argument[0][0] === '$') { $argumentName = substr($argument[0], 1); $argumentType = new Void_(); } else { $argumentType = $typeResolver->resolve($argument[0], $context); $argumentName = ''; if (isset($argument[1])) { $argument[1] = self::stripRestArg($argument[1]); $argumentName = substr($argument[1], 1); } } $argument = [ 'name' => $argumentName, 'type' => $argumentType]; } } else { $arguments = []; } return new static($methodName, $arguments, $returnType, $static, $description); } /** * Retrieves the method name. * * @return string */ public function getMethodName() { return $this->methodName; } /** * @return string[] */ public function getArguments() { return $this->arguments; } /** * 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() { return $this->isStatic; } /** * @return Type */ public function getReturnType() { return $this->returnType; } public function __toString() { $arguments = []; foreach ($this->arguments as $argument) { $arguments[] = $argument['type'] . ' $' . $argument['name']; } return trim(($this->isStatic() ? 'static ' : '') . (string)$this->returnType . ' ' . $this->methodName . '(' . implode(', ', $arguments) . ')' . ($this->description ? ' ' . $this->description->render() : '')); } private function filterArguments($arguments) { foreach ($arguments as &$argument) { if (is_string($argument)) { $argument = [ 'name' => $argument ]; } if (! isset($argument['type'])) { $argument['type'] = new Void_(); } $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) ); } } return $arguments; } private static function stripRestArg($argument) { if (strpos($argument, '...') === 0) { $argument = trim(substr($argument, 3)); } return $argument; } } reflection-docblock/src/DocBlock/Tags/Covers.php 0000604 00000004106 15224653673 0015605 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\FqsenResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a @covers tag in a Docblock. */ final class Covers extends BaseTag implements Factory\StaticMethod { protected $name = 'covers'; /** @var Fqsen */ private $refers = null; /** * Initializes this tag. * * @param Fqsen $refers * @param Description $description */ public function __construct(Fqsen $refers, Description $description = null) { $this->refers = $refers; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, DescriptionFactory $descriptionFactory = null, FqsenResolver $resolver = null, TypeContext $context = null ) { Assert::string($body); Assert::notEmpty($body); $parts = preg_split('/\s+/Su', $body, 2); return new static( $resolver->resolve($parts[0], $context), $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context) ); } /** * Returns the structural element this tag refers to. * * @return Fqsen */ public function getReference() { return $this->refers; } /** * Returns a string representation of this tag. * * @return string */ public function __toString() { return $this->refers . ($this->description ? ' ' . $this->description->render() : ''); } } reflection-docblock/src/DocBlock/Tags/InvalidTag.php 0000604 00000007702 15224653673 0016373 0 ustar 00 <?php declare(strict_types=1); namespace phpDocumentor\Reflection\DocBlock\Tags; use Closure; use Exception; use phpDocumentor\Reflection\DocBlock\Tag; use ReflectionClass; use ReflectionException; use ReflectionFunction; use Throwable; use function array_map; use function get_class; use function get_resource_type; use function is_array; use function is_object; use function is_resource; use function sprintf; /** * This class represents an exception during the tag creation * * Since the internals of the library are relaying on the correct syntax of a docblock * we cannot simply throw exceptions at all time because the exceptions will break the creation of a * docklock. Just silently ignore the exceptions is not an option because the user as an issue to fix. * * This tag holds that error information until a using application is able to display it. The object wil just behave * like any normal tag. So the normal application flow will not break. */ final class InvalidTag implements Tag { /** @var string */ private $name; /** @var string */ private $body; /** @var Throwable|null */ private $throwable; private function __construct(string $name, string $body) { $this->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'); $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); $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; } } reflection-docblock/src/DocBlock/Tags/Return_.php 0000604 00000003600 15224653673 0015760 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}return tag in a Docblock. */ final class Return_ extends BaseTag implements Factory\StaticMethod { protected $name = 'return'; /** @var Type */ private $type; public function __construct(Type $type, Description $description = null) { $this->type = $type; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::string($body); Assert::allNotNull([$typeResolver, $descriptionFactory]); $parts = preg_split('/\s+/Su', $body, 2); $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context); $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context); return new static($type, $description); } /** * Returns the type section of the variable. * * @return Type */ public function getType() { return $this->type; } public function __toString() { return $this->type . ' ' . $this->description; } } reflection-docblock/src/DocBlock/Tags/Example.php 0000604 00000010560 15224653673 0015740 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\Tag; use Webmozart\Assert\Assert; /** * Reflection class for a {@}example tag in a Docblock. */ final class Example extends BaseTag { /** * @var string Path to a file to use as an example. May also be an absolute URI. */ private $filePath; /** * @var bool Whether the file path component represents an URI. This determines how the file portion * appears at {@link getContent()}. */ private $isURI = false; /** * @var int */ private $startingLine; /** * @var int */ private $lineCount; public function __construct($filePath, $isURI, $startingLine, $lineCount, $description) { Assert::notEmpty($filePath); Assert::integer($startingLine); Assert::greaterThanEq($startingLine, 0); $this->filePath = $filePath; $this->startingLine = $startingLine; $this->lineCount = $lineCount; $this->name = 'example'; if ($description !== null) { $this->description = trim($description); } $this->isURI = $isURI; } /** * {@inheritdoc} */ public function getContent() { if (null === $this->description) { $filePath = '"' . $this->filePath . '"'; if ($this->isURI) { $filePath = $this->isUriRelative($this->filePath) ? str_replace('%2F', '/', rawurlencode($this->filePath)) :$this->filePath; } return trim($filePath . ' ' . parent::getDescription()); } return $this->description; } /** * {@inheritdoc} */ public static function create($body) { // File component: File path in quotes or File URI / Source information if (! preg_match('/^(?:\"([^\"]+)\"|(\S+))(?:\s+(.*))?$/sux', $body, $matches)) { return null; } $filePath = null; $fileUri = null; if ('' !== $matches[1]) { $filePath = $matches[1]; } else { $fileUri = $matches[2]; } $startingLine = 1; $lineCount = null; $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]) && $contentMatches[2] !== '') { $lineCount = (int)$contentMatches[2]; } if (array_key_exists(3, $contentMatches)) { $description = $contentMatches[3]; } } } return new static( $filePath !== null?$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() { return $this->filePath; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return $this->filePath . ($this->description ? ' ' . $this->description : ''); } /** * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute). * * @param string $uri * * @return bool */ private function isUriRelative($uri) { return false === strpos($uri, ':'); } /** * @return int */ public function getStartingLine() { return $this->startingLine; } /** * @return int */ public function getLineCount() { return $this->lineCount; } } reflection-docblock/src/DocBlock/Tags/Source.php 0000604 00000005556 15224653673 0015616 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}source tag in a Docblock. */ final class Source extends BaseTag implements Factory\StaticMethod { /** @var string */ protected $name = 'source'; /** @var int The starting line, relative to the structural element's location. */ private $startingLine = 1; /** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */ private $lineCount = null; public function __construct($startingLine, $lineCount = null, Description $description = null) { Assert::integerish($startingLine); Assert::nullOrIntegerish($lineCount); $this->startingLine = (int)$startingLine; $this->lineCount = $lineCount !== null ? (int)$lineCount : null; $this->description = $description; } /** * {@inheritdoc} */ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) { 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() { 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() { return $this->lineCount; } public function __toString() { return $this->startingLine . ($this->lineCount !== null ? ' ' . $this->lineCount : '') . ($this->description ? ' ' . $this->description->render() : ''); } } reflection-docblock/src/DocBlock/Tags/PropertyWrite.php 0000604 00000006345 15224653673 0017212 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; /** * Reflection class for a {@}property-write tag in a Docblock. */ class PropertyWrite extends BaseTag implements Factory\StaticMethod { /** @var string */ protected $name = 'property-write'; /** @var Type */ private $type; /** @var string */ protected $variableName = ''; /** * @param string $variableName * @param Type $type * @param Description $description */ public function __construct($variableName, Type $type = null, Description $description = null) { Assert::string($variableName); $this->variableName = $variableName; $this->type = $type; $this->description = $description; } /** * {@inheritdoc} */ public static function create( $body, TypeResolver $typeResolver = null, DescriptionFactory $descriptionFactory = null, TypeContext $context = null ) { Assert::stringNotEmpty($body); Assert::allNotNull([$typeResolver, $descriptionFactory]); $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); $type = null; $variableName = ''; // if the first item that is encountered is not a variable; it is a type if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { $type = $typeResolver->resolve(array_shift($parts), $context); array_shift($parts); } // if the next item starts with a $ or ...$ it must be the variable name if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { $variableName = array_shift($parts); array_shift($parts); if (substr($variableName, 0, 1) === '$') { $variableName = substr($variableName, 1); } } $description = $descriptionFactory->create(implode('', $parts), $context); return new static($variableName, $type, $description); } /** * Returns the variable's name. * * @return string */ public function getVariableName() { return $this->variableName; } /** * Returns the variable's type or null if unknown. * * @return Type|null */ public function getType() { return $this->type; } /** * Returns a string representation for this tag. * * @return string */ public function __toString() { return ($this->type ? $this->type . ' ' : '') . '$' . $this->variableName . ($this->description ? ' ' . $this->description : ''); } } reflection-docblock/src/Utils.php 0000604 00000004462 15224653673 0013073 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; use phpDocumentor\Reflection\Exception\PcreException; use function preg_last_error; use function preg_split as php_preg_split; abstract class Utils { /** * Wrapper function for phps preg_split * * This function is inspired by {@link https://github.com/thecodingmachine/safe/blob/master/generated/pcre.php}. But * since this library is all about performance we decided to strip everything we don't need. Reducing the amount * of files that have to be loaded, ect. * * @param string $pattern The pattern to search for, as a string. * @param string $subject The input string. * @param int|null $limit If specified, then only substrings up to limit are returned with the * rest of the string being placed in the last substring. A limit of -1 or 0 means "no limit". * @param int $flags flags can be any combination of the following flags (combined with the | bitwise operator): * *PREG_SPLIT_NO_EMPTY* * If this flag is set, only non-empty pieces will be returned by preg_split(). * *PREG_SPLIT_DELIM_CAPTURE* * If this flag is set, parenthesized expression in the delimiter pattern will be captured * and returned as well. * *PREG_SPLIT_OFFSET_CAPTURE* * If this flag is set, for every occurring match the appendant string offset will also be returned. * Note that this changes the return value in an array where every element is an array consisting of the * matched string at offset 0 and its string offset into subject at offset 1. * * @return string[] Returns an array containing substrings of subject split along boundaries matched by pattern * * @throws PcreException */ public static function pregSplit(string $pattern, string $subject, ?int $limit = -1, int $flags = 0) : array { $parts = php_preg_split($pattern, $subject, $limit, $flags); if ($parts === false) { throw PcreException::createFromPhpError(preg_last_error()); } return $parts; } } type-resolver/src/FqsenResolver.php 0000604 00000004252 15224653673 0013476 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; use InvalidArgumentException; use phpDocumentor\Reflection\Types\Context; use function explode; use function implode; use function strpos; class FqsenResolver { /** @var string Definition of the NAMESPACE operator in PHP */ private const OPERATOR_NAMESPACE = '\\'; public function resolve(string $fqsen, ?Context $context = null) : Fqsen { if ($context === null) { $context = new Context(''); } if ($this->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)); } } type-resolver/src/PseudoTypes/LowercaseString.php 0000604 00000001503 15224653673 0016273 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\String_; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class LowercaseString extends String_ implements PseudoType { public function underlyingType(): Type { return new String_(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'lowercase-string'; } } type-resolver/src/PseudoTypes/True_.php 0000604 00000001556 15224653673 0014246 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link https://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\Boolean; use function class_alias; /** * Value Object representing the PseudoType 'False', which is a Boolean type. * * @psalm-immutable */ final class True_ extends Boolean implements PseudoType { public function underlyingType(): Type { return new Boolean(); } public function __toString(): string { return 'true'; } } class_alias('\phpDocumentor\Reflection\PseudoTypes\True_', 'phpDocumentor\Reflection\Types\True_', false); type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php 0000604 00000001525 15224653673 0017771 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\String_; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class NonEmptyLowercaseString extends String_ implements PseudoType { public function underlyingType(): Type { return new String_(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'non-empty-lowercase-string'; } } type-resolver/src/PseudoTypes/CallableString.php 0000604 00000001501 15224653673 0016044 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\String_; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class CallableString extends String_ implements PseudoType { public function underlyingType(): Type { return new String_(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'callable-string'; } } type-resolver/src/PseudoTypes/PositiveInteger.php 0000604 00000001477 15224653673 0016312 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\Integer; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class PositiveInteger extends Integer implements PseudoType { public function underlyingType(): Type { return new Integer(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'positive-int'; } } type-resolver/src/PseudoTypes/NumericString.php 0000604 00000001477 15224653673 0015763 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\String_; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class NumericString extends String_ implements PseudoType { public function underlyingType(): Type { return new String_(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'numeric-string'; } } type-resolver/src/PseudoTypes/False_.php 0000604 00000001562 15224653673 0014356 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link https://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\Boolean; use function class_alias; /** * Value Object representing the PseudoType 'False', which is a Boolean type. * * @psalm-immutable */ final class False_ extends Boolean implements PseudoType { public function underlyingType(): Type { return new Boolean(); } public function __toString(): string { return 'false'; } } class_alias('\phpDocumentor\Reflection\PseudoTypes\False_', 'phpDocumentor\Reflection\Types\False_', false); type-resolver/src/PseudoTypes/HtmlEscapedString.php 0000604 00000001510 15224653673 0016536 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\String_; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class HtmlEscapedString extends String_ implements PseudoType { public function underlyingType(): Type { return new String_(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'html-escaped-string'; } } type-resolver/src/PseudoTypes/TraitString.php 0000604 00000001473 15224653673 0015440 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\String_; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class TraitString extends String_ implements PseudoType { public function underlyingType(): Type { return new String_(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'trait-string'; } } type-resolver/src/PseudoTypes/NonEmptyString.php 0000604 00000001502 15224653673 0016117 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\PseudoTypes; use phpDocumentor\Reflection\PseudoType; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\String_; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class NonEmptyString extends String_ implements PseudoType { public function underlyingType(): Type { return new String_(); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'non-empty-string'; } } type-resolver/src/PseudoType.php 0000604 00000000555 15224653673 0013003 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; interface PseudoType extends Type { public function underlyingType(): Type; } type-resolver/src/TypeResolver.php 0000604 00000040415 15224653673 0013344 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; use ArrayIterator; use InvalidArgumentException; use phpDocumentor\Reflection\Types\Array_; use phpDocumentor\Reflection\Types\Collection; use phpDocumentor\Reflection\Types\Compound; use phpDocumentor\Reflection\Types\Context; use phpDocumentor\Reflection\Types\Integer; use phpDocumentor\Reflection\Types\Iterable_; use phpDocumentor\Reflection\Types\Nullable; use phpDocumentor\Reflection\Types\Object_; use phpDocumentor\Reflection\Types\String_; use RuntimeException; use const PREG_SPLIT_DELIM_CAPTURE; use const PREG_SPLIT_NO_EMPTY; use function array_keys; use function array_pop; use function class_exists; use function class_implements; use function count; use function in_array; use function preg_split; use function strlen; use function strpos; use function strtolower; use function substr; use function trim; final class TypeResolver { /** @var string Definition of the ARRAY operator for types */ private const OPERATOR_ARRAY = '[]'; /** @var string Definition of the NAMESPACE operator in PHP */ private const OPERATOR_NAMESPACE = '\\'; /** @var int the iterator parser is inside a compound context */ private const PARSER_IN_COMPOUND = 0; /** @var int the iterator parser is inside a nullable expression context */ private const PARSER_IN_NULLABLE = 1; /** @var int the iterator parser is inside an array expression context */ private const PARSER_IN_ARRAY_EXPRESSION = 2; /** @var int the iterator parser is inside a collection expression context */ private const PARSER_IN_COLLECTION_EXPRESSION = 3; /** * @var array<string, string> List of recognized keywords and unto which Value Object they map * @psalm-var array<string, class-string<Type>> */ private $keywords = [ 'string' => Types\String_::class, 'int' => Types\Integer::class, 'integer' => Types\Integer::class, 'bool' => Types\Boolean::class, 'boolean' => Types\Boolean::class, 'real' => Types\Float_::class, 'float' => Types\Float_::class, 'double' => Types\Float_::class, 'object' => Object_::class, 'mixed' => Types\Mixed_::class, 'array' => Array_::class, 'resource' => Types\Resource_::class, 'void' => Types\Void_::class, 'null' => Types\Null_::class, 'scalar' => Types\Scalar::class, 'callback' => Types\Callable_::class, 'callable' => Types\Callable_::class, 'false' => Types\Boolean::class, 'true' => Types\Boolean::class, 'self' => Types\Self_::class, '$this' => Types\This::class, 'static' => Types\Static_::class, 'parent' => Types\Parent_::class, 'iterable' => Iterable_::class, ]; /** @var FqsenResolver */ private $fqsenResolver; /** * Initializes this TypeResolver with the means to create and resolve Fqsen objects. */ public function __construct(?FqsenResolver $fqsenResolver = null) { $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver(); } /** * 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::getNamespaceAliases() to check whether the first part of the relative type name should not be * replaced with another namespace. * @uses Context::getNamespace() to determine with what to prefix the type name. * * @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(''); } // split the type string into tokens `|`, `?`, `<`, `>`, `,`, `(`, `)[]`, '<', '>' and type names $tokens = preg_split( '/(\\||\\?|<|>|, ?|\\(|\\)(?:\\[\\])+)/', $type, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); if ($tokens === false) { throw new InvalidArgumentException('Unable to split the type string "' . $type . '" into tokens'); } $tokenIterator = new ArrayIterator($tokens); return $this->parseTypes($tokenIterator, $context, self::PARSER_IN_COMPOUND); } /** * Analyse each tokens and creates types * * @param ArrayIterator $tokens the iterator on tokens * @param int $parserContext on of self::PARSER_* constants, indicating * the context where we are in the parsing */ private function parseTypes(ArrayIterator $tokens, Context $context, int $parserContext) : Type { $types = []; $token = ''; while ($tokens->valid()) { $token = $tokens->current(); if ($token === '|') { if (count($types) === 0) { throw new RuntimeException( 'A type is missing before a type separator' ); } if ($parserContext !== self::PARSER_IN_COMPOUND && $parserContext !== self::PARSER_IN_ARRAY_EXPRESSION && $parserContext !== self::PARSER_IN_COLLECTION_EXPRESSION ) { throw new RuntimeException( 'Unexpected type separator' ); } $tokens->next(); } elseif ($token === '?') { if ($parserContext !== self::PARSER_IN_COMPOUND && $parserContext !== self::PARSER_IN_ARRAY_EXPRESSION && $parserContext !== self::PARSER_IN_COLLECTION_EXPRESSION ) { throw new RuntimeException( 'Unexpected nullable character' ); } $tokens->next(); $type = $this->parseTypes($tokens, $context, self::PARSER_IN_NULLABLE); $types[] = new Nullable($type); } elseif ($token === '(') { $tokens->next(); $type = $this->parseTypes($tokens, $context, self::PARSER_IN_ARRAY_EXPRESSION); $resolvedType = new Array_($type); $token = $tokens->current(); // Someone did not properly close their array expression .. if ($token === null) { break; } // we generate arrays corresponding to the number of '[]' after the ')' $numberOfArrays = (strlen($token) - 1) / 2; for ($i = 0; $i < $numberOfArrays - 1; ++$i) { $resolvedType = new Array_($resolvedType); } $types[] = $resolvedType; $tokens->next(); } elseif ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION && $token[0] === ')') { break; } elseif ($token === '<') { if (count($types) === 0) { throw new RuntimeException( 'Unexpected collection operator "<", class name is missing' ); } $classType = array_pop($types); if ($classType !== null) { $types[] = $this->resolveCollection($tokens, $classType, $context); } $tokens->next(); } elseif ($parserContext === self::PARSER_IN_COLLECTION_EXPRESSION && ($token === '>' || trim($token) === ',') ) { break; } else { $type = $this->resolveSingleType($token, $context); $tokens->next(); if ($parserContext === self::PARSER_IN_NULLABLE) { return $type; } $types[] = $type; } } if ($token === '|') { throw new RuntimeException( 'A type is missing after a type separator' ); } if (count($types) === 0) { if ($parserContext === self::PARSER_IN_NULLABLE) { throw new RuntimeException( 'A type is missing after a nullable character' ); } if ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION) { throw new RuntimeException( 'A type is missing in an array expression' ); } if ($parserContext === self::PARSER_IN_COLLECTION_EXPRESSION) { throw new RuntimeException( 'A type is missing in a collection expression' ); } } elseif (count($types) === 1) { return $types[0]; } return new Compound($types); } /** * resolve the given type into a type object * * @param string $type the type string, representing a single type * * @return Type|Array_|Object_ */ private function resolveSingleType(string $type, Context $context) { switch (true) { case $this->isKeyword($type): return $this->resolveKeyword($type); case $this->isTypedArray($type): return $this->resolveTypedArray($type, $context); 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. */ 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 ); } if (!in_array(Type::class, class_implements($typeClassName), true)) { throw new InvalidArgumentException( 'The class "' . $typeClassName . '" must implement the interface "phpDocumentor\Reflection\Type"' ); } $this->keywords[$keyword] = $typeClassName; } /** * Detects whether the given type represents an array. * * @param string $type A relative or absolute type as defined in the phpDocumentor documentation. */ private function isTypedArray(string $type) : bool { return substr($type, -2) === self::OPERATOR_ARRAY; } /** * Detects whether the given type represents a PHPDoc keyword. * * @param string $type A relative or absolute type as defined in the phpDocumentor documentation. */ private function isKeyword(string $type) : bool { return in_array(strtolower($type), array_keys($this->keywords), true); } /** * 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. */ private function isPartialStructuralElementName(string $type) : bool { return ($type[0] !== self::OPERATOR_NAMESPACE) && !$this->isKeyword($type); } /** * 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 the given typed array string (i.e. `string[]`) into an Array object with the right types set. */ private function resolveTypedArray(string $type, Context $context) : Array_ { return new Array_($this->resolveSingleType(substr($type, 0, -2), $context)); } /** * Resolves the given keyword (such as `string`) into a Type object representing that keyword. */ private function resolveKeyword(string $type) : Type { $className = $this->keywords[strtolower($type)]; return new $className(); } /** * Resolves the given FQSEN string into an FQSEN object. */ private function resolveTypedObject(string $type, ?Context $context = null) : Object_ { return new Object_($this->fqsenResolver->resolve($type, $context)); } /** * Resolves the collection values and keys * * @return Array_|Collection */ private function resolveCollection(ArrayIterator $tokens, Type $classType, Context $context) : Type { $isArray = ((string) $classType === 'array'); // allow only "array" or class name before "<" if (!$isArray && (!$classType instanceof Object_ || $classType->getFqsen() === null)) { throw new RuntimeException( $classType . ' is not a collection' ); } $tokens->next(); $valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION); $keyType = null; if ($tokens->current() !== null && trim($tokens->current()) === ',') { // if we have a comma, then we just parsed the key type, not the value type $keyType = $valueType; if ($isArray) { // check the key type for an "array" collection. We allow only // strings or integers. if (!$keyType instanceof String_ && !$keyType instanceof Integer && !$keyType instanceof Compound ) { throw new RuntimeException( 'An array can have only integers or strings as keys' ); } if ($keyType instanceof Compound) { foreach ($keyType->getIterator() as $item) { if (!$item instanceof String_ && !$item instanceof Integer ) { throw new RuntimeException( 'An array can have only integers or strings as keys' ); } } } } $tokens->next(); // now let's parse the value type $valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION); } if ($tokens->current() !== '>') { if (empty($tokens->current())) { throw new RuntimeException( 'Collection: ">" is missing' ); } throw new RuntimeException( 'Unexpected character "' . $tokens->current() . '", ">" is missing' ); } if ($isArray) { return new Array_($valueType, $keyType); } /** @psalm-suppress RedundantCondition */ if ($classType instanceof Object_) { return $this->makeCollectionFromObject($classType, $valueType, $keyType); } throw new RuntimeException('Invalid $classType provided'); } private function makeCollectionFromObject(Object_ $object, Type $valueType, ?Type $keyType = null) : Collection { return new Collection($object->getFqsen(), $valueType, $keyType); } } type-resolver/src/Type.php 0000604 00000000671 15224653673 0011622 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; interface Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string; } type-resolver/src/Types/Intersection.php 0000604 00000002007 15224653673 0014446 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ declare(strict_types=1); namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing a Compound Type. * * A Intersection Type is not so much a special keyword or object reference but is a series of Types that are separated * using an AND operator (`&`). This combination of types signifies that whatever is associated with this Intersection * type may contain a value with any of the given types. * * @psalm-immutable */ final class Intersection extends AggregatedType { /** * Initializes a intersection type (i.e. `\A&\B`) and tests if the provided types all implement the Type interface. * * @param array<Type> $types */ public function __construct(array $types) { parent::__construct($types, '&'); } } type-resolver/src/Types/Float_.php 0000604 00000001110 15224653673 0013176 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing a Float. */ final class Float_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'float'; } } type-resolver/src/Types/Object_.php 0000604 00000003354 15224653673 0013353 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use InvalidArgumentException; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\Type; use function strpos; /** * Value Object representing an object. * * An object can be either typed or untyped. When an object is typed it means that it has an identifier, the FQSEN, * pointing to an element in PHP. Object types that are untyped do not refer to a specific class but represent objects * in general. */ final class Object_ implements Type { /** @var Fqsen|null */ private $fqsen; /** * Initializes this object with an optional FQSEN, if not provided this object is considered 'untyped'. * * @throws InvalidArgumentException When provided $fqsen is not a valid type. */ public function __construct(?Fqsen $fqsen = null) { if (strpos((string) $fqsen, '::') !== false || strpos((string) $fqsen, '()') !== false) { throw new InvalidArgumentException( 'Object types can only refer to a class, interface or trait but a method, function, constant or ' . 'property was received: ' . (string) $fqsen ); } $this->fqsen = $fqsen; } /** * Returns the FQSEN associated with this object. */ public function getFqsen() : ?Fqsen { return $this->fqsen; } public function __toString() : string { if ($this->fqsen) { return (string) $this->fqsen; } return 'object'; } } type-resolver/src/Types/Void_.php 0000604 00000001342 15224653673 0013041 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the pseudo-type 'void'. * * Void is generally only used when working with return types as it signifies that the method intentionally does not * return any value. */ final class Void_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'void'; } } type-resolver/src/Types/Callable_.php 0000604 00000001126 15224653673 0013637 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing a Callable type. */ final class Callable_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'callable'; } } type-resolver/src/Types/Array_.php 0000604 00000001275 15224653673 0013223 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; /** * Represents an array type as described in the PSR-5, the PHPDoc Standard. * * An array can be represented in two forms: * * 1. Untyped (`array`), where the key and value type is unknown and hence classified as 'Mixed_'. * 2. Types (`string[]`), where the value type is provided by preceding an opening and closing square bracket with a * type name. */ final class Array_ extends AbstractList { } type-resolver/src/Types/Static_.php 0000604 00000001740 15224653673 0013371 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the 'static' type. * * Self, as a Type, represents the class in which the associated element was called. This differs from self as self does * not take inheritance into account but static means that the return type is always that of the class of the called * element. * * See the documentation on late static binding in the PHP Documentation for more information on the difference between * static and self. */ final class Static_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'static'; } } type-resolver/src/Types/This.php 0000604 00000001464 15224653673 0012715 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the '$this' pseudo-type. * * $this, as a Type, represents the instance of the class associated with the element as it was called. $this is * commonly used when documenting fluent interfaces since it represents that the same object is returned. */ final class This implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return '$this'; } } type-resolver/src/Types/Compound.php 0000604 00000004272 15224653673 0013572 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use ArrayIterator; use InvalidArgumentException; use IteratorAggregate; use phpDocumentor\Reflection\Type; use function implode; /** * Value Object representing a Compound Type. * * A Compound Type is not so much a special keyword or object reference but is a series of Types that are separated * using an OR operator (`|`). This combination of types signifies that whatever is associated with this compound type * may contain a value with any of the given types. */ final class Compound implements Type, IteratorAggregate { /** @var Type[] */ private $types; /** * Initializes a compound type (i.e. `string|int`) and tests if the provided types all implement the Type interface. * * @param Type[] $types * * @throws InvalidArgumentException When types are not all instance of Type. */ public function __construct(array $types) { foreach ($types as $type) { /** @psalm-suppress RedundantConditionGivenDocblockType */ if (!$type instanceof Type) { throw new InvalidArgumentException('A compound type can only have other types as elements'); } } $this->types = $types; } /** * 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 isset($this->types[$index]); } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return implode('|', $this->types); } /** * {@inheritdoc} */ public function getIterator() { return new ArrayIterator($this->types); } } type-resolver/src/Types/Context.php 0000604 00000005464 15224653673 0013436 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use function strlen; use function substr; use function trim; /** * Provides information about the Context in which the DocBlock occurs that receives this context. * * A DocBlock does not know of its own accord in which namespace it occurs and which namespace aliases are applicable * for the block of code in which it is in. This information is however necessary to resolve Class names in tags since * you can provide a short form or make use of namespace aliases. * * The phpDocumentor Reflection component knows how to create this class but if you use the DocBlock parser from your * own application it is possible to generate a Context class using the ContextFactory; this will analyze the file in * which an associated class resides for its namespace and imports. * * @see ContextFactory::createFromClassReflector() * @see ContextFactory::createForNamespace() */ final class Context { /** @var string The current namespace. */ private $namespace; /** @var string[] List of namespace aliases => Fully Qualified Namespace. */ 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. */ 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[] */ public function getNamespaceAliases() : array { return $this->namespaceAliases; } } type-resolver/src/Types/Boolean.php 0000604 00000001117 15224653673 0013360 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing a Boolean type. */ final class Boolean implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'bool'; } } type-resolver/src/Types/Parent_.php 0000604 00000001277 15224653673 0013400 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the 'parent' type. * * Parent, as a Type, represents the parent class of class in which the associated element was defined. */ final class Parent_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'parent'; } } type-resolver/src/Types/Iterable_.php 0000604 00000001123 15224653673 0013664 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing iterable type */ final class Iterable_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'iterable'; } } type-resolver/src/Types/Resource_.php 0000604 00000001132 15224653673 0013724 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the 'resource' Type. */ final class Resource_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'resource'; } } type-resolver/src/Types/Nullable.php 0000604 00000002060 15224653673 0013535 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing a nullable type. The real type is wrapped. */ final class Nullable implements Type { /** @var Type The actual type that is wrapped */ private $realType; /** * Initialises this nullable type using the real type embedded */ public function __construct(Type $realType) { $this->realType = $realType; } /** * Provide access to the actual type directly, if needed. */ public function getActualType() : Type { return $this->realType; } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return '?' . $this->realType->__toString(); } } type-resolver/src/Types/Mixed_.php 0000604 00000001133 15224653673 0013204 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing an unknown, or mixed, type. */ final class Mixed_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'mixed'; } } type-resolver/src/Types/Collection.php 0000604 00000003171 15224653673 0014076 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\Type; /** * Represents a collection type as described in the PSR-5, the PHPDoc Standard. * * A collection can be represented in two forms: * * 1. `ACollectionObject<aValueType>` * 2. `ACollectionObject<aValueType,aKeyType>` * * - ACollectionObject can be 'array' or an object that can act as an array * - aValueType and aKeyType can be any type expression */ 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 . '>'; } } type-resolver/src/Types/InterfaceString.php 0000604 00000002236 15224653673 0015073 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\Type; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class InterfaceString implements Type { /** @var Fqsen|null */ private $fqsen; /** * Initializes this representation of a class string with the given Fqsen. */ public function __construct(?Fqsen $fqsen = null) { $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 { if ($this->fqsen === null) { return 'interface-string'; } return 'interface-string<' . (string) $this->fqsen . '>'; } } type-resolver/src/Types/AggregatedType.php 0000604 00000005313 15224653673 0014677 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ declare(strict_types=1); namespace phpDocumentor\Reflection\Types; use ArrayIterator; use IteratorAggregate; use phpDocumentor\Reflection\Type; use function array_key_exists; use function implode; /** * Base class for aggregated types like Compound and Intersection * * A Aggregated Type is not so much a special keyword or object reference but is a series of Types that are separated * using separator. * * @psalm-immutable * @template-implements IteratorAggregate<int, Type> */ abstract class AggregatedType implements Type, IteratorAggregate { /** * @psalm-allow-private-mutation * @var array<int, Type> */ private $types = []; /** @var string */ private $token; /** * @param array<Type> $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<int, Type> */ public function getIterator(): ArrayIterator { return new ArrayIterator($this->types); } /** * @psalm-suppress ImpureMethodCall */ private function add(Type $type): void { if ($type instanceof self) { 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; } } type-resolver/src/Types/Integer.php 0000604 00000001031 15224653673 0013371 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; final class Integer implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'int'; } } type-resolver/src/Types/Null_.php 0000604 00000001123 15224653673 0013047 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing a null value or type. */ final class Null_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'null'; } } type-resolver/src/Types/ContextFactory.php 0000604 00000030152 15224653673 0014756 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use ArrayIterator; use InvalidArgumentException; use ReflectionClass; use ReflectionClassConstant; use ReflectionMethod; use ReflectionParameter; use ReflectionProperty; use Reflector; use RuntimeException; use UnexpectedValueException; use const T_AS; use const T_CLASS; use const T_CURLY_OPEN; use const T_DOLLAR_OPEN_CURLY_BRACES; use const T_NAMESPACE; use const T_NS_SEPARATOR; use const T_STRING; use const T_USE; use function array_merge; use function file_exists; use function file_get_contents; use function get_class; use function is_string; use function token_get_all; use function trim; /** * Convenience class to create a Context for DocBlocks when not using the Reflection Component of phpDocumentor. * * For a DocBlock to be able to resolve types that use partial namespace names or rely on namespace imports we need to * provide a bit of context so that the DocBlock can read that and based on it decide how to resolve the types to * Fully Qualified names. * * @see Context for more information. */ final class ContextFactory { /** The literal used at the end of a use statement. */ private const T_LITERAL_END_OF_USE = ';'; /** The literal used between sets of use statements */ private const T_LITERAL_USE_SEPARATOR = ','; /** * Build a Context given a Class Reflection. * * @see Context for more information on Contexts. */ public function createFromReflector(Reflector $reflector) : Context { if ($reflector instanceof ReflectionClass) { 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) { return $this->createFromReflectionClass($class); } throw new InvalidArgumentException('Unable to get class of ' . $parameter->getName()); } private function createFromReflectionMethod(ReflectionMethod $method) : Context { return $this->createFromReflectionClass($method->getDeclaringClass()); } private function createFromReflectionProperty(ReflectionProperty $property) : Context { return $this->createFromReflectionClass($property->getDeclaringClass()); } private function createFromReflectionClassConstant(ReflectionClassConstant $constant) : Context { return $this->createFromReflectionClass($constant->getDeclaringClass()); } private function createFromReflectionClass(ReflectionClass $class) : Context { $fileName = $class->getFileName(); $namespace = $class->getNamespaceName(); if (is_string($fileName) && file_exists($fileName)) { $contents = file_get_contents($fileName); if ($contents === false) { throw new RuntimeException('Unable to read file "' . $fileName . '"'); } return $this->createForNamespace($namespace, $contents); } return new Context($namespace, []); } /** * Build a Context for a namespace in the provided file contents. * * @see Context for more information on Contexts. * * @param string $namespace It does not matter if a `\` precedes the namespace name, * this method first normalizes. * @param string $fileContents The file's contents to retrieve the aliases from with the given namespace. */ public function createForNamespace(string $namespace, string $fileContents) : Context { $namespace = trim($namespace, '\\'); $useStatements = []; $currentNamespace = ''; $tokens = new ArrayIterator(token_get_all($fileContents)); while ($tokens->valid()) { switch ($tokens->current()[0]) { case T_NAMESPACE: $currentNamespace = $this->parseNamespace($tokens); break; case T_CLASS: // Fast-forward the iterator through the class so that any // T_USE tokens found within are skipped - these are not // valid namespace use statements so should be ignored. $braceLevel = 0; $firstBraceFound = false; while ($tokens->valid() && ($braceLevel > 0 || !$firstBraceFound)) { if ($tokens->current() === '{' || $tokens->current()[0] === T_CURLY_OPEN || $tokens->current()[0] === T_DOLLAR_OPEN_CURLY_BRACES) { if (!$firstBraceFound) { $firstBraceFound = true; } ++$braceLevel; } if ($tokens->current() === '}') { --$braceLevel; } $tokens->next(); } break; case T_USE: if ($currentNamespace === $namespace) { $useStatements = array_merge($useStatements, $this->parseUseStatement($tokens)); } break; } $tokens->next(); } return new Context($namespace, $useStatements); } /** * Deduce the name from tokens when we are at the T_NAMESPACE token. */ private function parseNamespace(ArrayIterator $tokens) : string { // skip to the first string or namespace separator $this->skipToNextStringOrNamespaceSeparator($tokens); $name = ''; while ($tokens->valid() && ($tokens->current()[0] === T_STRING || $tokens->current()[0] === T_NS_SEPARATOR) ) { $name .= $tokens->current()[1]; $tokens->next(); } return $name; } /** * Deduce the names of all imports when we are at the T_USE token. * * @return string[] */ private function parseUseStatement(ArrayIterator $tokens) : array { $uses = []; while (true) { $this->skipToNextStringOrNamespaceSeparator($tokens); $uses = array_merge($uses, $this->extractUseStatements($tokens)); if ($tokens->current()[0] === self::T_LITERAL_END_OF_USE) { return $uses; } } return $uses; } /** * Fast-forwards the iterator as longs as we don't encounter a T_STRING or T_NS_SEPARATOR token. */ private function skipToNextStringOrNamespaceSeparator(ArrayIterator $tokens) : void { while ($tokens->valid() && ($tokens->current()[0] !== T_STRING) && ($tokens->current()[0] !== T_NS_SEPARATOR)) { $tokens->next(); } } /** * Deduce the namespace name and alias of an import when we are at the T_USE token or have not reached the end of * a USE statement yet. This will return a key/value array of the alias => namespace. * * @return string[] * * @psalm-suppress TypeDoesNotContainType */ private function extractUseStatements(ArrayIterator $tokens) : array { $extractedUseStatements = []; $groupedNs = ''; $currentNs = ''; $currentAlias = ''; $state = 'start'; while ($tokens->valid()) { $currentToken = $tokens->current(); $tokenId = is_string($currentToken) ? $currentToken : $currentToken[0]; $tokenValue = is_string($currentToken) ? null : $currentToken[1]; switch ($state) { case 'start': switch ($tokenId) { case T_STRING: case T_NS_SEPARATOR: $currentNs .= $tokenValue; $currentAlias = $tokenValue; break; case T_CURLY_OPEN: case '{': $state = 'grouped'; $groupedNs = $currentNs; break; case T_AS: $state = 'start-alias'; break; case self::T_LITERAL_USE_SEPARATOR: case self::T_LITERAL_END_OF_USE: $state = 'end'; break; default: break; } break; case 'start-alias': switch ($tokenId) { case T_STRING: $currentAlias = $tokenValue; break; case self::T_LITERAL_USE_SEPARATOR: case self::T_LITERAL_END_OF_USE: $state = 'end'; break; default: break; } break; case 'grouped': switch ($tokenId) { case T_STRING: case T_NS_SEPARATOR: $currentNs .= $tokenValue; $currentAlias = $tokenValue; break; case T_AS: $state = 'grouped-alias'; break; case self::T_LITERAL_USE_SEPARATOR: $state = 'grouped'; $extractedUseStatements[$currentAlias] = $currentNs; $currentNs = $groupedNs; $currentAlias = ''; break; case self::T_LITERAL_END_OF_USE: $state = 'end'; break; default: break; } break; case 'grouped-alias': switch ($tokenId) { case T_STRING: $currentAlias = $tokenValue; break; case self::T_LITERAL_USE_SEPARATOR: $state = 'grouped'; $extractedUseStatements[$currentAlias] = $currentNs; $currentNs = $groupedNs; $currentAlias = ''; break; case self::T_LITERAL_END_OF_USE: $state = 'end'; break; default: break; } } if ($state === 'end') { break; } $tokens->next(); } if ($groupedNs !== $currentNs) { $extractedUseStatements[$currentAlias] = $currentNs; } return $extractedUseStatements; } } type-resolver/src/Types/Scalar.php 0000604 00000001217 15224653673 0013207 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the 'scalar' pseudo-type, which is either a string, integer, float or boolean. */ final class Scalar implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'scalar'; } } type-resolver/src/Types/Self_.php 0000604 00000001247 15224653673 0013035 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the 'self' type. * * Self, as a Type, represents the class in which the associated element was defined. */ final class Self_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'self'; } } type-resolver/src/Types/Expression.php 0000604 00000002053 15224653673 0014140 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Represents an expression type as described in the PSR-5, the PHPDoc Standard. * * @psalm-immutable */ final class Expression implements Type { /** @var Type */ protected $valueType; /** * Initializes this representation of an array with the given Type. */ public function __construct(Type $valueType) { $this->valueType = $valueType; } /** * Returns the value for the keys 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 { return '(' . $this->valueType . ')'; } } type-resolver/src/Types/AbstractList.php 0000604 00000003650 15224653673 0014404 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Represents a list of values. This is an abstract class for Array_ and Collection. */ abstract class AbstractList implements Type { /** @var Type */ protected $valueType; /** @var Type|null */ protected $keyType; /** @var Type */ protected $defaultKeyType; /** * Initializes this representation of an array with the given Type. */ public function __construct(?Type $valueType = null, ?Type $keyType = null) { if ($valueType === null) { $valueType = new Mixed_(); } $this->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 { if ($this->keyType === null) { return $this->defaultKeyType; } return $this->keyType; } /** * Returns the value for the keys 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 . '[]'; } } type-resolver/src/Types/ArrayKey.php 0000604 00000001256 15224653673 0013534 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; /** * Value Object representing a array-key Type. * * A array-key Type is the supertype (but not a union) of int and string. * * @psalm-immutable */ final class ArrayKey extends AggregatedType { public function __construct() { parent::__construct([new String_(), new Integer()], '|'); } public function __toString(): string { return 'array-key'; } } type-resolver/src/Types/String_.php 0000604 00000001124 15224653673 0013404 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the type 'string'. */ final class String_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { return 'string'; } } type-resolver/src/Types/ClassString.php 0000604 00000002222 15224653673 0014233 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\Type; /** * Value Object representing the type 'string'. * * @psalm-immutable */ final class ClassString implements Type { /** @var Fqsen|null */ private $fqsen; /** * Initializes this representation of a class string with the given Fqsen. */ public function __construct(?Fqsen $fqsen = null) { $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 { if ($this->fqsen === null) { return 'class-string'; } return 'class-string<' . (string) $this->fqsen . '>'; } } type-resolver/src/Types/Never_.php 0000604 00000001361 15224653673 0013220 0 ustar 00 <?php declare(strict_types=1); /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\Types; use phpDocumentor\Reflection\Type; /** * Value Object representing the return-type 'never'. * * Never is generally only used when working with return types as it signifies that the method that only * ever throw or exit. * * @psalm-immutable */ final class Never_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString(): string { return 'never'; } } type-resolver/LICENSE 0000604 00000002070 15224653673 0010401 0 ustar 00 The MIT License (MIT) Copyright (c) 2010 Mike van Riel 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. type-resolver/README.md 0000604 00000022334 15224653673 0010660 0 ustar 00 [](https://opensource.org/licenses/MIT) [](https://travis-ci.org/phpDocumentor/TypeResolver) [](https://ci.appveyor.com/project/phpDocumentor/TypeResolver/branch/master) [](https://coveralls.io/github/phpDocumentor/TypeResolver?branch=master) [](https://scrutinizer-ci.com/g/phpDocumentor/TypeResolver/?branch=master) [](https://scrutinizer-ci.com/g/phpDocumentor/TypeResolver/?branch=master) [](https://packagist.org/packages/phpDocumentor/TypeResolver) [](https://packagist.org/packages/phpDocumentor/TypeResolver) TypeResolver and FqsenResolver ============================== The specification on types in DocBlocks (PSR-5) describes various keywords and special constructs but also how to statically resolve the partial name of a Class into a Fully Qualified Class Name (FQCN). PSR-5 also introduces an additional way to describe deeper elements than Classes, Interfaces and Traits called the Fully Qualified Structural Element Name (FQSEN). Using this it is possible to refer to methods, properties and class constants but also functions and global constants. This package provides two Resolvers that are capable of 1. Returning a series of Value Object for given expression while resolving any partial class names, and 2. Returning an FQSEN object after resolving any partial Structural Element Names into Fully Qualified Structural Element names. ## Installing The easiest way to install this library is with [Composer](https://getcomposer.org) using the following command: $ composer require phpdocumentor/type-resolver ## Examples Ready to dive in and don't want to read through all that text below? Just consult the [examples](examples) folder and check which type of action that your want to accomplish. ## On Types and Element Names This component can be used in one of two ways 1. To resolve a Type or 2. To resolve a Fully Qualified Structural Element Name The big difference between these two is in the number of things it can resolve. The TypeResolver can resolve: - a php primitive or pseudo-primitive such as a string or void (`@var string` or `@return void`). - a composite such as an array of string (`@var string[]`). - a compound such as a string or integer (`@var string|integer`). - an array expression (`@var (string|TypeResolver)[]`) - an object or interface such as the TypeResolver class (`@var TypeResolver` or `@var \phpDocumentor\Reflection\TypeResolver`) > please note that if you want to pass partial class names that additional steps are necessary, see the > chapter `Resolving partial classes and FQSENs` for more information. Where the FqsenResolver can resolve: - Constant expressions (i.e. `@see \MyNamespace\MY_CONSTANT`) - Function expressions (i.e. `@see \MyNamespace\myFunction()`) - Class expressions (i.e. `@see \MyNamespace\MyClass`) - Interface expressions (i.e. `@see \MyNamespace\MyInterface`) - Trait expressions (i.e. `@see \MyNamespace\MyTrait`) - Class constant expressions (i.e. `@see \MyNamespace\MyClass::MY_CONSTANT`) - Property expressions (i.e. `@see \MyNamespace\MyClass::$myProperty`) - Method expressions (i.e. `@see \MyNamespace\MyClass::myMethod()`) ## Resolving a type In order to resolve a type you will have to instantiate the class `\phpDocumentor\Reflection\TypeResolver` and call its `resolve` method like this: ```php $typeResolver = new \phpDocumentor\Reflection\TypeResolver(); $type = $typeResolver->resolve('string|integer'); ``` In this example you will receive a Value Object of class `\phpDocumentor\Reflection\Types\Compound` that has two elements, one of type `\phpDocumentor\Reflection\Types\String_` and one of type `\phpDocumentor\Reflection\Types\Integer`. 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 `\phpDocumentor\Reflection\Types\Context` class that will inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply. ### Resolving nullable types Php 7.1 introduced nullable types e.g. `?string`. Type resolver will resolve the original type without the nullable notation `?` just like it would do without the `?`. After that the type is wrapped in a `\phpDocumentor\Reflection\Types\Nullable` object. The `Nullable` type has a method to fetch the actual type. ## Resolving an FQSEN A Fully Qualified Structural Element Name is a reference to another element in your code bases and can be resolved using the `\phpDocumentor\Reflection\FqsenResolver` class' `resolve` method, like this: ```php $fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver(); $fqsen = $fqsenResolver->resolve('\phpDocumentor\Reflection\FqsenResolver::resolve()'); ``` In this example we resolve a Fully Qualified Structural Element Name (meaning that it includes the full namespace, class name and element name) and receive a Value Object of type `\phpDocumentor\Reflection\Fqsen`. The real power of this resolver is in its capability to expand partial element names into Fully Qualified Structural Element Names; but in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply. ## Resolving partial Classes and Structural Element Names Perhaps the best feature of this library is that it knows how to resolve partial class names into fully qualified class names. For example, you have this file: ```php namespace My\Example; use phpDocumentor\Reflection\Types; class Classy { /** * @var Types\Context * @see Classy::otherFunction() */ public function __construct($context) {} public function otherFunction(){} } ``` Suppose that you would want to resolve (and expand) the type in the `@var` tag and the element name in the `@see` tag. For the resolvers to know how to expand partial names you have to provide a bit of _Context_ for them by instantiating a new class named `\phpDocumentor\Reflection\Types\Context` with the name of the namespace and the aliases that are in play. ### Creating a Context You can do this by manually creating a Context like this: ```php $context = new \phpDocumentor\Reflection\Types\Context( '\My\Example', [ 'Types' => '\phpDocumentor\Reflection\Types'] ); ``` Or by using the `\phpDocumentor\Reflection\Types\ContextFactory` to instantiate a new context based on a Reflector object or by providing the namespace that you'd like to extract and the source code of the file in which the given type expression occurs. ```php $contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory(); $context = $contextFactory->createFromReflector(new ReflectionMethod('\My\Example\Classy', '__construct')); ``` or ```php $contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory(); $context = $contextFactory->createForNamespace('\My\Example', file_get_contents('My/Example/Classy.php')); ``` ### Using the Context After you have obtained a Context it is just a matter of passing it along with the `resolve` method of either Resolver class as second argument and the Resolvers will take this into account when resolving partial names. To obtain the resolved class name for the `@var` tag in the example above you can do: ```php $typeResolver = new \phpDocumentor\Reflection\TypeResolver(); $type = $typeResolver->resolve('Types\Context', $context); ``` When you do this you will receive an object of class `\phpDocumentor\Reflection\Types\Object_` for which you can call the `getFqsen` method to receive a Value Object that represents the complete FQSEN. So that would be `phpDocumentor\Reflection\Types\Context`. > Why is the FQSEN wrapped in another object `Object_`? > > The resolve method of the TypeResolver only returns object with the interface `Type` and the FQSEN is a common type that does not represent a Type. Also: in some cases a type can represent an "Untyped Object", meaning that it is an object (signified by the `object` keyword) but does not refer to a specific element using an FQSEN. Another example is on how to resolve the FQSEN of a method as can be seen with the `@see` tag in the example above. To resolve that you can do the following: ```php $fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver(); $type = $fqsenResolver->resolve('Classy::otherFunction()', $context); ``` Because Classy is a Class in the current namespace its FQSEN will have the `My\Example` namespace and by calling the `resolve` method of the FQSEN Resolver you will receive an `Fqsen` object that refers to `\My\Example\Classy::otherFunction()`. type-resolver/composer.json 0000604 00000001512 15224653673 0012116 0 ustar 00 { "name": "phpdocumentor/type-resolver", "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "type": "library", "license": "MIT", "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "require": { "php": "^7.1", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { "mockery/mockery": "~1", "ext-tokenizer": "^7.1", "phpunit/phpunit": "^7.0" }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src" } }, "autoload-dev": { "psr-4": { "phpDocumentor\\Reflection\\": "tests/unit" } }, "extra": { "branch-alias": { "dev-master": "1.x-dev" } } } reflection-common/phpunit.xml.dist 0000777 00000001504 15224675025 0013356 0 ustar 00 <?xml version="1.0" encoding="utf-8"?> <phpunit bootstrap="tests/common/bootstrap.php" colors="true"> <testsuites> <testsuite name="phpDocumentor"> <directory>./tests/unit/</directory> </testsuite> </testsuites> <filter> <whitelist> <directory suffix=".php">src</directory> </whitelist> </filter> <logging> <log type="coverage-html" title="phpDocumentor Reflection Common" target="build/coverage" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70" /> <log type="coverage-clover" target="build/logs/clover.xml"/> <log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false" /> </logging> </phpunit> reflection-common/.gitignore 0000777 00000000036 15224675025 0012172 0 ustar 00 composer.phar vendor/ build/ reflection-common/.travis.yml 0000604 00000003155 15224675025 0012305 0 ustar 00 language: php php: [ 7.1, 7.2, nightly ] sudo: false env: matrix: fast_finish: true allow_failures: - php: nightly install: - travis_retry composer install --no-interaction --prefer-dist --optimize-autoloader script: - ./vendor/bin/phpunit --no-coverage jobs: include: - stage: analysis php: 7.1 script: - ./vendor/bin/phpunit after_script: - travis_retry wget --no-verbose https://phar.io/releases/phive.phar - travis_retry php phive.phar --no-progress install --trust-gpg-keys E82B2FB314E9906E php-coveralls/php-coveralls && ./tools/php-coveralls --verbose - travis_retry wget --no-verbose https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml - stage: analysis php: 7.1 before_script: - travis_retry wget --no-verbose https://phar.io/releases/phive.phar - travis_retry php phive.phar --no-progress install --trust-gpg-keys 8E730BA25823D8B5 phpstan script: - ./tools/phpstan analyse src --level max --configuration phpstan.neon - stage: analysis php: 7.1 script: - composer create-project symplify/easy-coding-standard temp/ecs ^3 && temp/ecs/bin/ecs check src tests cache: directories: - $HOME/.composer - $HOME/.phive notifications: irc: "irc.freenode.org#phpdocumentor" slack: secure: "fjumM0h+4w3EYM4dpgqvpiCug7m4sSIC5+HATgwga/Nrc6IjlbWvGOv3JPgD3kQUhi18VmZfUYPmCv916SIbMnv8JWcrSaJXnPCgmxidvYkuzQDIw1HDJbVppGnkmwQA/qjIrM3sIEMfnu/arLRJQLI363aStZzGPxwIa4PDKcg=" email: - me@mikevanriel.com - ashnazg@php.net reflection-common/tests/unit/FqsenTest.php 0000777 00000004335 15224675025 0014756 0 ustar 00 <?php /** * phpDocumentor * * PHP Version 5.5 * * @copyright 2010-2015 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection; /** * Class FqsenTest * @coversDefaultClass phpDocumentor\Reflection\Fqsen */ class FqsenTest extends \PHPUnit_Framework_TestCase { /** * @param string $fqsen * @covers ::__construct * @dataProvider validFqsenProvider */ public function testValidFormats($fqsen, $name) { $instance = new Fqsen($fqsen); $this->assertEquals($name, $instance->getName()); } /** * Data provider for ValidFormats tests. Contains a complete list from psr-5 draft. * * @return array */ public function validFqsenProvider() { return [ ['\\', ''], ['\My\Space', 'Space'], ['\My\Space\myFunction()', 'myFunction'], ['\My\Space\MY_CONSTANT', 'MY_CONSTANT'], ['\My\Space\MY_CONSTANT2', 'MY_CONSTANT2'], ['\My\Space\MyClass', 'MyClass'], ['\My\Space\MyInterface', 'MyInterface'], ['\My\Space\MyTrait', 'MyTrait'], ['\My\Space\MyClass::myMethod()', 'myMethod'], ['\My\Space\MyClass::$my_property', 'my_property'], ['\My\Space\MyClass::MY_CONSTANT', 'MY_CONSTANT'], ]; } /** * @param string $fqsen * @covers ::__construct * @dataProvider invalidFqsenProvider * @expectedException \InvalidArgumentException */ public function testInValidFormats($fqsen) { new Fqsen($fqsen); } /** * Data provider for invalidFormats tests. Contains a complete list from psr-5 draft. * * @return array */ public function invalidFqsenProvider() { return [ ['\My\*'], ['\My\Space\.()'], ['My\Space'], ]; } /** * @covers ::__construct * @covers ::__toString */ public function testToString() { $className = new Fqsen('\\phpDocumentor\\Application'); $this->assertEquals('\\phpDocumentor\\Application', (string)$className); } } reflection-common/tests/common/bootstrap.php 0000777 00000000345 15224675025 0015365 0 ustar 00 <?php /** * phpDocumentor * * PHP Version 5.4 * * @copyright 2010-2014 Mike van Riel / Naenius (http://www.naenius.com) * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ reflection-common/composer.lock 0000777 00000101741 15224675025 0012710 0 ustar 00 { "_readme": [ "This file locks the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], "hash": "49ee00389e4ccd00d7e93a147103b2ab", "packages": [], "packages-dev": [ { "name": "doctrine/instantiator", "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", "shasum": "" }, "require": { "php": ">=5.3,<8.0-DEV" }, "require-dev": { "athletic/athletic": "~0.1.8", "ext-pdo": "*", "ext-phar": "*", "phpunit/phpunit": "~4.0", "squizlabs/php_codesniffer": "2.0.*@ALPHA" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-0": { "Doctrine\\Instantiator\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "http://ocramius.github.com/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "homepage": "https://github.com/doctrine/instantiator", "keywords": [ "constructor", "instantiate" ], "time": "2014-10-13 12:58:55" }, { "name": "phpdocumentor/reflection-docblock", "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "~4.0" }, "suggest": { "dflydev/markdown": "~1.0", "erusev/parsedown": "~1.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "psr-0": { "phpDocumentor": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "mike.vanriel@naenius.com" } ], "time": "2015-02-03 12:10:50" }, { "name": "phpspec/prophecy", "version": "v1.4.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "phpdocumentor/reflection-docblock": "~2.0", "sebastian/comparator": "~1.1" }, "require-dev": { "phpspec/phpspec": "~2.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.4.x-dev" } }, "autoload": { "psr-0": { "Prophecy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Konstantin Kudryashov", "email": "ever.zet@gmail.com", "homepage": "http://everzet.com" }, { "name": "Marcello Duarte", "email": "marcello.duarte@gmail.com" } ], "description": "Highly opinionated mocking framework for PHP 5.3+", "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", "fake", "mock", "spy", "stub" ], "time": "2015-04-27 22:15:08" }, { "name": "phpunit/php-code-coverage", "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", "reference": "6b7d2094ca2a685a2cad846cb7cd7a30e8b9470f" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6b7d2094ca2a685a2cad846cb7cd7a30e8b9470f", "reference": "6b7d2094ca2a685a2cad846cb7cd7a30e8b9470f", "shasum": "" }, "require": { "php": ">=5.3.3", "phpunit/php-file-iterator": "~1.3", "phpunit/php-text-template": "~1.2", "phpunit/php-token-stream": "~1.3", "sebastian/environment": "~1.0", "sebastian/version": "~1.0" }, "require-dev": { "ext-xdebug": ">=2.1.4", "phpunit/phpunit": "~4" }, "suggest": { "ext-dom": "*", "ext-xdebug": ">=2.2.1", "ext-xmlwriter": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.1.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sb@sebastian-bergmann.de", "role": "lead" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ "coverage", "testing", "xunit" ], "time": "2015-06-01 07:35:26" }, { "name": "phpunit/php-file-iterator", "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a923bb15680d0089e2316f7a4af8f437046e96bb", "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.4.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sb@sebastian-bergmann.de", "role": "lead" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ "filesystem", "iterator" ], "time": "2015-04-02 05:19:05" }, { "name": "phpunit/php-text-template", "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", "autoload": { "classmap": [ "Text/" ] }, "notification-url": "https://packagist.org/downloads/", "include-path": [ "" ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sb@sebastian-bergmann.de", "role": "lead" } ], "description": "Simple template engine.", "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ "template" ], "time": "2014-01-30 17:20:04" }, { "name": "phpunit/php-timer", "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", "autoload": { "classmap": [ "PHP/" ] }, "notification-url": "https://packagist.org/downloads/", "include-path": [ "" ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sb@sebastian-bergmann.de", "role": "lead" } ], "description": "Utility class for timing", "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], "time": "2013-08-02 07:42:54" }, { "name": "phpunit/php-token-stream", "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", "reference": "eab81d02569310739373308137284e0158424330" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/eab81d02569310739373308137284e0158424330", "reference": "eab81d02569310739373308137284e0158424330", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "~4.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.4-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Wrapper around PHP's tokenizer extension.", "homepage": "https://github.com/sebastianbergmann/php-token-stream/", "keywords": [ "tokenizer" ], "time": "2015-04-08 04:46:07" }, { "name": "phpunit/phpunit", "version": "4.6.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", "reference": "816d12536a7a032adc3b68737f82cfbbf98b79c1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/816d12536a7a032adc3b68737f82cfbbf98b79c1", "reference": "816d12536a7a032adc3b68737f82cfbbf98b79c1", "shasum": "" }, "require": { "ext-dom": "*", "ext-json": "*", "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", "phpspec/prophecy": "~1.3,>=1.3.1", "phpunit/php-code-coverage": "~2.0,>=2.0.11", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "~1.0", "phpunit/phpunit-mock-objects": "~2.3", "sebastian/comparator": "~1.1", "sebastian/diff": "~1.2", "sebastian/environment": "~1.2", "sebastian/exporter": "~1.2", "sebastian/global-state": "~1.0", "sebastian/version": "~1.0", "symfony/yaml": "~2.1|~3.0" }, "suggest": { "phpunit/php-invoker": "~1.1" }, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { "dev-master": "4.6.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "The PHP Unit Testing framework.", "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], "time": "2015-05-29 06:00:03" }, { "name": "phpunit/phpunit-mock-objects", "version": "2.3.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", "reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/253c005852591fd547fc18cd5b7b43a1ec82d8f7", "reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7", "shasum": "" }, "require": { "doctrine/instantiator": "~1.0,>=1.0.2", "php": ">=5.3.3", "phpunit/php-text-template": "~1.2" }, "require-dev": { "phpunit/phpunit": "~4.4" }, "suggest": { "ext-soap": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.3.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sb@sebastian-bergmann.de", "role": "lead" } ], "description": "Mock Object library for PHPUnit", "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", "keywords": [ "mock", "xunit" ], "time": "2015-05-29 05:19:18" }, { "name": "sebastian/comparator", "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", "sebastian/exporter": "~1.2" }, "require-dev": { "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", "homepage": "http://www.github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], "time": "2015-01-29 16:28:08" }, { "name": "sebastian/diff", "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "~4.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.3-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Diff implementation", "homepage": "http://www.github.com/sebastianbergmann/diff", "keywords": [ "diff" ], "time": "2015-02-22 15:13:53" }, { "name": "sebastian/environment", "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.3.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], "time": "2015-01-01 10:01:08" }, { "name": "sebastian/exporter", "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", "reference": "84839970d05254c73cde183a721c7af13aede943" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", "reference": "84839970d05254c73cde183a721c7af13aede943", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/recursion-context": "~1.0" }, "require-dev": { "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.2.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides the functionality to export PHP variables for visualization", "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "time": "2015-01-27 07:23:06" }, { "name": "sebastian/global-state", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "~4.2" }, "suggest": { "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Snapshotting of global state", "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "time": "2014-10-06 09:23:50" }, { "name": "sebastian/recursion-context", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", "reference": "3989662bbb30a29d20d9faa04a846af79b276252" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", "reference": "3989662bbb30a29d20d9faa04a846af79b276252", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "time": "2015-01-24 09:48:32" }, { "name": "sebastian/version", "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", "shasum": "" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", "time": "2015-02-24 06:35:25" }, { "name": "symfony/yaml", "version": "v2.7.0", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", "reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/Yaml/zipball/4a29a5248aed4fb45f626a7bbbd330291492f5c3", "reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3", "shasum": "" }, "require": { "php": ">=5.3.9" }, "require-dev": { "symfony/phpunit-bridge": "~2.7" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.7-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", "time": "2015-05-02 15:21:08" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": [], "platform-dev": [] } reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php 0000604 00000000714 15224675025 0017551 0 ustar 00 <?php /** * This file is part of phpDocumentor. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> * @license http://www.opensource.org/licenses/mit-license.php MIT * @link http://phpdoc.org */ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; interface Strategy { public function create($body); } reflection-docblock/.coveralls.yml 0000604 00000000117 15224675571 0013260 0 ustar 00 service_name: travis-ci coverage_clover: coverage.xml json_path: coverage.json reflection-docblock/appveyor.yml 0000604 00000003554 15224675571 0013065 0 ustar 00 build: false clone_folder: c:\reflectiondocblock max_jobs: 3 platform: x86 pull_requests: do_not_increment_build_number: true version: '{build}.{branch}' skip_tags: true branches: only: - master environment: matrix: - php_ver_target: 7.1 - php_ver_target: 7.2 matrix: fast_finish: false cache: - c:\php -> appveyor.yml - '%LOCALAPPDATA%\Composer\files' init: - SET PATH=C:\Program Files\OpenSSL;c:\tools\php;%PATH% - SET COMPOSER_NO_INTERACTION=1 - SET PHP=1 - SET ANSICON=121x90 (121x90) install: - IF EXIST c:\tools\php (SET PHP=0) - ps: appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php_ver_target | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') - cd c:\tools\php - IF %PHP%==1 copy /Y php.ini-development php.ini - IF %PHP%==1 echo max_execution_time=1200 >> php.ini - IF %PHP%==1 echo date.timezone="UTC" >> php.ini - IF %PHP%==1 echo extension_dir=ext >> php.ini - IF %PHP%==1 echo extension=php_curl.dll >> php.ini - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini - IF %PHP%==1 echo zend.assertions=1 >> php.ini - IF %PHP%==1 echo assert.exception=On >> php.ini - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat - appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar - cd c:\reflectiondocblock - composer install --no-interaction --prefer-dist --no-progress - composer global require phpunit/phpunit ^6 - composer global config bin-dir --absolute test_script: - cd c:\reflectiondocblock - c:\Users\appveyor\AppData\Roaming\Composer\vendor\bin\phpunit --no-coverage reflection-docblock/easy-coding-standard.neon 0000604 00000002264 15224675571 0015353 0 ustar 00 includes: - temp/ecs/config/clean-code.neon - temp/ecs/config/psr2-checkers.neon - temp/ecs/config/spaces.neon - temp/ecs/config/common.neon checkers: PhpCsFixer\Fixer\Operator\ConcatSpaceFixer: spacing: one parameters: exclude_checkers: # from temp/ecs/config/common.neon - PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer - PhpCsFixer\Fixer\PhpUnit\PhpUnitStrictFixer - PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer # from temp/ecs/config/spaces.neon - PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer skip: SlevomatCodingStandard\Sniffs\Classes\UnusedPrivateElementsSniff: # WIP code - src/DocBlock/StandardTagFactory.php PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\EmptyStatementSniff: # WIP code - src/DocBlock/StandardTagFactory.php PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes\ValidClassNameSniff: - src/DocBlock/Tags/Return_.php - src/DocBlock/Tags/Var_.php PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff: - */tests/** type-resolver/phive.xml 0000604 00000000406 15224675571 0011233 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?> <phive xmlns="https://phar.io/phive"> <phar name="phpunit" version="^6.5.5" installed="6.5.11" location="./tools/phpunit"/> <phar name="phpstan" version="^0.9.1" installed="0.10.2" location="./tools/phpstan"/> </phive> type-resolver/phpcs.xml.dist 0000604 00000001707 15224675571 0012204 0 ustar 00 <?xml version="1.0"?> <ruleset name="phpDocumentor"> <description>The coding standard for phpDocumentor.</description> <file>src</file> <file>tests/unit</file> <exclude-pattern>*/tests/unit/Types/ContextFactoryTest.php</exclude-pattern> <arg value="p"/> <rule ref="PSR2"> <include-pattern>*\.php</include-pattern> </rule> <rule ref="Doctrine"> <exclude name="SlevomatCodingStandard.TypeHints.UselessConstantTypeHint.UselessDocComment" /> </rule> <rule ref="Squiz.Classes.ValidClassName.NotCamelCaps"> <exclude-pattern>*/src/*_.php</exclude-pattern> </rule> <rule ref="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming.SuperfluousPrefix"> <exclude-pattern>*/src/*/Abstract*.php</exclude-pattern> </rule> <rule ref="Generic.Formatting.SpaceAfterNot"> <properties> <property name="spacing" value="0" /> </properties> </rule> </ruleset> type-resolver/appveyor.yml 0000604 00000003322 15224675571 0011766 0 ustar 00 build: false clone_folder: c:\typeresolver max_jobs: 3 platform: x86 pull_requests: do_not_increment_build_number: true version: '{build}.{branch}' skip_tags: true branches: only: - master environment: matrix: - php_ver_target: 7.1 - php_ver_target: 7.2 matrix: fast_finish: false cache: - c:\php -> appveyor.yml - '%LOCALAPPDATA%\Composer\files' init: - SET PATH=C:\Program Files\OpenSSL;c:\tools\php;%PATH% - SET COMPOSER_NO_INTERACTION=1 - SET PHP=1 - SET ANSICON=121x90 (121x90) install: - IF EXIST c:\tools\php (SET PHP=0) - ps: appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php_ver_target | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') - cd c:\tools\php - IF %PHP%==1 copy /Y php.ini-development php.ini - IF %PHP%==1 echo max_execution_time=1200 >> php.ini - IF %PHP%==1 echo date.timezone="UTC" >> php.ini - IF %PHP%==1 echo extension_dir=ext >> php.ini - IF %PHP%==1 echo extension=php_curl.dll >> php.ini - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini - IF %PHP%==1 echo zend.assertions=1 >> php.ini - IF %PHP%==1 echo assert.exception=On >> php.ini - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat - appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar - cd c:\typeresolver - composer install --no-interaction --prefer-dist --no-progress test_script: - cd c:\typeresolver - vendor\bin\phpunit --no-coverage type-resolver/composer-require-config.json 0000604 00000000475 15224675571 0015043 0 ustar 00 { "symbol-whitelist" : [ "null", "true", "false", "static", "self", "parent", "array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", "XSLTProcessor" ], "php-core-extensions" : [ "Core", "pcre", "Reflection", "tokenizer", "SPL", "standard" ] } type-resolver/.github/workflows/push.yml 0000604 00000002070 15224675571 0014474 0 ustar 00 on: push name: Qa workflow jobs: composer: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - name: composer uses: docker://composer env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: install --no-interaction --prefer-dist --optimize-autoloader - name: Code style check uses: docker://phpdoc/phpcs-ga:master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: -d memory_limit=1024M -s - name: composer-require-checker uses: docker://phpga/composer-require-checker-ga env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: check --config-file ./composer-require-config.json composer.json - name: Psalm uses: docker://mickaelandrieu/psalm-ga env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: PHPStan uses: docker://oskarstark/phpstan-ga env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: analyse src tests --level max --configuration phpstan.neon type-resolver/phpstan.neon 0000604 00000001024 15224675571 0011731 0 ustar 00 parameters: ignoreErrors: - message: '#Parameter \#1 \$types of class phpDocumentor\\Reflection\\Types\\Compound constructor expects array<phpDocumentor\\Reflection\\Type>, array<int, string> given\.#' path: %currentWorkingDirectory%/tests/unit/Types/CompoundTest.php - message: '#Parameter \#2 \$fileContents of method phpDocumentor\\Reflection\\Types\\ContextFactory::createForNamespace\(\) expects string, string|false given\.#' path: %currentWorkingDirectory%/tests/unit/Types/ContextFactoryTest.php type-resolver/psalm.xml 0000604 00000001021 15224675571 0011226 0 ustar 00 <?xml version="1.0"?> <psalm totallyTyped="false" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config file:///composer/vendor/vimeo/psalm/config.xsd" > <projectFiles> <directory name="src" /> <ignoreFiles> <directory name="vendor" /> </ignoreFiles> </projectFiles> <issueHandlers> <LessSpecificReturnType errorLevel="info" /> </issueHandlers> </psalm> type-resolver/composer.lock 0000604 00000143027 15224675571 0012106 0 ustar 00 { "_readme": [ "This file locks the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], "content-hash": "8168e5df1ad1444a9512e8b63bab2bfe", "packages": [ { "name": "phpdocumentor/reflection-common", "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { "dev-master": "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" ], "time": "2018-08-07T13:53:10+00:00" } ], "packages-dev": [ { "name": "doctrine/instantiator", "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.13", "phpstan/phpstan-phpunit": "^0.11", "phpstan/phpstan-shim": "^0.11", "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.2.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "http://ocramius.github.com/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], "time": "2019-03-17T17:37:11+00:00" }, { "name": "hamcrest/hamcrest-php", "version": "v2.0.0", "source": { "type": "git", "url": "https://github.com/hamcrest/hamcrest-php.git", "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", "shasum": "" }, "require": { "php": "^5.3|^7.0" }, "replace": { "cordoval/hamcrest-php": "*", "davedevelopment/hamcrest-php": "*", "kodova/hamcrest-php": "*" }, "require-dev": { "phpunit/php-file-iterator": "1.3.3", "phpunit/phpunit": "~4.0", "satooshi/php-coveralls": "^1.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "hamcrest" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD" ], "description": "This is the PHP port of Hamcrest Matchers", "keywords": [ "test" ], "time": "2016-01-20T08:20:44+00:00" }, { "name": "mockery/mockery", "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", "reference": "0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/mockery/mockery/zipball/0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2", "reference": "0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2", "shasum": "" }, "require": { "hamcrest/hamcrest-php": "~2.0", "lib-pcre": ">=7.0", "php": ">=5.6.0" }, "require-dev": { "phpunit/phpunit": "~5.7.10|~6.5|~7.0|~8.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-0": { "Mockery": "library/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Pádraic Brady", "email": "padraic.brady@gmail.com", "homepage": "http://blog.astrumfutura.com" }, { "name": "Dave Marshall", "email": "dave.marshall@atstsolutions.co.uk", "homepage": "http://davedevelopment.co.uk" } ], "description": "Mockery is a simple yet flexible PHP mock object framework", "homepage": "https://github.com/mockery/mockery", "keywords": [ "BDD", "TDD", "library", "mock", "mock objects", "mockery", "stub", "test", "test double", "testing" ], "time": "2019-02-13T09:37:52+00:00" }, { "name": "myclabs/deep-copy", "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", "shasum": "" }, "require": { "php": "^7.1" }, "replace": { "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" }, "files": [ "src/DeepCopy/deep_copy.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", "keywords": [ "clone", "copy", "duplicate", "object", "object graph" ], "time": "2019-04-07T13:18:21+00:00" }, { "name": "phar-io/manifest", "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", "phar-io/version": "^2.0", "php": "^5.6 || ^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "time": "2018-07-08T19:23:20+00:00" }, { "name": "phar-io/version", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Library for handling version information and constraints", "time": "2018-07-08T19:19:57+00:00" }, { "name": "phpdocumentor/reflection-docblock", "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "~4.0" }, "suggest": { "dflydev/markdown": "~1.0", "erusev/parsedown": "~1.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "psr-0": { "phpDocumentor": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "mike.vanriel@naenius.com" } ], "time": "2016-01-25T08:17:30+00:00" }, { "name": "phpspec/prophecy", "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.8.x-dev" } }, "autoload": { "psr-0": { "Prophecy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Konstantin Kudryashov", "email": "ever.zet@gmail.com", "homepage": "http://everzet.com" }, { "name": "Marcello Duarte", "email": "marcello.duarte@gmail.com" } ], "description": "Highly opinionated mocking framework for PHP 5.3+", "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", "fake", "mock", "spy", "stub" ], "time": "2018-08-05T17:53:17+00:00" }, { "name": "phpunit/php-code-coverage", "version": "6.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", "php": "^7.1", "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", "sebastian/environment": "^3.1 || ^4.0", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "suggest": { "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "6.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ "coverage", "testing", "xunit" ], "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "050bedf145a257b1ff02746c31894800e5122946" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", "reference": "050bedf145a257b1ff02746c31894800e5122946", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ "filesystem", "iterator" ], "time": "2018-09-13T20:33:42+00:00" }, { "name": "phpunit/php-text-template", "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Simple template engine.", "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ "template" ], "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Utility class for timing", "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], "time": "2019-06-07T04:22:29+00:00" }, { "name": "phpunit/php-token-stream", "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Wrapper around PHP's tokenizer extension.", "homepage": "https://github.com/sebastianbergmann/php-token-stream/", "keywords": [ "tokenizer" ], "time": "2018-10-30T05:52:18+00:00" }, { "name": "phpunit/phpunit", "version": "7.5.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", "reference": "9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c", "reference": "9ba59817745b0fe0c1a5a3032dfd4a6d2994ad1c", "shasum": "" }, "require": { "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "myclabs/deep-copy": "^1.7", "phar-io/manifest": "^1.0.2", "phar-io/version": "^2.0", "php": "^7.1", "phpspec/prophecy": "^1.7", "phpunit/php-code-coverage": "^6.0.7", "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", "sebastian/environment": "^4.0", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^2.0", "sebastian/version": "^2.0.1" }, "conflict": { "phpunit/phpunit-mock-objects": "*" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*", "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { "dev-master": "7.5-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "The PHP Unit Testing framework.", "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], "time": "2019-05-28T11:59:40+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "time": "2017-03-04T06:30:41+00:00" }, { "name": "sebastian/comparator", "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "shasum": "" }, "require": { "php": "^7.1", "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], "time": "2018-07-12T15:12:46+00:00" }, { "name": "sebastian/diff", "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.5 || ^8.0", "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff", "udiff", "unidiff", "unified diff" ], "time": "2019-02-04T06:01:07+00:00" }, { "name": "sebastian/environment", "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { "phpunit/phpunit": "^7.5" }, "suggest": { "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.2-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], "time": "2019-05-05T09:05:15+00:00" }, { "name": "sebastian/exporter", "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", "shasum": "" }, "require": { "php": "^7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides the functionality to export PHP variables for visualization", "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "time": "2017-04-03T13:19:02+00:00" }, { "name": "sebastian/global-state", "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Snapshotting of global state", "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", "shasum": "" }, "require": { "php": "^7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "time": "2017-08-03T12:35:26+00:00" }, { "name": "sebastian/object-reflector", "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", "reference": "773f97c67f28de00d397be301821b06708fca0be" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", "reference": "773f97c67f28de00d397be301821b06708fca0be", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", "time": "2017-03-29T09:07:27+00:00" }, { "name": "sebastian/recursion-context", "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "time": "2017-03-03T06:23:57+00:00" }, { "name": "sebastian/resource-operations", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", "shasum": "" }, "require": { "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "time": "2018-10-04T04:07:39+00:00" }, { "name": "sebastian/version", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { "php": ">=5.6" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, { "name": "theseer/tokenizer", "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": "^7.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "time": "2019-04-04T09:56:43+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "^7.1" }, "platform-dev": { "ext-tokenizer": "^7.1" } } reflection-common/phive.xml 0000604 00000000404 15224675571 0012031 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?> <phive xmlns="https://phar.io/phive"> <phar name="phpunit" version="^6.5.5" installed="6.5.5" location="./tools/phpunit"/> <phar name="phpstan" version="^0.9.1" installed="0.9.1" location="./tools/phpstan"/> </phive> reflection-common/phpstan.neon 0000604 00000000000 15224675571 0012522 0 ustar 00 reflection-common/appveyor.yml 0000604 00000003336 15224675571 0012573 0 ustar 00 build: false clone_folder: c:\reflectioncommon max_jobs: 3 platform: x86 pull_requests: do_not_increment_build_number: true version: '{build}.{branch}' skip_tags: true branches: only: - master environment: matrix: - php_ver_target: 7.1 - php_ver_target: 7.2 matrix: fast_finish: false cache: - c:\php -> appveyor.yml - '%LOCALAPPDATA%\Composer\files' init: - SET PATH=C:\Program Files\OpenSSL;c:\tools\php;%PATH% - SET COMPOSER_NO_INTERACTION=1 - SET PHP=1 - SET ANSICON=121x90 (121x90) install: - IF EXIST c:\tools\php (SET PHP=0) - ps: appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php_ver_target | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') - cd c:\tools\php - IF %PHP%==1 copy /Y php.ini-development php.ini - IF %PHP%==1 echo max_execution_time=1200 >> php.ini - IF %PHP%==1 echo date.timezone="UTC" >> php.ini - IF %PHP%==1 echo extension_dir=ext >> php.ini - IF %PHP%==1 echo extension=php_curl.dll >> php.ini - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini - IF %PHP%==1 echo zend.assertions=1 >> php.ini - IF %PHP%==1 echo assert.exception=On >> php.ini - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat - appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar - cd c:\reflectioncommon - composer install --no-interaction --prefer-dist --no-progress test_script: - cd c:\reflectioncommon - vendor\bin\phpunit --no-coverage reflection-common/easy-coding-standard.neon 0000604 00000001151 15224675571 0015055 0 ustar 00 includes: - temp/ecs/config/clean-code.neon - temp/ecs/config/psr2.neon - temp/ecs/config/common.neon parameters: exclude_checkers: # from temp/ecs/config/common.neon - PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer - PhpCsFixer\Fixer\PhpUnit\PhpUnitStrictFixer - PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer # from temp/ecs/config/spaces.neon - PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer skip: PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff: - */tests/** reflection-common/phpmd.xml.dist 0000604 00000001515 15224675571 0012774 0 ustar 00 <?xml version="1.0" encoding="UTF-8" ?> <ruleset name="ProxyManager rules" xmlns="http://pmd.sf.net/ruleset/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd" > <rule ref="rulesets/codesize.xml"/> <rule ref="rulesets/unusedcode.xml"/> <rule ref="rulesets/design.xml"> <!-- eval is needed to generate runtime classes --> <exclude name="EvalExpression"/> </rule> <rule ref="rulesets/naming.xml"> <exclude name="LongVariable"/> </rule> <rule ref="rulesets/naming.xml/LongVariable"> <properties> <property name="minimum">40</property> </properties> </rule> </ruleset> reflection-common/.scrutinizer.yml 0000604 00000002215 15224675571 0013360 0 ustar 00 before_commands: - "composer install --no-dev --prefer-source" checks: php: excluded_dependencies: - phpstan/phpstan tools: external_code_coverage: enabled: true timeout: 300 filter: excluded_paths: ["tests", "vendor"] php_code_sniffer: enabled: true config: standard: PSR2 filter: paths: ["src/*", "tests/*"] excluded_paths: [] php_cpd: enabled: true excluded_dirs: ["tests", "vendor"] php_cs_fixer: enabled: true config: level: all filter: paths: ["src/*", "tests/*"] php_loc: enabled: true excluded_dirs: ["tests", "vendor"] php_mess_detector: enabled: true config: ruleset: phpmd.xml.dist design_rules: { eval_expression: false } filter: paths: ["src/*"] php_pdepend: enabled: true excluded_dirs: ["tests", "vendor"] php_analyzer: enabled: true filter: paths: ["src/*", "tests/*"] sensiolabs_security_checker: true