[
  {
    "path": ".gitattributes",
    "content": "/.gitattributes export-ignore\n/.gitignore export-ignore\n/.yamllint.yaml export-ignore\n/composer-require-checker.json export-ignore\n/composer.lock export-ignore\n/phpmd.xml.dist export-ignore\n/phpunit.xml.dist export-ignore\n/Makefile export-ignore\n/phive.xml export-ignore\n/phpcs.xml.dist export-ignore\n/phpstan.neon export-ignore\n/phpstan-baseline.neon export-ignore\n/psalm.xml export-ignore\n/phpdoc.dist.xml export-ignore\n/tests/ export-ignore\n/docs/ export-ignore\n/.github/ export-ignore\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"composer\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n    open-pull-requests-limit: 10\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/documentation.yml",
    "content": "# https://docs.github.com/en/actions\n\nname: \"Documentation\"\n\non: # yamllint disable-line rule:truthy\n  push:\n    branches:\n      - \"6.x\"\n  workflow_dispatch: null\n\njobs:\n  run:\n    name: \"Documentation\"\n    uses: \"phpDocumentor/.github/.github/workflows/documentation.yml@main\"\n    with:\n      deploy: true\n      component: \"reflection-docblock\"\n    secrets:\n      token: \"${{ secrets.BOT_TOKEN }}\"\n"
  },
  {
    "path": ".github/workflows/integrate.yaml",
    "content": "# https://docs.github.com/en/actions\n\nname: \"Integrate\"\n\non: # yamllint disable-line rule:truthy\n  push:\n    branches:\n      - \"6.x\"\n  pull_request: null\n  # Allow manually triggering the workflow.\n  workflow_dispatch: null\n\njobs:\n  code-coverage:\n    name: \"Code Coverage\"\n    uses: \"phpDocumentor/.github/.github/workflows/code-coverage.yml@v0.9\"\n    with:\n      composer-root-version: \"6.x-dev\"\n\n  coding-standards:\n    name: \"Coding Standards\"\n    uses: \"phpDocumentor/.github/.github/workflows/coding-standards.yml@v0.9\"\n    with:\n      composer-root-version: \"6.x-dev\"\n\n  dependency-analysis:\n    name: \"Dependency analysis\"\n    uses: \"phpDocumentor/.github/.github/workflows/dependency-analysis.yml@v0.9\"\n    with:\n      composer-root-version: \"6.x-dev\"\n\n  lint-root:\n    name: \"Lint root\"\n    uses: \"phpDocumentor/.github/.github/workflows/lint.yml@v0.9\"\n    with:\n      composer-options: \"--no-check-publish --ansi\"\n\n  static-analysis:\n    name: \"Static analysis\"\n    uses: \"phpDocumentor/.github/.github/workflows/static-analysis.yml@v0.9\"\n    with:\n      php-extensions: \"none, ctype, dom, json, mbstring, phar, simplexml, tokenizer, xml, xmlwriter, fileinfo, pcntl, posix\"\n      composer-root-version: \"6.x-dev\"\n\n  unit-tests:\n    name: \"Unit test\"\n    uses: \"phpDocumentor/.github/.github/workflows/continuous-integration.yml@v0.9\"\n    with:\n      composer-root-version: \"6.x-dev\"\n      upcoming-releases: true\n\n  integration-tests:\n    name: \"Integration test\"\n    uses: \"phpDocumentor/.github/.github/workflows/continuous-integration.yml@v0.9\"\n    with:\n      composer-root-version: \"6.x-dev\"\n      upcoming-releases: true\n      test-suite: \"integration\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# IDE Shizzle; it is recommended to use a global .gitignore for this but since this is an OSS project we want to make\n# it easy to contribute\n.idea\n/nbproject/private/\n.buildpath\n.project\n.settings\n\n# Build folder and vendor folder are generated code; no need to version this\nbuild/\ntemp/\ntools/\nvendor/\n*.phar\n\n# By default the phpunit.xml.dist is provided; you can override this using a local config file\nphpunit.xml\n.phpunit.result.cache\n\n.phpdoc\n"
  },
  {
    "path": ".yamllint.yaml",
    "content": "extends: \"default\"\n\nignore: |\n  .build/\n  .notes/\n  vendor/\nrules:\n  braces:\n    max-spaces-inside-empty: 0\n    max-spaces-inside: 1\n    min-spaces-inside-empty: 0\n    min-spaces-inside: 1\n  brackets:\n    max-spaces-inside-empty: 0\n    max-spaces-inside: 0\n    min-spaces-inside-empty: 0\n    min-spaces-inside: 0\n  colons:\n    max-spaces-after: 1\n    max-spaces-before: 0\n  commas:\n    max-spaces-after: 1\n    max-spaces-before: 0\n    min-spaces-after: 1\n  comments:\n    ignore-shebangs: true\n    min-spaces-from-content: 1\n    require-starting-space: true\n  comments-indentation: \"enable\"\n  document-end:\n    present: false\n  document-start:\n    present: false\n  indentation:\n    check-multi-line-strings: false\n    indent-sequences: true\n    spaces: 2\n  empty-lines:\n    max-end: 0\n    max-start: 0\n    max: 1\n  empty-values:\n    forbid-in-block-mappings: true\n    forbid-in-flow-mappings: true\n  hyphens:\n    max-spaces-after: 2\n  key-duplicates: \"enable\"\n  key-ordering: \"disable\"\n  line-length: \"disable\"\n  new-line-at-end-of-file: \"enable\"\n  new-lines:\n    type: \"unix\"\n  octal-values:\n    forbid-implicit-octal: true\n  quoted-strings:\n    quote-type: \"double\"\n  trailing-spaces: \"enable\"\n  truthy:\n    allowed-values:\n      - \"false\"\n      - \"true\"\n\nyaml-files:\n  - \"*.yaml\"\n  - \"*.yml\"\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2010 Mike van Riel\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": ".PHONY: help\nhelp: ## Displays this list of targets with descriptions\n\t@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = \":.*?## \"}; {printf \"\\033[32m%-30s\\033[0m %s\\n\", $$1, $$2}'\n\n.PHONY: code-style\ncode-style:\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest -d memory_limit=1024M -s\n\n.PHONY: fix-code-style\nfix-code-style:\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest phpcbf\n\n.PHONY: static-code-analysis\nstatic-code-analysis: vendor ## Runs a static code analysis with phpstan/phpstan and vimeo/psalm\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpstan --configuration=phpstan.neon --memory-limit=1024M\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/psalm.phar\n\n.PHONY: test\ntest: test-unit ## Runs all test suites with phpunit/phpunit\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpunit\n\n.PHONY: test-unit\ntest-unit: ## Runs unit tests with phpunit/phpunit\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpunit --testsuite=unit\n\n.PHONY: dependency-analysis\ndependency-analysis: vendor ## Runs a dependency analysis with maglnet/composer-require-checker\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 .phive/composer-require-checker check --config-file=/opt/project/composer-require-checker.json\n\nvendor: composer.json composer.lock\n\tcomposer validate --no-check-publish\n\tcomposer install --no-interaction --no-progress\n\n.PHONY: benchmark\nbenchmark:\n\tdocker run -it --rm -v${CURDIR}:/opt/project -w /opt/project php:7.4-cli tools/phpbench run\n\n.PHONY: rector\nrector: ## Refactor code using rector\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/rector process\n\n.PHONY: pre-commit-test\npre-commit-test: fix-code-style test code-style static-code-analysis\n\n.PHONY: docs\ndocs: ## Generate documentation with phpDocumentor\n\tdocker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpdoc:3\n"
  },
  {
    "path": "README.md",
    "content": "[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Integrate](https://github.com/phpDocumentor/ReflectionDocBlock/actions/workflows/integrate.yaml/badge.svg)](https://github.com/phpDocumentor/ReflectionDocBlock/actions/workflows/integrate.yaml)\n[![Scrutinizer Code Coverage](https://img.shields.io/scrutinizer/coverage/g/phpDocumentor/ReflectionDocBlock.svg)](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionDocBlock/?branch=master)\n[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/phpDocumentor/ReflectionDocBlock.svg)](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionDocBlock/?branch=master)\n[![Stable Version](https://img.shields.io/packagist/v/phpdocumentor/reflection-docblock.svg?label=stable)](https://packagist.org/packages/phpdocumentor/reflection-docblock)\n[![Unstable Version](https://img.shields.io/packagist/v/phpdocumentor/reflection-docblock.svg?include_prereleases&label=unstable)](https://packagist.org/packages/phpdocumentor/reflection-docblock)\n\nReflectionDocBlock \n==================\n\nIntroduction\n------------\n\nThe ReflectionDocBlock component of phpDocumentor provides a DocBlock parser\nthat is 100% compatible with the [PHPDoc standard](http://phpdoc.org/docs/latest).\n\nWith this component, a library can provide support for annotations via DocBlocks\nor otherwise retrieve information that is embedded in a DocBlock.\n\nInstallation\n------------\n\n```bash\ncomposer require phpdocumentor/reflection-docblock\n```\n\nUsage\n-----\n\nIn order to parse the DocBlock one needs a DocBlockFactory that can be\ninstantiated using its `createInstance` factory method like this:\n\n```php\n$factory  = \\phpDocumentor\\Reflection\\DocBlockFactory::createInstance();\n```\n\nThen we can use the `create` method of the factory to interpret the DocBlock.\nPlease note that it is also possible to provide a class that has the\n`getDocComment()` method, such as an object of type `ReflectionClass`, the\ncreate method will read that if it exists.\n\n```php\n$docComment = <<<DOCCOMMENT\n/**\n * This is an example of a summary.\n *\n * This is a Description. A Summary and Description are separated by either\n * two subsequent newlines (thus a whiteline in between as can be seen in this\n * example), or when the Summary ends with a dot (`.`) and some form of\n * whitespace.\n */\nDOCCOMMENT;\n\n$docblock = $factory->create($docComment);\n```\n\nThe `create` method will yield an object of type `\\phpDocumentor\\Reflection\\DocBlock`\nwhose methods can be queried:\n\n```php\n// Contains the summary for this DocBlock\n$summary = $docblock->getSummary();\n\n// Contains \\phpDocumentor\\Reflection\\DocBlock\\Description object\n$description = $docblock->getDescription();\n\n// You can either cast it to string\n$description = (string) $docblock->getDescription();\n\n// Or use the render method to get a string representation of the Description.\n$description = $docblock->getDescription()->render();\n```\n\n> For more examples it would be best to review the scripts in the [`/docs/examples` folder](/docs/examples).\n"
  },
  {
    "path": "composer-require-checker.json",
    "content": "{\n  \"symbol-whitelist\" : [\n    \"null\", \"true\", \"false\",\n    \"static\", \"self\", \"parent\",\n    \"array\", \"string\", \"int\", \"float\", \"bool\", \"iterable\", \"callable\", \"void\", \"object\", \"XSLTProcessor\",\n    \"PHPStan\\\\PhpDocParser\\\\ParserConfig\"\n  ],\n  \"php-core-extensions\" : [\n    \"Core\",\n    \"pcre\",\n    \"Reflection\",\n    \"tokenizer\",\n    \"SPL\",\n    \"standard\"\n  ]\n}\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"phpdocumentor/reflection-docblock\",\n    \"description\": \"With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.\",\n    \"type\": \"library\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Mike van Riel\",\n            \"email\": \"me@mikevanriel.com\"\n        },\n        {\n            \"name\": \"Jaap van Otterdijk\",\n            \"email\": \"opensource@ijaap.nl\"\n        }\n    ],\n    \"require\": {\n        \"php\": \"^7.4 || ^8.0\",\n        \"phpdocumentor/type-resolver\": \"^2.0\",\n        \"webmozart/assert\": \"^1.9.1 || ^2\",\n        \"phpdocumentor/reflection-common\": \"^2.2\",\n        \"ext-filter\": \"*\",\n        \"phpstan/phpdoc-parser\": \"^2.0\",\n        \"doctrine/deprecations\": \"^1.1\"\n    },\n    \"require-dev\": {\n        \"mockery/mockery\": \"~1.3.5 || ~1.6.0\",\n        \"phpunit/phpunit\": \"^9.5\",\n        \"phpstan/phpstan\": \"^1.8\",\n        \"phpstan/phpstan-mockery\": \"^1.1\",\n        \"phpstan/extension-installer\": \"^1.1\",\n        \"phpstan/phpstan-webmozart-assert\": \"^1.2\",\n        \"psalm/phar\": \"^5.26\",\n        \"shipmonk/dead-code-detector\": \"^0.5.1\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"phpDocumentor\\\\Reflection\\\\\": \"src\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"phpDocumentor\\\\Reflection\\\\\": [\"tests/unit\", \"tests/integration\"]\n        }\n    },\n    \"config\": {\n        \"platform\": {\n            \"php\":\"7.4.0\"\n        },\n        \"allow-plugins\": {\n            \"phpstan/extension-installer\": true\n        }\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"5.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "docs/contributing.rst",
    "content": "Contributing\n============\n\nContributions are welcome! If you would like to contribute to ReflectionDocBlock, please follow these guidelines:\n\n- Fork the repository and create your branch from ``main``.\n- Ensure your code follows the project's coding standards.\n- Write tests for your changes.\n- Submit a pull request with a clear description of your changes.\n\nFor questions or discussions, please open an issue on GitHub.\n\n"
  },
  {
    "path": "docs/examples/01-interpreting-a-simple-docblock.php",
    "content": "<?php\nrequire_once(__DIR__ . '/../../vendor/autoload.php');\n\nuse phpDocumentor\\Reflection\\DocBlockFactory;\n\n$docComment = <<<DOCCOMMENT\n/**\n * This is an example of a summary.\n *\n * This is a Description. A Summary and Description are separated by either\n * two subsequent newlines (thus a whiteline in between as can be seen in this\n * example), or when the Summary ends with a dot (`.`) and some form of\n * whitespace.\n */\nDOCCOMMENT;\n\n$factory  = DocBlockFactory::createInstance();\n$docblock = $factory->create($docComment);\n\n// Should contain the first line of the DocBlock\n$summary = $docblock->getSummary();\n\n// Contains an object of type Description; you can either cast it to string or use\n// the render method to get a string representation of the Description.\n//\n// In subsequent examples we will be fiddling a bit more with the Description.\n$description = $docblock->getDescription();\n"
  },
  {
    "path": "docs/examples/02-interpreting-tags.php",
    "content": "<?php\nrequire_once(__DIR__ . '/../../vendor/autoload.php');\n\nuse phpDocumentor\\Reflection\\DocBlockFactory;\n\n$docComment = <<<DOCCOMMENT\n/**\n * This is an example of a summary.\n *\n * @see \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory\n */\nDOCCOMMENT;\n\n$factory  = DocBlockFactory::createInstance();\n$docblock = $factory->create($docComment);\n\n// You can check if a DocBlock has one or more see tags\n$hasSeeTag = $docblock->hasTag('see');\n\n// Or we can get a complete list of all tags\n$tags = $docblock->getTags();\n\n// But we can also grab all tags of a specific type, such as `see`\n$seeTags = $docblock->getTagsByName('see');\n"
  },
  {
    "path": "docs/examples/03-reconstituting-a-docblock.php",
    "content": "<?php\n\nrequire_once(__DIR__ . '/../../vendor/autoload.php');\n\nuse phpDocumentor\\Reflection\\DocBlock\\Serializer;\nuse phpDocumentor\\Reflection\\DocBlockFactory;\n\n$docComment = <<<DOCCOMMENT\n/**\n * This is an example of a summary.\n *\n * And here is an example of the description\n * of a DocBlock that can span multiple lines.\n *\n * @see \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory\n */\nDOCCOMMENT;\n\n$factory  = DocBlockFactory::createInstance();\n$docblock = $factory->create($docComment);\n\n// Create the serializer that will reconstitute the DocBlock back to its original form.\n$serializer = new Serializer(0, '', true, null, null, PHP_EOL);\n\n// Reconstitution is performed by the `getDocComment()` method.\n$reconstitutedDocComment = $serializer->getDocComment($docblock);\n\n"
  },
  {
    "path": "docs/examples/04-adding-your-own-tag.php",
    "content": "<?php\n/**\n * In this example we demonstrate how you can add your own Tag using a Static Factory method in your Tag class.\n */\n\nrequire_once(__DIR__ . '/../../vendor/autoload.php');\n\nuse phpDocumentor\\Reflection\\DocBlock\\Serializer;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlockFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse Webmozart\\Assert\\Assert;\n\n/**\n * An example of a custom tag called `my-tag` with an optional description.\n *\n * A Custom Tag is a class that can consist of two parts:\n *\n * 1. a method `create` that is a static factory for this class.\n * 2. methods and properties that have this object act as an immutable Value Object representing a Tag instance.\n *\n * The static factory `create` is used to convert a tag line (without the tag name) into an instance of the\n * same tag object with the right constructor parameters set. This method has a dynamic list of parameters so that you\n * can inject various dependencies, see the method's DocBlock for more information.\n *\n * An object of this class, and its methods and properties, represent a single instance of that tag in your\n * documentation in the form of a Value Object whose properties should not be changed after instantiation (it should be\n * immutable).\n *\n * > Important: Tag classes that act as Factories using the `create` method should implement the Tag interface.\n * > Instead, you could extend the abstract class BaseTag that already implements the Tag interface\n */\nfinal class MyTag extends BaseTag\n{\n    /**\n     * A required property that is used by Formatters to reconstitute the complete tag line.\n     *\n     * @see Formatter\n     *\n     * @var string\n     */\n    protected string $name = 'my-tag';\n\n    /**\n     * The constructor for this Tag; this should contain all properties for this object.\n     *\n     * @param Description $description An example of how to add a Description to the tag; the Description is often\n     *                                 an optional variable so passing null is allowed in this instance (though you can\n     *                                 also construct an empty description object).\n     *\n     * @see BaseTag for the declaration of the description property and getDescription method.\n     */\n    public function __construct(?Description $description = null)\n    {\n        $this->description = $description;\n    }\n\n    /**\n     * A static Factory that creates a new instance of the current Tag.\n     *\n     * In this example the MyTag tag can be created by passing a description text as $body. Because we have added\n     * a $descriptionFactory that is type-hinted as DescriptionFactory we can now construct a new Description object\n     * and pass that to the constructor.\n     *\n     * > You could directly instantiate a Description object here but that won't be parsed for inline tags and Types\n     * > won't be resolved. The DescriptionFactory will take care of those actions.\n     *\n     * The `create` method's interface states that this method only features a single parameter (`$body`) but the\n     * {@see TagFactory} will read the signature of this method and if it has more parameters then it will try\n     * to find declarations for it in the ServiceLocator of the TagFactory (see {@see TagFactory::$serviceLocator}).\n     *\n     * > Important: all properties following the `$body` should default to `null`, otherwise PHP will error because\n     * > it no longer matches the interface. This is why you often see the default tags check that an optional argument\n     * > is not null nonetheless.\n     *\n     * @param string             $body\n     * @param DescriptionFactory $descriptionFactory\n     * @param Context|null       $context The Context is used to resolve Types and FQSENs, although optional\n     *                                    it is highly recommended to pass it. If you omit it then it is assumed that\n     *                                    the DocBlock is in the global namespace and has no `use` statements.\n     *\n     * @see Tag for the interface declaration of the `create` method.\n     * @see Tag::create() for more information on this method's workings.\n     */\n    public static function create(string $body, ?DescriptionFactory $descriptionFactory = null, ?Context $context = null): self\n    {\n        Assert::notNull($descriptionFactory);\n\n        return new static($descriptionFactory->create($body, $context));\n    }\n\n    /**\n     * Returns a rendition of the original tag line.\n     *\n     * This method is used to reconstitute a DocBlock into its original form by the {@see Serializer}. It should\n     * feature all parts of the tag so that the serializer can put it back together.\n     */\n    public function __toString(): string\n    {\n        return (string)$this->description;\n    }\n}\n\n$docComment = <<<DOCCOMMENT\n/**\n * This is an example of a summary.\n *\n * @my-tag I have a description\n */\nDOCCOMMENT;\n\n// Make a mapping between the tag name `my-tag` and the Tag class containing the Factory Method `create`.\n$customTags = ['my-tag' => MyTag::class];\n\n// Do pass the list of custom tags to the Factory for the DocBlockFactory.\n$factory = DocBlockFactory::createInstance($customTags);\n// You can also add Tags later using `$factory->registerTagHandler()` with a tag name and Tag class name.\n\n// Create the DocBlock\n$docblock = $factory->create($docComment);\n\n// Take a look: the $customTagObjects now contain an array with your newly added tag\n$customTagObjects = $docblock->getTagsByName('my-tag');\n\n// As an experiment: let's reconstitute the DocBlock and observe that because we added a __toString() method\n// to the tag class that we can now also see it.\n$serializer              = new Serializer(0, '',true, null, null, PHP_EOL);\n$reconstitutedDocComment = $serializer->getDocComment($docblock);\n"
  },
  {
    "path": "docs/examples/playing-with-descriptions/02-escaping.php",
    "content": "<?php\n\nrequire_once(__DIR__ . '/../../../vendor/autoload.php');\n\nuse phpDocumentor\\Reflection\\DocBlockFactory;\n\n$docComment = <<<DOCCOMMENT\n/**\n * This is an example of a summary.\n *\n * You can escape the @-sign by surrounding it with braces, for example: {@}. And escape a closing brace within an\n * inline tag by adding an opening brace in front of it like this: {}.\n *\n * Here are example texts where you can see how they could be used in a real life situation:\n *\n *     This is a text with an {@internal inline tag where a closing brace ({}) is shown}.\n *     Or an {@internal inline tag with a literal {{@}link{} in it}.\n *\n * Do note that an {@internal inline tag that has an opening brace ({) does not break out}.\n */\nDOCCOMMENT;\n\n$factory  = DocBlockFactory::createInstance();\n$docblock = $factory->create($docComment);\n\n// Escaping is automatic so this happens in the DescriptionFactory.\n$description = $docblock->getDescription();\n\n// This is the rendition that we will receive of the Description.\n$receivedDocComment = <<<DOCCOMMENT\n/**\n * This is an example of a summary.\n *\n * You can escape the @-sign by surrounding it with braces, for example: {@}. And escape a closing brace within an\n * inline tag by adding an opening brace in front of it like this: {}.\n *\n * Here are example texts where you can see how they could be used in a real life situation:\n *\n *     This is a text with an {@internal inline tag where a closing brace ({}) is shown}.\n *     Or an {@internal inline tag with a literal {{@}link{} in it}.\n *\n * Do note that an {@internal inline tag that has an opening brace ({) does not break out}.\n */\nDOCCOMMENT;\n\n// Render it using the default PassthroughFormatter\n$foundDescription = $description->render();\n"
  },
  {
    "path": "docs/how-to/adding-your-own-tag.rst",
    "content": "Add Your Own Tag\n=======================\n\nThis guide demonstrates how to add your own custom tag to a DocBlock using ReflectionDocBlock.\n\n.. literalinclude:: ../examples/04-adding-your-own-tag.php\n   :language: php\n   :linenos:\n\n"
  },
  {
    "path": "docs/how-to/index.rst",
    "content": "How-to\n=============\n\nPractical guides for common tasks with ReflectionDocBlock:\n\n.. toctree::\n   :maxdepth: 1\n\n   interpreting-a-simple-docblock\n   interpreting-tags\n   reconstituting-a-docblock\n   adding-your-own-tag\n\n"
  },
  {
    "path": "docs/how-to/interpreting-a-simple-docblock.rst",
    "content": "Interpret a Simple DocBlock\n==================================\n\nThis guide demonstrates how to parse a simple DocBlock and extract its summary and description using ReflectionDocBlock.\n\n.. literalinclude:: ../examples/01-interpreting-a-simple-docblock.php\n   :language: php\n   :linenos:\n\n"
  },
  {
    "path": "docs/how-to/interpreting-tags.rst",
    "content": "Interpret Tags in a DocBlock\n===================================\n\nThis guide demonstrates how to interpret tags within a DocBlock using ReflectionDocBlock.\n\n.. literalinclude:: ../examples/02-interpreting-tags.php\n   :language: php\n   :linenos:\n\n"
  },
  {
    "path": "docs/how-to/reconstituting-a-docblock.rst",
    "content": "Reconstituting a DocBlock\n=========================\n\nReflectionDocBlock not only allows you to read and parse DocBlocks, but also to reconstruct them. This is useful if you need to add, remove, or modify tags in your codebase programmatically. For example, you might want to update type information, add custom tags, or strip deprecated tags as part of a refactoring or code generation process.\n\nBelow is a practical example of how to reconstitute a DocBlock using this library:\n\n.. literalinclude:: ../examples/03-reconstituting-a-docblock.php\n   :language: php\n   :caption: examples/03-reconstituting-a-docblock.php\n"
  },
  {
    "path": "docs/index.rst",
    "content": "ReflectionDocBlock Documentation\n===========================================\n\nReflectionDocBlock is a PHP library that provides a DocBlock parser fully compatible with the PHPDoc standard. It allows you to parse, interpret, and extract information from DocBlocks in your PHP code, enabling support for annotations and metadata extraction.\n\nKey Features and Use Cases\n--------------------------\n- **Documentation Generation**: Used as a core component in tools like phpDocumentor to generate API documentation from your code's DocBlocks.\n- **Type and Metadata Extraction**: Integrations and tools use this library to gather type information and other metadata, enabling advanced features such as static analysis, code introspection, and automated serialization.\n- **Serializer Support**: Helps serializers and similar tools to interpret type information in array and object structures, making it easier to transform nested objects correctly.\n- **DocBlock Reconstitution**: Not only can you read DocBlocks, but you can also reconstruct them. This is useful for adding, removing, or modifying tags in your codebase programmatically.\n- **Standalone or Integrated**: Designed for standalone use, but also serves as a key component of the phpDocumentor suite.\n\nUnique Advantages\n-----------------\n- **Simple, Intuitive API**: Focus on ease of use, so you can work with DocBlocks without needing to understand the complexities of parsing.\n- **Widely Adopted**: Used by over 1000 packages on Packagist, making it a proven and reliable choice for PHP developers.\n- **Actively Maintained**: Supports PHP 7.4 and 8+, and is maintained by the phpDocumentor team and contributors.\n\nQuick Start Example\n-------------------\nHere's a minimal example of how to use ReflectionDocBlock in your project:\n\n.. literalinclude:: examples/01-interpreting-a-simple-docblock.php\n   :language: php\n   :caption: examples/01-interpreting-a-simple-docblock.php\n\nFor more detailed usage and how-to guides, see the ``how-to/`` section.\n\n.. toctree::\n   :maxdepth: 2\n   :hidden:\n\n   installation\n   how-to/index\n   upgrade-to-v6\n   contributing\n"
  },
  {
    "path": "docs/installation.rst",
    "content": "Installation\n============\n\nTo install ReflectionDocBlock, use Composer:\n\n.. code-block:: bash\n\n   composer require phpdocumentor/reflection-docblock\n\n"
  },
  {
    "path": "docs/upgrade-to-v6.rst",
    "content": "Upgrade Guide to v6\n===================\n\nThis guide helps you upgrade your project to ReflectionDocBlock v6. It covers breaking changes, removals, new features, and migration tips to ensure a smooth transition.\n\nSupported PHP Versions\n----------------------\n- v6 requires PHP 7.4 or higher (PHP 8+ recommended).\n\nBreaking Changes & Removals\n---------------------------\n- **Removal of `::create` static method for type-based tags**\n    - The `create` static method has been removed from tag classes that represent type definitions, such as `@param` and `@return` tags. Most users will not be affected, as these methods are rarely used directly. The deprecation notice for these methods was present throughout v5.\n    - **Migration:**\n        - If you are instantiating these tag objects directly, use the tag factory or the recommended construction pattern instead.\n        - Before:\n            .. code-block:: php\n\n               $tag = Param::create($body);\n        - After:\n            .. code-block:: php\n\n               $factory = \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StandardTagFactory::createInstance();\n               $tag = $factory->create('@param int $foo');\n\n- **StandardTagFactory instantiation**\n    - `StandardTagFactory` must now be created via `createInstance()`.\n    - **Migration:**\n        - Before:\n            .. code-block:: php\n\n               $factory = new StandardTagFactory();\n        - After:\n            .. code-block:: php\n\n               $factory = StandardTagFactory::createInstance();\n\n- **Removed methods**\n    - `Method::getArguments` has been removed.\n    - `Method::create` has been removed.\n    - **Migration:**\n        - Refactor code to use the new API for method arguments and creation.\n\nTypeResolver Upgrade\n-------------------\n- **Generics Support**: The TypeResolver component now supports generics,\n    which replaces the previous `Collection` type handling. This allows\n    for more accurate and expressive type definitions, such as `MyClass<int, MyClass>` or `Collection<MyClass>`,\n    and improves compatibility with modern PHPDoc standards.\n\n- For more details and advanced migration scenarios, consult the `TypeResolver upgrade guide <https://docs.phpdoc.org/components/type-resolver/guides/upgrade-v1-to-v2.html#upgrade-to-version-2>`_\n"
  },
  {
    "path": "phive.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phive xmlns=\"https://phar.io/phive\">\n  <phar name=\"phpunit\" version=\"^9.5\" installed=\"9.5.8\" location=\"./tools/phpunit\" copy=\"true\"/>\n</phive>\n"
  },
  {
    "path": "phpcs.xml.dist",
    "content": "<?xml version=\"1.0\"?>\n<ruleset name=\"ReflectionDocBlock\">\n <description>The coding standard for this library.</description>\n\n    <file>src</file>\n    <file>tests/unit</file>\n    <exclude-pattern>*/tests/unit/Types/ContextFactoryTest\\.php</exclude-pattern>\n    <exclude-pattern>*/tests/unit/Assets/*</exclude-pattern>\n    <arg value=\"p\"/>\n\n    <!-- Set the minimum PHP version for PHPCompatibility.\n         This should be kept in sync with the requirements in the composer.json file. -->\n    <config name=\"testVersion\" value=\"7.4-\"/>\n\n    <rule ref=\"phpDocumentor\">\n        <exclude name=\"SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException\" />\n    </rule>\n\n    <rule ref=\"SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming.SuperfluousPrefix\">\n        <exclude-pattern>*/src/*/Abstract*\\.php</exclude-pattern>\n    </rule>\n</ruleset>\n"
  },
  {
    "path": "phpdoc.dist.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<phpdocumentor\n        configVersion=\"3\"\n        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n        xmlns=\"https://www.phpdoc.org\"\n        xsi:noNamespaceSchemaLocation=\"data/xsd/phpdoc.xsd\"\n>\n    <title>Reflection Docblock</title>\n    <paths>\n        <output>build/docs</output>\n    </paths>\n    <version number=\"6.0.0\">\n        <folder>latest</folder>\n        <api>\n            <source dsn=\"./\">\n                <path>src/</path>\n            </source>\n            <output>api</output>\n            <ignore hidden=\"true\" symlinks=\"true\">\n                <path>tests/**/*</path>\n                <path>build/**/*</path>\n                <path>var/**/*</path>\n                <path>vendor/**/*</path>\n            </ignore>\n            <extensions>\n                <extension>php</extension>\n            </extensions>\n            <ignore-tags>\n                <ignore-tag>template</ignore-tag>\n                <ignore-tag>template-extends</ignore-tag>\n                <ignore-tag>template-implements</ignore-tag>\n                <ignore-tag>extends</ignore-tag>\n                <ignore-tag>implements</ignore-tag>\n            </ignore-tags>\n            <default-package-name>phpDocumentor</default-package-name>\n        </api>\n        <guide>\n            <source dsn=\".\">\n                <path>docs</path>\n            </source>\n            <output>guides</output>\n        </guide>\n    </version>\n    <setting name=\"guides.enabled\" value=\"true\"/>\n    <template name=\"default\" />\n</phpdocumentor>\n"
  },
  {
    "path": "phpmd.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<ruleset\n    name=\"ProxyManager rules\"\n    xmlns=\"http://pmd.sf.net/ruleset/1.0.0\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd\"\n    xsi:noNamespaceSchemaLocation=\"http://pmd.sf.net/ruleset_xml_schema.xsd\"\n>\n    <rule ref=\"rulesets/codesize.xml\"/>\n    <rule ref=\"rulesets/unusedcode.xml\"/>\n    <rule ref=\"rulesets/design.xml\">\n        <!-- eval is needed to generate runtime classes -->\n        <exclude name=\"EvalExpression\"/>\n    </rule>\n    <rule ref=\"rulesets/naming.xml\">\n        <exclude name=\"LongVariable\"/>\n    </rule>\n    <rule ref=\"rulesets/naming.xml/LongVariable\">\n        <properties>\n            <property name=\"minimum\">40</property>\n        </properties>\n    </rule>\n</ruleset>\n"
  },
  {
    "path": "phpstan-baseline.neon",
    "content": "parameters:\n\tignoreErrors:\n\t\t-\n\t\t\tmessage: \"#^Unused phpDocumentor\\\\\\\\Reflection\\\\\\\\DocBlock\\\\\\\\ExampleFinder\\\\:\\\\:getExampleDirectories$#\"\n\t\t\tcount: 1\n\t\t\tpath: src/DocBlock/ExampleFinder.php\n\n\t\t-\n\t\t\tmessage: \"#^Unused phpDocumentor\\\\\\\\Reflection\\\\\\\\DocBlock\\\\\\\\ExampleFinder\\\\:\\\\:setExampleDirectories$#\"\n\t\t\tcount: 1\n\t\t\tpath: src/DocBlock/ExampleFinder.php\n\n\t\t-\n\t\t\tmessage: \"#^Unused phpDocumentor\\\\\\\\Reflection\\\\\\\\DocBlock\\\\\\\\ExampleFinder\\\\:\\\\:setSourceDirectory$#\"\n\t\t\tcount: 1\n\t\t\tpath: src/DocBlock/ExampleFinder.php\n\n\t\t-\n\t\t\tmessage: \"#^Unused phpDocumentor\\\\\\\\Reflection\\\\\\\\DocBlock\\\\\\\\Tags\\\\\\\\Factory\\\\\\\\MethodParameterFactory\\\\:\\\\:formatNull$#\"\n\t\t\tcount: 1\n\t\t\tpath: src/DocBlock/Tags/Factory/MethodParameterFactory.php\n"
  },
  {
    "path": "phpstan.neon",
    "content": "includes:\n\t- phpstan-baseline.neon\n\nparameters:\n    level: max\n    ignoreErrors:\n        - '#Method phpDocumentor\\\\Reflection\\\\DocBlock\\\\StandardTagFactory::createTag\\(\\) should return phpDocumentor\\\\Reflection\\\\DocBlock\\\\Tag but returns mixed#'\n        - '#Offset 2 on array\\{string, 28, int\\} on left side of \\?\\? always exists and is not nullable\\.#'\n        -\n          path: src/DocBlockFactoryInterface.php\n          identifier: shipmonk.deadMethod\n        -\n          path: src/DocBlock/TagFactory.php\n          identifier: shipmonk.deadMethod\n    paths:\n        - src\n        - tests/unit\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"https://schema.phpunit.de/9.3/phpunit.xsd\" colors=\"true\" convertDeprecationsToExceptions=\"false\" beStrictAboutOutputDuringTests=\"false\" forceCoversAnnotation=\"true\" verbose=\"true\" bootstrap=\"vendor/autoload.php\">\n  <coverage>\n    <include>\n      <directory suffix=\".php\">./src/</directory>\n    </include>\n    <report>\n      <clover outputFile=\"build/logs/clover.xml\"/>\n      <html outputDirectory=\"build/coverage\" lowUpperBound=\"35\" highLowerBound=\"70\"/>\n    </report>\n  </coverage>\n  <testsuites>\n    <testsuite name=\"unit\">\n      <directory>./tests/unit</directory>\n    </testsuite>\n    <testsuite name=\"integration\">\n      <directory>./tests/integration</directory>\n    </testsuite>\n  </testsuites>\n  <logging/>\n  <listeners>\n    <listener class=\"Mockery\\Adapter\\Phpunit\\TestListener\" file=\"vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/TestListener.php\"/>\n  </listeners>\n</phpunit>\n"
  },
  {
    "path": "psalm.xml",
    "content": "<?xml version=\"1.0\"?>\n<psalm\n    errorLevel=\"2\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xmlns=\"https://getpsalm.org/schema/config\"\n    xsi:schemaLocation=\"https://getpsalm.org/schema/config file:///composer/vendor/vimeo/psalm/config.xsd\"\n>\n    <projectFiles>\n        <directory name=\"src\" />\n        <ignoreFiles>\n            <directory name=\"vendor\" />\n        </ignoreFiles>\n    </projectFiles>\n\n    <issueHandlers>\n        <RedundantConditionGivenDocblockType>\n            <errorLevel type=\"info\">\n                <!-- Psalm is very strict and believe that because we documented a type, it is redundant to assert it -->\n                <file name=\"src/DocBlock/StandardTagFactory.php\"/>\n            </errorLevel>\n        </RedundantConditionGivenDocblockType>\n\n        <PossiblyNullArrayOffset>\n            <errorLevel type=\"info\">\n                <!-- Psalm forbid accessing an array with a null offset but it's still working code without notice -->\n                <file name=\"src/DocBlock/StandardTagFactory.php\"/>\n            </errorLevel>\n        </PossiblyNullArrayOffset>\n\n        <DeprecatedInterface>\n            <errorLevel type=\"info\">\n                <!-- Will be removed in 6.0.0 issues/211 -->\n                <referencedClass name=\"phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod\"/>\n            </errorLevel>\n        </DeprecatedInterface>\n\n        <DeprecatedMethod>\n            <errorLevel type=\"info\">\n                <!-- Will be removed in 6.0.0 issues/361 -->\n                <referencedMethod name=\"phpDocumentor\\Reflection\\DocBlock\\Tags\\Param::create\"/>\n            </errorLevel>\n        </DeprecatedMethod>\n\n        <NoInterfaceProperties>\n            <errorLevel type=\"info\">\n                <file name=\"src/DocBlock/Tags/Factory/ParamFactory.php\"/>\n                <file name=\"src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php\"/>\n            </errorLevel>\n        </NoInterfaceProperties>\n\n        <TooManyArguments>\n            <errorLevel type=\"info\">\n                <file name=\"src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php\"/>\n            </errorLevel>\n        </TooManyArguments>\n\n        <RedundantConditionGivenDocblockType>\n            <errorLevel type=\"info\">\n                <!-- Psalm manage to infer a more precise type than PHPStan. notNull assert is needed for PHPStan but\n                Psalm sees it as redundant -->\n                <directory name=\"src/DocBlock/Tags/\"/>\n            </errorLevel>\n        </RedundantConditionGivenDocblockType>\n\n        <ArgumentTypeCoercion>\n            <errorLevel type=\"info\">\n                <!-- PHP handles invalid preg_split flags just fine. -->\n                <file name=\"src/Utils.php\"/>\n            </errorLevel>\n        </ArgumentTypeCoercion>\n\n        <InvalidArgument>\n            <errorLevel type=\"suppress\">\n                <referencedFunction name=\"PHPStan\\PhpDocParser\\Parser\\PhpDocParser::__construct\"/>\n                <referencedFunction name=\"PHPStan\\PhpDocParser\\Parser\\TypeParser::__construct\"/>\n            </errorLevel>\n        </InvalidArgument>\n    </issueHandlers>\n</psalm>\n"
  },
  {
    "path": "src/DocBlock/Description.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter;\n\nuse function vsprintf;\n\n/**\n * Object representing to description for a DocBlock.\n *\n * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine\n * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete\n * description text using the format that you would prefer.\n *\n * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is\n * thus recommended to use that to create a Description object, like this:\n *\n *     $description = $descriptionFactory->create('This is a {@see Description}', $context);\n *\n * The description factory will interpret the given body and create a body template and list of tags from them, and pass\n * that onto the constructor if this class.\n *\n * > The $context variable is a class of type {@see \\phpDocumentor\\Reflection\\Types\\Context} and contains the namespace\n * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial\n * > type names and FQSENs.\n *\n * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this:\n *\n *     $description = new Description(\n *         'This is a %1$s',\n *         [ new See(new Fqsen('\\phpDocumentor\\Reflection\\DocBlock\\Description')) ]\n *     );\n *\n * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object\n * is mainly responsible for rendering.\n *\n * @see DescriptionFactory to create a new Description.\n * @see Tags\\Formatter for the formatting of the body and tags.\n */\nclass Description\n{\n    private string $bodyTemplate;\n\n    /** @var Tag[] */\n    private array $tags;\n\n    /**\n     * Initializes a Description with its body (template) and a listing of the tags used in the body template.\n     *\n     * @param Tag[] $tags\n     */\n    public function __construct(string $bodyTemplate, array $tags = [])\n    {\n        $this->bodyTemplate = $bodyTemplate;\n        $this->tags         = $tags;\n    }\n\n    /**\n     * Returns the body template.\n     */\n    public function getBodyTemplate(): string\n    {\n        return $this->bodyTemplate;\n    }\n\n    /**\n     * Returns the tags for this DocBlock.\n     *\n     * @return Tag[]\n     */\n    public function getTags(): array\n    {\n        return $this->tags;\n    }\n\n    /**\n     * Renders this description as a string where the provided formatter will format the tags in the expected string\n     * format.\n     */\n    public function render(?Formatter $formatter = null): string\n    {\n        if ($this->tags === []) {\n            return vsprintf($this->bodyTemplate, []);\n        }\n\n        if ($formatter === null) {\n            $formatter = new PassthroughFormatter();\n        }\n\n        $tags = [];\n        foreach ($this->tags as $tag) {\n            $tags[] = '{' . $formatter->format($tag) . '}';\n        }\n\n        return vsprintf($this->bodyTemplate, $tags);\n    }\n\n    /**\n     * Returns a plain string representation of this description.\n     */\n    public function __toString(): string\n    {\n        return $this->render();\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/DescriptionFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\Factory;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse phpDocumentor\\Reflection\\Utils;\n\nuse function count;\nuse function implode;\nuse function ltrim;\nuse function min;\nuse function str_replace;\nuse function strlen;\nuse function strpos;\nuse function substr;\nuse function trim;\n\nuse const PREG_SPLIT_DELIM_CAPTURE;\n\n/**\n * Creates a new Description object given a body of text.\n *\n * Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their\n * body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the\n * Description object's `render` method.\n *\n * In addition to the above does a Description support two types of escape sequences:\n *\n * 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}`\n * 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description\n *    of an inline tag.\n *\n * If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning\n * of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping\n * over unexpected spaces as can be observed with tag descriptions.\n */\nclass DescriptionFactory\n{\n    private Factory $tagFactory;\n\n    /**\n     * Initializes this factory with the means to construct (inline) tags.\n     */\n    public function __construct(Factory $tagFactory)\n    {\n        $this->tagFactory = $tagFactory;\n    }\n\n    /**\n     * Returns the parsed text of this description.\n     */\n    public function create(string $contents, ?TypeContext $context = null): Description\n    {\n        $tokens   = $this->lex($contents);\n        $count    = count($tokens);\n        $tagCount = 0;\n        $tags     = [];\n\n        for ($i = 1; $i < $count; $i += 2) {\n            $tags[]     = $this->tagFactory->create($tokens[$i], $context);\n            $tokens[$i] = '%' . ++$tagCount . '$s';\n        }\n\n        //In order to allow \"literal\" inline tags, the otherwise invalid\n        //sequence \"{@}\" is changed to \"@\", and \"{}\" is changed to \"}\".\n        //\"%\" is escaped to \"%%\" because of vsprintf.\n        //See unit tests for examples.\n        for ($i = 0; $i < $count; $i += 2) {\n            $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);\n        }\n\n        return new Description(implode('', $tokens), $tags);\n    }\n\n    /**\n     * Strips the contents from superfluous whitespace and splits the description into a series of tokens.\n     *\n     * @return string[] A series of tokens of which the description text is composed.\n     */\n    private function lex(string $contents): array\n    {\n        $contents = $this->removeSuperfluousStartingWhitespace($contents);\n\n        // performance optimalization; if there is no inline tag, don't bother splitting it up.\n        if (strpos($contents, '{@') === false) {\n            return [$contents];\n        }\n\n        return Utils::pregSplit(\n            '/\\{\n                # \"{@}\" and \"{@*}\" are not a valid inline tags. This ensures that we do not treat them as one, but treat\n                # them literally.\n                (?!(?:@\\}|@\\*\\}) )\n                # We want to capture the whole tag line, but without the inline tag delimiters.\n                (\\@\n                    # Match everything up to the next delimiter.\n                    [^{}]*\n                    # Nested inline tag content should not be captured, or it will appear in the result separately.\n                    (?:\n                        # Match nested inline tags.\n                        (?:\n                            # Because we did not catch the tag delimiters earlier, we must be explicit with them here.\n                            # Notice that this also matches \"{}\", as a way to later introduce it as an escape sequence.\n                            \\{(?1)?\\}\n                            |\n                            # Make sure we match hanging \"{\".\n                            \\{\n                        )\n                        # Match content after the nested inline tag.\n                        [^{}]*\n                    )* # If there are more inline tags, match them as well. We use \"*\" since there may not be any\n                       # nested inline tags.\n                )\n            \\}/Sux',\n            $contents,\n            0,\n            PREG_SPLIT_DELIM_CAPTURE\n        );\n    }\n\n    /**\n     * Removes the superfluous from a multi-line description.\n     *\n     * When a description has more than one line then it can happen that the second and subsequent lines have an\n     * additional indentation. This is commonly in use with tags like this:\n     *\n     *     {@}since 1.1.0 This is an example\n     *         description where we have an\n     *         indentation in the second and\n     *         subsequent lines.\n     *\n     * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent\n     * lines and this may cause rendering issues when, for example, using a Markdown converter.\n     */\n    private function removeSuperfluousStartingWhitespace(string $contents): string\n    {\n        $lines = Utils::pregSplit(\"/\\r\\n?|\\n/\", $contents);\n\n        // if there is only one line then we don't have lines with superfluous whitespace and\n        // can use the contents as-is\n        if (count($lines) <= 1) {\n            return $contents;\n        }\n\n        // determine how many whitespace characters need to be stripped\n        $startingSpaceCount = 9999999;\n        for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) {\n            // lines with a no length do not count as they are not indented at all\n            if (trim($lines[$i]) === '') {\n                continue;\n            }\n\n            // determine the number of prefixing spaces by checking the difference in line length before and after\n            // an ltrim\n            $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i])));\n        }\n\n        // strip the number of spaces from each line\n        if ($startingSpaceCount > 0) {\n            for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) {\n                $lines[$i] = substr($lines[$i], $startingSpaceCount);\n            }\n        }\n\n        return implode(\"\\n\", $lines);\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/ExampleFinder.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Example;\n\nuse function array_slice;\nuse function file;\nuse function getcwd;\nuse function implode;\nuse function is_readable;\nuse function rtrim;\nuse function sprintf;\nuse function trim;\n\nuse const DIRECTORY_SEPARATOR;\n\n/**\n * Class used to find an example file's location based on a given ExampleDescriptor.\n */\nclass ExampleFinder\n{\n    private string $sourceDirectory = '';\n\n    /** @var string[] */\n    private array $exampleDirectories = [];\n\n    /**\n     * Attempts to find the example contents for the given descriptor.\n     */\n    public function find(Example $example): string\n    {\n        $filename = $example->getFilePath();\n\n        $file = $this->getExampleFileContents($filename);\n        if ($file === null) {\n            return sprintf('** File not found : %s **', $filename);\n        }\n\n        return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount()));\n    }\n\n    /**\n     * Registers the project's root directory where an 'examples' folder can be expected.\n     */\n    public function setSourceDirectory(string $directory = ''): void\n    {\n        $this->sourceDirectory = $directory;\n    }\n\n    /**\n     * Returns the project's root directory where an 'examples' folder can be expected.\n     */\n    public function getSourceDirectory(): string\n    {\n        return $this->sourceDirectory;\n    }\n\n    /**\n     * Registers a series of directories that may contain examples.\n     *\n     * @param string[] $directories\n     */\n    public function setExampleDirectories(array $directories): void\n    {\n        $this->exampleDirectories = $directories;\n    }\n\n    /**\n     * Returns a series of directories that may contain examples.\n     *\n     * @return string[]\n     */\n    public function getExampleDirectories(): array\n    {\n        return $this->exampleDirectories;\n    }\n\n    /**\n     * Attempts to find the requested example file and returns its contents or null if no file was found.\n     *\n     * This method will try several methods in search of the given example file, the first one it encounters is\n     * returned:\n     *\n     * 1. Iterates through all examples folders for the given filename\n     * 2. Checks the source folder for the given filename\n     * 3. Checks the 'examples' folder in the current working directory for examples\n     * 4. Checks the path relative to the current working directory for the given filename\n     *\n     * @return string[] all lines of the example file\n     */\n    private function getExampleFileContents(string $filename): ?array\n    {\n        $normalizedPath = null;\n\n        foreach ($this->exampleDirectories as $directory) {\n            $exampleFileFromConfig = $this->constructExamplePath($directory, $filename);\n            if (is_readable($exampleFileFromConfig)) {\n                $normalizedPath = $exampleFileFromConfig;\n                break;\n            }\n        }\n\n        if ($normalizedPath === null) {\n            if (is_readable($this->getExamplePathFromSource($filename))) {\n                $normalizedPath = $this->getExamplePathFromSource($filename);\n            } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) {\n                $normalizedPath = $this->getExamplePathFromExampleDirectory($filename);\n            } elseif (is_readable($filename)) {\n                $normalizedPath = $filename;\n            }\n        }\n\n        $lines = $normalizedPath !== null && is_readable($normalizedPath) ? file($normalizedPath) : false;\n\n        return $lines !== false ? $lines : null;\n    }\n\n    /**\n     * Get example filepath based on the example directory inside your project.\n     */\n    private function getExamplePathFromExampleDirectory(string $file): string\n    {\n        return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file;\n    }\n\n    /**\n     * Returns a path to the example file in the given directory..\n     */\n    private function constructExamplePath(string $directory, string $file): string\n    {\n        return rtrim($directory, '\\\\/') . DIRECTORY_SEPARATOR . $file;\n    }\n\n    /**\n     * Get example filepath based on sourcecode.\n     */\n    private function getExamplePathFromSource(string $file): string\n    {\n        return sprintf(\n            '%s%s%s',\n            trim($this->getSourceDirectory(), '\\\\/'),\n            DIRECTORY_SEPARATOR,\n            trim($file, '\"')\n        );\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Serializer.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse phpDocumentor\\Reflection\\DocBlock;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter;\n\nuse function sprintf;\nuse function str_repeat;\nuse function str_replace;\nuse function strlen;\nuse function wordwrap;\n\n/**\n * Converts a DocBlock back from an object to a complete DocComment including Asterisks.\n */\nclass Serializer\n{\n    /** @var string The string to indent the comment with. */\n    protected string $indentString = ' ';\n\n    /** @var int The number of times the indent string is repeated. */\n    protected int $indent = 0;\n\n    /** @var bool Whether to indent the first line with the given indent amount and string. */\n    protected bool $isFirstLineIndented = true;\n\n    /** @var int|null The max length of a line. */\n    protected ?int $lineLength = null;\n\n    /** @var Formatter A custom tag formatter. */\n    protected Formatter $tagFormatter;\n    private string $lineEnding;\n\n    /**\n     * Create a Serializer instance.\n     *\n     * @param int       $indent          The number of times the indent string is repeated.\n     * @param string    $indentString    The string to indent the comment with.\n     * @param bool      $indentFirstLine Whether to indent the first line.\n     * @param int|null  $lineLength      The max length of a line or NULL to disable line wrapping.\n     * @param Formatter $tagFormatter    A custom tag formatter, defaults to PassthroughFormatter.\n     * @param string    $lineEnding      Line ending used in the output, by default \\n is used.\n     */\n    public function __construct(\n        int $indent = 0,\n        string $indentString = ' ',\n        bool $indentFirstLine = true,\n        ?int $lineLength = null,\n        ?Formatter $tagFormatter = null,\n        string $lineEnding = \"\\n\"\n    ) {\n        $this->indent              = $indent;\n        $this->indentString        = $indentString;\n        $this->isFirstLineIndented = $indentFirstLine;\n        $this->lineLength          = $lineLength;\n        $this->tagFormatter        = $tagFormatter ?: new PassthroughFormatter();\n        $this->lineEnding = $lineEnding;\n    }\n\n    /**\n     * Generate a DocBlock comment.\n     *\n     * @param DocBlock $docblock The DocBlock to serialize.\n     *\n     * @return string The serialized doc block.\n     */\n    public function getDocComment(DocBlock $docblock): string\n    {\n        $indent      = str_repeat($this->indentString, $this->indent);\n        $firstIndent = $this->isFirstLineIndented ? $indent : '';\n        // 3 === strlen(' * ')\n        $wrapLength = $this->lineLength !== null ? $this->lineLength - strlen($indent) - 3 : null;\n\n        $text = $this->removeTrailingSpaces(\n            $indent,\n            $this->addAsterisksForEachLine(\n                $indent,\n                $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength)\n            )\n        );\n\n        $comment = $firstIndent . \"/**\\n\";\n        if ($text) {\n            $comment .= $indent . ' * ' . $text . \"\\n\";\n            $comment .= $indent . \" *\\n\";\n        }\n\n        $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment);\n\n        return str_replace(\"\\n\", $this->lineEnding, $comment . $indent . ' */');\n    }\n\n    private function removeTrailingSpaces(string $indent, string $text): string\n    {\n        return str_replace(\n            sprintf(\"\\n%s * \\n\", $indent),\n            sprintf(\"\\n%s *\\n\", $indent),\n            $text\n        );\n    }\n\n    private function addAsterisksForEachLine(string $indent, string $text): string\n    {\n        return str_replace(\n            \"\\n\",\n            sprintf(\"\\n%s * \", $indent),\n            $text\n        );\n    }\n\n    private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, ?int $wrapLength): string\n    {\n        $text = $docblock->getSummary() . ((string) $docblock->getDescription() ? \"\\n\\n\" . $docblock->getDescription()\n                : '');\n        if ($wrapLength !== null) {\n            $text = wordwrap($text, $wrapLength);\n\n            return $text;\n        }\n\n        return $text;\n    }\n\n    private function addTagBlock(DocBlock $docblock, ?int $wrapLength, string $indent, string $comment): string\n    {\n        foreach ($docblock->getTags() as $tag) {\n            $tagText = $this->tagFormatter->format($tag);\n            if ($wrapLength !== null) {\n                $tagText = wordwrap($tagText, $wrapLength);\n            }\n\n            $tagText = str_replace(\n                \"\\n\",\n                sprintf(\"\\n%s * \", $indent),\n                $tagText\n            );\n\n            $comment .= sprintf(\"%s * %s\\n\", $indent, $tagText);\n        }\n\n        return $comment;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/StandardTagFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse InvalidArgumentException;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Author;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\AbstractPHPStanFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ExtendsFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\Factory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ImplementsFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MixinFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ParamFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyReadFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyWriteFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ReturnFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateCovariantFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ThrowsFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\VarFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Link as LinkTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\See as SeeTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Since;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Source;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Version;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse ReflectionMethod;\nuse ReflectionNamedType;\nuse ReflectionParameter;\nuse Webmozart\\Assert\\Assert;\n\nuse function array_key_exists;\nuse function array_merge;\nuse function array_slice;\nuse function call_user_func_array;\nuse function get_class;\nuse function is_object;\nuse function preg_match;\nuse function sprintf;\nuse function strpos;\nuse function trim;\n\n/**\n * Creates a Tag object given the contents of a tag.\n *\n * This Factory is capable of determining the appropriate class for a tag and instantiate it using its `create`\n * factory method. The `create` factory method of a Tag can have a variable number of arguments; this way you can\n * pass the dependencies that you need to construct a tag object.\n *\n * > Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise\n * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to\n * > verify that a dependency is actually passed.\n *\n * This Factory also features a Service Locator component that is used to pass the right dependencies to the\n * `create` method of a tag; each dependency should be registered as a service or as a parameter.\n *\n * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass\n * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface.\n */\nfinal class StandardTagFactory implements TagFactory\n{\n    /** PCRE regular expression matching a tag name. */\n    public const REGEX_TAGNAME = '[\\w\\-\\_\\\\\\\\:]+';\n\n    /**\n     * @var array<string, class-string<Tag>|Tag|Factory> An array with a tag as a key, and an\n     *                               FQCN to a class that handles it as an array value.\n     */\n    private array $tagHandlerMappings = [\n        'author'             => Author::class,\n        'covers'             => Covers::class,\n        'deprecated'         => Deprecated::class,\n        'link'               => LinkTag::class,\n        'see'                => SeeTag::class,\n        'since'              => Since::class,\n        'source'             => Source::class,\n        'uses'               => Uses::class,\n        'version'            => Version::class,\n    ];\n\n    /**\n     * @var array<class-string<Tag>> An array with an annotation as a key, and an\n     *      FQCN to a class that handles it as an array value.\n     */\n    private array $annotationMappings = [];\n\n    /**\n     * @var ReflectionParameter[][] a lazy-loading cache containing parameters\n     *      for each tagHandler that has been used.\n     */\n    private array $tagHandlerParameterCache = [];\n\n    private FqsenResolver $fqsenResolver;\n\n    /**\n     * @var mixed[] an array representing a simple Service Locator where we can store parameters and\n     *     services that can be inserted into the Factory Methods of Tag Handlers.\n     */\n    private array $serviceLocator = [];\n\n    private function __construct(FqsenResolver $fqsenResolver)\n    {\n        $this->fqsenResolver = $fqsenResolver;\n\n        $this->addService($fqsenResolver, FqsenResolver::class);\n    }\n\n    /**\n     * Initialize this tag factory with the means to resolve an FQSEN.\n     *\n     * @see self::registerTagHandler() to add a new tag handler to the existing default list.\n     */\n    public static function createInstance(FqsenResolver $fqsenResolver): self\n    {\n        $tagFactory = new self($fqsenResolver);\n        $descriptionFactory = new DescriptionFactory($tagFactory);\n\n        $typeResolver = new TypeResolver($fqsenResolver);\n\n        $phpstanTagFactory = new AbstractPHPStanFactory(\n            new ParamFactory($typeResolver, $descriptionFactory),\n            new VarFactory($typeResolver, $descriptionFactory),\n            new ReturnFactory($typeResolver, $descriptionFactory),\n            new PropertyFactory($typeResolver, $descriptionFactory),\n            new PropertyReadFactory($typeResolver, $descriptionFactory),\n            new PropertyWriteFactory($typeResolver, $descriptionFactory),\n            new MethodFactory($typeResolver, $descriptionFactory),\n            new MixinFactory($typeResolver, $descriptionFactory),\n            new ImplementsFactory($typeResolver, $descriptionFactory),\n            new ExtendsFactory($typeResolver, $descriptionFactory),\n            new TemplateFactory($typeResolver, $descriptionFactory),\n            new TemplateCovariantFactory($typeResolver, $descriptionFactory),\n            new ThrowsFactory($typeResolver, $descriptionFactory),\n        );\n\n        $tagFactory->addService($descriptionFactory);\n        $tagFactory->addService($typeResolver);\n        $tagFactory->registerTagHandler('param', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('var', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('return', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('property', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('property-read', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('property-write', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('method', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('mixin', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('extends', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('implements', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('template', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('template-covariant', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('template-extends', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('template-implements', $phpstanTagFactory);\n        $tagFactory->registerTagHandler('throws', $phpstanTagFactory);\n\n        return $tagFactory;\n    }\n\n    public function create(string $tagLine, ?TypeContext $context = null): Tag\n    {\n        if (!$context) {\n            $context = new TypeContext('');\n        }\n\n        [$tagName, $tagBody] = $this->extractTagParts($tagLine);\n\n        return $this->createTag(trim($tagBody), $tagName, $context);\n    }\n\n    /**\n     * @param mixed $value\n     */\n    public function addParameter(string $name, $value): void\n    {\n        $this->serviceLocator[$name] = $value;\n    }\n\n    public function addService(object $service, ?string $alias = null): void\n    {\n        $this->serviceLocator[$alias ?? get_class($service)] = $service;\n    }\n\n    /** {@inheritDoc} */\n    public function registerTagHandler(string $tagName, $handler): void\n    {\n        Assert::stringNotEmpty($tagName);\n        if (strpos($tagName, '\\\\') !== false && $tagName[0] !== '\\\\') {\n            throw new InvalidArgumentException(\n                'A namespaced tag must have a leading backslash as it must be fully qualified'\n            );\n        }\n\n        if (is_object($handler)) {\n            Assert::isInstanceOf($handler, Factory::class);\n            $this->tagHandlerMappings[$tagName] = $handler;\n\n            return;\n        }\n\n        Assert::classExists($handler);\n        Assert::implementsInterface($handler, Tag::class);\n        $this->tagHandlerMappings[$tagName] = $handler;\n    }\n\n    /**\n     * Extracts all components for a tag.\n     *\n     * @return string[]\n     */\n    private function extractTagParts(string $tagLine): array\n    {\n        $matches = [];\n        if (!preg_match('/^@(' . self::REGEX_TAGNAME . ')((?:[\\s\\(\\{])\\s*([^\\s].*)|$)/us', $tagLine, $matches)) {\n            throw new InvalidArgumentException(\n                'The tag \"' . $tagLine . '\" does not seem to be wellformed, please check it for errors'\n            );\n        }\n\n        return array_slice($matches, 1);\n    }\n\n    /**\n     * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the\n     * body was invalid.\n     */\n    private function createTag(string $body, string $name, TypeContext $context): Tag\n    {\n        $handlerClassName = $this->findHandlerClassName($name, $context);\n        $arguments        = $this->getArgumentsForParametersFromWiring(\n            $this->fetchParametersForHandlerFactoryMethod($handlerClassName),\n            $this->getServiceLocatorWithDynamicParameters($context, $name, $body)\n        );\n\n        if (array_key_exists('tagLine', $arguments)) {\n            $arguments['tagLine'] = sprintf('@%s %s', $name, $body);\n        }\n\n        try {\n            $callable = [$handlerClassName, 'create'];\n            Assert::isCallable($callable);\n            /** @phpstan-var callable(string): ?Tag $callable */\n            $tag = call_user_func_array($callable, $arguments);\n\n            return $tag ?? InvalidTag::create($body, $name);\n        } catch (InvalidArgumentException $e) {\n            return InvalidTag::create($body, $name)->withError($e);\n        }\n    }\n\n    /**\n     * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).\n     *\n     * @return class-string<Tag>|Tag|Factory\n     */\n    private function findHandlerClassName(string $tagName, TypeContext $context)\n    {\n        $handlerClassName = Generic::class;\n        if (isset($this->tagHandlerMappings[$tagName])) {\n            $handlerClassName = $this->tagHandlerMappings[$tagName];\n        } elseif ($this->isAnnotation($tagName)) {\n            // TODO: Annotation support is planned for a later stage and as such is disabled for now\n            $tagName = (string) $this->fqsenResolver->resolve($tagName, $context);\n            if (isset($this->annotationMappings[$tagName])) {\n                $handlerClassName = $this->annotationMappings[$tagName];\n            }\n        }\n\n        return $handlerClassName;\n    }\n\n    /**\n     * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters.\n     *\n     * @param ReflectionParameter[] $parameters\n     * @param mixed[]               $locator\n     *\n     * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters\n     *     is provided with this method.\n     */\n    private function getArgumentsForParametersFromWiring(array $parameters, array $locator): array\n    {\n        $arguments = [];\n        foreach ($parameters as $parameter) {\n            $type     = $parameter->getType();\n            $typeHint = null;\n            if ($type instanceof ReflectionNamedType) {\n                $typeHint = $type->getName();\n                if ($typeHint === 'self') {\n                    $declaringClass = $parameter->getDeclaringClass();\n                    if ($declaringClass !== null) {\n                        $typeHint = $declaringClass->getName();\n                    }\n                }\n            }\n\n            $parameterName = $parameter->getName();\n            if (isset($locator[$typeHint ?? ''])) {\n                $arguments[$parameterName] = $locator[$typeHint ?? ''];\n                continue;\n            }\n\n            if (isset($locator[$parameterName])) {\n                $arguments[$parameterName] = $locator[$parameterName];\n                continue;\n            }\n\n            $arguments[$parameterName] = null;\n        }\n\n        return $arguments;\n    }\n\n    /**\n     * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given\n     * tag handler class name.\n     *\n     * @param class-string<Tag>|Tag|Factory $handler\n     *\n     * @return ReflectionParameter[]\n     */\n    private function fetchParametersForHandlerFactoryMethod($handler): array\n    {\n        $handlerClassName = is_object($handler) ? get_class($handler) : $handler;\n\n        if (!isset($this->tagHandlerParameterCache[$handlerClassName])) {\n            $methodReflection                                  = new ReflectionMethod($handlerClassName, 'create');\n            $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters();\n        }\n\n        return $this->tagHandlerParameterCache[$handlerClassName];\n    }\n\n    /**\n     * Returns a copy of this class' Service Locator with added dynamic parameters,\n     * such as the tag's name, body and Context.\n     *\n     * @param TypeContext $context The Context (namespace and aliases) that may be\n     *  passed and is used to resolve FQSENs.\n     * @param string      $tagName The name of the tag that may be\n     *  passed onto the factory method of the Tag class.\n     * @param string      $tagBody The body of the tag that may be\n     *  passed onto the factory method of the Tag class.\n     *\n     * @return mixed[]\n     */\n    private function getServiceLocatorWithDynamicParameters(\n        TypeContext $context,\n        string $tagName,\n        string $tagBody\n    ): array {\n        return array_merge(\n            $this->serviceLocator,\n            [\n                'name' => $tagName,\n                'body' => $tagBody,\n                TypeContext::class => $context,\n            ]\n        );\n    }\n\n    /**\n     * Returns whether the given tag belongs to an annotation.\n     *\n     * @todo this method should be populated once we implement Annotation notation support.\n     */\n    private function isAnnotation(string $tagContent): bool\n    {\n        // 1. Contains a namespace separator\n        // 2. Contains parenthesis\n        // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part\n        //    of the annotation class name matches the found tag name\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tag.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\n\ninterface Tag\n{\n    public function getName(): string;\n\n    /**\n     * @return Tag|mixed Class that implements Tag\n     * @phpstan-return ?Tag\n     */\n    public static function create(string $body);\n\n    public function render(?Formatter $formatter = null): string;\n\n    public function __toString(): string;\n}\n"
  },
  {
    "path": "src/DocBlock/TagFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse InvalidArgumentException;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\Factory;\n\ninterface TagFactory extends Factory\n{\n    /**\n     * Adds a parameter to the service locator that can be injected in a tag's factory method.\n     *\n     * When calling a tag's \"create\" method we always check the signature for dependencies to inject. One way is to\n     * typehint a parameter in the signature so that we can use that interface or class name to inject a dependency\n     * (see {@see addService()} for more information on that).\n     *\n     * Another way is to check the name of the argument against the names in the Service Locator. With this method\n     * you can add a variable that will be inserted when a tag's create method is not typehinted and has a matching\n     * name.\n     *\n     * Be aware that there are two reserved names:\n     *\n     * - name, representing the name of the tag.\n     * - body, representing the complete body of the tag.\n     *\n     * These parameters are injected at the last moment and will override any existing parameter with those names.\n     *\n     * @param mixed $value\n     */\n    public function addParameter(string $name, $value): void;\n\n    /**\n     * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided.\n     *\n     * When calling a tag's \"create\" method we always check the signature for dependencies to inject. If a parameter\n     * has a typehint then the ServiceLocator is queried to see if a Service is registered for that typehint.\n     *\n     * Because interfaces are regularly used as type-hints this method provides an alias parameter; if the FQCN of the\n     * interface is passed as alias then every time that interface is requested the provided service will be returned.\n     */\n    public function addService(object $service): void;\n\n    /**\n     * Registers a handler for tags.\n     *\n     * If you want to use your own tags then you can use this method to instruct the TagFactory\n     * to register the name of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement\n     * the {@see Tag} interface (and thus the create method).\n     *\n     * @param string                    $tagName Name of tag to register a handler for. When registering a namespaced\n     *                                   tag, the full name, along with a prefixing slash MUST be provided.\n     * @param class-string<Tag>|Factory $handler FQCN of handler.\n     *\n     * @throws InvalidArgumentException If the tag name is not a string.\n     * @throws InvalidArgumentException If the tag name is namespaced (contains backslashes) but\n     *                                   does not start with a backslash.\n     * @throws InvalidArgumentException If the handler is not a string.\n     * @throws InvalidArgumentException If the handler is not an existing class.\n     * @throws InvalidArgumentException If the handler does not implement the {@see Tag} interface.\n     */\n    public function registerTagHandler(string $tagName, $handler): void;\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Author.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse InvalidArgumentException;\n\nuse function filter_var;\nuse function preg_match;\nuse function trim;\n\nuse const FILTER_VALIDATE_EMAIL;\n\n/**\n * Reflection class for an {@}author tag in a Docblock.\n */\nfinal class Author extends BaseTag\n{\n    /** @var string register that this is the author tag. */\n    protected string $name = 'author';\n\n    /** @var string The name of the author */\n    private string $authorName;\n\n    /** @var string The email of the author */\n    private string $authorEmail;\n\n    /**\n     * Initializes this tag with the author name and e-mail.\n     */\n    public function __construct(string $authorName, string $authorEmail)\n    {\n        if ($authorEmail && !filter_var($authorEmail, FILTER_VALIDATE_EMAIL)) {\n            throw new InvalidArgumentException('The author tag does not have a valid e-mail address');\n        }\n\n        $this->authorName  = $authorName;\n        $this->authorEmail = $authorEmail;\n    }\n\n    /**\n     * Gets the author's name.\n     *\n     * @return string The author's name.\n     */\n    public function getAuthorName(): string\n    {\n        return $this->authorName;\n    }\n\n    /**\n     * Returns the author's email.\n     *\n     * @return string The author's email.\n     */\n    public function getEmail(): string\n    {\n        return $this->authorEmail;\n    }\n\n    /**\n     * Returns this tag in string form.\n     */\n    public function __toString(): string\n    {\n        if ($this->authorEmail) {\n            $authorEmail = '<' . $this->authorEmail . '>';\n        } else {\n            $authorEmail = '';\n        }\n\n        $authorName = $this->authorName;\n\n        return $authorName . ($authorEmail !== '' ? ($authorName !== '' ? ' ' : '') . $authorEmail : '');\n    }\n\n    /**\n     * Attempts to create a new Author object based on the tag body.\n     */\n    public static function create(string $body): ?self\n    {\n        $splitTagContent = preg_match('/^([^\\<]*)(?:\\<([^\\>]*)\\>)?$/u', $body, $matches);\n        if (!$splitTagContent) {\n            return null;\n        }\n\n        $authorName = trim($matches[1]);\n        $email      = isset($matches[2]) ? trim($matches[2]) : '';\n\n        return new static($authorName, $email);\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/BaseTag.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\n\n/**\n * Parses a tag definition for a DocBlock.\n */\nabstract class BaseTag implements DocBlock\\Tag\n{\n    /** @var string Name of the tag */\n    protected string $name = '';\n\n    /** @var Description|null Description of the tag. */\n    protected ?Description $description = null;\n\n    /**\n     * Gets the name of this tag.\n     *\n     * @return string The name of this tag.\n     */\n    public function getName(): string\n    {\n        return $this->name;\n    }\n\n    public function getDescription(): ?Description\n    {\n        return $this->description;\n    }\n\n    public function render(?Formatter $formatter = null): string\n    {\n        if ($formatter === null) {\n            $formatter = new Formatter\\PassthroughFormatter();\n        }\n\n        return $formatter->format($this);\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Covers.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse phpDocumentor\\Reflection\\Utils;\nuse Webmozart\\Assert\\Assert;\n\nuse function array_key_exists;\nuse function explode;\n\n/**\n * Reflection class for a @covers tag in a Docblock.\n */\nfinal class Covers extends BaseTag\n{\n    protected string $name = 'covers';\n\n    private Fqsen $refers;\n\n    /**\n     * Initializes this tag.\n     */\n    public function __construct(Fqsen $refers, ?Description $description = null)\n    {\n        $this->refers      = $refers;\n        $this->description = $description;\n    }\n\n    public static function create(\n        string $body,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?FqsenResolver $resolver = null,\n        ?TypeContext $context = null\n    ): self {\n        Assert::stringNotEmpty($body);\n        Assert::notNull($descriptionFactory);\n        Assert::notNull($resolver);\n\n        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);\n\n        return new static(\n            self::resolveFqsen($parts[0], $resolver, $context),\n            $descriptionFactory->create($parts[1] ?? '', $context)\n        );\n    }\n\n    private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context): Fqsen\n    {\n        Assert::notNull($fqsenResolver);\n        $fqsenParts = explode('::', $parts);\n        $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);\n\n        if (!array_key_exists(1, $fqsenParts)) {\n            return $resolved;\n        }\n\n        return new Fqsen($resolved . '::' . $fqsenParts[1]);\n    }\n\n    /**\n     * Returns the structural element this tag refers to.\n     */\n    public function getReference(): Fqsen\n    {\n        return $this->refers;\n    }\n\n    /**\n     * Returns a string representation of this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $refers = (string) $this->refers;\n\n        return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Deprecated.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse Webmozart\\Assert\\Assert;\n\nuse function preg_match;\n\n/**\n * Reflection class for a {@}deprecated tag in a Docblock.\n */\nfinal class Deprecated extends BaseTag\n{\n    protected string $name = 'deprecated';\n\n    /**\n     * PCRE regular expression matching a version vector.\n     * Assumes the \"x\" modifier.\n     */\n    public const REGEX_VECTOR = '(?:\n        # Normal release vectors.\n        \\d\\S*\n        |\n        # VCS version vectors. Per PHPCS, they are expected to\n        # follow the form of the VCS name, followed by \":\", followed\n        # by the version vector itself.\n        # By convention, popular VCSes like CVS, SVN and GIT use \"$\"\n        # around the actual version vector.\n        [^\\s\\:]+\\:\\s*\\$[^\\$]+\\$\n    )';\n\n    /** @var string|null The version vector. */\n    private ?string $version = null;\n\n    public function __construct(?string $version = null, ?Description $description = null)\n    {\n        Assert::nullOrNotEmpty($version);\n\n        $this->version     = $version;\n        $this->description = $description;\n    }\n\n    /**\n     * @return static\n     */\n    public static function create(\n        ?string $body,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): self {\n        if ($body === null || $body === '') {\n            return new static();\n        }\n\n        $matches = [];\n        if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {\n            return new static(\n                null,\n                $descriptionFactory !== null ? $descriptionFactory->create($body, $context) : null\n            );\n        }\n\n        Assert::notNull($descriptionFactory);\n\n        return new static(\n            $matches[1],\n            $descriptionFactory->create($matches[2] ?? '', $context)\n        );\n    }\n\n    /**\n     * Gets the version section of the tag.\n     */\n    public function getVersion(): ?string\n    {\n        return $this->version;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $version = (string) $this->version;\n\n        return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Example.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse Webmozart\\Assert\\Assert;\n\nuse function array_key_exists;\nuse function preg_match;\nuse function rawurlencode;\nuse function str_replace;\nuse function strpos;\nuse function trim;\n\n/**\n * Reflection class for a {@}example tag in a Docblock.\n */\nfinal class Example implements Tag\n{\n    /** @var string Path to a file to use as an example. May also be an absolute URI. */\n    private string $filePath;\n\n    /**\n     * @var bool Whether the file path component represents an URI. This determines how the file portion\n     *     appears at {@link getContent()}.\n     */\n    private bool $isURI;\n\n    private int $startingLine;\n\n    private int $lineCount;\n\n    private ?string $content = null;\n\n    public function __construct(\n        string $filePath,\n        bool $isURI,\n        int $startingLine,\n        int $lineCount,\n        ?string $content\n    ) {\n        Assert::stringNotEmpty($filePath);\n        Assert::greaterThanEq($startingLine, 1);\n        Assert::greaterThanEq($lineCount, 0);\n\n        $this->filePath     = $filePath;\n        $this->startingLine = $startingLine;\n        $this->lineCount    = $lineCount;\n        if ($content !== null) {\n            $this->content = trim($content);\n        }\n\n        $this->isURI = $isURI;\n    }\n\n    public function getContent(): string\n    {\n        if ($this->content === null || $this->content === '') {\n            $filePath = $this->filePath;\n            if ($this->isURI) {\n                $filePath = $this->isUriRelative($this->filePath)\n                    ? str_replace('%2F', '/', rawurlencode($this->filePath))\n                    : $this->filePath;\n            }\n\n            return trim($filePath);\n        }\n\n        return $this->content;\n    }\n\n    public function getDescription(): ?string\n    {\n        return $this->content;\n    }\n\n    public static function create(string $body): ?Tag\n    {\n        // File component: File path in quotes or File URI / Source information\n        if (!preg_match('/^\\s*(?:(\\\"[^\\\"]+\\\")|(\\S+))(?:\\s+(.*))?$/sux', $body, $matches)) {\n            return null;\n        }\n\n        $filePath = null;\n        $fileUri  = null;\n        if (array_key_exists(1, $matches) && $matches[1] !== '') {\n            $filePath = $matches[1];\n        } else {\n            $fileUri = array_key_exists(2, $matches) ? $matches[2] : '';\n        }\n\n        $startingLine = 1;\n        $lineCount    = 0;\n        $description  = null;\n\n        if (array_key_exists(3, $matches)) {\n            $description = $matches[3];\n\n            // Starting line / Number of lines / Description\n            if (preg_match('/^([1-9]\\d*)(?:\\s+((?1))\\s*)?(.*)$/sux', $matches[3], $contentMatches)) {\n                $startingLine = (int) $contentMatches[1];\n                if (isset($contentMatches[2])) {\n                    $lineCount = (int) $contentMatches[2];\n                }\n\n                if (array_key_exists(3, $contentMatches)) {\n                    $description = $contentMatches[3];\n                }\n            }\n        }\n\n        return new static(\n            $filePath ?? ($fileUri ?? ''),\n            $fileUri !== null,\n            $startingLine,\n            $lineCount,\n            $description\n        );\n    }\n\n    /**\n     * Returns the file path.\n     *\n     * @return string Path to a file to use as an example.\n     *     May also be an absolute URI.\n     */\n    public function getFilePath(): string\n    {\n        return trim($this->filePath, '\"');\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        $filePath = $this->filePath;\n        $isDefaultLine = $this->startingLine === 1 && $this->lineCount === 0;\n        $startingLine = !$isDefaultLine ? (string) $this->startingLine : '';\n        $lineCount = !$isDefaultLine ? (string) $this->lineCount : '';\n        $content = (string) $this->content;\n\n        return $filePath\n            . ($startingLine !== ''\n                ? ($filePath !== '' ? ' ' : '') . $startingLine\n                : '')\n            . ($lineCount !== ''\n                ? ($filePath !== '' || $startingLine !== '' ? ' ' : '') . $lineCount\n                : '')\n            . ($content !== ''\n                ? ($filePath !== '' || $startingLine !== '' || $lineCount !== '' ? ' ' : '') . $content\n                : '');\n    }\n\n    /**\n     * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute).\n     */\n    private function isUriRelative(string $uri): bool\n    {\n        return strpos($uri, ':') === false;\n    }\n\n    public function getStartingLine(): int\n    {\n        return $this->startingLine;\n    }\n\n    public function getLineCount(): int\n    {\n        return $this->lineCount;\n    }\n\n    public function getName(): string\n    {\n        return 'example';\n    }\n\n    public function render(?Formatter $formatter = null): string\n    {\n        if ($formatter === null) {\n            $formatter = new Formatter\\PassthroughFormatter();\n        }\n\n        return $formatter->format($this);\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Extends_.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}extends tag in a Docblock.\n */\nclass Extends_ extends TagWithType\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        $this->name        = 'extends';\n        $this->type        = $type;\n        $this->description = $description;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php",
    "content": "<?php\n/*\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n *  @link      http://phpdoc.org\n *\n */\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse PHPStan\\PhpDocParser\\Lexer\\Lexer;\nuse PHPStan\\PhpDocParser\\Parser\\ConstExprParser;\nuse PHPStan\\PhpDocParser\\Parser\\ParserException;\nuse PHPStan\\PhpDocParser\\Parser\\PhpDocParser;\nuse PHPStan\\PhpDocParser\\Parser\\TokenIterator;\nuse PHPStan\\PhpDocParser\\Parser\\TypeParser;\nuse PHPStan\\PhpDocParser\\ParserConfig;\nuse RuntimeException;\n\nuse function property_exists;\nuse function rtrim;\nuse function str_replace;\nuse function trim;\n\n/**\n * Factory class creating tags using phpstan's parser\n *\n * This class uses {@see PHPStanFactory} implementations to create tags\n * from the ast of the phpstan docblock parser.\n *\n * @internal This class is not part of the BC promise of this library.\n */\nclass AbstractPHPStanFactory implements Factory\n{\n    private PhpDocParser $parser;\n    private Lexer $lexer;\n    /** @var PHPStanFactory[] */\n    private array $factories;\n\n    public function __construct(PHPStanFactory ...$factories)\n    {\n        $config = new ParserConfig(['indexes' => true, 'lines' => true]);\n        $this->lexer = new Lexer($config);\n        $constParser = new ConstExprParser($config);\n        $this->parser = new PhpDocParser(\n            $config,\n            new TypeParser($config, $constParser),\n            $constParser\n        );\n\n        $this->factories = $factories;\n    }\n\n    public function create(string $tagLine, ?TypeContext $context = null): Tag\n    {\n        try {\n            $tokens = $this->tokenizeLine($tagLine);\n            $ast = $this->parser->parseTag($tokens);\n            if (property_exists($ast->value, 'description') === true) {\n                $ast->value->setAttribute(\n                    'description',\n                    rtrim($ast->value->description . $tokens->joinUntil(Lexer::TOKEN_END), \"\\n\")\n                );\n            }\n        } catch (ParserException $e) {\n            return InvalidTag::create($tagLine, '')->withError($e);\n        }\n\n        if ($context === null) {\n            $context = new TypeContext('');\n        }\n\n        try {\n            foreach ($this->factories as $factory) {\n                if ($factory->supports($ast, $context)) {\n                    return $factory->create($ast, $context);\n                }\n            }\n        } catch (RuntimeException $e) {\n            return InvalidTag::create((string) $ast->value, 'method')->withError($e);\n        } catch (ParserException $e) {\n            return InvalidTag::create((string) $ast->value, $ast->name)->withError($e);\n        }\n\n        return InvalidTag::create(\n            (string) $ast->value,\n            $ast->name\n        );\n    }\n\n    /**\n     * Solve the issue with the lexer not tokenizing the line correctly\n     *\n     * This method is a workaround for the lexer that includes newline tokens with spaces. For\n     * phpstan this isn't an issue, as it doesn't do a lot of things with the indentation of descriptions.\n     * But for us is important to keep the indentation of the descriptions, so we need to fix the lexer output.\n     */\n    private function tokenizeLine(string $tagLine): TokenIterator\n    {\n        // Prefix continuation lines with \"* \", which is consumed by the phpstan parser as TOKEN_PHPDOC_EOL.\n        $tagLine = str_replace(\"\\n\", \"\\n* \", $tagLine);\n        $tokens = $this->lexer->tokenize($tagLine . \"\\n\");\n        $fixed = [];\n        foreach ($tokens as $token) {\n            if ($token[Lexer::TYPE_OFFSET] === Lexer::TOKEN_PHPDOC_EOL) {\n                // Strip \"* \" prefix (and other horizontal whitespace) again so it doesn't and up in the\n                // description when we joinUntil() in create().\n                $fixed[] = [\n                    Lexer::VALUE_OFFSET => trim($token[Lexer::VALUE_OFFSET], \"* \\t\"),\n                    Lexer::TYPE_OFFSET => $token[Lexer::TYPE_OFFSET],\n                    Lexer::LINE_OFFSET => $token[Lexer::LINE_OFFSET] ?? 0,\n                ];\n\n                continue;\n            }\n\n            $fixed[] = $token;\n        }\n\n        return new TokenIterator($fixed);\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/ExtendsFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Extends_;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ExtendsTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class ExtendsFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof ExtendsTagValueNode && $node->name === '@extends';\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, ExtendsTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Extends_(\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/Factory.php",
    "content": "<?php\n/*\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n *  @link      http://phpdoc.org\n *\n */\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse InvalidArgumentException;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\n\ninterface Factory\n{\n    /**\n     * Factory method responsible for instantiating the correct sub type.\n     *\n     * @param string $tagLine The text for this tag, including description.\n     *\n     * @return Tag A new tag object.\n     *\n     * @throws InvalidArgumentException If an invalid tag line was presented.\n     */\n    public function create(string $tagLine, ?TypeContext $context = null): Tag;\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/ImplementsFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Implements_;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ImplementsTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class ImplementsFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof ImplementsTagValueNode && $node->name === '@implements';\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, ImplementsTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Implements_(\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/MethodFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Method;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter;\nuse phpDocumentor\\Reflection\\Type;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Mixed_;\nuse phpDocumentor\\Reflection\\Types\\Void_;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\MethodTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\MethodTagValueParameterNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function array_map;\nuse function trim;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class MethodFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, MethodTagValueNode::class);\n\n        return new Method(\n            $tagValue->methodName,\n            array_map(\n                function (MethodTagValueParameterNode $param) use ($context) {\n                    return new MethodParameter(\n                        trim($param->parameterName, '$'),\n                        $param->type === null ? new Mixed_() : $this->typeResolver->createType(\n                            $param->type,\n                            $context\n                        ),\n                        $param->isReference,\n                        $param->isVariadic,\n                        $param->defaultValue === null ?\n                            MethodParameter::NO_DEFAULT_VALUE :\n                            (string) $param->defaultValue\n                    );\n                },\n                $tagValue->parameters\n            ),\n            $this->createReturnType($tagValue, $context),\n            $tagValue->isStatic,\n            $this->descriptionFactory->create($tagValue->description, $context),\n            false,\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof MethodTagValueNode;\n    }\n\n    private function createReturnType(MethodTagValueNode $tagValue, Context $context): Type\n    {\n        if ($tagValue->returnType === null) {\n            return new Void_();\n        }\n\n        return $this->typeResolver->createType($tagValue->returnType, $context);\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/MethodParameterFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse function array_key_last;\nuse function get_class;\nuse function gettype;\nuse function method_exists;\nuse function ucfirst;\nuse function var_export;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class MethodParameterFactory\n{\n    /**\n     * Formats the given default value to a string-able mixin\n     *\n     * @param mixed $defaultValue\n     */\n    public function format($defaultValue): string\n    {\n        $method = 'format' . ucfirst(gettype($defaultValue));\n        if (method_exists($this, $method)) {\n            return $this->{$method}($defaultValue);\n        }\n\n        return '';\n    }\n\n    private function formatDouble(float $defaultValue): string\n    {\n        return var_export($defaultValue, true);\n    }\n\n    /**\n     * @param mixed $defaultValue\n     */\n    private function formatNull($defaultValue): string\n    {\n        return 'null';\n    }\n\n    private function formatInteger(int $defaultValue): string\n    {\n        return var_export($defaultValue, true);\n    }\n\n    private function formatString(string $defaultValue): string\n    {\n        return var_export($defaultValue, true);\n    }\n\n    private function formatBoolean(bool $defaultValue): string\n    {\n        return var_export($defaultValue, true);\n    }\n\n    /**\n     * @param array<(array<mixed>|int|float|bool|string|object|null)> $defaultValue\n     */\n    private function formatArray(array $defaultValue): string\n    {\n        $formatedValue = '[';\n\n        foreach ($defaultValue as $key => $value) {\n            $method = 'format' . ucfirst(gettype($value));\n            if (!method_exists($this, $method)) {\n                continue;\n            }\n\n            $formatedValue .= $this->{$method}($value);\n\n            if ($key === array_key_last($defaultValue)) {\n                continue;\n            }\n\n            $formatedValue .= ',';\n        }\n\n        return $formatedValue . ']';\n    }\n\n    private function formatObject(object $defaultValue): string\n    {\n        return 'new ' . get_class($defaultValue) . '()';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/MixinFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Mixin;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\MixinTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class MixinFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, MixinTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Mixin(\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof MixinTagValueNode;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/PHPStanFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\n\ninterface PHPStanFactory\n{\n    public function create(PhpDocTagNode $node, Context $context): Tag;\n\n    public function supports(PhpDocTagNode $node, Context $context): bool;\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/ParamFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Param;\nuse phpDocumentor\\Reflection\\Exception\\ParserException;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\InvalidTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ParamTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\TypelessParamTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode;\nuse PHPStan\\PhpDocParser\\Ast\\Type\\OffsetAccessTypeNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\nuse function trim;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class ParamFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n\n        if ($tagValue instanceof InvalidTagValueNode) {\n            return InvalidTag::create($tagValue->value, 'param')->withError(\n                ParserException::from($tagValue->exception)\n            );\n        }\n\n        Assert::isInstanceOfAny(\n            $tagValue,\n            [\n                ParamTagValueNode::class,\n                TypelessParamTagValueNode::class,\n            ]\n        );\n\n        if (($tagValue->type ?? null) instanceof OffsetAccessTypeNode) {\n            return InvalidTag::create(\n                (string) $tagValue,\n                'param'\n            );\n        }\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Param(\n            trim($tagValue->parameterName, '$'),\n            $this->typeResolver->createType($tagValue->type ?? new IdentifierTypeNode('mixed'), $context),\n            $tagValue->isVariadic,\n            $this->descriptionFactory->create($description, $context),\n            $tagValue->isReference\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof ParamTagValueNode\n            || $node->value instanceof TypelessParamTagValueNode\n            || $node->name === '@param';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/PropertyFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Property;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PropertyTagValueNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\nuse function trim;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class PropertyFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Property(\n            trim($tagValue->propertyName, '$'),\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof PropertyTagValueNode && $node->name === '@property';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/PropertyReadFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PropertyTagValueNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\nuse function trim;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class PropertyReadFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->typeResolver = $typeResolver;\n        $this->descriptionFactory = $descriptionFactory;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new PropertyRead(\n            trim($tagValue->propertyName, '$'),\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof PropertyTagValueNode && $node->name === '@property-read';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/PropertyWriteFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PropertyTagValueNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\nuse function trim;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class PropertyWriteFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new PropertyWrite(\n            trim($tagValue->propertyName, '$'),\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof PropertyTagValueNode && $node->name === '@property-write';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/ReturnFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ReturnTagValueNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class ReturnFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, ReturnTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Return_(\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof ReturnTagValueNode;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/TemplateCovariantFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\TemplateCovariant;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\TemplateTagValueNode;\nuse PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class TemplateCovariantFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof TemplateTagValueNode && $node->name === '@template-covariant';\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, TemplateTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new TemplateCovariant(\n            $this->typeResolver->createType(new IdentifierTypeNode($tagValue->name), $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/TemplateFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Template;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\TemplateTagValueNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class TemplateFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n\n        Assert::isInstanceOf($tagValue, TemplateTagValueNode::class);\n        $name = $tagValue->name;\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Template(\n            $name,\n            $this->typeResolver->createType($tagValue->bound, $context),\n            $this->typeResolver->createType($tagValue->default, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof TemplateTagValueNode && $node->name === '@template';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/ThrowsFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ThrowsTagValueNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class ThrowsFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, ThrowsTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Throws(\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof ThrowsTagValueNode;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Factory/VarFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\VarTagValueNode;\nuse Webmozart\\Assert\\Assert;\n\nuse function is_string;\nuse function trim;\n\n/**\n * @internal This class is not part of the BC promise of this library.\n */\nfinal class VarFactory implements PHPStanFactory\n{\n    private DescriptionFactory $descriptionFactory;\n    private TypeResolver $typeResolver;\n\n    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->typeResolver = $typeResolver;\n    }\n\n    public function create(PhpDocTagNode $node, Context $context): Tag\n    {\n        $tagValue = $node->value;\n        Assert::isInstanceOf($tagValue, VarTagValueNode::class);\n\n        $description = $tagValue->getAttribute('description');\n        if (is_string($description) === false) {\n            $description = $tagValue->description;\n        }\n\n        return new Var_(\n            trim($tagValue->variableName, '$'),\n            $this->typeResolver->createType($tagValue->type, $context),\n            $this->descriptionFactory->create($description, $context)\n        );\n    }\n\n    public function supports(PhpDocTagNode $node, Context $context): bool\n    {\n        return $node->value instanceof VarTagValueNode;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Formatter/AlignFormatter.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\n\nuse function max;\nuse function str_repeat;\nuse function strlen;\n\nclass AlignFormatter implements Formatter\n{\n    /** @var int The maximum tag name length. */\n    protected int $maxLen = 0;\n\n    /**\n     * @param Tag[] $tags All tags that should later be aligned with the formatter.\n     */\n    public function __construct(array $tags)\n    {\n        foreach ($tags as $tag) {\n            $this->maxLen = max($this->maxLen, strlen($tag->getName()));\n        }\n    }\n\n    /**\n     * Formats the given tag to return a simple plain text version.\n     */\n    public function format(Tag $tag): string\n    {\n        return '@' . $tag->getName() .\n            str_repeat(\n                ' ',\n                $this->maxLen - strlen($tag->getName()) + 1\n            ) .\n            $tag;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Formatter/PassthroughFormatter.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\n\nuse function trim;\n\nclass PassthroughFormatter implements Formatter\n{\n    /**\n     * Formats the given tag to return a simple plain text version.\n     */\n    public function format(Tag $tag): string\n    {\n        return trim('@' . $tag->getName() . ' ' . $tag);\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Formatter.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\n\ninterface Formatter\n{\n    /**\n     * Formats a tag into a string representation according to a specific format, such as Markdown.\n     */\n    public function format(Tag $tag): string;\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Generic.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse InvalidArgumentException;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse Webmozart\\Assert\\Assert;\n\nuse function preg_match;\n\n/**\n * Parses a tag definition for a DocBlock.\n */\nfinal class Generic extends BaseTag\n{\n    /**\n     * Parses a tag and populates the member variables.\n     *\n     * @param string      $name        Name of the tag.\n     * @param Description $description The contents of the given tag.\n     */\n    public function __construct(string $name, ?Description $description = null)\n    {\n        $this->validateTagName($name);\n\n        $this->name        = $name;\n        $this->description = $description;\n    }\n\n    /**\n     * Creates a new tag that represents any unknown tag type.\n     *\n     * @return static\n     */\n    public static function create(\n        string $body,\n        string $name = '',\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): self {\n        Assert::stringNotEmpty($name);\n        Assert::notNull($descriptionFactory);\n\n        $description = $body !== '' ? $descriptionFactory->create($body, $context) : null;\n\n        return new static($name, $description);\n    }\n\n    /**\n     * Returns the tag as a serialized string\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        return $description;\n    }\n\n    /**\n     * Validates if the tag name matches the expected format, otherwise throws an exception.\n     */\n    private function validateTagName(string $name): void\n    {\n        if (!preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) {\n            throw new InvalidArgumentException(\n                'The tag name \"' . $name . '\" is not wellformed. Tags may only consist of letters, underscores, '\n                . 'hyphens and backslashes.'\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Implements_.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}implements tag in a Docblock.\n */\nclass Implements_ extends TagWithType\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        $this->name        = 'implements';\n        $this->type        = $type;\n        $this->description = $description;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/InvalidTag.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Closure;\nuse Exception;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse ReflectionClass;\nuse ReflectionException;\nuse ReflectionFunction;\nuse Throwable;\n\nuse function array_map;\nuse function get_class;\nuse function get_resource_type;\nuse function is_array;\nuse function is_object;\nuse function is_resource;\nuse function sprintf;\n\nuse const PHP_VERSION_ID;\n\n/**\n * This class represents an exception during the tag creation\n *\n * Since the internals of the library are relaying on the correct syntax of a docblock\n * we cannot simply throw exceptions at all time because the exceptions will break the creation of a\n * docklock. Just silently ignore the exceptions is not an option because the user as an issue to fix.\n *\n * This tag holds that error information until a using application is able to display it. The object will just behave\n * like any normal tag. So the normal application flow will not break.\n */\nfinal class InvalidTag implements Tag\n{\n    private string $name;\n\n    private string $body;\n\n    private ?Throwable $throwable = null;\n\n    private function __construct(string $name, string $body)\n    {\n        $this->name = $name;\n        $this->body = $body;\n    }\n\n    public function getException(): ?Throwable\n    {\n        return $this->throwable;\n    }\n\n    public function getName(): string\n    {\n        return $this->name;\n    }\n\n    public static function create(string $body, string $name = ''): self\n    {\n        return new self($name, $body);\n    }\n\n    public function withError(Throwable $exception): self\n    {\n        $this->flattenExceptionBacktrace($exception);\n        $tag            = new self($this->name, $this->body);\n        $tag->throwable = $exception;\n\n        return $tag;\n    }\n\n    /**\n     * Removes all complex types from backtrace\n     *\n     * Not all objects are serializable. So we need to remove them from the\n     * stored exception to be sure that we do not break existing library usage.\n     */\n    private function flattenExceptionBacktrace(Throwable $exception): void\n    {\n        $traceProperty = (new ReflectionClass(Exception::class))->getProperty('trace');\n        if (PHP_VERSION_ID < 80100) {\n            $traceProperty->setAccessible(true);\n        }\n\n        do {\n            $trace = $exception->getTrace();\n            if (isset($trace[0]['args'])) {\n                $trace = array_map(\n                    function (array $call): array {\n                        $call['args'] = array_map([$this, 'flattenArguments'], $call['args'] ?? []);\n\n                        return $call;\n                    },\n                    $trace\n                );\n            }\n\n            $traceProperty->setValue($exception, $trace);\n            $exception = $exception->getPrevious();\n        } while ($exception !== null);\n\n        if (PHP_VERSION_ID >= 80100) {\n            return;\n        }\n\n        $traceProperty->setAccessible(false);\n    }\n\n    /**\n     * @param mixed $value\n     *\n     * @return mixed\n     *\n     * @throws ReflectionException\n     */\n    private function flattenArguments($value)\n    {\n        if ($value instanceof Closure) {\n            $closureReflection = new ReflectionFunction($value);\n            $value             = sprintf(\n                '(Closure at %s:%s)',\n                $closureReflection->getFileName(),\n                $closureReflection->getStartLine()\n            );\n        } elseif (is_object($value)) {\n            $value = sprintf('object(%s)', get_class($value));\n        } elseif (is_resource($value)) {\n            $value = sprintf('resource(%s)', get_resource_type($value));\n        } elseif (is_array($value)) {\n            $value = array_map([$this, 'flattenArguments'], $value);\n        }\n\n        return $value;\n    }\n\n    public function render(?Formatter $formatter = null): string\n    {\n        if ($formatter === null) {\n            $formatter = new Formatter\\PassthroughFormatter();\n        }\n\n        return $formatter->format($this);\n    }\n\n    public function __toString(): string\n    {\n        return $this->body;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Link.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse phpDocumentor\\Reflection\\Utils;\nuse Webmozart\\Assert\\Assert;\n\n/**\n * Reflection class for a {@}link tag in a Docblock.\n */\nfinal class Link extends BaseTag\n{\n    protected string $name = 'link';\n\n    private string $link;\n\n    /**\n     * Initializes a link to a URL.\n     */\n    public function __construct(string $link, ?Description $description = null)\n    {\n        $this->link        = $link;\n        $this->description = $description;\n    }\n\n    public static function create(\n        string $body,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): self {\n        Assert::notNull($descriptionFactory);\n\n        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);\n        $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;\n\n        return new static($parts[0], $description);\n    }\n\n    /**\n     * Gets the link\n     */\n    public function getLink(): string\n    {\n        return $this->link;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $link = $this->link;\n\n        return $link . ($description !== '' ? ($link !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Method.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Exception\\CannotCreateTag;\nuse phpDocumentor\\Reflection\\Type;\nuse phpDocumentor\\Reflection\\Types\\Void_;\nuse Webmozart\\Assert\\Assert;\n\nuse function implode;\n/**\n * Reflection class for an {@}method in a Docblock.\n */\n\nfinal class Method extends BaseTag\n{\n    protected string $name = 'method';\n\n    private string $methodName;\n\n    private bool $isStatic;\n\n    private Type $returnType;\n\n    private bool $returnsReference;\n\n    /** @var MethodParameter[] */\n    private array $parameters;\n\n    /**\n     * @param MethodParameter[] $parameters\n     */\n    public function __construct(\n        string $methodName,\n        array $parameters = [],\n        ?Type $returnType = null,\n        bool $static = false,\n        ?Description $description = null,\n        bool $returnsReference = false\n    ) {\n        Assert::stringNotEmpty($methodName);\n\n        if ($returnType === null) {\n            $returnType = new Void_();\n        }\n\n        $this->methodName       = $methodName;\n        $this->returnType       = $returnType;\n        $this->isStatic         = $static;\n        $this->description      = $description;\n        $this->returnsReference = $returnsReference;\n        $this->parameters = $parameters;\n    }\n\n    /**\n     * Retrieves the method name.\n     */\n    public function getMethodName(): string\n    {\n        return $this->methodName;\n    }\n\n    /** @return MethodParameter[] */\n    public function getParameters(): array\n    {\n        return $this->parameters;\n    }\n\n    /**\n     * Checks whether the method tag describes a static method or not.\n     *\n     * @return bool TRUE if the method declaration is for a static method, FALSE otherwise.\n     */\n    public function isStatic(): bool\n    {\n        return $this->isStatic;\n    }\n\n    public function getReturnType(): Type\n    {\n        return $this->returnType;\n    }\n\n    public function returnsReference(): bool\n    {\n        return $this->returnsReference;\n    }\n\n    public function __toString(): string\n    {\n        $arguments = [];\n        foreach ($this->parameters as $parameter) {\n            $arguments[] = (string) $parameter;\n        }\n\n        $argumentStr = '(' . implode(', ', $arguments) . ')';\n\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $static = $this->isStatic ? 'static' : '';\n\n        $returnType = (string) $this->returnType;\n\n        $methodName = $this->methodName;\n\n        $reference = $this->returnsReference ? '&' : '';\n\n        return $static\n            . ($returnType !== '' ? ($static !== '' ? ' ' : '') . $returnType : '')\n            . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $reference . $methodName : '')\n            . $argumentStr\n            . ($description !== '' ? ' ' . $description : '');\n    }\n\n    public static function create(string $body): void\n    {\n        throw new CannotCreateTag('Method tag cannot be created');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/MethodParameter.php",
    "content": "<?php\n/**\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n *  @link      http://phpdoc.org\n */\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodParameterFactory;\nuse phpDocumentor\\Reflection\\Type;\n\nfinal class MethodParameter\n{\n    private Type $type;\n\n    private bool $isReference;\n\n    private bool $isVariadic;\n\n    private string $name;\n\n    /** @var mixed */\n    private $defaultValue;\n\n    public const NO_DEFAULT_VALUE = '__NO_VALUE__';\n\n    /**\n     * @param mixed $defaultValue\n     */\n    public function __construct(\n        string $name,\n        Type $type,\n        bool $isReference = false,\n        bool $isVariadic = false,\n        $defaultValue = self::NO_DEFAULT_VALUE\n    ) {\n        $this->type = $type;\n        $this->isReference = $isReference;\n        $this->isVariadic = $isVariadic;\n        $this->name = $name;\n        $this->defaultValue = $defaultValue;\n    }\n\n    public function getName(): string\n    {\n        return $this->name;\n    }\n\n    public function getType(): Type\n    {\n        return $this->type;\n    }\n\n    public function isReference(): bool\n    {\n        return $this->isReference;\n    }\n\n    public function isVariadic(): bool\n    {\n        return $this->isVariadic;\n    }\n\n    public function getDefaultValue(): ?string\n    {\n        if ($this->defaultValue === self::NO_DEFAULT_VALUE) {\n            return null;\n        }\n\n        return (new MethodParameterFactory())->format($this->defaultValue);\n    }\n\n    public function __toString(): string\n    {\n        return $this->getType() . ' ' .\n            ($this->isReference() ? '&' : '') .\n            ($this->isVariadic() ? '...' : '') .\n            '$' . $this->getName() .\n            (\n                $this->defaultValue !== self::NO_DEFAULT_VALUE ?\n                    ' = ' . (new MethodParameterFactory())->format($this->defaultValue) :\n                ''\n            );\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Mixin.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}mixin tag in a Docblock.\n */\nfinal class Mixin extends TagWithType\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        $this->name        = 'mixin';\n        $this->type        = $type;\n        $this->description = $description;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Param.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for the {@}param tag in a Docblock.\n */\nfinal class Param extends TagWithType\n{\n    private ?string $variableName = null;\n\n    /** @var bool determines whether this is a variadic argument */\n    private bool $isVariadic;\n\n    /** @var bool determines whether this is passed by reference */\n    private bool $isReference;\n\n    public function __construct(\n        ?string $variableName,\n        ?Type $type = null,\n        bool $isVariadic = false,\n        ?Description $description = null,\n        bool $isReference = false\n    ) {\n        $this->name         = 'param';\n        $this->variableName = $variableName;\n        $this->type         = $type;\n        $this->isVariadic   = $isVariadic;\n        $this->description  = $description;\n        $this->isReference  = $isReference;\n    }\n\n    /**\n     * Returns the variable's name.\n     */\n    public function getVariableName(): ?string\n    {\n        return $this->variableName;\n    }\n\n    /**\n     * Returns whether this tag is variadic.\n     */\n    public function isVariadic(): bool\n    {\n        return $this->isVariadic;\n    }\n\n    /**\n     * Returns whether this tag is passed by reference.\n     */\n    public function isReference(): bool\n    {\n        return $this->isReference;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $variableName = '';\n        if ($this->variableName !== null && $this->variableName !== '') {\n            $variableName .= ($this->isReference ? '&' : '') . ($this->isVariadic ? '...' : '');\n            $variableName .= '$' . $this->variableName;\n        }\n\n        $type = (string) $this->type;\n\n        return $type\n            . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '')\n            . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Property.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\nuse Webmozart\\Assert\\Assert;\n\n/**\n * Reflection class for a {@}property tag in a Docblock.\n */\nfinal class Property extends TagWithType\n{\n    protected ?string $variableName = null;\n\n    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)\n    {\n        Assert::string($variableName);\n\n        $this->name         = 'property';\n        $this->variableName = $variableName;\n        $this->type         = $type;\n        $this->description  = $description;\n    }\n\n    /**\n     * Returns the variable's name.\n     */\n    public function getVariableName(): ?string\n    {\n        return $this->variableName;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description !== null) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        if ($this->variableName !== null && $this->variableName !== '') {\n            $variableName = '$' . $this->variableName;\n        } else {\n            $variableName = '';\n        }\n\n        $type = (string) $this->type;\n\n        return $type\n            . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '')\n            . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/PropertyRead.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\nuse Webmozart\\Assert\\Assert;\n\n/**\n * Reflection class for a {@}property-read tag in a Docblock.\n */\nfinal class PropertyRead extends TagWithType\n{\n    protected ?string $variableName = null;\n\n    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)\n    {\n        Assert::string($variableName);\n\n        $this->name         = 'property-read';\n        $this->variableName = $variableName;\n        $this->type         = $type;\n        $this->description  = $description;\n    }\n\n    /**\n     * Returns the variable's name.\n     */\n    public function getVariableName(): ?string\n    {\n        return $this->variableName;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description !== null) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        if ($this->variableName !== null && $this->variableName !== '') {\n            $variableName = '$' . $this->variableName;\n        } else {\n            $variableName = '';\n        }\n\n        $type = (string) $this->type;\n\n        return $type\n            . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '')\n            . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/PropertyWrite.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\nuse Webmozart\\Assert\\Assert;\n\n/**\n * Reflection class for a {@}property-write tag in a Docblock.\n */\nfinal class PropertyWrite extends TagWithType\n{\n    protected string $variableName;\n\n    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)\n    {\n        Assert::string($variableName);\n\n        $this->name         = 'property-write';\n        $this->variableName = $variableName;\n        $this->type         = $type;\n        $this->description  = $description;\n    }\n\n    /**\n     * Returns the variable's name.\n     */\n    public function getVariableName(): ?string\n    {\n        return $this->variableName;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        if ($this->variableName) {\n            $variableName = '$' . $this->variableName;\n        } else {\n            $variableName = '';\n        }\n\n        $type = (string) $this->type;\n\n        return $type\n            . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '')\n            . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Reference/Fqsen.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference;\n\nuse phpDocumentor\\Reflection\\Fqsen as RealFqsen;\n\n/**\n * Fqsen reference used by {@see \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See}\n */\nfinal class Fqsen implements Reference\n{\n    private RealFqsen $fqsen;\n\n    public function __construct(RealFqsen $fqsen)\n    {\n        $this->fqsen = $fqsen;\n    }\n\n    /**\n     * @return string string representation of the referenced fqsen\n     */\n    public function __toString(): string\n    {\n        return (string) $this->fqsen;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Reference/Reference.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference;\n\n/**\n * Interface for references in {@see \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See}\n */\ninterface Reference\n{\n    public function __toString(): string;\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Reference/Url.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference;\n\nuse Webmozart\\Assert\\Assert;\n\n/**\n * Url reference used by {@see \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See}\n */\nfinal class Url implements Reference\n{\n    private string $uri;\n\n    public function __construct(string $uri)\n    {\n        Assert::stringNotEmpty($uri);\n        $this->uri = $uri;\n    }\n\n    public function __toString(): string\n    {\n        return $this->uri;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Return_.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}return tag in a Docblock.\n */\nfinal class Return_ extends TagWithType\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        $this->name        = 'return';\n        $this->type        = $type;\n        $this->description = $description;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/See.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen as FqsenRef;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Reference;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse phpDocumentor\\Reflection\\Utils;\nuse Webmozart\\Assert\\Assert;\n\nuse function array_key_exists;\nuse function explode;\nuse function preg_match;\n\n/**\n * Reflection class for an {@}see tag in a Docblock.\n */\nfinal class See extends BaseTag\n{\n    protected string $name = 'see';\n\n    protected Reference $refers;\n\n    /**\n     * Initializes this tag.\n     */\n    public function __construct(Reference $refers, ?Description $description = null)\n    {\n        $this->refers      = $refers;\n        $this->description = $description;\n    }\n\n    public static function create(\n        string $body,\n        ?FqsenResolver $typeResolver = null,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): self {\n        Assert::notNull($descriptionFactory);\n\n        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);\n        $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;\n\n        // https://tools.ietf.org/html/rfc2396#section-3\n        if (preg_match('#\\w://\\w#', $parts[0])) {\n            return new static(new Url($parts[0]), $description);\n        }\n\n        return new static(new FqsenRef(self::resolveFqsen($parts[0], $typeResolver, $context)), $description);\n    }\n\n    private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context): Fqsen\n    {\n        Assert::notNull($fqsenResolver);\n        $fqsenParts = explode('::', $parts);\n        $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);\n\n        if (!array_key_exists(1, $fqsenParts)) {\n            return $resolved;\n        }\n\n        return new Fqsen($resolved . '::' . $fqsenParts[1]);\n    }\n\n    /**\n     * Returns the ref of this tag.\n     */\n    public function getReference(): Reference\n    {\n        return $this->refers;\n    }\n\n    /**\n     * Returns a string representation of this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $refers = (string) $this->refers;\n\n        return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Since.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse Webmozart\\Assert\\Assert;\n\nuse function preg_match;\n\n/**\n * Reflection class for a {@}since tag in a Docblock.\n */\nfinal class Since extends BaseTag\n{\n    protected string $name = 'since';\n\n    /**\n     * PCRE regular expression matching a version vector.\n     * Assumes the \"x\" modifier.\n     */\n    public const REGEX_VECTOR = '(?:\n        # Normal release vectors.\n        \\d\\S*\n        |\n        # VCS version vectors. Per PHPCS, they are expected to\n        # follow the form of the VCS name, followed by \":\", followed\n        # by the version vector itself.\n        # By convention, popular VCSes like CVS, SVN and GIT use \"$\"\n        # around the actual version vector.\n        [^\\s\\:]+\\:\\s*\\$[^\\$]+\\$\n    )';\n\n    /** @var string|null The version vector. */\n    private ?string $version = null;\n\n    public function __construct(?string $version = null, ?Description $description = null)\n    {\n        Assert::nullOrNotEmpty($version);\n\n        $this->version     = $version;\n        $this->description = $description;\n    }\n\n    public static function create(\n        ?string $body,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): ?self {\n        if ($body === null || $body === '') {\n            return new static();\n        }\n\n        $matches = [];\n        if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {\n            return null;\n        }\n\n        Assert::notNull($descriptionFactory);\n\n        return new static(\n            $matches[1],\n            $descriptionFactory->create($matches[2] ?? '', $context)\n        );\n    }\n\n    /**\n     * Gets the version section of the tag.\n     */\n    public function getVersion(): ?string\n    {\n        return $this->version;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description !== null) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $version = (string) $this->version;\n\n        return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Source.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse Webmozart\\Assert\\Assert;\n\nuse function preg_match;\n\n/**\n * Reflection class for a {@}source tag in a Docblock.\n */\nfinal class Source extends BaseTag\n{\n    protected string $name = 'source';\n\n    /** @var int The starting line, relative to the structural element's location. */\n    private int $startingLine;\n\n    /** @var int|null The number of lines, relative to the starting line. NULL means \"to the end\". */\n    private ?int $lineCount = null;\n\n    /**\n     * @param int|string      $startingLine should be a to int convertible value\n     * @param int|string|null $lineCount    should be a to int convertible value\n     */\n    public function __construct($startingLine, $lineCount = null, ?Description $description = null)\n    {\n        Assert::integerish($startingLine);\n        Assert::nullOrIntegerish($lineCount);\n\n        $this->startingLine = (int) $startingLine;\n        $this->lineCount    = $lineCount !== null ? (int) $lineCount : null;\n        $this->description  = $description;\n    }\n\n    public static function create(\n        string $body,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): self {\n        Assert::stringNotEmpty($body);\n        Assert::notNull($descriptionFactory);\n\n        $startingLine = 1;\n        $lineCount    = null;\n        $description  = null;\n\n        // Starting line / Number of lines / Description\n        if (preg_match('/^([1-9]\\d*)\\s*(?:((?1))\\s+)?(.*)$/sux', $body, $matches)) {\n            $startingLine = (int) $matches[1];\n            if (isset($matches[2]) && $matches[2] !== '') {\n                $lineCount = (int) $matches[2];\n            }\n\n            $description = $matches[3];\n        }\n\n        return new static($startingLine, $lineCount, $descriptionFactory->create($description ?? '', $context));\n    }\n\n    /**\n     * Gets the starting line.\n     *\n     * @return int The starting line, relative to the structural element's\n     *     location.\n     */\n    public function getStartingLine(): int\n    {\n        return $this->startingLine;\n    }\n\n    /**\n     * Returns the number of lines.\n     *\n     * @return int|null The number of lines, relative to the starting line. NULL\n     *     means \"to the end\".\n     */\n    public function getLineCount(): ?int\n    {\n        return $this->lineCount;\n    }\n\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $startingLine = (string) $this->startingLine;\n\n        $lineCount = $this->lineCount !== null ? ' ' . $this->lineCount : '';\n\n        return $startingLine\n            . $lineCount\n            . ($description !== ''\n                ? ' ' . $description\n                : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/TagWithType.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\Exception\\CannotCreateTag;\nuse phpDocumentor\\Reflection\\Type;\n\nabstract class TagWithType extends BaseTag\n{\n    /** @var ?Type */\n    protected ?Type $type = null;\n\n    /**\n     * Returns the type section of the variable.\n     */\n    public function getType(): ?Type\n    {\n        return $this->type;\n    }\n\n    final public static function create(string $body): Tag\n    {\n        throw new CannotCreateTag('Typed tag cannot be created');\n    }\n\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $type = (string) $this->type;\n\n        return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Template.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\Exception\\CannotCreateTag;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}template tag in a Docblock.\n */\nfinal class Template extends BaseTag\n{\n    /** @var non-empty-string */\n    private string $templateName;\n\n    /** @var ?Type The real type */\n    private ?Type $bound;\n\n    private ?Type $default;\n\n    /** @param non-empty-string $templateName */\n    public function __construct(\n        string $templateName,\n        ?Type $bound = null,\n        ?Type $default = null,\n        ?Description $description = null\n    ) {\n        $this->name = 'template';\n        $this->templateName = $templateName;\n        $this->bound = $bound;\n        $this->default = $default;\n        $this->description = $description;\n    }\n\n    /**\n     * @deprecated Create using static factory is deprecated,\n     *  this method should not be called directly by library consumers\n     */\n    public static function create(string $body): ?Tag\n    {\n        throw new CannotCreateTag('Template tag cannot be created');\n    }\n\n    public function getTemplateName(): string\n    {\n        return $this->templateName;\n    }\n\n    public function getBound(): ?Type\n    {\n        return $this->bound;\n    }\n\n    public function getDefault(): ?Type\n    {\n        return $this->default;\n    }\n\n    public function __toString(): string\n    {\n        $bound = $this->bound !== null ? ' of ' . $this->bound : '';\n        $default = $this->default !== null ? ' = ' . $this->default : '';\n\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        return $this->templateName . $bound . $default . ($description !== '' ? ' ' . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/TemplateCovariant.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}template-covariant tag in a Docblock.\n */\nfinal class TemplateCovariant extends TagWithType\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        $this->name        = 'template-covariant';\n        $this->type        = $type;\n        $this->description = $description;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/TemplateExtends.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}template-extends tag in a Docblock.\n */\nfinal class TemplateExtends extends Extends_\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        parent::__construct($type, $description);\n        $this->name = 'template-extends';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/TemplateImplements.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}template-implements tag in a Docblock.\n */\nfinal class TemplateImplements extends Implements_\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        parent::__construct($type, $description);\n        $this->name = 'template-implements';\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Throws.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\n\n/**\n * Reflection class for a {@}throws tag in a Docblock.\n */\nfinal class Throws extends TagWithType\n{\n    public function __construct(Type $type, ?Description $description = null)\n    {\n        $this->name        = 'throws';\n        $this->type        = $type;\n        $this->description = $description;\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Uses.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse phpDocumentor\\Reflection\\Utils;\nuse Webmozart\\Assert\\Assert;\n\nuse function array_key_exists;\nuse function explode;\n\n/**\n * Reflection class for a {@}uses tag in a Docblock.\n */\nfinal class Uses extends BaseTag\n{\n    protected string $name = 'uses';\n\n    protected Fqsen $refers;\n\n    /**\n     * Initializes this tag.\n     */\n    public function __construct(Fqsen $refers, ?Description $description = null)\n    {\n        $this->refers      = $refers;\n        $this->description = $description;\n    }\n\n    public static function create(\n        string $body,\n        ?FqsenResolver $resolver = null,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): self {\n        Assert::notNull($resolver);\n        Assert::notNull($descriptionFactory);\n\n        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);\n\n        return new static(\n            self::resolveFqsen($parts[0], $resolver, $context),\n            $descriptionFactory->create($parts[1] ?? '', $context)\n        );\n    }\n\n    private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context): Fqsen\n    {\n        Assert::notNull($fqsenResolver);\n        $fqsenParts = explode('::', $parts);\n        $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);\n\n        if (!array_key_exists(1, $fqsenParts)) {\n            return $resolved;\n        }\n\n        return new Fqsen($resolved . '::' . $fqsenParts[1]);\n    }\n\n    /**\n     * Returns the structural element this tag refers to.\n     */\n    public function getReference(): Fqsen\n    {\n        return $this->refers;\n    }\n\n    /**\n     * Returns a string representation of this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $refers = (string) $this->refers;\n\n        return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Var_.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Type;\nuse Webmozart\\Assert\\Assert;\n\n/**\n * Reflection class for a {@}var tag in a Docblock.\n */\nfinal class Var_ extends TagWithType\n{\n    protected ?string $variableName = '';\n\n    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)\n    {\n        Assert::string($variableName);\n\n        $this->name         = 'var';\n        $this->variableName = $variableName;\n        $this->type         = $type;\n        $this->description  = $description;\n    }\n\n    /**\n     * Returns the variable's name.\n     */\n    public function getVariableName(): ?string\n    {\n        return $this->variableName;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description !== null) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        if ($this->variableName !== null && $this->variableName !== '') {\n            $variableName = '$' . $this->variableName;\n        } else {\n            $variableName = '';\n        }\n\n        $type = (string) $this->type;\n\n        return $type\n            . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '')\n            . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock/Tags/Version.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context as TypeContext;\nuse Webmozart\\Assert\\Assert;\n\nuse function preg_match;\n\n/**\n * Reflection class for a {@}version tag in a Docblock.\n */\nfinal class Version extends BaseTag\n{\n    protected string $name = 'version';\n\n    /**\n     * PCRE regular expression matching a version vector.\n     * Assumes the \"x\" modifier.\n     */\n    public const REGEX_VECTOR = '(?:\n        # Normal release vectors.\n        \\d\\S*\n        |\n        # VCS version vectors. Per PHPCS, they are expected to\n        # follow the form of the VCS name, followed by \":\", followed\n        # by the version vector itself.\n        # By convention, popular VCSes like CVS, SVN and GIT use \"$\"\n        # around the actual version vector.\n        [^\\s\\:]+\\:\\s*\\$[^\\$]+\\$\n    )';\n\n    /** @var string|null The version vector. */\n    private ?string $version = null;\n\n    public function __construct(?string $version = null, ?Description $description = null)\n    {\n        Assert::nullOrStringNotEmpty($version);\n\n        $this->version     = $version;\n        $this->description = $description;\n    }\n\n    public static function create(\n        ?string $body,\n        ?DescriptionFactory $descriptionFactory = null,\n        ?TypeContext $context = null\n    ): ?self {\n        if ($body === null || $body === '') {\n            return new static();\n        }\n\n        $matches = [];\n        if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {\n            return null;\n        }\n\n        $description = null;\n        if ($descriptionFactory !== null) {\n            $description = $descriptionFactory->create($matches[2] ?? '', $context);\n        }\n\n        return new static(\n            $matches[1],\n            $description\n        );\n    }\n\n    /**\n     * Gets the version section of the tag.\n     */\n    public function getVersion(): ?string\n    {\n        return $this->version;\n    }\n\n    /**\n     * Returns a string representation for this tag.\n     */\n    public function __toString(): string\n    {\n        if ($this->description) {\n            $description = $this->description->render();\n        } else {\n            $description = '';\n        }\n\n        $version = (string) $this->version;\n\n        return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');\n    }\n}\n"
  },
  {
    "path": "src/DocBlock.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\TagWithType;\nuse Webmozart\\Assert\\Assert;\n\nfinal class DocBlock\n{\n    /** @var string The opening line for this docblock. */\n    private string $summary;\n\n    /** @var DocBlock\\Description The actual description for this docblock. */\n    private DocBlock\\Description $description;\n\n    /** @var Tag[] An array containing all the tags in this docblock; except inline. */\n    private array $tags = [];\n\n    /** @var Types\\Context|null Information about the context of this DocBlock. */\n    private ?Types\\Context $context = null;\n\n    /** @var Location|null Information about the location of this DocBlock. */\n    private ?Location $location = null;\n\n    /** @var bool Is this DocBlock (the start of) a template? */\n    private bool $isTemplateStart;\n\n    /** @var bool Does this DocBlock signify the end of a DocBlock template? */\n    private bool $isTemplateEnd;\n\n    /**\n     * @param DocBlock\\Tag[] $tags\n     * @param Types\\Context  $context  The context in which the DocBlock occurs.\n     * @param Location       $location The location within the file that this DocBlock occurs in.\n     */\n    public function __construct(\n        string $summary = '',\n        ?DocBlock\\Description $description = null,\n        array $tags = [],\n        ?Types\\Context $context = null,\n        ?Location $location = null,\n        bool $isTemplateStart = false,\n        bool $isTemplateEnd = false\n    ) {\n        Assert::allIsInstanceOf($tags, Tag::class);\n\n        $this->summary     = $summary;\n        $this->description = $description ?: new DocBlock\\Description('');\n        foreach ($tags as $tag) {\n            $this->addTag($tag);\n        }\n\n        $this->context  = $context;\n        $this->location = $location;\n\n        $this->isTemplateEnd   = $isTemplateEnd;\n        $this->isTemplateStart = $isTemplateStart;\n    }\n\n    public function getSummary(): string\n    {\n        return $this->summary;\n    }\n\n    public function getDescription(): DocBlock\\Description\n    {\n        return $this->description;\n    }\n\n    /**\n     * Returns the current context.\n     */\n    public function getContext(): ?Types\\Context\n    {\n        return $this->context;\n    }\n\n    /**\n     * Returns the current location.\n     */\n    public function getLocation(): ?Location\n    {\n        return $this->location;\n    }\n\n    /**\n     * Returns whether this DocBlock is the start of a Template section.\n     *\n     * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker\n     * (`#@+`) that is appended directly after the opening `/**` of a DocBlock.\n     *\n     * An example of such an opening is:\n     *\n     * ```\n     * /**#@+\n     *  * My DocBlock\n     *  * /\n     * ```\n     *\n     * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all\n     * elements that follow until another DocBlock is found that contains the closing marker (`#@-`).\n     *\n     * @see self::isTemplateEnd() for the check whether a closing marker was provided.\n     */\n    public function isTemplateStart(): bool\n    {\n        return $this->isTemplateStart;\n    }\n\n    /**\n     * Returns whether this DocBlock is the end of a Template section.\n     *\n     * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality.\n     */\n    public function isTemplateEnd(): bool\n    {\n        return $this->isTemplateEnd;\n    }\n\n    /**\n     * Returns the tags for this DocBlock.\n     *\n     * @return Tag[]\n     */\n    public function getTags(): array\n    {\n        return $this->tags;\n    }\n\n    /**\n     * Returns an array of tags matching the given name. If no tags are found\n     * an empty array is returned.\n     *\n     * @param string $name String to search by.\n     *\n     * @return Tag[]\n     */\n    public function getTagsByName(string $name): array\n    {\n        $result = [];\n\n        foreach ($this->getTags() as $tag) {\n            if ($tag->getName() !== $name) {\n                continue;\n            }\n\n            $result[] = $tag;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Returns an array of tags with type matching the given name. If no tags are found\n     * an empty array is returned.\n     *\n     * @param string $name String to search by.\n     *\n     * @return TagWithType[]\n     */\n    public function getTagsWithTypeByName(string $name): array\n    {\n        $result = [];\n\n        foreach ($this->getTagsByName($name) as $tag) {\n            if (!$tag instanceof TagWithType) {\n                continue;\n            }\n\n            $result[] = $tag;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Checks if a tag of a certain type is present in this DocBlock.\n     *\n     * @param string $name Tag name to check for.\n     */\n    public function hasTag(string $name): bool\n    {\n        foreach ($this->getTags() as $tag) {\n            if ($tag->getName() === $name) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Remove a tag from this DocBlock.\n     *\n     * @param Tag $tagToRemove The tag to remove.\n     */\n    public function removeTag(Tag $tagToRemove): void\n    {\n        foreach ($this->tags as $key => $tag) {\n            if ($tag === $tagToRemove) {\n                unset($this->tags[$key]);\n                break;\n            }\n        }\n    }\n\n    /**\n     * Adds a tag to this DocBlock.\n     *\n     * @param Tag $tag The tag to add.\n     */\n    private function addTag(Tag $tag): void\n    {\n        $this->tags[] = $tag;\n    }\n}\n"
  },
  {
    "path": "src/DocBlockFactory.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse InvalidArgumentException;\nuse LogicException;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\TagFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\Factory;\nuse Webmozart\\Assert\\Assert;\n\nuse function array_shift;\nuse function count;\nuse function explode;\nuse function is_object;\nuse function method_exists;\nuse function preg_match;\nuse function preg_replace;\nuse function str_replace;\nuse function strpos;\nuse function substr;\nuse function trim;\n\nfinal class DocBlockFactory implements DocBlockFactoryInterface\n{\n    private DocBlock\\DescriptionFactory $descriptionFactory;\n\n    private TagFactory $tagFactory;\n\n    /**\n     * Initializes this factory with the required subcontractors.\n     */\n    public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory)\n    {\n        $this->descriptionFactory = $descriptionFactory;\n        $this->tagFactory = $tagFactory;\n    }\n\n    /**\n     * Factory method for easy instantiation.\n     *\n     * @param array<string, class-string<Tag>|Factory> $additionalTags\n     */\n    public static function createInstance(array $additionalTags = []): DocBlockFactoryInterface\n    {\n        $fqsenResolver = new FqsenResolver();\n        $tagFactory = StandardTagFactory::createInstance($fqsenResolver);\n        $descriptionFactory = new DescriptionFactory($tagFactory);\n\n        $docBlockFactory = new self($descriptionFactory, $tagFactory);\n        foreach ($additionalTags as $tagName => $tagHandler) {\n            $docBlockFactory->registerTagHandler($tagName, $tagHandler);\n        }\n\n        return $docBlockFactory;\n    }\n\n    /**\n     * @param object|string $docblock A string containing the DocBlock to parse or an object supporting the\n     *                                getDocComment method (such as a ReflectionClass object).\n     */\n    public function create($docblock, ?Types\\Context $context = null, ?Location $location = null): DocBlock\n    {\n        if (is_object($docblock)) {\n            if (!method_exists($docblock, 'getDocComment')) {\n                $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method';\n\n                throw new InvalidArgumentException($exceptionMessage);\n            }\n\n            $docblock = $docblock->getDocComment();\n            Assert::string($docblock);\n        }\n\n        Assert::stringNotEmpty($docblock);\n\n        if ($context === null) {\n            $context = new Types\\Context('');\n        }\n\n        $parts = $this->splitDocBlock($this->stripDocComment($docblock));\n\n        [$templateMarker, $summary, $description, $tags] = $parts;\n\n        return new DocBlock(\n            $summary,\n            $description ? $this->descriptionFactory->create($description, $context) : null,\n            $this->parseTagBlock($tags, $context),\n            $context,\n            $location,\n            $templateMarker === '#@+',\n            $templateMarker === '#@-'\n        );\n    }\n\n    /**\n     * @param class-string<Tag>|Factory $handler\n     */\n    public function registerTagHandler(string $tagName, $handler): void\n    {\n        $this->tagFactory->registerTagHandler($tagName, $handler);\n    }\n\n    /**\n     * Strips the asterisks from the DocBlock comment.\n     *\n     * @param string $comment String containing the comment text.\n     */\n    private function stripDocComment(string $comment): string\n    {\n        $comment = preg_replace('#[ \\t]*(?:\\/\\*\\*|\\*\\/|\\*)?[ \\t]?(.*)?#u', '$1', $comment);\n        Assert::string($comment);\n        $comment = trim($comment);\n\n        // reg ex above is not able to remove */ from a single line docblock\n        if (substr($comment, -2) === '*/') {\n            $comment = trim(substr($comment, 0, -2));\n        }\n\n        return str_replace([\"\\r\\n\", \"\\r\"], \"\\n\", $comment);\n    }\n\n    // phpcs:disable\n\n    /**\n     * Splits the DocBlock into a template marker, summary, description and block of tags.\n     *\n     * @param string $comment Comment to split into the sub-parts.\n     *\n     * @return string[] containing the template marker (if any), summary, description and a string containing the tags.\n     *\n     * @author Mike van Riel <me@mikevanriel.com> for extending the regex with template marker support.\n     *\n     * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.\n     */\n    private function splitDocBlock(string $comment): array\n    {\n        // phpcs:enable\n        // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This\n        // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the\n        // performance impact of running a regular expression\n        if (strpos($comment, '@') === 0) {\n            return ['', '', '', $comment];\n        }\n\n        // clears all extra horizontal whitespace from the line endings to prevent parsing issues\n        $comment = preg_replace('/\\h*$/Sum', '', $comment);\n        Assert::string($comment);\n        /*\n         * Splits the docblock into a template marker, summary, description and tags section.\n         *\n         * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may\n         *   occur after it and will be stripped).\n         * - The short description is started from the first character until a dot is encountered followed by a\n         *   newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing\n         *   errors). This is optional.\n         * - The long description, any character until a new line is encountered followed by an @ and word\n         *   characters (a tag). This is optional.\n         * - Tags; the remaining characters\n         *\n         * Big thanks to RichardJ for contributing this Regular Expression\n         */\n        preg_match(\n            '/\n            \\A\n            # 1. Extract the template marker\n            (?:(\\#\\@\\+|\\#\\@\\-)\\n?)?\n\n            # 2. Extract the summary\n            (?:\n              (?! @\\pL ) # The summary may not start with an @\n              (\n                [^\\n.]+\n                (?:\n                  (?! \\. \\n | \\n{2} )     # End summary upon a dot followed by newline or two newlines\n                  [\\n.]* (?! [ \\t]* @\\pL ) # End summary when an @ is found as first character on a new line\n                  [^\\n.]+                 # Include anything else\n                )*\n                \\.?\n              )?\n            )\n\n            # 3. Extract the description\n            (?:\n              \\s*        # Some form of whitespace _must_ precede a description because a summary must be there\n              (?! @\\pL ) # The description may not start with an @\n              (\n                [^\\n]+\n                (?: \\n+\n                  (?! [ \\t]* @\\pL ) # End description when an @ is found as first character on a new line\n                  [^\\n]+            # Include anything else\n                )*\n              )\n            )?\n\n            # 4. Extract the tags (anything that follows)\n            (\\s+ [\\s\\S]*)? # everything that follows\n            /ux',\n            $comment,\n            $matches\n        );\n        array_shift($matches);\n\n        while (count($matches) < 4) {\n            $matches[] = '';\n        }\n\n        return $matches;\n    }\n\n    /**\n     * Creates the tag objects.\n     *\n     * @param string $tags Tag block to parse.\n     * @param Types\\Context $context Context of the parsed Tag\n     *\n     * @return DocBlock\\Tag[]\n     */\n    private function parseTagBlock(string $tags, Types\\Context $context): array\n    {\n        $tags = $this->filterTagBlock($tags);\n        if ($tags === null) {\n            return [];\n        }\n\n        $result = [];\n        $lines = $this->splitTagBlockIntoTagLines($tags);\n        foreach ($lines as $key => $tagLine) {\n            $result[$key] = $this->tagFactory->create(trim($tagLine), $context);\n        }\n\n        return $result;\n    }\n\n    /**\n     * @return string[]\n     */\n    private function splitTagBlockIntoTagLines(string $tags): array\n    {\n        $result = [];\n        foreach (explode(\"\\n\", $tags) as $tagLine) {\n            if ($tagLine !== '' && strpos($tagLine, '@') === 0) {\n                $result[] = $tagLine;\n            } else {\n                $result[count($result) - 1] .= \"\\n\" . $tagLine;\n            }\n        }\n\n        return $result;\n    }\n\n    private function filterTagBlock(string $tags): ?string\n    {\n        $tags = trim($tags);\n        if (!$tags) {\n            return null;\n        }\n\n        if ($tags[0] !== '@') {\n            // @codeCoverageIgnoreStart\n            // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that\n            // we didn't foresee.\n\n            throw new LogicException('A tag block started with text instead of an at-sign(@): ' . $tags);\n\n            // @codeCoverageIgnoreEnd\n        }\n\n        return $tags;\n    }\n}\n"
  },
  {
    "path": "src/DocBlockFactoryInterface.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\n\n// phpcs:ignore SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix\ninterface DocBlockFactoryInterface\n{\n    /**\n     * Factory method for easy instantiation.\n     *\n     * @param array<string, class-string<Tag>> $additionalTags\n     */\n    public static function createInstance(array $additionalTags = []): self;\n\n    /**\n     * @param string|object $docblock\n     */\n    public function create($docblock, ?Types\\Context $context = null, ?Location $location = null): DocBlock;\n}\n"
  },
  {
    "path": "src/Exception/CannotCreateTag.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Exception;\n\nuse LogicException;\n\nfinal class CannotCreateTag extends LogicException\n{\n}\n"
  },
  {
    "path": "src/Exception/ParserException.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Exception;\n\nuse InvalidArgumentException;\n\nfinal class ParserException extends InvalidArgumentException implements ReflectionDocblockException\n{\n    public static function from(\\PHPStan\\PhpDocParser\\Parser\\ParserException $exception): self\n    {\n        return new self(\n            'Failed to parse docblock: ' . $exception->getMessage(),\n            0,\n            $exception\n        );\n    }\n}\n"
  },
  {
    "path": "src/Exception/PcreException.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Exception;\n\nuse InvalidArgumentException;\n\nuse const PREG_BACKTRACK_LIMIT_ERROR;\nuse const PREG_BAD_UTF8_ERROR;\nuse const PREG_BAD_UTF8_OFFSET_ERROR;\nuse const PREG_INTERNAL_ERROR;\nuse const PREG_JIT_STACKLIMIT_ERROR;\nuse const PREG_NO_ERROR;\nuse const PREG_RECURSION_LIMIT_ERROR;\n\nfinal class PcreException extends InvalidArgumentException\n{\n    public static function createFromPhpError(int $errorCode): self\n    {\n        switch ($errorCode) {\n            case PREG_BACKTRACK_LIMIT_ERROR:\n                return new self('Backtrack limit error');\n\n            case PREG_RECURSION_LIMIT_ERROR:\n                return new self('Recursion limit error');\n\n            case PREG_BAD_UTF8_ERROR:\n                return new self('Bad UTF8 error');\n\n            case PREG_BAD_UTF8_OFFSET_ERROR:\n                return new self('Bad UTF8 offset error');\n\n            case PREG_JIT_STACKLIMIT_ERROR:\n                return new self('Jit stacklimit error');\n\n            case PREG_NO_ERROR:\n            case PREG_INTERNAL_ERROR:\n            default:\n        }\n\n        return new self('Unknown Pcre error');\n    }\n}\n"
  },
  {
    "path": "src/Exception/ReflectionDocblockException.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Exception;\n\nuse Throwable;\n\ninterface ReflectionDocblockException extends Throwable\n{\n}\n"
  },
  {
    "path": "src/Utils.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse phpDocumentor\\Reflection\\Exception\\PcreException;\nuse Webmozart\\Assert\\Assert;\n\nuse function preg_last_error;\nuse function preg_split as php_preg_split;\n\nabstract class Utils\n{\n    /**\n     * Wrapper function for phps preg_split\n     *\n     * This function is inspired by {@link https://github.com/thecodingmachine/safe/blob/master/generated/pcre.php}. But\n     * since this library is all about performance we decided to strip everything we don't need. Reducing the amount\n     * of files that have to be loaded, etc.\n     *\n     * @param string $pattern The pattern to search for, as a string.\n     * @param string $subject The input string.\n     * @param int $limit If specified, then only substrings up to limit are returned with the\n     *      rest of the string being placed in the last substring. A limit of -1 or 0 means \"no limit\".\n     * @param int $flags flags can be any combination of the following flags (combined with the | bitwise operator):\n     * *PREG_SPLIT_NO_EMPTY*\n     *      If this flag is set, only non-empty pieces will be returned by preg_split().\n     * *PREG_SPLIT_DELIM_CAPTURE*\n     *      If this flag is set, parenthesized expression in the delimiter pattern will be captured\n     *      and returned as well.\n     * *PREG_SPLIT_OFFSET_CAPTURE*\n     *      If this flag is set, for every occurring match the appendant string offset will also be returned.\n     *      Note that this changes the return value in an array where every element is an array consisting of the\n     *      matched string at offset 0 and its string offset into subject at offset 1.\n     *\n     * @return string[] Returns an array containing substrings of subject\n     *                                                      split along boundaries matched by pattern\n     *\n     * @throws PcreException\n     */\n    public static function pregSplit(string $pattern, string $subject, int $limit = -1, int $flags = 0): array\n    {\n        $parts = php_preg_split($pattern, $subject, $limit, $flags);\n        if ($parts === false) {\n            throw PcreException::createFromPhpError(preg_last_error());\n        }\n\n        Assert::allString($parts);\n\n        return $parts;\n    }\n}\n"
  },
  {
    "path": "tests/coverage-checker.php",
    "content": "<?php\n// based on https://ocramius.github.io/blog/automated-code-coverage-check-for-github-pull-requests-with-travis/\n$inputFile  = __DIR__ . '/../build/logs/clover.xml';\n$percentage = min(100, max(0, (int) $argv[1]));\n\nif (!file_exists($inputFile)) {\n    throw new InvalidArgumentException('Invalid input file provided');\n}\n\nif (!$percentage) {\n    throw new InvalidArgumentException('An integer checked percentage must be given as parameter');\n}\n\n$xml             = new SimpleXMLElement(file_get_contents($inputFile));\n$metrics         = $xml->xpath('//metrics');\n$totalElements   = 0;\n$checkedElements = 0;\n\nforeach ($metrics as $metric) {\n    $totalElements   += (int) $metric['elements'];\n    $checkedElements += (int) $metric['coveredelements'];\n}\n\n$coverage = ($checkedElements / $totalElements) * 100;\n\nif ($coverage < $percentage) {\n    echo 'Code coverage is ' . $coverage . '%, which is below the accepted ' . $percentage . '%' . PHP_EOL;\n    exit(1);\n}\n\necho 'Code coverage is ' . $coverage . '% - OK!' . PHP_EOL;\n"
  },
  {
    "path": "tests/integration/DocblockSeeTagResolvingTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\See;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversNothing\n */\nclass DocblockSeeTagResolvingTest extends TestCase\n{\n    public function testResolvesSeeFQSENOfInlineTags()\n    {\n        $context = new Context('\\Project\\Sub\\Level', ['Issue2425B' => '\\Project\\Other\\Level\\Issue2425B', 'Aliased' => 'Project\\Other\\Level\\Issue2425C']);\n        $docblockString = <<<DOCBLOCK\n/**\n * Class summary.\n *\n * A description containing an inline {@see Issue2425B::bar()} tag\n * to a class inside of the project referenced via a use statement.\n *\n * And here is another inline {@see Aliased::bar()} tag to a class\n * aliased via a use statement.\n */\nDOCBLOCK;\n\n\n\n        $factory  = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docblockString, $context);\n\n        /** @var See $see1 */\n        $see1 = $docblock->getDescription()->getTags()[0];\n\n        $this->assertSame('\\Project\\Other\\Level\\Issue2425B::bar()', (string)$see1->getReference());\n    }\n}\n"
  },
  {
    "path": "tests/integration/DocblocksWithAnnotationsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n *  @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversNothing\n */\nfinal class DocblocksWithAnnotationsTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    public function testDocblockWithAnnotations(): void\n    {\n        $docComment = <<<DOCCOMMENT\n            /**\n     * @var \\DateTime[]\n     * @Groups({\"a\", \"b\"})\n     * @ORM\\Entity\n     */\nDOCCOMMENT;\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        $this->assertCount(3, $docblock->getTags());\n    }\n\n    public function testDocblockWithAnnotationHavingZeroValue(): void\n    {\n        $docComment = <<<DOCCOMMENT\n            /**\n     * @my-tag 0\n     */\nDOCCOMMENT;\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        $this->assertSame(0, (int) $docblock->getTagsByName('my-tag')[0]->render());\n    }\n}\n"
  },
  {
    "path": "tests/integration/InterpretingDocBlocksTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Method;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Param;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\See;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Since;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Template;\nuse phpDocumentor\\Reflection\\Exception\\ParserException;\nuse phpDocumentor\\Reflection\\PseudoTypes\\ConstExpression;\nuse phpDocumentor\\Reflection\\Types\\Array_;\nuse phpDocumentor\\Reflection\\Types\\Compound;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Integer;\nuse phpDocumentor\\Reflection\\Types\\Mixed_;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse phpDocumentor\\Reflection\\Types\\Self_;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse phpDocumentor\\Reflection\\Types\\Void_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversNothing\n */\nclass InterpretingDocBlocksTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    public function testInterpretingSummaryWithEllipsis(): void\n    {\n        $docblock = <<<DOCBLOCK\n/**\n * This is a short (...) description.\n *\n * This is a long description.\n *\n * @return void\n */\nDOCBLOCK;\n\n        $factory = DocBlockFactory::createInstance();\n        $phpdoc = $factory->create($docblock);\n\n        $summary = 'This is a short (...) description.';\n        $description = 'This is a long description.';\n\n        $this->assertInstanceOf(DocBlock::class, $phpdoc);\n        $this->assertSame($summary, $phpdoc->getSummary());\n        $this->assertSame($description, $phpdoc->getDescription()->render());\n        $this->assertCount(1, $phpdoc->getTags());\n        $this->assertTrue($phpdoc->hasTag('return'));\n    }\n\n    public function testInterpretingASimpleDocBlock(): void\n    {\n        /** @var DocBlock $docblock */\n        $docblock;\n        /** @var string $summary */\n        $summary;\n        /** @var Description $description */\n        $description;\n\n        include(__DIR__ . '/../../docs/examples/01-interpreting-a-simple-docblock.php');\n\n        $descriptionText = <<<DESCRIPTION\nThis is a Description. A Summary and Description are separated by either\ntwo subsequent newlines (thus a whiteline in between as can be seen in this\nexample), or when the Summary ends with a dot (`.`) and some form of\nwhitespace.\nDESCRIPTION;\n\n        $this->assertInstanceOf(DocBlock::class, $docblock);\n        $this->assertSame('This is an example of a summary.', $summary);\n        $this->assertInstanceOf(Description::class, $description);\n        $this->assertSame(\n            str_replace(\n                PHP_EOL,\n                \"\\n\",\n                $descriptionText\n            ),\n            $description->render()\n        );\n        $this->assertEmpty($docblock->getTags());\n    }\n\n    public function testInterpretingTags(): void\n    {\n        /** @var DocBlock $docblock */\n        $docblock;\n        /** @var boolean $hasSeeTag */\n        $hasSeeTag;\n        /** @var Tag[] $tags */\n        $tags;\n        /** @var See[] $seeTags */\n        $seeTags;\n\n        include(__DIR__ . '/../../docs/examples/02-interpreting-tags.php');\n\n        $this->assertTrue($hasSeeTag);\n        $this->assertCount(1, $tags);\n        $this->assertCount(1, $seeTags);\n\n        $this->assertInstanceOf(See::class, $tags[0]);\n        $this->assertInstanceOf(See::class, $seeTags[0]);\n\n        $seeTag = $seeTags[0];\n        $this->assertSame('\\\\' . StandardTagFactory::class, (string)$seeTag->getReference());\n        $this->assertSame('', (string)$seeTag->getDescription());\n    }\n\n    public function testDescriptionsCanEscapeAtSignsAndClosingBraces(): void\n    {\n        /** @var string $docComment */\n        $docComment;\n        /** @var DocBlock $docblock */\n        $docblock;\n        /** @var Description $description */\n        $description;\n        /** @var string $receivedDocComment */\n        $receivedDocComment;\n        /** @var string $foundDescription */\n        $foundDescription;\n\n        include(__DIR__ . '/../../docs/examples/playing-with-descriptions/02-escaping.php');\n\n        $this->assertSame(\n            str_replace(\n                PHP_EOL,\n                \"\\n\",\n                <<<'DESCRIPTION'\nYou can escape the @-sign by surrounding it with braces, for example: @. And escape a closing brace within an\ninline tag by adding an opening brace in front of it like this: }.\n\nHere are example texts where you can see how they could be used in a real life situation:\n\n    This is a text with an {@internal inline tag where a closing brace (}) is shown}.\n    Or an {@internal inline tag with a literal {@link} in it}.\n\nDo note that an {@internal inline tag that has an opening brace ({) does not break out}.\nDESCRIPTION\n            ),\n            $foundDescription\n        );\n    }\n\n    public function testMultilineTags(): void\n    {\n        $docComment = <<<DOC\n/**\n * This is an example of a summary.\n *\n * @param array<\n *   int,\n *   string     \n * > \\$store\n */\nDOC;\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        self::assertEquals(\n            [\n                new Param(\n                    'store',\n                    new Array_(\n                        new String_(),\n                        new Integer()\n                    ),\n                    false,\n                    new Description(''),\n                ),\n            ],\n            $docblock->getTags()\n        );\n\n    }\n\n    public function testMethodRegression(): void\n    {\n        $docComment = <<<DOC\n/**\n * This is an example of a summary.\n *\n * @method void setInteger(integer \\$integer)\n */\nDOC;\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        self::assertEquals(\n            [\n                new Method(\n                    'setInteger',\n                    [\n                        new MethodParameter('integer', new Integer())\n                    ],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            $docblock->getTags()\n        );\n    }\n\n    public function testInvalidTypeParamResultsInInvalidTag(): void\n    {\n        $docComment = '\n/**\n * This is an example of a summary.\n *\n * @param array\\Foo> $test\n */\n';\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        $tags = $docblock->getTags();\n\n        self::assertCount(1, $docblock->getTags());\n        self::assertInstanceOf(InvalidTag::class, $tags[0]);\n        self::assertCount(1, $docblock->getTags());\n        self::assertSame('Failed to parse docblock: Unexpected token \">\", expected variable at offset 16 on line 1', $tags[0]->getException()->getMessage());\n\n\n//        self::assertEquals(\n//            [\n//                InvalidTag::create(\n//                    'array\\Foo> $test',\n//                    'param',\n//                )->withError(\n//                    new ParserException(\n//                        'Could not find type in array\\Foo> $test, please check for malformed notations', 'aa', 1)\n//                ),\n//            ],\n//            $docblock->getTags()\n//        );\n    }\n\n    public function testConstantReferenceTypes(): void\n    {\n        $docComment = <<<DOC\n    /**\n     * @return self::STATUS_*\n     */\nDOC;\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        self::assertEquals(\n            [\n                new Return_(new ConstExpression(new Self_(), 'STATUS_*'), new Description('')),\n            ],\n            $docblock->getTags()\n        );\n    }\n\n    public function testRegressionWordpressDocblocks(): void\n    {\n        $docComment = <<<DOC\n    /**\n     * Install a package.\n     *\n     * Copies the contents of a package from a source directory, and installs them in\n     * a destination directory. Optionally removes the source. It can also optionally\n     * clear out the destination folder if it already exists.\n     *\n     * @since 2.8.0\n     * @since 6.2.0 Use move_dir() instead of copy_dir() when possible.\n     *\n     * @global WP_Filesystem_Base \\$wp_filesystem        WordPress filesystem subclass.\n     * @global array              \\$wp_theme_directories\n     *\n     * @param array|string \\$args {\n     *     Optional. Array or string of arguments for installing a package. Default empty array.\n     *\n     *     @type string \\$source                      Required path to the package source. Default empty.\n     *     @type string \\$destination                 Required path to a folder to install the package in.\n     *                                               Default empty.\n     *     @type bool   \\$clear_destination           Whether to delete any files already in the destination\n     *                                               folder. Default false.\n     *     @type bool   \\$clear_working               Whether to delete the files from the working directory\n     *                                               after copying them to the destination. Default false.\n     *     @type bool   \\$abort_if_destination_exists Whether to abort the installation if\n     *                                               the destination folder already exists. Default true.\n     *     @type array  \\$hook_extra                  Extra arguments to pass to the filter hooks called by\n     *                                               WP_Upgrader::install_package(). Default empty array.\n     * }\n     *\n     * @return array|WP_Error The result (also stored in `WP_Upgrader::\\$result`), or a WP_Error on failure.\n     */\nDOC;\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        self::assertEquals(\n            new DocBlock(\n                'Install a package.',\n                new Description(\n                    'Copies the contents of a package from a source directory, and installs them in' . PHP_EOL .\n                    'a destination directory. Optionally removes the source. It can also optionally' . PHP_EOL .\n                    'clear out the destination folder if it already exists.'\n                ),\n                [\n                    new Since('2.8.0', new Description('')),\n                    new Since('6.2.0', new Description('Use move_dir() instead of copy_dir() when possible.')),\n                    new Generic(\n                        'global',\n                        new Description('WP_Filesystem_Base $wp_filesystem        WordPress filesystem subclass.')\n                    ),\n                    new Generic(\n                        'global',\n                        new Description('array              $wp_theme_directories')\n                    ),\n                    new Param(\n                        'args',\n                        new Compound([new Array_(), new String_()]),\n                        false,\n                        new Description(\n                            '{' . \"\\n\" .\n                            '    Optional. Array or string of arguments for installing a package. Default empty array.' . \"\\n\" .\n                            \"\\n\" .\n                            '    @type string $source                      Required path to the package source. Default empty.' . \"\\n\" .\n                            '    @type string $destination                 Required path to a folder to install the package in.' . \"\\n\" .\n                            '                                              Default empty.' . \"\\n\" .\n                            '    @type bool   $clear_destination           Whether to delete any files already in the destination' . \"\\n\" .\n                            '                                              folder. Default false.' . \"\\n\" .\n                            '    @type bool   $clear_working               Whether to delete the files from the working directory' . \"\\n\" .\n                            '                                              after copying them to the destination. Default false.' . \"\\n\" .\n                            '    @type bool   $abort_if_destination_exists Whether to abort the installation if' . \"\\n\" .\n                            '                                              the destination folder already exists. Default true.' . \"\\n\" .\n                            '    @type array  $hook_extra                  Extra arguments to pass to the filter hooks called by' . \"\\n\" .\n                            '                                              WP_Upgrader::install_package(). Default empty array.' . \"\\n\" .\n                            '}'\n                        )\n                    ),\n                    new Return_(\n                        new Compound([new Array_(), new Object_(new Fqsen('\\WP_Error'))]),\n                        new Description('The result (also stored in `WP_Upgrader::$result`), or a WP_Error on failure.')\n                    ),\n                ],\n                new Context('\\\\')\n            ),\n            $docblock\n        );\n    }\n\n    public function testIndentationIsKept(): void\n    {\n        $docComment = <<<DOC\n\t/**\n\t * Registers the script module if no script module with that script module\n\t * identifier has already been registered.\n\t *\n\t * @since 6.5.0\n\t *\n\t * @param array             \\$deps     {\n\t *                                        Optional. List of dependencies.\n\t *\n\t *                                        @type string|array ...$0 {\n\t *                                            An array of script module identifiers of the dependencies of this script\n\t *                                            module. The dependencies can be strings or arrays. If they are arrays,\n\t *                                            they need an `id` key with the script module identifier, and can contain\n\t *                                            an `import` key with either `static` or `dynamic`. By default,\n\t *                                            dependencies that don't contain an `import` key are considered static.\n\t *\n\t *                                            @type string \\$id     The script module identifier.\n\t *                                            @type string \\$import Optional. Import type. May be either `static` or\n\t *                                                                 `dynamic`. Defaults to `static`.\n\t *                                        }\n\t *                                    }\n\t */\nDOC;\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        self::assertEquals(\n            new DocBlock(\n                'Registers the script module if no script module with that script module\nidentifier has already been registered.',\n                new Description(\n                    ''\n                ),\n                [\n                    new Since('6.5.0', new Description('')),\n                    new Param(\n                        'deps',\n                        new Array_(),\n                        false,\n                        new Description(\"{\n    Optional. List of dependencies.\n\n    @type string|array ...$0 {\n        An array of script module identifiers of the dependencies of this script\n        module. The dependencies can be strings or arrays. If they are arrays,\n        they need an `id` key with the script module identifier, and can contain\n        an `import` key with either `static` or `dynamic`. By default,\n        dependencies that don't contain an `import` key are considered static.\n\n        @type string \\$id     The script module identifier.\n        @type string \\$import Optional. Import type. May be either `static` or\n                             `dynamic`. Defaults to `static`.\n    }\n}\"\n                        )\n                    ),\n                ],\n                new Context('\\\\')\n            ),\n            $docblock\n        );\n    }\n\n    public function testProcessTemplateTag(): void\n    {\n        $docComment = <<<DOCBLOCK\n        /** \n         * @template T as \\Type this is a description\n         * @template TDefault as \\Type = \\\\String_ this is a description\n         */\nDOCBLOCK;\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        self::assertEquals(\n            [\n                new Template(\n                    'T',\n                    new Object_(new Fqsen('\\\\Type')),\n                    new Mixed_(),\n                    new Description('this is a description')\n                ),\n                new Template(\n                    'TDefault',\n                    new Object_(new Fqsen('\\\\Type')),\n                    new Object_(new Fqsen('\\\\String_')),\n                    new Description('this is a description')\n                ),\n            ],\n            $docblock->getTags()\n        );\n    }\n\n    public function testParamTagDescriptionIsCorrectly(): void\n    {\n        $docComment = '\n\t/**\n\t * @param int $baz Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius, tellus in cursus\n\t *     dictum, justo odio sagittis velit, id iaculis mi dui id nisi.\n\t */\n';\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        $paramTags = $docblock->getTagsWithTypeByName('param')[0];\n\n        self::assertSame('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius, tellus in cursus\ndictum, justo odio sagittis velit, id iaculis mi dui id nisi.', (string) $paramTags->getDescription());\n    }\n\n    public function testParamBlockDescriptionPreservesStarContinuationLines(): void\n    {\n        $docComment = <<<DOC\n/**\n * @param array \\$foo {\n *     Description of foo.\n *\n *     @type string \\$bar Description of bar with\n *                       * a list\n *                       * spanning *multiple* lines\n * }\n */\nDOC;\n\n        $factory = DocBlockFactory::createInstance();\n        $docblock = $factory->create($docComment);\n\n        self::assertEquals(\n            [\n                new Param(\n                    'foo',\n                    new Array_(),\n                    false,\n                    new Description(<<<'DESCRIPTION'\n{\n    Description of foo.\n\n    @type string $bar Description of bar with\n                      * a list\n                      * spanning *multiple* lines\n}\nDESCRIPTION\n                    ),\n                ),\n            ],\n            $docblock->getTags()\n        );\n    }\n}\n"
  },
  {
    "path": "tests/integration/ModifyBackTraceSafeTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection;\n\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversNothing\n */\nclass ModifyBackTraceSafeTest extends TestCase\n{\n    /**\n     * @doesNotPerformAssertions\n     */\n    public function testBackTraceModificationDoesNotImpactFunctionArguments()\n    {\n        $traverser = new Traverser();\n        $node1 = new Node();\n        $node1->children[] = new Node();\n        $node1->children[] = new Node();\n\n        $traverser->traverse([new Node(), $node1]);\n    }\n}\n\n\nclass Node {\n    public $children = [];\n}\n\nclass Traverser\n{\n    public function traverse(array $nodes)\n    {\n        $this->traverseArray($nodes);\n    }\n\n    public function traverseArray(array $nodes): array\n    {\n        $doNodes = [];\n\n        foreach ($nodes as &$node) {\n            $node = $this->callback($node);\n            $node = $this->traverseNode($node);\n\n            $doNodes[] = $node;\n        }\n\n        return $doNodes;\n    }\n\n    public function callback(Node $class) : Node\n    {\n        $docblock = <<<DOCBLOCK\n /**\n  * @see sql.php\n  */\nDOCBLOCK;\n\n        $factor = DocBlockFactory::createInstance();\n\n        $factor->create($docblock);\n\n        return $class;\n    }\n\n    private function traverseNode(Node $node) : Node\n    {\n        if ($node->children) {\n            $this->traverseArray($node->children);\n        }\n\n        return $node;\n    }\n}\n"
  },
  {
    "path": "tests/integration/ReconstitutingADocBlockTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic;\nuse phpDocumentor\\Reflection\\Types\\ContextFactory;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversNothing\n */\nclass ReconstitutingADocBlockTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    public function testReconstituteADocBlock(): void\n    {\n        /** @var string $docComment */\n        $docComment;\n        /** @var string $reconstitutedDocComment */\n        $reconstitutedDocComment;\n\n        include(__DIR__ . '/../../docs/examples/03-reconstituting-a-docblock.php');\n\n        $this->assertSame($docComment, $reconstitutedDocComment);\n    }\n\n\n    /**\n     * Method\n     *\n     * Method which contains a modulo sign (%) in its description.\n     *\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @covers ::__construct\n     * @covers ::render\n     * @covers ::__toString\n     */\n    public function testDescriptionCanContainPercent(): void\n    {\n        $factory = DocBlockFactory::createInstance();\n        $contextFactory = new ContextFactory();\n\n        $method = new \\ReflectionMethod(self::class, 'testDescriptionCanContainPercent');\n\n        $docblock = $factory->create(\n            $method,\n            $contextFactory->createFromReflector($method->getDeclaringClass())\n        );\n\n        $tag1 = new Generic('JoinColumn', new Description('(name=\"column_id\", referencedColumnName=\"id\")'));\n        $tag2 = new Generic('JoinColumn', new Description('(name=\"column_id_2\", referencedColumnName=\"id\")'));\n\n        $tags = [\n            $tag1,\n            $tag2,\n        ];\n\n        $fixture  = $docblock->getDescription();\n        $expected = 'Method which contains a modulo sign (%) in its description.';\n        $this->assertSame($expected, (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/integration/TypedTagsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace integration;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Method;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Param;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_;\nuse phpDocumentor\\Reflection\\DocBlockFactory;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\PseudoTypes\\ArrayShape;\nuse phpDocumentor\\Reflection\\PseudoTypes\\ArrayShapeItem;\nuse phpDocumentor\\Reflection\\Type;\nuse phpDocumentor\\Reflection\\Types\\Array_;\nuse phpDocumentor\\Reflection\\Types\\Callable_;\nuse phpDocumentor\\Reflection\\Types\\CallableParameter;\nuse phpDocumentor\\Reflection\\PseudoTypes\\Generic;\nuse phpDocumentor\\Reflection\\Types\\Integer;\nuse phpDocumentor\\Reflection\\Types\\Nullable;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse phpDocumentor\\Reflection\\Types\\Void_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversNothing\n */\nfinal class TypedTagsTest extends TestCase\n{\n    /** @dataProvider typeProvider */\n    public function testParamFormats(string $type, Type $expectedType): void\n    {\n        $docblock = <<<DOCBLOCK\n/**\n * @param $type \\$param\n */\nDOCBLOCK;\n\n        $factory = DocBlockFactory::createInstance();\n        $phpdoc = $factory->create($docblock);\n\n        $this->assertInstanceOf(Param::class, $phpdoc->getTags()[0]);\n        $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getType());\n    }\n\n    /** @dataProvider typeProvider */\n    public function testVarFormats(string $type, Type $expectedType): void\n    {\n        $docblock = <<<DOCBLOCK\n/**\n * @var $type \\$param\n */\nDOCBLOCK;\n\n        $factory = DocBlockFactory::createInstance();\n        $phpdoc = $factory->create($docblock);\n\n        $this->assertInstanceOf(Var_::class, $phpdoc->getTags()[0]);\n        $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getType());\n    }\n\n    /** @dataProvider typeProvider */\n    public function testMethodFormats(string $type, Type $expectedType): void\n    {\n        $docblock = <<<DOCBLOCK\n/**\n * @method $type setValue($type \\$param)\n */\nDOCBLOCK;\n\n        $factory = DocBlockFactory::createInstance();\n        $phpdoc = $factory->create($docblock);\n\n        $this->assertInstanceOf(Method::class, $phpdoc->getTags()[0]);\n        $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getReturnType());\n        $this->assertEquals($expectedType, current($phpdoc->getTags()[0]->getParameters())->getType());\n    }\n\n    /** @dataProvider invalidFormatsProvider */\n    public function testInvalidParam(string $type): void\n    {\n        $docblock = <<<DOCBLOCK\n/**\n * @param $type \\$param\n */\nDOCBLOCK;\n\n        $factory = DocBlockFactory::createInstance();\n        $phpdoc = $factory->create($docblock);\n\n        $this->assertInstanceOf(InvalidTag::class, $phpdoc->getTags()[0]);\n        $this->assertEquals(\"$type \\$param\", (string) $phpdoc->getTags()[0]);\n\n    }\n\n    /** @dataProvider invalidFormatsProvider */\n    public function testInvalidMethod(string $type): void\n    {\n        $docblock = <<<DOCBLOCK\n/**\n * @method $type setValue($type \\$param)\n */\nDOCBLOCK;\n\n        $factory = DocBlockFactory::createInstance();\n        $phpdoc = $factory->create($docblock);\n\n        $this->assertInstanceOf(InvalidTag::class, $phpdoc->getTags()[0]);\n        $this->assertEquals(\"$type setValue($type \\$param)\", (string) $phpdoc->getTags()[0]);\n\n    }\n\n    public static function typeProvider(): array\n    {\n        return [\n            [\n                'int',\n                new Integer(),\n            ],\n            [\n                'integer',\n                new Integer(),\n            ],\n            [\n                'string',\n                new String_(),\n            ],\n            [\n                'T',\n                new Object_(new Fqsen('\\\\T')),\n            ],\n            [\n                'array',\n                new Array_(),\n            ],\n            [\n                'int[]',\n                new Array_(new Integer()),\n            ],\n            [\n                'int[][]',\n                new Array_(new Array_(new Integer())),\n            ],\n            [\n                'array<int, string>',\n                new Array_(new String_(), new Integer()),\n            ],\n            [\n                'array{\n                   foo: int,\n                   bar?: ?string\n                }',\n                new ArrayShape(\n                    new ArrayShapeItem('foo', new Integer(), false),\n                    new ArrayShapeItem('bar', new Nullable(new String_()), true),\n\n                )\n            ],\n            [\n                'Collection<int, string>',\n                new Generic(new Fqsen('\\\\Collection'), [new Integer(), new String_()]),\n            ],\n            [\n                'Collection<TKey, Tvalue>',\n                new Generic(new Fqsen('\\\\Collection'), [new Object_(new Fqsen('\\\\TKey')), new Object_(new Fqsen('\\\\Tvalue'))]),\n            ],\n            [\n                'Collection<Tvalue>',\n                new Generic(new Fqsen('\\\\Collection'), [new Object_(new Fqsen('\\\\Tvalue'))]),\n            ],\n            [\n                'callable(int $foo, string $bar): void',\n                new Callable_('callable', [new CallableParameter(new Integer(), 'foo'), new CallableParameter(new String_(), 'bar')], new Void_()),\n            ],\n        ];\n    }\n\n    public static function invalidFormatsProvider(): \\Generator\n    {\n        foreach (['<', '{', '('] as $badChar) {\n            yield \"invalid format open $badChar\" => [\"array$badChar\\\\fooo\"];\n        }\n\n        foreach (['>', '}', ')'] as $badChar) {\n            yield \"invalid format close $badChar\" => [\"array\\\\fooo$badChar\"];\n        }\n    }\n}\n"
  },
  {
    "path": "tests/integration/UsingTagsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversNothing\n */\nclass UsingTagsTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    public function testAddingYourOwnTagUsingAStaticMethodAsFactory(): void\n    {\n        /** @var object[] $customTagObjects */\n        $customTagObjects;\n        /** @var string $docComment */\n        $docComment;\n        /** @var string $reconstitutedDocComment */\n        $reconstitutedDocComment;\n\n        include(__DIR__ . '/../../docs/examples/04-adding-your-own-tag.php');\n\n        $this->assertInstanceOf(\\MyTag::class, $customTagObjects[0]);\n        $this->assertSame('my-tag', $customTagObjects[0]->getName());\n        $this->assertSame('I have a description', (string) $customTagObjects[0]->getDescription());\n        $this->assertSame($docComment, $reconstitutedDocComment);\n    }\n}\n"
  },
  {
    "path": "tests/unit/Assets/CustomParam.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Assets;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\nuse phpDocumentor\\Reflection\\FqsenResolver;\n\nfinal class CustomParam implements Tag\n{\n    /** @var string|null */\n    public $myParam;\n\n    /** @var FqsenResolver|null */\n    public $fqsenResolver;\n\n    public function getName() : string\n    {\n        return 'spy';\n    }\n\n    public static function create(string $body, ?FqsenResolver $fqsenResolver = null, ?string $myParam = null)\n    {\n        $tag = new self();\n        $tag->fqsenResolver = $fqsenResolver;\n        $tag->myParam = $myParam;\n\n        return $tag;\n    }\n\n    public function render(?Formatter $formatter = null) : string\n    {\n        return $this->getName();\n    }\n\n    public function __toString() : string\n    {\n        return $this->getName();\n    }\n}\n"
  },
  {
    "path": "tests/unit/Assets/CustomServiceClass.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Assets;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter;\n\nfinal class CustomServiceClass implements Tag\n{\n    /** @var Formatter|null */\n    public $formatter;\n\n    public function getName() : string\n    {\n        return 'spy';\n    }\n\n    public static function create(string $body, ?PassthroughFormatter $formatter = null)\n    {\n        $tag = new self();\n        $tag->formatter = $formatter;\n\n        return $tag;\n    }\n\n    public function render(?Formatter $formatter = null) : string\n    {\n        return $this->getName();\n    }\n\n    public function __toString() : string\n    {\n        return $this->getName();\n    }\n}\n"
  },
  {
    "path": "tests/unit/Assets/CustomServiceInterface.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Assets;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod;\n\nfinal class CustomServiceInterface implements Tag\n{\n    /** @var Formatter|null */\n    public $formatter;\n\n    public function getName() : string\n    {\n        return 'spy';\n    }\n\n    public static function create(string $body, ?Formatter $formatter = null)\n    {\n        $tag = new self();\n        $tag->formatter = $formatter;\n\n        return $tag;\n    }\n\n    public function render(?Formatter $formatter = null) : string\n    {\n        return $this->getName();\n    }\n\n    public function __toString() : string\n    {\n        return $this->getName();\n    }\n}\n"
  },
  {
    "path": "tests/unit/Assets/CustomTagFactory.php",
    "content": "<?php\n/*\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n *  @link      http://phpdoc.org\n *\n */\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Assets;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\Factory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic;\nuse phpDocumentor\\Reflection\\Types\\Context;\n\nclass CustomTagFactory implements Factory\n{\n    /** @var CustomServiceClass|null */\n    public $class;\n\n    public function create(string $tagLine, ?Context $context = null, ?CustomServiceClass $class = null): Tag\n    {\n        $this->class = $class;\n\n        return new Generic('custom');\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/DescriptionFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Link as LinkTag;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function str_replace;\n\nuse const PHP_EOL;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n * @covers ::<private>\n */\nclass DescriptionFactoryTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     * @dataProvider provideSimpleExampleDescriptions\n     */\n    public function testDescriptionCanParseASimpleString(string $contents): void\n    {\n        $tagFactory = m::mock(TagFactory::class);\n        $tagFactory->shouldReceive('create')->never();\n\n        $factory     = new DescriptionFactory($tagFactory);\n        $description = $factory->create($contents, new Context(''));\n\n        $this->assertSame($contents, $description->render());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     * @dataProvider provideEscapeSequences\n     */\n    public function testEscapeSequences(string $contents, string $expected): void\n    {\n        $tagFactory = m::mock(TagFactory::class);\n        $tagFactory->shouldReceive('create')->never();\n\n        $factory     = new DescriptionFactory($tagFactory);\n        $description = $factory->create($contents, new Context(''));\n\n        $this->assertSame($expected, $description->render());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testDescriptionCanParseAStringWithInlineTag(): void\n    {\n        $contents   = 'This is text for a {@link http://phpdoc.org/ description} that uses an inline tag.';\n        $context    = new Context('');\n        $tagFactory = m::mock(TagFactory::class);\n        $tagFactory->shouldReceive('create')\n            ->once()\n            ->with('@link http://phpdoc.org/ description', $context)\n            ->andReturn(new LinkTag('http://phpdoc.org/', new Description('description')));\n\n        $factory     = new DescriptionFactory($tagFactory);\n        $description = $factory->create($contents, $context);\n\n        $this->assertSame($contents, $description->render());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testDescriptionCanParseAStringStartingWithInlineTag(): void\n    {\n        $contents   = '{@link http://phpdoc.org/ This} is text for a description that starts with an inline tag.';\n        $context    = new Context('');\n        $tagFactory = m::mock(TagFactory::class);\n        $tagFactory->shouldReceive('create')\n            ->once()\n            ->with('@link http://phpdoc.org/ This', $context)\n            ->andReturn(new LinkTag('http://phpdoc.org/', new Description('This')));\n\n        $factory     = new DescriptionFactory($tagFactory);\n        $description = $factory->create($contents, $context);\n\n        $this->assertSame($contents, $description->render());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testDescriptionCanParseAStringContainingMultipleTags(): void\n    {\n        $contents   = 'This description has a {@link http://phpdoc.org/ This} another {@link http://phpdoc.org/ This2}';\n        $context    = new Context('');\n        $tagFactory = m::mock(TagFactory::class);\n        $tagFactory->shouldReceive('create')\n            ->twice()\n            ->andReturnValues(\n                [\n                    new LinkTag('http://phpdoc.org/', new Description('This')),\n                    new LinkTag('http://phpdoc.org/', new Description('This2')),\n                ]\n            );\n\n        $factory     = new DescriptionFactory($tagFactory);\n        $description = $factory->create($contents, $context);\n\n        $this->assertSame($contents, $description->render());\n        $this->assertSame('This description has a %1$s another %2$s', $description->getBodyTemplate());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testIfSuperfluousStartingSpacesAreRemoved(): void\n    {\n        $factory         = new DescriptionFactory(m::mock(TagFactory::class));\n        $descriptionText = <<<DESCRIPTION\nThis is a multiline\n  description that you commonly\n  see with tags.\n\n      It does have a multiline code sample\n      that should align, no matter what\n\n  All spaces superfluous spaces on the\n  second and later lines should be\n  removed but the code sample should\n  still be indented.\nDESCRIPTION;\n\n        $expectedDescription = <<<DESCRIPTION\nThis is a multiline\ndescription that you commonly\nsee with tags.\n\n    It does have a multiline code sample\n    that should align, no matter what\n\nAll spaces superfluous spaces on the\nsecond and later lines should be\nremoved but the code sample should\nstill be indented.\nDESCRIPTION;\n\n        $description = $factory->create($descriptionText, new Context(''));\n\n        $this->assertSame(str_replace(PHP_EOL, \"\\n\", $expectedDescription), $description->render());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testDescriptionWithBrokenInlineTags(): void\n    {\n        $contents   = 'This {@see $name} is a broken use case, but used in real life.';\n        $context    = new Context('');\n        $tagFactory = m::mock(TagFactory::class);\n        $tagFactory->shouldReceive('create')\n            ->once()\n            ->with('@see $name', $context)\n            ->andReturn(InvalidTag::create('$name', 'see'));\n\n        $factory     = new DescriptionFactory($tagFactory);\n        $description = $factory->create($contents, $context);\n\n        $this->assertSame($contents, $description->render());\n    }\n\n    /**\n     * Provides a series of example strings that the parser should correctly interpret and return.\n     *\n     * @return string[][]\n     */\n    public function provideSimpleExampleDescriptions(): array\n    {\n        return [\n            ['This is text for a description.'],\n            ['This is text for a description containing { that is literal.'],\n            ['This is text for a description containing } that is literal.'],\n            ['This is text for a description with {just a text} that is not a tag.'],\n        ];\n    }\n\n    /**\n     * @return string[][]\n     */\n    public function provideEscapeSequences(): array\n    {\n        return [\n            ['This is text for a description with a {@}.', 'This is text for a description with a @.'],\n            ['This is text for a description with a {@*}.', 'This is text for a description with a {@*}.'],\n            ['This is text for a description with a {}.', 'This is text for a description with a }.'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/DescriptionTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Description\n */\nclass DescriptionTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @covers ::__construct\n     * @covers ::render\n     */\n    public function testDescriptionCanRenderUsingABodyWithPlaceholdersAndTags(): void\n    {\n        $body     = 'This is a %1$s body.';\n        $expected = 'This is a {@internal significant} body.';\n        $tags     = [new Generic('internal', new Description('significant '))];\n\n        $fixture = new Description($body, $tags);\n\n        // without formatter (thus the PassthroughFormatter by default)\n        $this->assertSame($expected, $fixture->render());\n\n        // with a custom formatter\n        $formatter = m::mock(PassthroughFormatter::class);\n        $formatter->shouldReceive('format')->with($tags[0])->andReturn('@internal significant');\n        $this->assertSame($expected, $fixture->render($formatter));\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @covers ::__construct\n     * @covers ::render\n     * @covers ::__toString\n     */\n    public function testDescriptionCanBeCastToString(): void\n    {\n        $body     = 'This is a %1$s body.';\n        $expected = 'This is a {@internal significant} body.';\n        $tags     = [new Generic('internal', new Description('significant '))];\n\n        $fixture = new Description($body, $tags);\n\n        $this->assertSame($expected, (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::getTags\n     */\n    public function testDescriptionTagsGetter(): void\n    {\n        $body = '@JoinTable(name=\"table\", joinColumns=%1$s, inverseJoinColumns=%2$s)';\n\n        $tag1 = new Generic('JoinColumn', new Description('(name=\"column_id\", referencedColumnName=\"id\")'));\n        $tag2 = new Generic('JoinColumn', new Description('(name=\"column_id_2\", referencedColumnName=\"id\")'));\n\n        $tags = [\n            $tag1,\n            $tag2,\n        ];\n\n        $fixture = new Description($body, $tags);\n\n        $this->assertCount(2, $fixture->getTags());\n\n        $actualTags = $fixture->getTags();\n        $this->assertSame($tags, $actualTags);\n        $this->assertSame($tag1, $actualTags[0]);\n        $this->assertSame($tag2, $actualTags[1]);\n    }\n\n    /**\n     * @covers ::getBodyTemplate\n     */\n    public function testDescriptionBodyTemplateGetter(): void\n    {\n        $body = 'See https://github.com/phpDocumentor/ReflectionDocBlock/pull/171 for more information';\n\n        $fixture = new Description($body, []);\n\n        $this->assertSame($body, $fixture->getBodyTemplate());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @covers ::__construct\n     * @covers ::render\n     * @covers ::__toString\n     */\n    public function testDescriptionMultipleTagsCanBeCastToString(): void\n    {\n        $body = '@JoinTable(name=\"table\", joinColumns=%1$s, inverseJoinColumns=%2$s)';\n\n        $tag1 = new Generic('JoinColumn', new Description('(name=\"column_id\", referencedColumnName=\"id\")'));\n        $tag2 = new Generic('JoinColumn', new Description('(name=\"column_id_2\", referencedColumnName=\"id\")'));\n\n        $tags = [\n            $tag1,\n            $tag2,\n        ];\n\n        $fixture  = new Description($body, $tags);\n        $expected = '@JoinTable(name=\"table\", joinColumns={@JoinColumn (name=\"column_id\", referencedColumnName=\"id\")}, '\n        . 'inverseJoinColumns={@JoinColumn (name=\"column_id_2\", referencedColumnName=\"id\")})';\n        $this->assertSame($expected, (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @covers ::__construct\n     * @covers ::render\n     * @covers ::__toString\n     */\n    public function testDescriptionWithEscapedCharactersAndNoTagsCanBeCastToString(): void\n    {\n        //% chars are escaped in \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory::create\n        $body = <<<'EOT'\n        {%% for user in users %%}\n            {{ user.name }}\n        {%% endfor %%}';\n        EOT;\n\n        $expected = <<<'EOT'\n        {% for user in users %}\n            {{ user.name }}\n        {% endfor %}';\n        EOT;\n\n        $fixture = new Description($body, []);\n\n        $this->assertSame($expected, (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/ExampleFinderTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Example;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\ExampleFinder\n * @covers ::<private>\n */\nclass ExampleFinderTest extends TestCase\n{\n    private ExampleFinder $fixture;\n\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    public function setUp(): void\n    {\n        $this->fixture = new ExampleFinder();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Example\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::find\n     * @covers ::getSourceDirectory\n     */\n    public function testFileNotFound(): void\n    {\n        $example = new Example('./example.php', false, 1, 0, 'Test');\n        $this->assertSame('** File not found : ./example.php **', $this->fixture->find($example));\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/SerializerTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function str_replace;\n\nuse const PHP_EOL;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Serializer\n * @covers ::<private>\n */\nclass SerializerTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     *\n     * @covers ::__construct\n     * @covers ::getDocComment\n     */\n    public function testReconstructsADocCommentFromADocBlock(): void\n    {\n        $expected = <<<'DOCCOMMENT'\n/**\n * This is a summary\n *\n * This is a description\n *\n * @unknown-tag Test description for the unknown tag\n */\nDOCCOMMENT;\n\n        $fixture = new Serializer();\n\n        $docBlock = new DocBlock(\n            'This is a summary',\n            new Description('This is a description'),\n            [\n                new DocBlock\\Tags\\Generic('unknown-tag', new Description('Test description for the unknown tag')),\n            ]\n        );\n\n        $this->assertSameString($expected, $fixture->getDocComment($docBlock));\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     *\n     * @covers ::__construct\n     * @covers ::getDocComment\n     */\n    public function testAddPrefixToDocBlock(): void\n    {\n        $expected = <<<'DOCCOMMENT'\naa/**\naa * This is a summary\naa *\naa * This is a description\naa *\naa * @unknown-tag Test description for the unknown tag\naa */\nDOCCOMMENT;\n\n        $fixture = new Serializer(2, 'a');\n\n        $docBlock = new DocBlock(\n            'This is a summary',\n            new Description('This is a description'),\n            [\n                new DocBlock\\Tags\\Generic('unknown-tag', new Description('Test description for the unknown tag')),\n            ]\n        );\n\n        $this->assertSameString($expected, $fixture->getDocComment($docBlock));\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     *\n     * @covers ::__construct\n     * @covers ::getDocComment\n     */\n    public function testAddPrefixToDocBlockExceptFirstLine(): void\n    {\n        $expected = <<<'DOCCOMMENT'\n/**\naa * This is a summary\naa *\naa * This is a description\naa *\naa * @unknown-tag Test description for the unknown tag\naa */\nDOCCOMMENT;\n\n        $fixture = new Serializer(2, 'a', false);\n\n        $docBlock = new DocBlock(\n            'This is a summary',\n            new Description('This is a description'),\n            [\n                new DocBlock\\Tags\\Generic('unknown-tag', new Description('Test description for the unknown tag')),\n            ]\n        );\n\n        $this->assertSameString($expected, $fixture->getDocComment($docBlock));\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     *\n     * @covers ::__construct\n     * @covers ::getDocComment\n     */\n    public function testWordwrapsAroundTheGivenAmountOfCharacters(): void\n    {\n        $expected = <<<'DOCCOMMENT'\n/**\n * This is a\n * summary\n *\n * This is a\n * description\n *\n * @unknown-tag\n * Test\n * description\n * for the\n * unknown tag\n */\nDOCCOMMENT;\n\n        $fixture = new Serializer(0, '', true, 15);\n\n        $docBlock = new DocBlock(\n            'This is a summary',\n            new Description('This is a description'),\n            [\n                new DocBlock\\Tags\\Generic('unknown-tag', new Description('Test description for the unknown tag')),\n            ]\n        );\n\n        $this->assertSameString($expected, $fixture->getDocComment($docBlock));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getDocComment\n     */\n    public function testNoExtraSpacesAfterTagRemoval(): void\n    {\n        $expected = <<<'DOCCOMMENT'\n/**\n * @unknown-tag\n */\nDOCCOMMENT;\n\n        $expectedAfterRemove = <<<'DOCCOMMENT_AFTER_REMOVE'\n/**\n */\nDOCCOMMENT_AFTER_REMOVE;\n\n        $fixture    = new Serializer(0, '', true, 15);\n        $genericTag = new DocBlock\\Tags\\Generic('unknown-tag');\n\n        $docBlock = new DocBlock('', null, [$genericTag]);\n        $this->assertSameString($expected, $fixture->getDocComment($docBlock));\n\n        $docBlock->removeTag($genericTag);\n        $this->assertSameString($expectedAfterRemove, $fixture->getDocComment($docBlock));\n    }\n\n    public function assertSameString(string $expected, string $actual): void\n    {\n        $expected = str_replace(PHP_EOL, \"\\n\", $expected);\n\n        self::assertSame($expected, $actual);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/StandardTagFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock;\n\nuse InvalidArgumentException;\nuse Mockery as m;\nuse Name\\Spaced\\Tag;\nuse phpDocumentor\\Reflection\\Assets\\CustomParam;\nuse phpDocumentor\\Reflection\\Assets\\CustomServiceClass;\nuse phpDocumentor\\Reflection\\Assets\\CustomServiceInterface;\nuse phpDocumentor\\Reflection\\Assets\\CustomTagFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Author;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Extends_;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Implements_;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Method;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Mixin;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Param;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Property;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\See;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Template;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\TemplateCovariant;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory\n * @covers ::<private>\n */\nclass StandardTagFactoryTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testCreatingAGenericTag(): void\n    {\n        $expectedTagName         = 'unknown-tag';\n        $expectedDescriptionText = 'This is a description';\n        $expectedDescription     = new Description($expectedDescriptionText);\n        $context                 = new Context('');\n\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $descriptionFactory\n            ->shouldReceive('create')\n            ->once()\n            ->with($expectedDescriptionText, $context)\n            ->andReturn($expectedDescription);\n\n        $tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));\n        $tagFactory->addService($descriptionFactory, DescriptionFactory::class);\n\n        $tag = $tagFactory->create('@' . $expectedTagName . ' This is a description', $context);\n\n        $this->assertInstanceOf(Generic::class, $tag);\n        $this->assertSame($expectedTagName, $tag->getName());\n        $this->assertSame($expectedDescription, $tag->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testCreatingAGenericTagWithDescriptionText(): void\n    {\n        $expectedTagName         = 'unknown-tag';\n        $expectedDescriptionText = ' foo Bar 123 ';\n        $context                 = new Context('');\n\n        $tagFactory = StandardTagFactory::createInstance(new FqsenResolver());\n        $tagFactory->addService(new DescriptionFactory($tagFactory), DescriptionFactory::class);\n\n        $tag = $tagFactory->create('@' . $expectedTagName . $expectedDescriptionText, $context);\n\n        $this->assertInstanceOf(Generic::class, $tag);\n        $this->assertSame('foo Bar 123', $tag . '');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testCreatingASpecificTag(): void\n    {\n        $context    = new Context('');\n        $tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));\n\n        $tag = $tagFactory->create('@author Mike van Riel <me@mikevanriel.com>', $context);\n\n        $this->assertInstanceOf(Author::class, $tag);\n        $this->assertSame('author', $tag->getName());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\Fqsen\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testAnEmptyContextIsCreatedIfNoneIsProvided(): void\n    {\n        $fqsen              = '\\Tag';\n        $resolver           = m::mock(FqsenResolver::class);\n        $resolver->allows('resolve')\n            ->with('Tag', m::type(Context::class))\n            ->andReturns(new Fqsen($fqsen))\n            ->getMock();\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $descriptionFactory->shouldIgnoreMissing();\n\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n        $tagFactory->addService($descriptionFactory, DescriptionFactory::class);\n\n        $tag = $tagFactory->create('@see Tag');\n\n        $this->assertInstanceOf(See::class, $tag);\n        $this->assertSame($fqsen, (string) $tag->getReference());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testPassingYourOwnSetOfTagHandlers(): void\n    {\n        $context    = new Context('');\n        $tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));\n        $tagFactory->registerTagHandler('user', Author::class);\n\n        $tag = $tagFactory->create('@user Mike van Riel <me@mikevanriel.com>', $context);\n\n        $this->assertInstanceOf(Author::class, $tag);\n        $this->assertSame('author', $tag->getName());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testPassingYourOwnSetOfTagHandlersWithGermanChars(): void\n    {\n        $fqsenResolver      = new FqsenResolver();\n        $tagFactory         = StandardTagFactory::createInstance($fqsenResolver);\n        $context            = new Context('');\n\n        $tagFactory->registerTagHandler('my-täg', Author::class);\n\n        $tag = $tagFactory->create('@my-täg foo bar ', $context);\n\n        $this->assertInstanceOf(Author::class, $tag);\n        $this->assertSame('author', $tag->getName());\n        $this->assertSame('foo bar', $tag . '');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testPassingYourOwnSetOfTagHandlersWithoutComment(): void\n    {\n        $fqsenResolver      = new FqsenResolver();\n        $tagFactory         = StandardTagFactory::createInstance($fqsenResolver);\n        $context            = new Context('');\n\n        $tagFactory->registerTagHandler('my-täg', Author::class);\n        $tag = $tagFactory->create('@my-täg', $context);\n\n        $this->assertInstanceOf(Author::class, $tag);\n        $this->assertSame('author', $tag->getName());\n    }\n\n    public function testTagWithHandlerObject(): void\n    {\n        $fqsenResolver = new FqsenResolver();\n\n        $customFactory = new CustomTagFactory();\n        $injectedClass = new CustomServiceClass();\n\n        $tagFactory = StandardTagFactory::createInstance($fqsenResolver);\n        $tagFactory->addService($injectedClass);\n        $tagFactory->registerTagHandler('param', $customFactory);\n        $tag = $tagFactory->create('@param foo');\n\n        self::assertSame('custom', $tag->getName());\n        self::assertSame($injectedClass, $customFactory->class);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testPassingYourOwnSetOfTagHandlersWithEmptyComment(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $this->expectExceptionMessage(\n            'The tag \"@my-täg \" does not seem to be wellformed, please check it for errors'\n        );\n\n        $fqsenResolver      = new FqsenResolver();\n        $context            = new Context('');\n\n        $tagFactory = StandardTagFactory::createInstance(\n            $fqsenResolver,\n        );\n\n        $tagFactory->create('@my-täg ', $context);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     *\n     * @covers ::create\n     */\n    public function testExceptionIsThrownIfProvidedTagIsNotWellformed(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $this->expectExceptionMessage(\n            'The tag \"@user[myuser\" does not seem to be wellformed, please check it for errors'\n        );\n        $tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));\n        $tagFactory->create('@user[myuser');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     *\n     * @covers ::__construct\n     * @covers ::addParameter\n     */\n    public function testAddParameterToServiceLocator(): void\n    {\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n        $tagFactory->registerTagHandler('spy', CustomParam::class);\n\n        $tagFactory->addParameter('myParam', 'myValue');\n        $spy = $tagFactory->create('@spy');\n\n        self::assertInstanceOf(CustomParam::class, $spy);\n        $this->assertSame($resolver, $spy->fqsenResolver);\n        $this->assertSame('myValue', $spy->myParam);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     *\n     * @covers ::addService\n     */\n    public function testAddServiceToServiceLocator(): void\n    {\n        $service = new PassthroughFormatter();\n\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n        $tagFactory->addService($service);\n        $tagFactory->registerTagHandler('spy', CustomServiceClass::class);\n\n        $spy = $tagFactory->create('@spy');\n\n        self::assertInstanceOf(CustomServiceClass::class, $spy);\n        $this->assertSame($service, $spy->formatter);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     *\n     * @covers ::addService\n     */\n    public function testInjectConcreteServiceForInterfaceToServiceLocator(): void\n    {\n        $interfaceName = Formatter::class;\n        $service       = new PassthroughFormatter();\n\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n        $tagFactory->addService($service, $interfaceName);\n        $tagFactory->registerTagHandler('spy', CustomServiceInterface::class);\n\n        $spy = $tagFactory->create('@spy');\n\n        self::assertInstanceOf(CustomServiceInterface::class, $spy);\n        $this->assertSame($service, $spy->formatter);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::create\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author\n     *\n     * @covers ::registerTagHandler\n     */\n    public function testRegisteringAHandlerForANewTag(): void\n    {\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n\n        $tagFactory->registerTagHandler('my-tag', Author::class);\n\n        // Assert by trying to create one\n        $tag = $tagFactory->create('@my-tag Mike van Riel <me@mikevanriel.com>');\n        $this->assertInstanceOf(Author::class, $tag);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     *\n     * @covers ::registerTagHandler\n     */\n    public function testHandlerRegistrationFailsIfProvidedTagNameIsNamespaceButNotFullyQualified(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n        // phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName\n        $tagFactory->registerTagHandler(\n            Tag::class, // @phpstan-ignore class.notFound\n            Author::class\n        );\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     *\n     * @covers ::registerTagHandler\n     */\n    public function testHandlerRegistrationFailsIfProvidedHandlerIsEmpty(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n        //@phpstan-ignore argument.type\n        $tagFactory->registerTagHandler('my-tag', '');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     *\n     * @covers ::registerTagHandler\n     */\n    public function testHandlerRegistrationFailsIfProvidedHandlerIsNotAnExistingClassName(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n\n        //@phpstan-ignore argument.type\n        $tagFactory->registerTagHandler('my-tag', 'IDoNotExist');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     *\n     * @covers ::registerTagHandler\n     */\n    public function testHandlerRegistrationFailsIfProvidedHandlerDoesNotImplementTheTagInterface(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $resolver   = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($resolver);\n\n        //@phpstan-ignore argument.type\n        $tagFactory->registerTagHandler('my-tag', 'stdClass');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::__construct\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::addService\n     * @uses \\phpDocumentor\\Reflection\\Docblock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Docblock\\Tags\\Return_\n     * @uses \\phpDocumentor\\Reflection\\Docblock\\Tags\\BaseTag\n     *\n     * @covers ::create\n     */\n    public function testReturnTagIsMappedCorrectly(): void\n    {\n        $context = new Context('');\n\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $descriptionFactory\n            ->shouldReceive('create')\n            ->once()\n            ->with('mixed test', $context)\n            ->andReturn(new Description(''));\n\n        $typeResolver = new TypeResolver();\n\n        $tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));\n        $tagFactory->addService($descriptionFactory, DescriptionFactory::class);\n        $tagFactory->addService($typeResolver, TypeResolver::class);\n\n        $tag = $tagFactory->create('@deprecated mixed test', $context);\n\n        $this->assertInstanceOf(Deprecated::class, $tag);\n        $this->assertSame('deprecated', $tag->getName());\n    }\n\n    /**\n     * @dataProvider validTagProvider\n     */\n    public function testValidFormattedTags(string $input, string $tagName, string $render): void\n    {\n        $fqsenResolver = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($fqsenResolver);\n        $tagFactory->registerTagHandler('tag', Generic::class);\n        $tag = $tagFactory->create($input);\n\n        self::assertSame($tagName, $tag->getName());\n        self::assertSame($render, $tag->render());\n    }\n\n    /**\n     * @return string[][]\n     * @phpstan-return array<string, array<int, string>>\n     */\n    public function validTagProvider(): array\n    {\n        //rendered result is adding a space, because the tags are not rendered properly.\n        return [\n            'tag without body' => [\n                '@tag',\n                'tag',\n                '@tag',\n            ],\n            'tag specialization' => [\n                '@tag:some-spec body',\n                'tag:some-spec',\n                '@tag:some-spec body',\n            ],\n            'tag specialization followed by parenthesis' => [\n                '@tag:some-spec(body)',\n                'tag:some-spec',\n                '@tag:some-spec (body)',\n            ],\n            'tag with textual description' => [\n                '@tag some text',\n                'tag',\n                '@tag some text',\n            ],\n            'tag body starting with square brackets is allowed' => [\n                '@tag [is valid]',\n                'tag',\n                '@tag [is valid]',\n            ],\n            'tag body starting with curly brackets is allowed' => [\n                '@tag {is valid}',\n                'tag',\n                '@tag {is valid}',\n            ],\n            'tag name followed by curly brackets directly is allowed' => [\n                '@tag{is valid}',\n                'tag',\n                '@tag {is valid}',\n            ],\n            'parenthesis directly following a tag name is valid' => [\n                '@tag(is valid)',\n                'tag',\n                '@tag (is valid)',\n            ],\n            'full-qualified-class-name following a tag name is valid' => [\n                '@tag \\InvalidArgumentException',\n                'tag',\n                '@tag \\InvalidArgumentException',\n            ],\n        ];\n    }\n\n    /**\n     * @dataProvider invalidTagProvider\n     */\n    public function testInValidFormattedTags(string $input): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $fqsenResolver = m::mock(FqsenResolver::class);\n        $tagFactory = StandardTagFactory::createInstance($fqsenResolver);\n        $tagFactory->registerTagHandler('tag', Generic::class);\n        $tagFactory->create($input);\n    }\n\n    /**\n     * @return string[][]\n     * @phpstan-return list<array<int, string>>\n     */\n    public function invalidTagProvider(): array\n    {\n        return [\n            ['@tag[invalid]'],\n            ['@tag@invalid'],\n        ];\n    }\n\n    /**\n     * @param class-string $expectedClass\n     *\n     * @dataProvider provideCreateWithTagWithTypesData\n     */\n    public function testCreateWithTagWithTypes(string $input, string $expectedClass): void\n    {\n        $tagFactory = StandardTagFactory::createInstance(new FqsenResolver());\n        $tag = $tagFactory->create($input);\n\n        $this->assertInstanceOf($expectedClass, $tag);\n    }\n\n    /**\n     * @return list<array{string, class-string}>\n     */\n    public static function provideCreateWithTagWithTypesData(): array\n    {\n        return [\n            ['@mixin Foo', Mixin::class],\n            ['@method string do()', Method::class],\n            ['@param Foo $bar', Param::class],\n            ['@property-read Foo $bar', PropertyRead::class],\n            ['@property Foo $bar', Property::class],\n            ['@property-write Foo $bar', PropertyWrite::class],\n            ['@return string', Return_::class],\n            ['@throws Throwable', Throws::class],\n            ['@var string $var', Var_::class],\n            ['@template T', Template::class],\n            ['@template-covariant T', TemplateCovariant::class],\n            ['@extends Foo<Bar>', Extends_::class],\n            ['@implements Foo<Bar>', Implements_::class],\n\n            // TODO: add factories for this tags\n            // ['@template-extends Foo', TemplateExtends::class],\n            // ['@template-implements Foo', TemplateImplements::class],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/AuthorTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author\n * @covers ::<private>\n */\nclass AuthorTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Author('Mike van Riel', 'mike@phpdoc.org');\n\n        $this->assertSame('author', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Author('Mike van Riel', 'mike@phpdoc.org');\n\n        $this->assertSame('@author Mike van Riel <mike@phpdoc.org>', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Author('Mike van Riel', 'mike@phpdoc.org');\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getAuthorName\n     */\n    public function testHasTheAuthorName(): void\n    {\n        $expected = 'Mike van Riel';\n\n        $fixture = new Author($expected, 'mike@phpdoc.org');\n\n        self::assertInstanceOf(Author::class, $fixture);\n        $this->assertSame($expected, $fixture->getAuthorName());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getEmail\n     */\n    public function testHasTheAuthorMailAddress(): void\n    {\n        $expected = 'mike@phpdoc.org';\n\n        $fixture = new Author('Mike van Riel', $expected);\n\n        self::assertInstanceOf(Author::class, $fixture);\n        $this->assertSame($expected, $fixture->getEmail());\n    }\n\n    /**\n     * @covers ::__construct\n     */\n    public function testInitializationFailsIfEmailIsNotValid(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        new Author('Mike van Riel', 'mike');\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Author('Mike van Riel', 'mike@phpdoc.org');\n\n        $this->assertSame('Mike van Riel <mike@phpdoc.org>', (string) $fixture);\n\n        // ---\n\n        $fixture = new Author('0', 'zero@foo.bar');\n\n        $this->assertSame('0 <zero@foo.bar>', (string) $fixture);\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutName(): void\n    {\n        $fixture = new Author('', 'mike@phpdoc.org');\n\n        $this->assertSame('<mike@phpdoc.org>', (string) $fixture);\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationWithEmptyEmail(): void\n    {\n        $fixture = new Author('Mike van Riel', '');\n\n        $this->assertSame('Mike van Riel', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author::<public>\n     *\n     * @covers ::create\n     * @dataProvider authorTagProvider\n     */\n    public function testFactoryMethod(string $input, string $output, string $name, string $email): void\n    {\n        $fixture = Author::create($input);\n\n        self::assertInstanceOf(Author::class, $fixture);\n        $this->assertSame($output, (string) $fixture);\n        $this->assertSame($name, $fixture->getAuthorName());\n        $this->assertSame($email, $fixture->getEmail());\n    }\n\n    /** @return mixed[][] */\n    public function authorTagProvider(): array\n    {\n        return [\n            [\n                'Mike van Riel <mike@phpdoc.org>',\n                'Mike van Riel <mike@phpdoc.org>',\n                'Mike van Riel',\n                'mike@phpdoc.org',\n            ],\n            [\n                'Mike van Riel < mike@phpdoc.org >',\n                'Mike van Riel <mike@phpdoc.org>',\n                'Mike van Riel',\n                'mike@phpdoc.org',\n            ],\n            [\n                'Mike van Riel',\n                'Mike van Riel',\n                'Mike van Riel',\n                '',\n            ],\n        ];\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author::<public>\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodReturnsNullIfItCouldNotReadBody(): void\n    {\n        $this->assertNull(Author::create('dfgr<'));\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/CoversTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\TagFactory;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers\n * @covers ::<private>\n */\nclass CoversTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Covers(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $this->assertSame('covers', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Covers(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $this->assertSame('@covers \\DateTime Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Covers(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getReference\n     */\n    public function testHasReferenceToFqsen(): void\n    {\n        $expected = new Fqsen('\\DateTime');\n\n        $fixture = new Covers($expected);\n\n        $this->assertSame($expected, $fixture->getReference());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Covers(new Fqsen('\\DateTime'), $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Covers(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $this->assertSame('\\DateTime Description', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Fqsen\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $resolver           = m::mock(FqsenResolver::class);\n        $context            = new Context('');\n\n        $fqsen       = new Fqsen('\\DateTime');\n        $description = new Description('My Description');\n\n        $descriptionFactory\n            ->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n        $resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen);\n\n        $fixture = Covers::create('DateTime My Description', $descriptionFactory, $resolver, $context);\n\n        $this->assertSame('\\DateTime My Description', (string) $fixture);\n        $this->assertSame($fqsen, $fixture->getReference());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Covers(new Fqsen('\\\\'));\n\n        $this->assertSame('\\\\', (string) $fixture);\n\n        // ---\n\n        $fixture = new Covers(new Fqsen('\\DateTime'));\n\n        $this->assertSame('\\DateTime', (string) $fixture);\n\n        // ---\n\n        $fixture = new Covers(new Fqsen('\\DateTime'), new Description(''));\n\n        $this->assertSame('\\DateTime', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithSpaceBeforeClass(): void\n    {\n        $fqsenResolver      = new FqsenResolver();\n        $descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));\n        $context            = new Context('');\n\n        $fixture = Covers::create(\n            'Foo My Description ',\n            $descriptionFactory,\n            $fqsenResolver,\n            $context\n        );\n\n        $this->assertSame('\\Foo My Description ', (string) $fixture);\n        $this->assertSame('\\Foo', (string) $fixture->getReference());\n        $this->assertSame('My Description ', $fixture->getDescription() . '');\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithDescription(): void\n    {\n        $fixture = new Covers(new Fqsen('\\DateTime'), new Description('My Description'));\n\n        $this->assertSame('\\DateTime My Description', (string) $fixture);\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfBodyIsNotEmpty(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $this->assertNull(Covers::create(''));\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/DeprecatedTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated\n * @covers ::<private>\n */\nclass DeprecatedTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Deprecated('1.0', new Description('Description'));\n\n        $this->assertSame('deprecated', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Deprecated('1.0', new Description('Description'));\n\n        $this->assertSame('@deprecated 1.0 Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Deprecated('1.0', new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVersion\n     */\n    public function testHasVersionNumber(): void\n    {\n        $expected = '1.0';\n\n        $fixture = new Deprecated($expected);\n\n        $this->assertSame($expected, $fixture->getVersion());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Deprecated('1.0', $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Deprecated('1.0', new Description('Description'));\n\n        $this->assertSame('1.0 Description', (string) $fixture);\n\n        // ---\n\n        $fixture = new Deprecated(null, new Description('My Description'));\n\n        $this->assertSame('My Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Deprecated(null, new Description(''));\n\n        $this->assertSame('', (string) $fixture);\n\n        // ---\n\n        $fixture = new Deprecated('1.0', new Description(''));\n\n        $this->assertSame('1.0', (string) $fixture);\n\n        // ---\n\n        $fixture = new Deprecated('1.0');\n\n        $this->assertSame('1.0', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $context            = new Context('');\n\n        $version     = '1.0';\n        $description = new Description('My Description');\n\n        $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n\n        $fixture = Deprecated::create('1.0 My Description', $descriptionFactory, $context);\n\n        $this->assertSame('1.0 My Description', (string) $fixture);\n        $this->assertSame($version, $fixture->getVersion());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodCreatesEmptyDeprecatedTag(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $descriptionFactory->shouldReceive('create')->never();\n\n        $fixture = Deprecated::create('', $descriptionFactory, new Context(''));\n\n        $this->assertSame('', (string) $fixture);\n        $this->assertNull($fixture->getVersion());\n        $this->assertNull($fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated::__construct\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodReturnsNullIfBodyDoesNotMatchRegex(): void\n    {\n        $this->assertEquals(new Deprecated(), Deprecated::create('dkhf<'));\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/ExampleTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Example\n * @covers ::<private>\n */\nclass ExampleTest extends TestCase\n{\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::create\n     * @covers ::__construct\n     * @covers ::getContent\n     */\n    public function testExampleWithoutContent(): void\n    {\n        $tag = Example::create('\"example1.php\"');\n        self::assertInstanceOf(Example::class, $tag);\n        $this->assertEquals('\"example1.php\"', $tag->getContent());\n        $this->assertEquals('', $tag->getDescription());\n        $this->assertEquals('example', $tag->getName());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::create\n     * @covers ::__construct\n     * @covers ::getFilePath\n     * @covers ::getDescription\n     */\n    public function testWithDescription(): void\n    {\n        $tag = Example::create('\"example1.php\" some text');\n        self::assertInstanceOf(Example::class, $tag);\n        $this->assertEquals('example1.php', $tag->getFilePath());\n        $this->assertEquals('some text', $tag->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::create\n     * @covers ::__construct\n     * @covers ::getFilePath\n     * @covers ::getStartingLine\n     */\n    public function testStartlineIsParsed(): void\n    {\n        $tag = Example::create('\"example1.php\" 10');\n        self::assertInstanceOf(Example::class, $tag);\n        $this->assertEquals('example1.php', $tag->getFilePath());\n        $this->assertEquals(10, $tag->getStartingLine());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::create\n     * @covers ::__construct\n     * @covers ::getFilePath\n     * @covers ::getStartingLine\n     * @covers ::getDescription\n     */\n    public function testAllowOmittingLineCount(): void\n    {\n        $tag = Example::create('\"example1.php\" 10 some text');\n        self::assertInstanceOf(Example::class, $tag);\n        $this->assertEquals('example1.php', $tag->getFilePath());\n        $this->assertEquals(10, $tag->getStartingLine());\n        $this->assertEquals('some text', $tag->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @covers ::create\n     * @covers ::__construct\n     * @covers ::getFilePath\n     * @covers ::getStartingLine\n     * @covers ::getLineCount\n     */\n    public function testLengthIsParsed(): void\n    {\n        $tag = Example::create('\"example1.php\" 10 5');\n        self::assertInstanceOf(Example::class, $tag);\n        $this->assertEquals('example1.php', $tag->getFilePath());\n        $this->assertEquals(10, $tag->getStartingLine());\n        $this->assertEquals(5, $tag->getLineCount());\n    }\n\n    /**\n     * @covers ::create\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $tag = Example::create('\"example1.php\" 10 5 test text');\n\n        $this->assertSame('\"example1.php\" 10 5 test text', (string) $tag);\n\n        // ---\n\n        $tag = Example::create('file://example1.php');\n\n        $this->assertSame('file://example1.php', (string) $tag);\n\n        // ---\n\n        $tag = Example::create('0 foo bar');\n\n        $this->assertSame('0 foo bar', (string) $tag);\n\n        // ---\n\n        $tag = Example::create('$redisCluster->pttl(\\'key\\');');\n\n        $this->assertSame('$redisCluster->pttl(\\'key\\');', (string) $tag);\n\n        // ---\n\n        $tag = Example::create(' \"example1.php\" 10 5 test text ');\n\n        $this->assertSame('\"example1.php\" 10 5 test text', (string) $tag);\n    }\n\n    /**\n     * @covers ::create\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $tag = Example::create('');\n\n        $this->assertSame('', (string) $tag);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     *\n     * @dataProvider tagContentProvider\n     * @covers ::create\n     * @covers ::__construct\n     * @covers ::getFilePath\n     * @covers ::getStartingLine\n     * @covers ::getLineCount\n     * @covers ::getDescription\n     * @covers ::getContent\n     */\n    public function testFactoryMethod(\n        string $input,\n        string $filePath,\n        int $startLine,\n        int $lineCount,\n        ?string $description,\n        string $content\n    ): void {\n        $tag = Example::create($input);\n        self::assertInstanceOf(Example::class, $tag);\n        $this->assertSame($filePath, $tag->getFilePath());\n        $this->assertSame($startLine, $tag->getStartingLine());\n        $this->assertSame($lineCount, $tag->getLineCount());\n        $this->assertSame($description, $tag->getDescription());\n        $this->assertSame($content, $tag->getContent());\n    }\n\n    /** @return mixed[][] */\n    public function tagContentProvider(): array\n    {\n        return [\n            [\n                '\"example1.php\" 10 5 test text ',\n                'example1.php',\n                10,\n                5,\n                'test text',\n                'test text',\n            ],\n            [\n                'example1.php 10 5 test text',\n                'example1.php',\n                10,\n                5,\n                'test text',\n                'test text',\n            ],\n            [\n                'example1.php 1 10 test text',\n                'example1.php',\n                1,\n                10,\n                'test text',\n                'test text',\n            ],\n            [\n                'example1.php',\n                'example1.php',\n                1,\n                0,\n                null,\n                'example1.php',\n            ],\n            [\n                'file://example1.php ',\n                'file://example1.php',\n                1,\n                0,\n                '',\n                'file://example1.php',\n            ],\n            [\n                '/example1.php',\n                '/example1.php',\n                1,\n                0,\n                null,\n                '/example1.php',\n            ],\n        ];\n    }\n\n    /**\n     * @dataProvider invalidExampleProvider\n     * @covers ::__construct\n     */\n    public function testValidatesArguments(\n        string $filePath,\n        bool $isUrl,\n        int $startLine,\n        int $lineCount,\n        string $description\n    ): void {\n        $this->expectException(InvalidArgumentException::class);\n\n        new Example(\n            $filePath,\n            $isUrl,\n            $startLine,\n            $lineCount,\n            $description\n        );\n    }\n\n    /** @return mixed[][] */\n    public function invalidExampleProvider(): array\n    {\n        return [\n            'invalid start' => [\n                '/some/path',\n                false,\n                -1,\n                0,\n                'text',\n            ],\n            'invalid start 2' => [\n                '/some/path',\n                false,\n                -10,\n                0,\n                'text',\n            ],\n            'invalid length' => [\n                '/some/path',\n                false,\n                1,\n                -1,\n                'text',\n            ],\n            'invalid length 2' => [\n                '/some/path',\n                false,\n                1,\n                -10,\n                'text',\n            ],\n            'empty filepath' => [\n                '',\n                false,\n                1,\n                0,\n                'text',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/ExtendsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Extends_\n */\nfinal class ExtendsTest extends TestCase\n{\n    public function testExtendsCreatedCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new Extends_($type);\n        $this->assertSame('extends', $fixture->getName());\n        $this->assertSame($type, $fixture->getType());\n    }\n\n    public function testRendersCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new Extends_($type);\n        $this->assertSame('@extends \\\\Type', $fixture->render());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/AbstractPHPStanFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse Exception;\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse PHPStan\\PhpDocParser\\Parser\\ParserException;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\n/**\n * @uses               \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\AbstractPHPStanFactory\n * @uses               \\phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag\n *\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\AbstractPHPStanFactory\n * @covers             ::<private>\n */\nclass AbstractPHPStanFactoryTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testCreateReturnsTagFromSupportingFactory(): void\n    {\n        $tag = m::mock(Tag::class);\n        $factory = m::mock(PHPStanFactory::class);\n        $factory->shouldReceive('supports')->andReturn(true);\n        $factory->shouldReceive('create')->andReturn($tag);\n\n        $sut = new AbstractPHPStanFactory($factory);\n\n        $result = $sut->create('@param string $param');\n\n        self::assertSame($tag, $result);\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testCreateReturnsInvalidTagWhenNoFactorySupports(): void\n    {\n        $factory = m::mock(PHPStanFactory::class);\n        $factory->shouldReceive('supports')->andReturn(false);\n\n        $sut = new AbstractPHPStanFactory($factory);\n\n        $result = $sut->create('@unknown string $param');\n\n        self::assertInstanceOf(InvalidTag::class, $result);\n        self::assertEquals('@unknown', $result->getName());\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testCreateReturnsInvalidTagWithErrorOnFactoryRuntimeException(): void\n    {\n        $factory = m::mock(PHPStanFactory::class);\n        $factory->shouldReceive('supports')->andReturn(true);\n        $factory->shouldReceive('create')->andThrow(new RuntimeException('Factory error'));\n\n        $sut = new AbstractPHPStanFactory($factory);\n\n        $result = $sut->create('@param string $param');\n\n        self::assertInstanceOf(InvalidTag::class, $result);\n        self::assertInstanceOf(Exception::class, $result->getException());\n        self::assertEquals('Factory error', $result->getException()->getMessage());\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testCreateReturnsInvalidTagWithErrorOnFactoryParserException(): void\n    {\n        $exception = m::mock(ParserException::class);\n        $exception->shouldReceive('getMessage')->andReturn('Parser error');\n\n        $factory = m::mock(PHPStanFactory::class);\n        $factory->shouldReceive('supports')->andReturn(true);\n        $factory->shouldReceive('create')->andThrow($exception);\n\n        $sut = new AbstractPHPStanFactory($factory);\n\n        $result = $sut->create('@param string $param');\n\n        self::assertInstanceOf(InvalidTag::class, $result);\n        self::assertSame($exception, $result->getException());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/ExtendsFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Extends_;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\PseudoTypes\\Generic;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Object_;\n\nfinal class ExtendsFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ExtendsFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ExtendsFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ExtendsFactory::supports\n     */\n    public function testExtendsIsCreated(): void\n    {\n        $ast = $this->parseTag('@extends SomeClass<OtherType>');\n        $factory = new ExtendsFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new Extends_(\n                new Generic(new Fqsen('\\\\SomeClass'), [new Object_(new Fqsen('\\\\OtherType'))]),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/ImplementsFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Implements_;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\PseudoTypes\\Generic;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Object_;\n\nfinal class ImplementsFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ImplementsFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ImplementsFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ImplementsFactory::supports\n     */\n    public function testImplementsIsCreated(): void\n    {\n        $ast = $this->parseTag('@implements SomeClass<OtherType>');\n        $factory = new ImplementsFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new Implements_(\n                new Generic(new Fqsen('\\\\SomeClass'), [new Object_(new Fqsen('\\\\OtherType'))]),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Method;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Integer;\nuse phpDocumentor\\Reflection\\Types\\Mixed_;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse phpDocumentor\\Reflection\\Types\\Void_;\n\nfinal class MethodFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodFactory::supports\n     * @dataProvider tagProvider\n     */\n    public function testIsCreated(string $tagLine, Method $tag): void\n    {\n        $ast = $this->parseTag($tagLine);\n        $factory = new MethodFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            $tag,\n            $factory->create($ast, $context)\n        );\n    }\n\n    /** @return array<array<string|Method>> */\n    public function tagProvider(): array\n    {\n        return [\n            [\n                '@method static string myMethod()',\n                new Method(\n                    'myMethod',\n                    [],\n                    new String_(),\n                    true,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method string myMethod()',\n                new Method(\n                    'myMethod',\n                    [],\n                    new String_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method myMethod()',\n                new Method(\n                    'myMethod',\n                    [],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method myMethod($a)',\n                new Method(\n                    'myMethod',\n                    [new MethodParameter('a', new Mixed_())],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method void setInteger(integer $integer)',\n                new Method(\n                    'setInteger',\n                    [new MethodParameter('integer', new Integer())],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method myMethod($a = 1)',\n                new Method(\n                    'myMethod',\n                    [new MethodParameter('a', new Mixed_(), false, false, '1')],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method myMethod(int $a = 1)',\n                new Method(\n                    'myMethod',\n                    [new MethodParameter('a', new Integer(), false, false, '1')],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method myMethod(int ...$a)',\n                new Method(\n                    'myMethod',\n                    [new MethodParameter('a', new Integer(), false, true)],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n            [\n                '@method myMethod(int &$a, string $b)',\n                new Method(\n                    'myMethod',\n                    [\n                        new MethodParameter('a', new Integer(), true, false),\n                        new MethodParameter('b', new String_(), false, false),\n                    ],\n                    new Void_(),\n                    false,\n                    new Description(''),\n                    false,\n                ),\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/MixinFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Mixin;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class MixinFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MixinFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MixinFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MixinFactory::supports\n     */\n    public function testMixinIsCreated(): void\n    {\n        $ast = $this->parseTag('@mixin string');\n        $factory = new MixinFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new Mixin(\n                new String_(),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Param;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\PseudoTypes\\IntegerValue;\nuse phpDocumentor\\Reflection\\PseudoTypes\\StringValue;\nuse phpDocumentor\\Reflection\\Types\\Compound;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Mixed_;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class ParamFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ParamFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ParamFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ParamFactory::supports\n     * @dataProvider paramInputProvider\n     */\n    public function testParamIsCreated(string $input, Tag $expected): void\n    {\n        $ast = $this->parseTag($input);\n        $factory = new ParamFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            $expected,\n            $factory->create($ast, $context)\n        );\n    }\n\n    /**\n     * @return array<int, array<int, string|Param|InvalidTag>>\n     */\n    public function paramInputProvider(): array\n    {\n        return [\n            [\n                '@param string $var',\n                new Param(\n                    'var',\n                    new String_(),\n                    false,\n                    new Description(''),\n                    false\n                ),\n            ],\n            [\n                '@param $param8 Description 4',\n                new Param(\n                    'param8',\n                    new Mixed_(),\n                    false,\n                    new Description('Description 4'),\n                    false\n                ),\n            ],\n            [\n                '@param $param9',\n                new Param(\n                    'param9',\n                    new Mixed_(),\n                    false,\n                    new Description(''),\n                    false\n                ),\n            ],\n            [\n                '@param \\'GET\\'|SomeClass $arg My Description',\n                new Param(\n                    'arg',\n                    new Compound(\n                        [\n                            new StringValue('GET'),\n                            new Object_(new Fqsen('\\SomeClass')),\n                        ]\n                    ),\n                    false,\n                    new Description('My Description'),\n                    false\n                ),\n            ],\n            [\n                '@param 8|SomeClass $arg My Description',\n                new Param(\n                    'arg',\n                    new Compound(\n                        [\n                            new IntegerValue(8),\n                            new Object_(new Fqsen('\\SomeClass')),\n                        ]\n                    ),\n                    false,\n                    new Description('My Description'),\n                    false\n                ),\n            ],\n            [\n                '@param array[\\Illuminate\\Notifications\\Channels\\Notification] $notification',\n                InvalidTag::create('array[\\Illuminate\\Notifications\\Channels\\Notification] $notification', 'param'),\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Property;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class PropertyFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyFactory::supports\n     */\n    public function testParamIsCreated(): void\n    {\n        $ast = $this->parseTag('@property string $var');\n        $factory = new PropertyFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new Property(\n                'var',\n                new String_(),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class PropertyReadFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyReadFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyReadFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyReadFactory::supports\n     */\n    public function testParamIsCreated(): void\n    {\n        $ast = $this->parseTag('@property-read string $var');\n        $factory = new PropertyReadFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new PropertyRead(\n                'var',\n                new String_(),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class PropertyWriteFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyWriteFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyWriteFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyWriteFactory::supports\n     */\n    public function testParamIsCreated(): void\n    {\n        $ast = $this->parseTag('@property-write string $var');\n        $factory = new PropertyWriteFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new PropertyWrite(\n                'var',\n                new String_(),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class ReturnFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ReturnFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ReturnFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ReturnFactory::supports\n     */\n    public function testParamIsCreated(): void\n    {\n        $ast = $this->parseTag('@return string');\n        $factory = new ReturnFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new Return_(\n                new String_(),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php",
    "content": "<?php\n/*\n * This file is part of phpDocumentor.\n *\n *  For the full copyright and license information, please view the LICENSE\n *  file that was distributed with this source code.\n *\n *  @link      http://phpdoc.org\n *\n */\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\TypeResolver;\nuse PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode;\nuse PHPStan\\PhpDocParser\\Lexer\\Lexer;\nuse PHPStan\\PhpDocParser\\Parser\\ConstExprParser;\nuse PHPStan\\PhpDocParser\\Parser\\PhpDocParser;\nuse PHPStan\\PhpDocParser\\Parser\\TokenIterator;\nuse PHPStan\\PhpDocParser\\Parser\\TypeParser;\nuse PHPStan\\PhpDocParser\\ParserConfig;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function property_exists;\n\nabstract class TagFactoryTestCase extends TestCase\n{\n    public function parseTag(string $tag): PhpDocTagNode\n    {\n        $config = new ParserConfig(['indexes' => true, 'lines' => true]);\n        $lexer = new Lexer($config);\n        $constParser = new ConstExprParser($config);\n        $phpDocParser = new PhpDocParser($config, new TypeParser($config, $constParser), $constParser);\n\n        $tagNode = $phpDocParser->parseTag(new TokenIterator($lexer->tokenize($tag)));\n        if (property_exists($tagNode->value, 'description') === true) {\n            $tagNode->value->setAttribute('description', $tagNode->value->description);\n        }\n\n        return $tagNode;\n    }\n\n    public function giveTypeResolver(): TypeResolver\n    {\n        return new TypeResolver(new FqsenResolver());\n    }\n\n    public function givenDescriptionFactory(): DescriptionFactory\n    {\n        $factory =  m::mock(DescriptionFactory::class);\n        $factory->shouldReceive('create')->andReturnUsing(static fn ($args) => new Description($args));\n\n        return $factory;\n    }\n\n    /**\n     * Call Mockery::close after each test.\n     *\n     * @after\n     */\n    public function closeMockery(): void\n    {\n        m::close();\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/TemplateCovariantFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\TemplateCovariant;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class TemplateCovariantFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateCovariantFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateCovariantFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateCovariantFactory::supports\n     * @dataProvider templateCovariantInputProvider\n     */\n    public function testTemplateCovariantIsCreated(string $input, Tag $expected): void\n    {\n        $ast = $this->parseTag($input);\n        $factory = new TemplateCovariantFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            $expected,\n            $factory->create($ast, $context)\n        );\n    }\n\n    /**\n     * @return array<int, array<int, string|TemplateCovariant>>\n     */\n    public function templateCovariantInputProvider(): array\n    {\n        return [\n            [\n                '@template-covariant string',\n                new TemplateCovariant(\n                    new String_(),\n                    new Description('')\n                ),\n            ],\n            [\n                '@template-covariant SomeClass Description',\n                new TemplateCovariant(\n                    new Object_(new Fqsen('\\SomeClass')),\n                    new Description('Description')\n                ),\n            ],\n            [\n                '@template-covariant SomeClass',\n                new TemplateCovariant(\n                    new Object_(new Fqsen('\\SomeClass')),\n                    new Description('')\n                ),\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/TemplateFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Template;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\Mixed_;\nuse phpDocumentor\\Reflection\\Types\\Object_;\n\nfinal class TemplateFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateFactory::supports\n     * @dataProvider templateInputProvider\n     */\n    public function testTemplateIsCreated(string $input, Tag $expected): void\n    {\n        $ast = $this->parseTag($input);\n        $factory = new TemplateFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            $expected,\n            $factory->create($ast, $context)\n        );\n    }\n\n    /**\n     * @return array<int, array<int, string|Template>>\n     */\n    public function templateInputProvider(): array\n    {\n        return [\n            [\n                '@template T',\n                new Template(\n                    'T',\n                    new Mixed_(),\n                    new Mixed_(),\n                    new Description('')\n                ),\n            ],\n            [\n                '@template T of SomeClass Description',\n                new Template(\n                    'T',\n                    new Object_(new Fqsen('\\SomeClass')),\n                    new Mixed_(),\n                    new Description('Description')\n                ),\n            ],\n            [\n                '@template T of SomeClass = Default',\n                new Template(\n                    'T',\n                    new Object_(new Fqsen('\\SomeClass')),\n                    new Object_(new Fqsen('\\Default')),\n                    new Description('')\n                ),\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/ThrowsFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class ThrowsFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ThrowsFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ThrowsFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ThrowsFactory::supports\n     */\n    public function testThrowsIsCreated(): void\n    {\n        $ast = $this->parseTag('@throws string');\n        $factory = new ThrowsFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new Throws(\n                new String_(),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\n\nfinal class VarFactoryTest extends TagFactoryTestCase\n{\n    /**\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\VarFactory::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\VarFactory::create\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\VarFactory::supports\n     */\n    public function testVarIsCreated(): void\n    {\n        $ast = $this->parseTag('@var string $var');\n        $factory = new VarFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());\n        $context = new Context('global');\n\n        self::assertTrue($factory->supports($ast, $context));\n        self::assertEquals(\n            new Var_(\n                'var',\n                new String_(),\n                new Description('')\n            ),\n            $factory->create($ast, $context)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Formatter/AlignFormatterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Link as LinkTag;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Param;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Version;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter\n */\nclass AlignFormatterTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::format\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter::__construct\n     */\n    public function testFormatterCallsToStringAndReturnsAStandardRepresentation(): void\n    {\n        $tags    = [\n            new Param('foobar', new String_()),\n            new Version('1.2.0'),\n            new LinkTag('http://www.example.com', new Description('Examples')),\n        ];\n        $fixture = new AlignFormatter($tags);\n\n        $expected = [\n            '@param   string $foobar',\n            '@version 1.2.0',\n            '@link    http://www.example.com Examples',\n        ];\n\n        foreach ($tags as $key => $tag) {\n            $this->assertSame(\n                $expected[$key],\n                $fixture->format($tag)\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/Formatter/PassthroughFormatterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n */\nclass PassthroughFormatterTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     *\n     * @covers ::format\n     */\n    public function testFormatterCallsToStringAndReturnsAStandardRepresentation(): void\n    {\n        $expected = '@unknown-tag This is a description';\n\n        $fixture = new PassthroughFormatter();\n\n        $this->assertSame(\n            $expected,\n            $fixture->format(new Generic('unknown-tag', new Description('This is a description')))\n        );\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n     *\n     * @covers ::format\n     */\n    public function testFormatterToStringWithoutDescription(): void\n    {\n        $expected = '@unknown-tag';\n        $fixture  = new PassthroughFormatter();\n\n        $this->assertSame(\n            $expected,\n            $fixture->format(new Generic('unknown-tag'))\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/GenericTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @generic      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic\n * @covers ::<private>\n */\nclass GenericTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Generic('generic', new Description('Description'));\n\n        $this->assertSame('generic', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Generic('generic', new Description('Description'));\n\n        $this->assertSame('@generic Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Generic('generic', new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Generic('generic', $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Generic('generic', new Description('Description'));\n\n        $this->assertSame('Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Generic('generic');\n\n        $this->assertSame('', (string) $fixture);\n\n        // ---\n\n        $fixture = new Generic('generic', new Description(''));\n\n        $this->assertSame('', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $context            = new Context('');\n\n        $generics    = 'generic';\n        $description = new Description('My Description');\n\n        $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n\n        $fixture = Generic::create('My Description', 'generic', $descriptionFactory, $context);\n\n        $this->assertSame('My Description', (string) $fixture);\n        $this->assertSame($generics, $fixture->getName());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfNameIsNotEmpty(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        Generic::create('', '');\n    }\n\n    /**\n     * @covers ::create\n     * @covers ::__construct\n     */\n    public function testFactoryMethodFailsIfNameContainsIllegalCharacters(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        Generic::create('', 'name/myname');\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/ImplementsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Implements_\n */\nfinal class ImplementsTest extends TestCase\n{\n    public function testCreatedCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new Implements_($type);\n        $this->assertSame('implements', $fixture->getName());\n        $this->assertSame($type, $fixture->getType());\n    }\n\n    public function testRendersCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new Implements_($type);\n        $this->assertSame('@implements \\\\Type', $fixture->render());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/InvalidTagTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Exception;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\nuse Throwable;\n\nuse function fopen;\nuse function is_string;\nuse function serialize;\nuse function unserialize;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag\n * @covers ::<private>\n * @covers ::getName\n * @covers ::render\n * @covers ::getException\n * @covers ::create\n */\nfinal class InvalidTagTest extends TestCase\n{\n    public function testCreationWithoutError(): void\n    {\n        $tag = InvalidTag::create('Body', 'name');\n\n        self::assertSame('name', $tag->getName());\n        self::assertSame('@name Body', $tag->render());\n        self::assertNull($tag->getException());\n    }\n\n    /**\n     * @covers ::withError\n     * @covers ::__toString\n     */\n    public function testCreationWithError(): void\n    {\n        $exception = new Exception();\n        $tag       = InvalidTag::create('Body', 'name')->withError($exception);\n\n        self::assertSame('name', $tag->getName());\n        self::assertSame('@name Body', $tag->render());\n        self::assertSame('Body', (string) $tag);\n        self::assertSame($exception, $tag->getException());\n    }\n\n    public function testCreationWithErrorContainingClosure(): void\n    {\n        try {\n            $this->throwExceptionFromClosureWithClosureArgument();\n        } catch (Throwable $e) {\n            $parentException = new Exception('test', 0, $e);\n            $tag             = InvalidTag::create('Body', 'name')->withError($parentException);\n            self::assertSame('name', $tag->getName());\n            self::assertSame('@name Body', $tag->render());\n            self::assertSame($parentException, $tag->getException());\n\n            self::assertSame($e, $tag->getException()->getPrevious());\n            $trace = $tag->getException()->getPrevious()->getTrace();\n\n            if (isset($trace[0]['args'])) { // Not set by default on 7.4\n                self::assertTrue(is_string($trace[0]['args'][0]));\n                self::assertStringStartsWith('(Closure at', $trace[0]['args'][0]);\n                self::assertStringContainsString(__FILE__, $trace[0]['args'][0]);\n            }\n\n            self::assertEquals($parentException, unserialize(serialize($parentException)));\n        }\n    }\n\n    private function throwExceptionFromClosureWithClosureArgument(): void\n    {\n        $function = static function (?callable $foo = null): void {\n            throw new InvalidArgumentException();\n        };\n\n        $function($function);\n    }\n\n    public function testCreationWithErrorContainingResource(): void\n    {\n        try {\n            $this->throwExceptionWithResourceArgument();\n        } catch (Throwable $e) {\n            $parentException = new Exception('test', 0, $e);\n            $tag             = InvalidTag::create('Body', 'name')->withError($parentException);\n            self::assertSame('name', $tag->getName());\n            self::assertSame('@name Body', $tag->render());\n            self::assertSame($parentException, $tag->getException());\n            self::assertSame($e, $tag->getException()->getPrevious());\n            $trace = $tag->getException()->getPrevious()->getTrace();\n\n            if (isset($trace[0]['args'])) { // Not set by default on 7.4\n                self::assertTrue(is_string($trace[0]['args'][0]));\n                self::assertStringStartsWith(\n                    'resource(stream)',\n                    $trace[0]['args'][0]\n                );\n            }\n\n            self::assertEquals($parentException, unserialize(serialize($parentException)));\n        }\n    }\n\n    private function throwExceptionWithResourceArgument(): void\n    {\n        $function = static function ($file): void {\n            throw new InvalidArgumentException();\n        };\n\n        $function(fopen(__FILE__, 'r'));\n    }\n\n    public function testCreationWithErrorFromEval(): void\n    {\n        $builder = static function (): InvalidArgumentException {\n            return new InvalidArgumentException();\n        };\n\n        $exception = eval('return $builder();');\n        $tag = InvalidTag::create('Body', 'name')->withError($exception);\n\n        self::assertSame('name', $tag->getName());\n        self::assertSame('@name Body', $tag->render());\n        self::assertSame('Body', (string) $tag);\n        self::assertSame($exception, $tag->getException());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/LinkTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\TagFactory;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link\n * @covers ::<private>\n */\nclass LinkTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Link('http://this.is.my/link', new Description('Description'));\n\n        $this->assertSame('link', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Link('http://this.is.my/link', new Description('Description'));\n\n        $this->assertSame('@link http://this.is.my/link Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Link('http://this.is.my/link', new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getLink\n     */\n    public function testHasLinkUrl(): void\n    {\n        $expected = 'http://this.is.my/link';\n\n        $fixture = new Link($expected);\n\n        $this->assertSame($expected, $fixture->getLink());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Link('http://this.is.my/link', $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Link('http://this.is.my/link', new Description('Description'));\n\n        $this->assertSame('http://this.is.my/link Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Link('http://this.is.my/link');\n\n        $this->assertSame('http://this.is.my/link', (string) $fixture);\n\n        // ---\n\n        $fixture = new Link('http://this.is.my/link', new Description(''));\n\n        $this->assertSame('http://this.is.my/link', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $context            = new Context('');\n\n        $links       = 'http://this.is.my/link';\n        $description = new Description('My Description');\n\n        $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n\n        $fixture = Link::create('http://this.is.my/link My Description', $descriptionFactory, $context);\n\n        $this->assertSame('http://this.is.my/link My Description', (string) $fixture);\n        $this->assertSame($links, $fixture->getLink());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithoutSpaceBeforeUrl(): void\n    {\n        $descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));\n        $context            = new Context('');\n\n        $fixture = Link::create(\n            'http://this.is.my/link My Description ',\n            $descriptionFactory,\n            $context\n        );\n\n        $this->assertSame('http://this.is.my/link My Description ', (string) $fixture);\n        $this->assertSame('My Description ', $fixture->getDescription() . '');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithSpaceBeforeUrl(): void\n    {\n        $descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));\n        $context            = new Context('');\n\n        $fixture = Link::create(\n            ' http://this.is.my/link My Description ',\n            $descriptionFactory,\n            $context\n        );\n\n        $this->assertSame('http://this.is.my/link My Description ', (string) $fixture);\n        $this->assertSame('http://this.is.my/link My Description ', $fixture->getDescription() . '');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodCreatesEmptyLinkTag(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $descriptionFactory->shouldReceive('create')->never();\n\n        $fixture = Link::create('', $descriptionFactory, new Context(''));\n\n        $this->assertSame('', (string) $fixture);\n        $this->assertSame('', $fixture->getLink());\n        $this->assertSame(null, $fixture->getDescription());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/MethodParameterTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\Type;\nuse phpDocumentor\\Reflection\\Types\\Array_;\nuse phpDocumentor\\Reflection\\Types\\Boolean;\nuse phpDocumentor\\Reflection\\Types\\Float_;\nuse phpDocumentor\\Reflection\\Types\\Integer;\nuse phpDocumentor\\Reflection\\Types\\Nullable;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nuse function sprintf;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method\n * @covers ::<private>\n */\nclass MethodParameterTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /** @return array<array{0: Type, 1: mixed, 2: string}> */\n    public function collectionDefaultValuesProvider(): array\n    {\n        return [\n            [new String_(), '1', '\\'1\\''],\n            [new Integer(), 1, '1'],\n            [new Boolean(), true, 'true'],\n            [new Float_(), 1.23, '1.23'],\n            [new Array_(), [1, '2', true], '[1,\\'2\\',true]'],\n            [new Array_(), [[1, 2], '2', true], '[[1,2],\\'2\\',true]'],\n            [new Nullable(new Float_()), null, 'null'],\n            [new Nullable(new Float_()), 1.23, '1.23'],\n            [new Object_(new Fqsen('\\\\stdClass')), new stdClass(), 'new stdClass()'],\n        ];\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter::getDefaultValue()\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @param mixed $defaultValue\n     *\n     * @dataProvider collectionDefaultValuesProvider\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingMethodParameterWithDefaultValue(\n        Type $type,\n        $defaultValue,\n        string $defaultValueStr\n    ): void {\n        $fixture = new MethodParameter('argument', $type, false, false, $defaultValue);\n\n        $this->assertSame(\n            sprintf('%s $argument = %s', $type, $defaultValueStr),\n            (string) $fixture\n        );\n        $this->assertSame(\n            $defaultValueStr,\n            $fixture->getDefaultValue()\n        );\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter::getDefaultValue()\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\MethodParameter::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingMethodParameterWithNoDefaultValue(): void\n    {\n        $fixture = new MethodParameter('argument', new Float_());\n\n        $this->assertSame(\n            'float $argument',\n            (string) $fixture\n        );\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/MethodTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Exception\\CannotCreateTag;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse phpDocumentor\\Reflection\\Types\\Void_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method\n * @covers ::<private>\n */\nclass MethodTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Method('myMethod');\n\n        $this->assertSame('method', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method::isStatic\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $arguments = [\n            new MethodParameter('argument1', new String_()),\n            new MethodParameter('argument2', new Object_()),\n        ];\n\n        $fixture = new Method(\n            'myMethod',\n            $arguments,\n            new Void_(),\n            true,\n            new Description('My Description')\n        );\n\n        $this->assertSame(\n            '@method static void myMethod(string $argument1, object $argument2) My Description',\n            $fixture->render()\n        );\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Method('myMethod');\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->allows('format')->with($fixture)->andReturns('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getMethodName\n     */\n    public function testHasMethodName(): void\n    {\n        $expected = 'myMethod';\n\n        $fixture = new Method($expected);\n\n        $this->assertSame($expected, $fixture->getMethodName());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getArguments\n     */\n    public function testHasArguments(): void\n    {\n        $arguments = [\n            new MethodParameter('argument1', new String_()),\n        ];\n\n        $fixture = new Method('myMethod', $arguments);\n\n        $this->assertSame($arguments, $fixture->getParameters());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getReturnType\n     */\n    public function testHasReturnType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new Method('myMethod', [], $expected);\n\n        $this->assertSame($expected, $fixture->getReturnType());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getReturnType\n     */\n    public function testReturnTypeCanBeInferredAsVoid(): void\n    {\n        $fixture = new Method('myMethod', []);\n\n        $this->assertEquals(new Void_(), $fixture->getReturnType());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::isStatic\n     */\n    public function testMethodCanBeStatic(): void\n    {\n        $expected = false;\n        $fixture  = new Method('myMethod', [], null, $expected);\n        $this->assertSame($expected, $fixture->isStatic());\n\n        $expected = true;\n        $fixture  = new Method('myMethod', [], null, $expected);\n        $this->assertSame($expected, $fixture->isStatic());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Method('myMethod', [], null, false, $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method::isStatic\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $arguments = [\n            new MethodParameter('argument1', new String_()),\n            new MethodParameter('argument2', new Object_()),\n        ];\n        $fixture   = new Method('myMethod', $arguments, new Void_(), true, new Description('My Description'));\n\n        $this->assertSame(\n            'static void myMethod(string $argument1, object $argument2) My Description',\n            (string) $fixture\n        );\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method::isStatic\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Method('myMethod', [], null, false, new Description(''));\n\n        $this->assertSame(\n            'void myMethod()',\n            (string) $fixture\n        );\n\n        $arguments = [\n            new MethodParameter('argument1', new String_()),\n            new MethodParameter('argument2', new Object_()),\n        ];\n        $fixture   = new Method('myMethod', $arguments, new Void_(), true);\n\n        $this->assertSame(\n            'static void myMethod(string $argument1, object $argument2)',\n            (string) $fixture\n        );\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getReturnType\n     */\n    public function testReturnsReference(): void\n    {\n        $expected = new String_();\n\n        $fixture = new Method('myMethod', [], $expected);\n\n        $this->assertFalse($fixture->returnsReference());\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodThrows(): void\n    {\n        $this->expectException(CannotCreateTag::class);\n        Method::create('');\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/ParamTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param\n * @covers ::<private>\n */\nclass ParamTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Param('myParameter', null, false, new Description('Description'));\n\n        $this->assertSame('param', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param::isVariadic\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Param('myParameter', new String_(), true, new Description('Description'));\n        $this->assertSame('@param string ...$myParameter Description', $fixture->render());\n\n        $fixture = new Param('myParameter', new String_(), false, new Description('Description'));\n        $this->assertSame('@param string $myParameter Description', $fixture->render());\n\n        $fixture = new Param('myParameter', null, false, new Description('Description'));\n        $this->assertSame('@param $myParameter Description', $fixture->render());\n\n        $fixture = new Param('myParameter');\n        $this->assertSame('@param $myParameter', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Param('myParameter');\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVariableName\n     */\n    public function testHasVariableName(): void\n    {\n        $expected = 'myParameter';\n\n        $fixture = new Param($expected);\n\n        $this->assertSame($expected, $fixture->getVariableName());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getType\n     */\n    public function testHasType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new Param('myParameter', $expected);\n\n        $this->assertSame($expected, $fixture->getType());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::isVariadic\n     */\n    public function testIfParameterIsVariadic(): void\n    {\n        $fixture = new Param('myParameter', new String_(), false);\n        $this->assertFalse($fixture->isVariadic());\n\n        $fixture = new Param('myParameter', new String_(), true);\n        $this->assertTrue($fixture->isVariadic());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Param('1.0', null, false, $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::isVariadic\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Param('myParameter', new String_(), true, new Description('Description'));\n\n        $this->assertSame('string ...$myParameter Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param::isReference\n     */\n    public function testIsReference(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Param('1.0', null, false, $expected);\n\n        $this->assertFalse($fixture->isReference());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/PropertyReadTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead\n * @covers ::<private>\n */\nclass PropertyReadTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new PropertyRead('myProperty', null, new Description('Description'));\n\n        $this->assertSame('property-read', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new PropertyRead('myProperty', new String_(), new Description('Description'));\n        $this->assertSame('@property-read string $myProperty Description', $fixture->render());\n\n        $fixture = new PropertyRead('myProperty', null, new Description('Description'));\n        $this->assertSame('@property-read $myProperty Description', $fixture->render());\n\n        $fixture = new PropertyRead('myProperty');\n        $this->assertSame('@property-read $myProperty', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new PropertyRead('myProperty');\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVariableName\n     */\n    public function testHasVariableName(): void\n    {\n        $expected = 'myProperty';\n\n        $fixture = new PropertyRead($expected);\n\n        $this->assertSame($expected, $fixture->getVariableName());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getType\n     */\n    public function testHasType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new PropertyRead('myProperty', $expected);\n\n        $this->assertSame($expected, $fixture->getType());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new PropertyRead('1.0', null, $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new PropertyRead('myProperty', new String_(), new Description('Description'));\n\n        $this->assertSame('string $myProperty Description', (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/PropertyTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Property\n * @covers ::<private>\n */\nclass PropertyTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Property::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Property('myProperty', null, new Description('Description'));\n\n        $this->assertSame('property', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Property::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Property::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Property('myProperty', new String_(), new Description('Description'));\n        $this->assertSame('@property string $myProperty Description', $fixture->render());\n\n        $fixture = new Property('myProperty', null, new Description('Description'));\n        $this->assertSame('@property $myProperty Description', $fixture->render());\n\n        $fixture = new Property('myProperty');\n        $this->assertSame('@property $myProperty', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Property::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Property('myProperty');\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVariableName\n     */\n    public function testHasVariableName(): void\n    {\n        $expected = 'myProperty';\n\n        $fixture = new Property($expected);\n\n        $this->assertSame($expected, $fixture->getVariableName());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getType\n     */\n    public function testHasType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new Property('myProperty', $expected);\n\n        $this->assertSame($expected, $fixture->getType());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Property('1.0', null, $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Property('myProperty', new String_(), new Description('Description'));\n\n        $this->assertSame('string $myProperty Description', (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/PropertyWriteTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite\n * @covers ::<private>\n */\nclass PropertyWriteTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new PropertyWrite('myProperty', null, new Description('Description'));\n\n        $this->assertSame('property-write', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new PropertyWrite('myProperty', new String_(), new Description('Description'));\n        $this->assertSame('@property-write string $myProperty Description', $fixture->render());\n\n        $fixture = new PropertyWrite('myProperty', null, new Description('Description'));\n        $this->assertSame('@property-write $myProperty Description', $fixture->render());\n\n        $fixture = new PropertyWrite('myProperty');\n        $this->assertSame('@property-write $myProperty', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new PropertyWrite('myProperty');\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVariableName\n     */\n    public function testHasVariableName(): void\n    {\n        $expected = 'myProperty';\n\n        $fixture = new PropertyWrite($expected);\n\n        $this->assertSame($expected, $fixture->getVariableName());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getType\n     */\n    public function testHasType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new PropertyWrite('myProperty', $expected);\n\n        $this->assertSame($expected, $fixture->getType());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new PropertyWrite('1.0', null, $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new PropertyWrite('myProperty', new String_(), new Description('Description'));\n\n        $this->assertSame('string $myProperty Description', (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/ReturnTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_\n * @covers ::<private>\n */\nclass ReturnTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Return_(new String_(), new Description('Description'));\n\n        $this->assertSame('return', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Return_(new String_(), new Description('Description'));\n\n        $this->assertSame('@return string Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Return_(new String_(), new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getType\n     */\n    public function testHasType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new Return_($expected);\n\n        $this->assertSame($expected, $fixture->getType());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Return_(new String_(), $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Return_(new String_(), new Description('Description'));\n\n        $this->assertSame('string Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Return_(new String_());\n\n        $this->assertSame('string', (string) $fixture);\n\n        // ---\n\n        $fixture = new Return_(new String_(), new Description(''));\n\n        $this->assertSame('string', (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/SeeTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\TagFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen as FqsenRef;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen as TagsFqsen;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url as UrlRef;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See\n * @covers ::<private>\n */\nclass SeeTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses   \\phpDocumentor\\Reflection\\Fqsen\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new See(new FqsenRef(new Fqsen('\\DateTime')), new Description('Description'));\n\n        $this->assertSame('see', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new See(new FqsenRef(new Fqsen('\\DateTime')), new Description('Description'));\n\n        $this->assertSame('@see \\DateTime Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses   \\phpDocumentor\\Reflection\\Fqsen\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new See(new FqsenRef(new Fqsen('\\DateTime')), new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses   \\phpDocumentor\\Reflection\\Fqsen\n     *\n     * @covers ::__construct\n     * @covers ::getReference\n     */\n    public function testHasReferenceToFqsen(): void\n    {\n        $expected = new FqsenRef(new Fqsen('\\DateTime'));\n\n        $fixture = new See($expected);\n\n        $this->assertSame($expected, $fixture->getReference());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses   \\phpDocumentor\\Reflection\\Fqsen\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new See(new FqsenRef(new Fqsen('\\DateTime')), $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses   \\phpDocumentor\\Reflection\\Fqsen\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new See(new FqsenRef(new Fqsen('\\DateTime::format()')), new Description('Description'));\n\n        $this->assertSame('\\DateTime::format() Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses   \\phpDocumentor\\Reflection\\Fqsen\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new See(new FqsenRef(new Fqsen('\\DateTime::format()')));\n\n        $this->assertSame('\\DateTime::format()', (string) $fixture);\n\n        // ---\n\n        $fixture = new See(new FqsenRef(new Fqsen('\\DateTime::format()')), new Description(''));\n\n        $this->assertSame('\\DateTime::format()', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses \\phpDocumentor\\Reflection\\Fqsen\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $resolver           = m::mock(FqsenResolver::class);\n        $context            = new Context('');\n\n        $fqsen       = new Fqsen('\\DateTime');\n        $description = new Description('My Description');\n\n        $descriptionFactory\n            ->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n        $resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen);\n\n        $fixture = See::create('DateTime My Description', $resolver, $descriptionFactory, $context);\n\n        $this->assertSame('\\DateTime My Description', (string) $fixture);\n        $this->assertInstanceOf(FqsenRef::class, $fixture->getReference());\n        $this->assertSame((string) $fqsen, (string) $fixture->getReference());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen\n     * @uses \\phpDocumentor\\Reflection\\Fqsen\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithNonClassFQSEN(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $resolver           = m::mock(FqsenResolver::class);\n        $context            = new Context('');\n\n        $fqsen       = new Fqsen('\\DateTime');\n        $description = new Description('My Description');\n\n        $descriptionFactory\n            ->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n        $resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen);\n\n        $fixture = See::create('DateTime::createFromFormat() My Description', $resolver, $descriptionFactory, $context);\n\n        $this->assertSame('\\DateTime::createFromFormat() My Description', (string) $fixture);\n        $this->assertInstanceOf(FqsenRef::class, $fixture->getReference());\n        $this->assertSame('\\DateTime::createFromFormat()', (string) $fixture->getReference());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithUrl(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $resolver           = m::mock(FqsenResolver::class);\n        $context            = new Context('');\n\n        $description = new Description('My Description');\n\n        $descriptionFactory\n            ->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n\n        $resolver->shouldNotReceive('resolve');\n\n        $fixture = See::create('https://test.org My Description', $resolver, $descriptionFactory, $context);\n\n        $this->assertSame('https://test.org My Description', (string) $fixture);\n        $this->assertInstanceOf(UrlRef::class, $fixture->getReference());\n        $this->assertSame('https://test.org', (string) $fixture->getReference());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithoutUrl(): void\n    {\n        $fqsenResolver      = new FqsenResolver();\n        $descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));\n        $context            = new Context('');\n\n        $fixture = See::create(\n            'Foo My Description ',\n            $fqsenResolver,\n            $descriptionFactory,\n            $context\n        );\n\n        $this->assertSame('\\Foo My Description ', (string) $fixture);\n        $this->assertInstanceOf(TagsFqsen::class, $fixture->getReference());\n        $this->assertSame('\\Foo', (string) $fixture->getReference());\n        $this->assertSame('My Description ', $fixture->getDescription() . '');\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfBodyIsNotEmpty(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $this->assertNull(See::create(''));\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfResolverIsNull(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        See::create('body');\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfDescriptionFactoryIsNull(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        See::create('body', new FqsenResolver());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/SinceTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since\n * @covers ::<private>\n */\nclass SinceTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Since('1.0', new Description('Description'));\n\n        $this->assertSame('since', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Since('1.0', new Description('Description'));\n\n        $this->assertSame('@since 1.0 Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Since('1.0', new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVersion\n     */\n    public function testHasVersionNumber(): void\n    {\n        $expected = '1.0';\n\n        $fixture = new Since($expected);\n\n        $this->assertSame($expected, $fixture->getVersion());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Since('1.0', $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Since('1.0', new Description('Description'));\n\n        $this->assertSame('1.0 Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Since('1.0');\n\n        $this->assertSame('1.0', (string) $fixture);\n\n        // ---\n\n        $fixture = new Since('1.0', new Description(''));\n\n        $this->assertSame('1.0', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $context            = new Context('');\n\n        $version     = '1.0';\n        $description = new Description('My Description');\n\n        $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n\n        $fixture = Since::create('1.0 My Description', $descriptionFactory, $context);\n\n        self::assertInstanceOf(Since::class, $fixture);\n        $this->assertSame('1.0 My Description', (string) $fixture);\n        $this->assertSame($version, $fixture->getVersion());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodCreatesEmptySinceTag(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $descriptionFactory->shouldReceive('create')->never();\n\n        $fixture = Since::create('', $descriptionFactory, new Context(''));\n\n        self::assertInstanceOf(Since::class, $fixture);\n        $this->assertSame('', (string) $fixture);\n        $this->assertSame(null, $fixture->getVersion());\n        $this->assertSame(null, $fixture->getDescription());\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodReturnsNullIfBodyDoesNotMatchRegex(): void\n    {\n        $this->assertNull(Since::create('dkhf<'));\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/SourceTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source\n * @covers ::<private>\n */\nclass SourceTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Source(1, null, new Description('Description'));\n\n        $this->assertSame('source', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Source(1, 10, new Description('Description'));\n        $this->assertSame('@source 1 10 Description', $fixture->render());\n\n        $fixture = new Source(1, null, new Description('Description'));\n        $this->assertSame('@source 1 Description', $fixture->render());\n\n        $fixture = new Source(1);\n        $this->assertSame('@source 1', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Source(1);\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getStartingLine\n     */\n    public function testHasStartingLine(): void\n    {\n        $expected = 1;\n\n        $fixture = new Source($expected);\n\n        $this->assertSame($expected, $fixture->getStartingLine());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getLineCount\n     */\n    public function testHasLineCount(): void\n    {\n        $expected = 2;\n\n        $fixture = new Source(1, $expected);\n\n        $this->assertSame($expected, $fixture->getLineCount());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Source('1', null, $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Source(1, 10, new Description('Description'));\n\n        $this->assertSame('1 10 Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Source(1);\n\n        $this->assertSame('1', (string) $fixture);\n\n        // ---\n\n        $fixture = new Source(1, 0);\n\n        $this->assertSame('1 0', (string) $fixture);\n\n        // ---\n\n        $fixture = new Source(1, 10, new Description(''));\n\n        $this->assertSame('1 10', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $context            = new Context('');\n\n        $description = new Description('My Description');\n        $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n\n        $fixture = Source::create('1 10 My Description', $descriptionFactory, $context);\n\n        $this->assertSame('1 10 My Description', (string) $fixture);\n        $this->assertSame(1, $fixture->getStartingLine());\n        $this->assertSame(10, $fixture->getLineCount());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source::<public>\n     * @uses \\phpDocumentor\\Reflection\\TypeResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfEmptyBodyIsGiven(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        Source::create('', $descriptionFactory);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\TypeResolver\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfDescriptionFactoryIsNull(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        Source::create('1');\n    }\n\n    /**\n     * @covers ::__construct\n     */\n    public function testExceptionIsThrownIfStartingLineIsNotInteger(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        new Source('blabla');\n    }\n\n    /**\n     * @covers ::__construct\n     */\n    public function testExceptionIsThrownIfLineCountIsNotIntegerOrNull(): void\n    {\n        $this->expectException('InvalidArgumentException');\n\n        //@phpstan-ignore argument.type\n        new Source('1', []);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/TemplateExtendsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\TemplateExtends\n */\nfinal class TemplateExtendsTest extends TestCase\n{\n    public function testExtendsCreatedCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new TemplateExtends($type);\n        $this->assertSame('template-extends', $fixture->getName());\n        $this->assertSame($type, $fixture->getType());\n    }\n\n    public function testRendersCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new TemplateExtends($type);\n        $this->assertSame('@template-extends \\\\Type', $fixture->render());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/TemplateImplementsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\Types\\Object_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\TemplateImplements\n */\nfinal class TemplateImplementsTest extends TestCase\n{\n    public function testCreatedCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new TemplateImplements($type);\n        $this->assertSame('template-implements', $fixture->getName());\n        $this->assertSame($type, $fixture->getType());\n    }\n\n    public function testRendersCorrectly(): void\n    {\n        $type = new Object_(new Fqsen('\\\\Type'));\n        $fixture = new TemplateImplements($type);\n        $this->assertSame('@template-implements \\\\Type', $fixture->render());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/TemplateTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\Mixed_;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Template\n * @covers ::<private>\n */\nfinal class TemplateTest extends TestCase\n{\n    /**\n     * @covers ::__construct\n     * @covers ::getTemplateName\n     * @covers ::getBound\n     * @covers ::getDefault\n     */\n    public function testTemplateCreatedCorrectly(): void\n    {\n        $fixture = new Template('myTemplate', new String_(), new Mixed_(), new Description(''));\n        $this->assertSame('template', $fixture->getName());\n        $this->assertSame('myTemplate', $fixture->getTemplateName());\n        $this->assertEquals(new String_(), $fixture->getBound());\n        $this->assertEquals(new Mixed_(), $fixture->getDefault());\n    }\n\n    public function testRendersCorrectly(): void\n    {\n        $fixture = new Template('myTemplate', new String_(), null, new Description(''));\n        $this->assertSame('@template myTemplate of string', $fixture->render());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/ThrowsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws\n * @covers ::<private>\n */\nclass ThrowsTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Throws(new String_(), new Description('Description'));\n\n        $this->assertSame('throws', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Throws(new String_(), new Description('Description'));\n\n        $this->assertSame('@throws string Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Throws(new String_(), new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getType\n     */\n    public function testHasType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new Throws($expected);\n\n        $this->assertSame($expected, $fixture->getType());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Throws(new String_(), $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Throws(new String_(), new Description('Description'));\n\n        $this->assertSame('string Description', (string) $fixture);\n\n        // ---\n\n        $fixture = new Throws(new String_(), new Description('My Description'));\n\n        $this->assertSame('string My Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Throws(new String_());\n\n        $this->assertSame('string', (string) $fixture);\n\n        // ---\n\n        $fixture = new Throws(new String_(), new Description(''));\n\n        $this->assertSame('string', (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/UsesTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\TagFactory;\nuse phpDocumentor\\Reflection\\Fqsen;\nuse phpDocumentor\\Reflection\\FqsenResolver;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses\n * @covers ::<private>\n */\nclass UsesTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Uses(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $this->assertSame('uses', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Uses(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $this->assertSame('@uses \\DateTime Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Uses(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getReference\n     */\n    public function testHasReferenceToFqsen(): void\n    {\n        $expected = new Fqsen('\\DateTime');\n\n        $fixture = new Uses($expected);\n\n        $this->assertSame($expected, $fixture->getReference());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Uses(new Fqsen('\\DateTime'), $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Uses(new Fqsen('\\DateTime'), new Description('Description'));\n\n        $this->assertSame('\\DateTime Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Uses(new Fqsen('\\\\'));\n\n        $this->assertSame('\\\\', (string) $fixture);\n\n        // ---\n\n        $fixture = new Uses(new Fqsen('\\DateTime'));\n\n        $this->assertSame('\\DateTime', (string) $fixture);\n\n        // ---\n\n        $fixture = new Uses(new Fqsen('\\DateTime'), new Description(''));\n\n        $this->assertSame('\\DateTime', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Fqsen\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $resolver           = m::mock(FqsenResolver::class);\n        $context            = new Context('');\n\n        $fqsen       = new Fqsen('\\DateTime');\n        $description = new Description('My Description');\n\n        $descriptionFactory\n            ->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n        $resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen);\n\n        $fixture = Uses::create('DateTime My Description', $resolver, $descriptionFactory, $context);\n\n        $this->assertSame('\\DateTime My Description', (string) $fixture);\n        $this->assertSame($fqsen, $fixture->getReference());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithoutSpaceBeforeClass(): void\n    {\n        $fqsenResolver      = new FqsenResolver();\n        $descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));\n        $context            = new Context('');\n\n        $fixture = Uses::create(\n            'Foo My Description ',\n            $fqsenResolver,\n            $descriptionFactory,\n            $context\n        );\n\n        $this->assertSame('\\Foo My Description ', (string) $fixture);\n        $this->assertInstanceOf(Fqsen::class, $fixture->getReference());\n        $this->assertSame('\\\\Foo', (string) $fixture->getReference());\n        $this->assertSame('My Description ', $fixture->getDescription() . '');\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\See::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\FqsenResolver\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodWithSpaceBeforeClass(): void\n    {\n        $fqsenResolver      = new FqsenResolver();\n        $descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));\n        $context            = new Context('');\n\n        $fixture = Uses::create(\n            ' Foo My Description ',\n            $fqsenResolver,\n            $descriptionFactory,\n            $context\n        );\n\n        $this->assertSame('\\ Foo My Description ', (string) $fixture);\n        $this->assertInstanceOf(Fqsen::class, $fixture->getReference());\n        $this->assertSame('\\\\', (string) $fixture->getReference());\n        $this->assertSame('Foo My Description ', $fixture->getDescription() . '');\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfBodyIsNotEmpty(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $this->assertNull(Uses::create(''));\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfResolverIsNull(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        Uses::create('body');\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodFailsIfDescriptionFactoryIsNull(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        Uses::create('body', new FqsenResolver());\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/VarTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_\n * @covers ::<private>\n */\nclass VarTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Var_('myVariable', null, new Description('Description'));\n\n        $this->assertSame('var', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfVariableNameIsOmittedIfEmpty(): void\n    {\n        $fixture = new Var_('', null, null);\n\n        $this->assertSame('@var', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Var_('myVariable', new String_(), new Description('Description'));\n        $this->assertSame('@var string $myVariable Description', $fixture->render());\n\n        $fixture = new Var_('myVariable', null, new Description('Description'));\n        $this->assertSame('@var $myVariable Description', $fixture->render());\n\n        $fixture = new Var_('myVariable');\n        $this->assertSame('@var $myVariable', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_::__construct\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Var_('myVariable');\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVariableName\n     */\n    public function testHasVariableName(): void\n    {\n        $expected = 'myVariable';\n\n        $fixture = new Var_($expected);\n\n        $this->assertSame($expected, $fixture->getVariableName());\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getType\n     */\n    public function testHasType(): void\n    {\n        $expected = new String_();\n\n        $fixture = new Var_('myVariable', $expected);\n\n        $this->assertSame($expected, $fixture->getType());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Var_('1.0', null, $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Var_('myVariable', new String_(), new Description('Description'));\n\n        $this->assertSame('string $myVariable Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\String_\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Var_('myVariable');\n\n        $this->assertSame('$myVariable', (string) $fixture);\n\n        // ---\n\n        $fixture = new Var_('myVariable', new String_());\n\n        $this->assertSame('string $myVariable', (string) $fixture);\n\n        // ---\n\n        $fixture = new Var_('myVariable', new String_(), new Description(''));\n\n        $this->assertSame('string $myVariable', (string) $fixture);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlock/Tags/VersionTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection\\DocBlock\\Tags;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version\n * @covers ::<private>\n */\nclass VersionTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfCorrectTagNameIsReturned(): void\n    {\n        $fixture = new Version('1.0', new Description('Description'));\n\n        $this->assertSame('version', $fixture->getName());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version::__toString\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getName\n     */\n    public function testIfTagCanBeRenderedUsingDefaultFormatter(): void\n    {\n        $fixture = new Version('1.0', new Description('Description'));\n\n        $this->assertSame('@version 1.0 Description', $fixture->render());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version::__construct\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::render\n     */\n    public function testIfTagCanBeRenderedUsingSpecificFormatter(): void\n    {\n        $fixture = new Version('1.0', new Description('Description'));\n\n        $formatter = m::mock(Formatter::class);\n        $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output');\n\n        $this->assertSame('Rendered output', $fixture->render($formatter));\n    }\n\n    /**\n     * @covers ::__construct\n     * @covers ::getVersion\n     */\n    public function testHasVersionNumber(): void\n    {\n        $expected = '1.0';\n\n        $fixture = new Version($expected);\n\n        $this->assertSame($expected, $fixture->getVersion());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers \\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag::getDescription\n     */\n    public function testHasDescription(): void\n    {\n        $expected = new Description('Description');\n\n        $fixture = new Version('1.0', $expected);\n\n        $this->assertSame($expected, $fixture->getDescription());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturned(): void\n    {\n        $fixture = new Version('1.0', new Description('Description'));\n\n        $this->assertSame('1.0 Description', (string) $fixture);\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::__toString\n     */\n    public function testStringRepresentationIsReturnedWithoutDescription(): void\n    {\n        $fixture = new Version('1.0');\n\n        $this->assertSame('1.0', (string) $fixture);\n\n        // ---\n\n        $fixture = new Version('1.0', new Description(''));\n\n        $this->assertSame('1.0', (string) $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethod(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $context            = new Context('');\n\n        $version     = '1.0';\n        $description = new Description('My Description');\n\n        $descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description);\n\n        $fixture = Version::create('1.0 My Description', $descriptionFactory, $context);\n\n        self::assertInstanceOf(Version::class, $fixture);\n        $this->assertSame('1.0 My Description', (string) $fixture);\n        $this->assertSame($version, $fixture->getVersion());\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version::<public>\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::create\n     */\n    public function testFactoryMethodCreatesEmptyVersionTag(): void\n    {\n        $descriptionFactory = m::mock(DescriptionFactory::class);\n        $descriptionFactory->shouldReceive('create')->never();\n\n        $fixture = Version::create('', $descriptionFactory, new Context(''));\n\n        self::assertInstanceOf(Version::class, $fixture);\n        $this->assertSame('', (string) $fixture);\n        $this->assertSame(null, $fixture->getVersion());\n        $this->assertSame(null, $fixture->getDescription());\n    }\n\n    /**\n     * @covers ::create\n     */\n    public function testFactoryMethodReturnsNullIfBodyDoesNotMatchRegex(): void\n    {\n        $this->assertNull(Version::create('dkhf<'));\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlockFactoryTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Description;\nuse phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tag;\nuse phpDocumentor\\Reflection\\DocBlock\\TagFactory;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Param;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\n\nuse function str_replace;\n\nuse const PHP_EOL;\n\n/**\n * @uses               \\Webmozart\\Assert\\Assert\n * @uses               \\phpDocumentor\\Reflection\\DocBlock\n *\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlockFactory\n * @covers             ::<private>\n */\nclass DocBlockFactoryTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     *\n     * @covers ::__construct\n     * @covers ::createInstance\n     */\n    public function testCreateFactoryUsingFactoryMethod(): void\n    {\n        $fixture = DocBlockFactory::createInstance();\n\n        $this->assertInstanceOf(DocBlockFactory::class, $fixture);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testCreateDocBlockFromReflection(): void\n    {\n        $fixture = new DocBlockFactory(m::mock(DescriptionFactory::class), m::mock(TagFactory::class));\n\n        $docBlock       = '/** This is a DocBlock */';\n        $classReflector = m::mock(ReflectionClass::class);\n        $classReflector->shouldReceive('getDocComment')->andReturn($docBlock);\n        $docblock = $fixture->create($classReflector);\n\n        $this->assertInstanceOf(DocBlock::class, $docblock);\n        $this->assertSame('This is a DocBlock', $docblock->getSummary());\n        $this->assertEquals(new Description(''), $docblock->getDescription());\n        $this->assertSame([], $docblock->getTags());\n        $this->assertEquals(new Context(''), $docblock->getContext());\n        $this->assertNull($docblock->getLocation());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testCreateDocBlockFromStringWithDocComment(): void\n    {\n        $fixture = new DocBlockFactory(m::mock(DescriptionFactory::class), m::mock(TagFactory::class));\n\n        $docblock = $fixture->create('/** This is a DocBlock */');\n\n        $this->assertInstanceOf(DocBlock::class, $docblock);\n        $this->assertSame('This is a DocBlock', $docblock->getSummary());\n        $this->assertEquals(new Description(''), $docblock->getDescription());\n        $this->assertSame([], $docblock->getTags());\n        $this->assertEquals(new Context(''), $docblock->getContext());\n        $this->assertNull($docblock->getLocation());\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::create\n     * @covers ::__construct\n     */\n    public function testCreateDocBlockFromStringWithoutDocComment(): void\n    {\n        $fixture = new DocBlockFactory(m::mock(DescriptionFactory::class), m::mock(TagFactory::class));\n\n        $docblock = $fixture->create('This is a DocBlock');\n\n        $this->assertInstanceOf(DocBlock::class, $docblock);\n        $this->assertSame('This is a DocBlock', $docblock->getSummary());\n        $this->assertEquals(new Description(''), $docblock->getDescription());\n        $this->assertSame([], $docblock->getTags());\n        $this->assertEquals(new Context(''), $docblock->getContext());\n        $this->assertNull($docblock->getLocation());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     *\n     * @dataProvider provideSummaryAndDescriptions\n     */\n    public function testSummaryAndDescriptionAreSeparated(string $given, string $summary, string $description): void\n    {\n        $tagFactory = m::mock(TagFactory::class);\n        $fixture    = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory);\n\n        $docblock = $fixture->create($given);\n\n        $this->assertSame($summary, $docblock->getSummary());\n        $this->assertEquals(new Description(str_replace(PHP_EOL, \"\\n\", $description)), $docblock->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testDescriptionsRetainFormatting(): void\n    {\n        $tagFactory = m::mock(TagFactory::class);\n        $fixture    = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory);\n\n        $given = <<<DOCBLOCK\n/**\n * This is a summary.\n * This is a multiline Description\n * that contains a code block.\n *\n *     See here: a CodeBlock\n */\nDOCBLOCK;\n\n        $description = \"This is a multiline Description\\nthat contains a code block.\\n\\n    See here: a CodeBlock\";\n\n        $docblock = $fixture->create($given);\n\n        $this->assertEquals(new Description($description), $docblock->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testTagsAreInterpretedUsingFactory(): void\n    {\n        $tag        = m::mock(Tag::class);\n        $tagFactory = m::mock(TagFactory::class);\n        $tagFactory->shouldReceive('create')->with(m::any(), m::type(Context::class))->andReturn($tag);\n\n        $fixture = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory);\n\n        $given = <<<DOCBLOCK\n/**\n * This is a summary.\n *\n * @author Mike van Riel <me@mikevanriel.com> This is with\n *   multiline description.\n */\nDOCBLOCK;\n\n        $docblock = $fixture->create($given, new Context(''));\n\n        $this->assertEquals([$tag], $docblock->getTags());\n    }\n\n    /**\n     * @return array<int, array<int, string>>\n     */\n    public function provideSummaryAndDescriptions(): array\n    {\n        return [\n            ['This is a DocBlock', 'This is a DocBlock', ''],\n            [\n                'This is a DocBlock. This should still be summary.',\n                'This is a DocBlock. This should still be summary.',\n                '',\n            ],\n            [\n                <<<DOCBLOCK\nThis is a DocBlock.\nThis should be a Description.\nDOCBLOCK\n,\n                'This is a DocBlock.',\n                'This should be a Description.',\n            ],\n            [\n                <<<DOCBLOCK\nThis is a\nmultiline Summary.\nThis should be a Description.\nDOCBLOCK\n,\n                \"This is a\\nmultiline Summary.\",\n                'This should be a Description.',\n            ],\n            [\n                <<<DOCBLOCK\nThis is a Summary without dot but with a whiteline\n\nThis should be a Description.\nDOCBLOCK\n,\n                'This is a Summary without dot but with a whiteline',\n                'This should be a Description.',\n            ],\n            [\n                <<<DOCBLOCK\nThis is a Summary with dot and with a whiteline.\n\nThis should be a Description.\nDOCBLOCK\n,\n                'This is a Summary with dot and with a whiteline.',\n                'This should be a Description.',\n            ],\n        ];\n    }\n\n    /**\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses   \\phpDocumentor\\Reflection\\Types\\Context\n     * @uses   \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param\n     *\n     * @covers ::__construct\n     * @covers ::create\n     */\n    public function testTagsWithContextNamespace(): void\n    {\n        $tagFactoryMock = m::mock(TagFactory::class);\n        $fixture        = new DocBlockFactory(m::mock(DescriptionFactory::class), $tagFactoryMock);\n        $context        = new Context('MyNamespace');\n\n        $tagFactoryMock->shouldReceive('create')->with(m::any(), $context)->andReturn(new Param('param'));\n        $docblock = $fixture->create('/** @param MyType $param */', $context);\n\n        $this->assertInstanceOf(DocBlock::class, $docblock);\n    }\n}\n"
  },
  {
    "path": "tests/unit/DocBlockTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This file is part of phpDocumentor.\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n *\n * @link      http://phpdoc.org\n */\n\nnamespace phpDocumentor\\Reflection;\n\nuse Mockery as m;\nuse phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated;\nuse phpDocumentor\\Reflection\\Types\\Context;\nuse phpDocumentor\\Reflection\\Types\\String_;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @uses \\Webmozart\\Assert\\Assert\n *\n * @coversDefaultClass \\phpDocumentor\\Reflection\\DocBlock\n * @covers ::<private>\n */\nclass DocBlockTest extends TestCase\n{\n    /**\n     * Call Mockery::close after each test.\n     */\n    public function tearDown(): void\n    {\n        m::close();\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::getSummary\n     */\n    public function testDocBlockCanHaveASummary(): void\n    {\n        $summary = 'This is a summary';\n\n        $fixture = new DocBlock($summary);\n\n        $this->assertSame($summary, $fixture->getSummary());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::getSummary\n     */\n    public function testDocBlockCanHaveEllipsisInSummary(): void\n    {\n        $summary = 'This is a short (...) description.';\n\n        $fixture = new DocBlock($summary);\n\n        $this->assertSame($summary, $fixture->getSummary());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::getDescription\n     */\n    public function testDocBlockCanHaveADescription(): void\n    {\n        $description = new DocBlock\\Description('');\n\n        $fixture = new DocBlock('', $description);\n\n        $this->assertSame($description, $fixture->getDescription());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tag\n     *\n     * @covers ::__construct\n     * @covers ::getTags\n     */\n    public function testDocBlockCanHaveTags(): void\n    {\n        $tags = [\n            m::mock(DocBlock\\Tag::class),\n        ];\n\n        $fixture = new DocBlock('', null, $tags);\n\n        $this->assertSame($tags, $fixture->getTags());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tag\n     *\n     * @covers ::__construct\n     * @covers ::getTags\n     */\n    public function testDocBlockAllowsOnlyTags(): void\n    {\n        $this->expectException('InvalidArgumentException');\n        $tags = [null];\n        // @phpstan-ignore argument.type\n        new DocBlock('', null, $tags);\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock::getTags\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tag\n     *\n     * @covers ::__construct\n     * @covers ::getTagsByName\n     */\n    public function testFindTagsInDocBlockByName(): void\n    {\n        $tag1 = m::mock(DocBlock\\Tag::class);\n        $tag2 = m::mock(DocBlock\\Tag::class);\n        $tag3 = m::mock(DocBlock\\Tag::class);\n        $tag4 = m::mock(DocBlock\\Tag::class);\n        $tags = [$tag1, $tag2, $tag3, $tag4];\n\n        $tag1->shouldReceive('getName')->andReturn('abc');\n        $tag2->shouldReceive('getName')->andReturn('abcd');\n        $tag4->shouldReceive('getName')->andReturn('abcd');\n        $tag3->shouldReceive('getName')->andReturn('ab');\n\n        $fixture = new DocBlock('', null, $tags);\n\n        $this->assertSame([$tag2, $tag4], $fixture->getTagsByName('abcd'));\n        $this->assertSame([], $fixture->getTagsByName('Ebcd'));\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock::getTags\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tag\n     *\n     * @covers ::__construct\n     * @covers ::getTagsWithTypeByName\n     */\n    public function testFindTagsWithTypeInDocBlockByName(): void\n    {\n        $tag1 = new DocBlock\\Tags\\Var_('foo', new String_());\n        $tag2 = new DocBlock\\Tags\\Var_('bar', new String_());\n        $tag3 = new DocBlock\\Tags\\Return_(new String_());\n        $tag4 = new DocBlock\\Tags\\Author('lall', '');\n\n        $fixture = new DocBlock('', null, [$tag1, $tag2, $tag3, $tag4]);\n\n        $this->assertSame([$tag1, $tag2], $fixture->getTagsWithTypeByName('var'));\n        $this->assertSame([$tag3], $fixture->getTagsWithTypeByName('return'));\n        $this->assertSame([], $fixture->getTagsWithTypeByName('author'));\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock::getTags\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tag\n     *\n     * @covers ::__construct\n     * @covers ::hasTag\n     */\n    public function testCheckIfThereAreTagsWithAGivenName(): void\n    {\n        $tag1 = m::mock(DocBlock\\Tag::class);\n        $tag2 = m::mock(DocBlock\\Tag::class);\n        $tag3 = m::mock(DocBlock\\Tag::class);\n        $tags = [$tag1, $tag2, $tag3];\n\n        $tag1->shouldReceive('getName')->twice()->andReturn('abc');\n        $tag2->shouldReceive('getName')->twice()->andReturn('abcd');\n        $tag3->shouldReceive('getName')->once();\n\n        $fixture = new DocBlock('', null, $tags);\n\n        $this->assertTrue($fixture->hasTag('abcd'));\n        $this->assertFalse($fixture->hasTag('Ebcd'));\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Types\\Context\n     *\n     * @covers ::__construct\n     * @covers ::getContext\n     */\n    public function testDocBlockKnowsInWhichNamespaceItIsAndWhichAliasesThereAre(): void\n    {\n        $context = new Context('');\n\n        $fixture = new DocBlock('', null, [], $context);\n\n        $this->assertSame($context, $fixture->getContext());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     * @uses \\phpDocumentor\\Reflection\\Location\n     *\n     * @covers ::__construct\n     * @covers ::getLocation\n     */\n    public function testDocBlockKnowsAtWhichLineItIs(): void\n    {\n        $location = new Location(10);\n\n        $fixture = new DocBlock('', null, [], null, $location);\n\n        $this->assertSame($location, $fixture->getLocation());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::isTemplateStart\n     * @covers ::isTemplateEnd\n     */\n    public function testDocBlockIsNotATemplateByDefault(): void\n    {\n        $fixture = new DocBlock('', null, [], null, null);\n\n        $this->assertFalse($fixture->isTemplateStart());\n        $this->assertFalse($fixture->isTemplateEnd());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::isTemplateStart\n     */\n    public function testDocBlockKnowsIfItIsTheStartOfADocBlockTemplate(): void\n    {\n        $fixture = new DocBlock('', null, [], null, null, true);\n\n        $this->assertTrue($fixture->isTemplateStart());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Description\n     *\n     * @covers ::__construct\n     * @covers ::isTemplateEnd\n     */\n    public function testDocBlockKnowsIfItIsTheEndOfADocBlockTemplate(): void\n    {\n        $fixture = new DocBlock('', null, [], null, null, false, true);\n\n        $this->assertTrue($fixture->isTemplateEnd());\n    }\n\n    /**\n     * @uses \\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated\n     *\n     * @covers ::__construct\n     * @covers ::removeTag\n     */\n    public function testRemoveTag(): void\n    {\n        $someTag    = new Deprecated();\n        $anotherTag = new Deprecated();\n\n        $fixture = new DocBlock('', null, [$someTag]);\n\n        $this->assertCount(1, $fixture->getTags());\n\n        $fixture->removeTag($anotherTag);\n\n        $this->assertCount(1, $fixture->getTags());\n\n        $fixture->removeTag($someTag);\n\n        $this->assertCount(0, $fixture->getTags());\n    }\n}\n"
  },
  {
    "path": "tests/unit/Exception/PcreExceptionTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection\\Exception;\n\nuse PHPUnit\\Framework\\TestCase;\n\nuse const PREG_BACKTRACK_LIMIT_ERROR;\nuse const PREG_BAD_UTF8_ERROR;\nuse const PREG_BAD_UTF8_OFFSET_ERROR;\nuse const PREG_INTERNAL_ERROR;\nuse const PREG_JIT_STACKLIMIT_ERROR;\nuse const PREG_NO_ERROR;\nuse const PREG_RECURSION_LIMIT_ERROR;\n\n/**\n * @coversDefaultClass \\phpDocumentor\\Reflection\\Exception\\PcreException\n */\nfinal class PcreExceptionTest extends TestCase\n{\n    /**\n     * @covers ::createFromPhpError\n     * @dataProvider errorCodeProvider\n     */\n    public function testErrorConversion(int $errorCode, string $message): void\n    {\n        $this->assertSame($message, PcreException::createFromPhpError($errorCode)->getMessage());\n    }\n\n    /**\n     * @return array<int, (string|int)[]>\n     */\n    public function errorCodeProvider(): array\n    {\n        return [\n            [\n                PREG_BACKTRACK_LIMIT_ERROR,\n                'Backtrack limit error',\n            ],\n            [\n                PREG_RECURSION_LIMIT_ERROR,\n                'Recursion limit error',\n            ],\n            [\n                PREG_BAD_UTF8_ERROR,\n                'Bad UTF8 error',\n            ],\n            [\n                PREG_BAD_UTF8_OFFSET_ERROR,\n                'Bad UTF8 offset error',\n            ],\n            [\n                PREG_JIT_STACKLIMIT_ERROR,\n                'Jit stacklimit error',\n            ],\n            [\n                PREG_NO_ERROR,\n                'Unknown Pcre error',\n            ],\n            [\n                PREG_INTERNAL_ERROR,\n                'Unknown Pcre error',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/unit/PregSplitTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace phpDocumentor\\Reflection;\n\nuse phpDocumentor\\Reflection\\Exception\\PcreException;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function set_error_handler;\n\nuse const E_WARNING;\n\nfinal class PregSplitTest extends TestCase\n{\n    /** @var callable|null */\n    private $errorHandler = null;\n\n    protected function tearDown(): void\n    {\n        if ($this->errorHandler === null) {\n            return;\n        }\n\n        set_error_handler($this->errorHandler, E_WARNING);\n    }\n\n    /**\n     * @covers \\phpDocumentor\\Reflection\\Utils::pregSplit\n     */\n    public function testSimplePregSplit(): void\n    {\n        $result = Utils::pregSplit('/\\s/', 'word split');\n\n        $this->assertSame(['word', 'split'], $result);\n    }\n\n    /**\n     * @covers \\phpDocumentor\\Reflection\\Utils::pregSplit\n     */\n    public function testPregSplitThrowsOnError(): void\n    {\n        //We need to disable the error handler for phpunit... because we expect some errors here\n        $this->errorHandler = set_error_handler(\n            static function (int $i, string $s, string $s2, int $x, ?array $trace = null): bool {\n                return true;\n            },\n            E_WARNING\n        );\n\n        $this->expectException(PcreException::class);\n        Utils::pregSplit('~InvalidRegular)Expression~', 'some word');\n    }\n}\n"
  }
]