diff options
Diffstat (limited to 'vendor/phpdocumentor/reflection-docblock/src/DocBlock')
35 files changed, 3443 insertions, 0 deletions
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php new file mode 100644 index 0000000..25a79e0 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php @@ -0,0 +1,114 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter; +use Webmozart\Assert\Assert; + +/** + * Object representing to description for a DocBlock. + * + * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine + * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete + * description text using the format that you would prefer. + * + * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is + * thus recommended to use that to create a Description object, like this: + * + * $description = $descriptionFactory->create('This is a {@see Description}', $context); + * + * The description factory will interpret the given body and create a body template and list of tags from them, and pass + * that onto the constructor if this class. + * + * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace + * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial + * > type names and FQSENs. + * + * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this: + * + * $description = new Description( + * 'This is a %1$s', + * [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ] + * ); + * + * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object + * is mainly responsible for rendering. + * + * @see DescriptionFactory to create a new Description. + * @see Description\Formatter for the formatting of the body and tags. + */ +class Description +{ + /** @var string */ + private $bodyTemplate; + + /** @var Tag[] */ + private $tags; + + /** + * Initializes a Description with its body (template) and a listing of the tags used in the body template. + * + * @param string $bodyTemplate + * @param Tag[] $tags + */ + public function __construct($bodyTemplate, array $tags = []) + { + Assert::string($bodyTemplate); + + $this->bodyTemplate = $bodyTemplate; + $this->tags = $tags; + } + + /** + * Returns the tags for this DocBlock. + * + * @return Tag[] + */ + public function getTags() + { + return $this->tags; + } + + /** + * Renders this description as a string where the provided formatter will format the tags in the expected string + * format. + * + * @param Formatter|null $formatter + * + * @return string + */ + public function render(Formatter $formatter = null) + { + if ($formatter === null) { + $formatter = new PassthroughFormatter(); + } + + $tags = []; + foreach ($this->tags as $tag) { + $tags[] = '{' . $formatter->format($tag) . '}'; + } + + return vsprintf($this->bodyTemplate, $tags); + } + + /** + * Returns a plain string representation of this description. + * + * @return string + */ + public function __toString() + { + return $this->render(); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php new file mode 100644 index 0000000..48f9c21 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php @@ -0,0 +1,191 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\Types\Context as TypeContext; + +/** + * Creates a new Description object given a body of text. + * + * Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their + * body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the + * Description object's `render` method. + * + * In addition to the above does a Description support two types of escape sequences: + * + * 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}` + * 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description + * of an inline tag. + * + * If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning + * of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping + * over unexpected spaces as can be observed with tag descriptions. + */ +class DescriptionFactory +{ + /** @var TagFactory */ + private $tagFactory; + + /** + * Initializes this factory with the means to construct (inline) tags. + * + * @param TagFactory $tagFactory + */ + public function __construct(TagFactory $tagFactory) + { + $this->tagFactory = $tagFactory; + } + + /** + * Returns the parsed text of this description. + * + * @param string $contents + * @param TypeContext $context + * + * @return Description + */ + public function create($contents, TypeContext $context = null) + { + list($text, $tags) = $this->parse($this->lex($contents), $context); + + return new Description($text, $tags); + } + + /** + * Strips the contents from superfluous whitespace and splits the description into a series of tokens. + * + * @param string $contents + * + * @return string[] A series of tokens of which the description text is composed. + */ + private function lex($contents) + { + $contents = $this->removeSuperfluousStartingWhitespace($contents); + + // performance optimalization; if there is no inline tag, don't bother splitting it up. + if (strpos($contents, '{@') === false) { + return [$contents]; + } + + return preg_split( + '/\{ + # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally. + (?!@\}) + # We want to capture the whole tag line, but without the inline tag delimiters. + (\@ + # Match everything up to the next delimiter. + [^{}]* + # Nested inline tag content should not be captured, or it will appear in the result separately. + (?: + # Match nested inline tags. + (?: + # Because we did not catch the tag delimiters earlier, we must be explicit with them here. + # Notice that this also matches "{}", as a way to later introduce it as an escape sequence. + \{(?1)?\} + | + # Make sure we match hanging "{". + \{ + ) + # Match content after the nested inline tag. + [^{}]* + )* # If there are more inline tags, match them as well. We use "*" since there may not be any + # nested inline tags. + ) + \}/Sux', + $contents, + null, + PREG_SPLIT_DELIM_CAPTURE + ); + } + + /** + * Parses the stream of tokens in to a new set of tokens containing Tags. + * + * @param string[] $tokens + * @param TypeContext $context + * + * @return string[]|Tag[] + */ + private function parse($tokens, TypeContext $context) + { + $count = count($tokens); + $tagCount = 0; + $tags = []; + + for ($i = 1; $i < $count; $i += 2) { + $tags[] = $this->tagFactory->create($tokens[$i], $context); + $tokens[$i] = '%' . ++$tagCount . '$s'; + } + + //In order to allow "literal" inline tags, the otherwise invalid + //sequence "{@}" is changed to "@", and "{}" is changed to "}". + //"%" is escaped to "%%" because of vsprintf. + //See unit tests for examples. + for ($i = 0; $i < $count; $i += 2) { + $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]); + } + + return [implode('', $tokens), $tags]; + } + + /** + * Removes the superfluous from a multi-line description. + * + * When a description has more than one line then it can happen that the second and subsequent lines have an + * additional indentation. This is commonly in use with tags like this: + * + * {@}since 1.1.0 This is an example + * description where we have an + * indentation in the second and + * subsequent lines. + * + * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent + * lines and this may cause rendering issues when, for example, using a Markdown converter. + * + * @param string $contents + * + * @return string + */ + private function removeSuperfluousStartingWhitespace($contents) + { + $lines = explode("\n", $contents); + + // if there is only one line then we don't have lines with superfluous whitespace and + // can use the contents as-is + if (count($lines) <= 1) { + return $contents; + } + + // determine how many whitespace characters need to be stripped + $startingSpaceCount = 9999999; + for ($i = 1; $i < count($lines); $i++) { + // lines with a no length do not count as they are not indented at all + if (strlen(trim($lines[$i])) === 0) { + continue; + } + + // determine the number of prefixing spaces by checking the difference in line length before and after + // an ltrim + $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i]))); + } + + // strip the number of spaces from each line + if ($startingSpaceCount > 0) { + for ($i = 1; $i < count($lines); $i++) { + $lines[$i] = substr($lines[$i], $startingSpaceCount); + } + } + + return implode("\n", $lines); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php new file mode 100644 index 0000000..571ed74 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php @@ -0,0 +1,170 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock\Tags\Example; + +/** + * Class used to find an example file's location based on a given ExampleDescriptor. + */ +class ExampleFinder +{ + /** @var string */ + private $sourceDirectory = ''; + + /** @var string[] */ + private $exampleDirectories = []; + + /** + * Attempts to find the example contents for the given descriptor. + * + * @param Example $example + * + * @return string + */ + public function find(Example $example) + { + $filename = $example->getFilePath(); + + $file = $this->getExampleFileContents($filename); + if (!$file) { + return "** File not found : {$filename} **"; + } + + return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount())); + } + + /** + * Registers the project's root directory where an 'examples' folder can be expected. + * + * @param string $directory + * + * @return void + */ + public function setSourceDirectory($directory = '') + { + $this->sourceDirectory = $directory; + } + + /** + * Returns the project's root directory where an 'examples' folder can be expected. + * + * @return string + */ + public function getSourceDirectory() + { + return $this->sourceDirectory; + } + + /** + * Registers a series of directories that may contain examples. + * + * @param string[] $directories + */ + public function setExampleDirectories(array $directories) + { + $this->exampleDirectories = $directories; + } + + /** + * Returns a series of directories that may contain examples. + * + * @return string[] + */ + public function getExampleDirectories() + { + return $this->exampleDirectories; + } + + /** + * Attempts to find the requested example file and returns its contents or null if no file was found. + * + * This method will try several methods in search of the given example file, the first one it encounters is + * returned: + * + * 1. Iterates through all examples folders for the given filename + * 2. Checks the source folder for the given filename + * 3. Checks the 'examples' folder in the current working directory for examples + * 4. Checks the path relative to the current working directory for the given filename + * + * @param string $filename + * + * @return string|null + */ + private function getExampleFileContents($filename) + { + $normalizedPath = null; + + foreach ($this->exampleDirectories as $directory) { + $exampleFileFromConfig = $this->constructExamplePath($directory, $filename); + if (is_readable($exampleFileFromConfig)) { + $normalizedPath = $exampleFileFromConfig; + break; + } + } + + if (!$normalizedPath) { + if (is_readable($this->getExamplePathFromSource($filename))) { + $normalizedPath = $this->getExamplePathFromSource($filename); + } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) { + $normalizedPath = $this->getExamplePathFromExampleDirectory($filename); + } elseif (is_readable($filename)) { + $normalizedPath = $filename; + } + } + + return $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : null; + } + + /** + * Get example filepath based on the example directory inside your project. + * + * @param string $file + * + * @return string + */ + private function getExamplePathFromExampleDirectory($file) + { + return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file; + } + + /** + * Returns a path to the example file in the given directory.. + * + * @param string $directory + * @param string $file + * + * @return string + */ + private function constructExamplePath($directory, $file) + { + return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file; + } + + /** + * Get example filepath based on sourcecode. + * + * @param string $file + * + * @return string + */ + private function getExamplePathFromSource($file) + { + return sprintf( + '%s%s%s', + trim($this->getSourceDirectory(), '\\/'), + DIRECTORY_SEPARATOR, + trim($file, '"') + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php new file mode 100644 index 0000000..0f355f5 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php @@ -0,0 +1,155 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock; +use Webmozart\Assert\Assert; + +/** + * Converts a DocBlock back from an object to a complete DocComment including Asterisks. + */ +class Serializer +{ + /** @var string The string to indent the comment with. */ + protected $indentString = ' '; + + /** @var int The number of times the indent string is repeated. */ + protected $indent = 0; + + /** @var bool Whether to indent the first line with the given indent amount and string. */ + protected $isFirstLineIndented = true; + + /** @var int|null The max length of a line. */ + protected $lineLength = null; + + /** @var DocBlock\Tags\Formatter A custom tag formatter. */ + protected $tagFormatter = null; + + /** + * Create a Serializer instance. + * + * @param int $indent The number of times the indent string is repeated. + * @param string $indentString The string to indent the comment with. + * @param bool $indentFirstLine Whether to indent the first line. + * @param int|null $lineLength The max length of a line or NULL to disable line wrapping. + * @param DocBlock\Tags\Formatter $tagFormatter A custom tag formatter, defaults to PassthroughFormatter. + */ + public function __construct($indent = 0, $indentString = ' ', $indentFirstLine = true, $lineLength = null, $tagFormatter = null) + { + Assert::integer($indent); + Assert::string($indentString); + Assert::boolean($indentFirstLine); + Assert::nullOrInteger($lineLength); + Assert::nullOrIsInstanceOf($tagFormatter, 'phpDocumentor\Reflection\DocBlock\Tags\Formatter'); + + $this->indent = $indent; + $this->indentString = $indentString; + $this->isFirstLineIndented = $indentFirstLine; + $this->lineLength = $lineLength; + $this->tagFormatter = $tagFormatter ?: new DocBlock\Tags\Formatter\PassthroughFormatter(); + } + + /** + * Generate a DocBlock comment. + * + * @param DocBlock $docblock The DocBlock to serialize. + * + * @return string The serialized doc block. + */ + public function getDocComment(DocBlock $docblock) + { + $indent = str_repeat($this->indentString, $this->indent); + $firstIndent = $this->isFirstLineIndented ? $indent : ''; + // 3 === strlen(' * ') + $wrapLength = $this->lineLength ? $this->lineLength - strlen($indent) - 3 : null; + + $text = $this->removeTrailingSpaces( + $indent, + $this->addAsterisksForEachLine( + $indent, + $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength) + ) + ); + + $comment = "{$firstIndent}/**\n"; + if ($text) { + $comment .= "{$indent} * {$text}\n"; + $comment .= "{$indent} *\n"; + } + + $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment); + $comment .= $indent . ' */'; + + return $comment; + } + + /** + * @param $indent + * @param $text + * @return mixed + */ + private function removeTrailingSpaces($indent, $text) + { + return str_replace("\n{$indent} * \n", "\n{$indent} *\n", $text); + } + + /** + * @param $indent + * @param $text + * @return mixed + */ + private function addAsterisksForEachLine($indent, $text) + { + return str_replace("\n", "\n{$indent} * ", $text); + } + + /** + * @param DocBlock $docblock + * @param $wrapLength + * @return string + */ + private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, $wrapLength) + { + $text = $docblock->getSummary() . ((string)$docblock->getDescription() ? "\n\n" . $docblock->getDescription() + : ''); + if ($wrapLength !== null) { + $text = wordwrap($text, $wrapLength); + return $text; + } + + return $text; + } + + /** + * @param DocBlock $docblock + * @param $wrapLength + * @param $indent + * @param $comment + * @return string + */ + private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment) + { + foreach ($docblock->getTags() as $tag) { + $tagText = $this->tagFormatter->format($tag); + if ($wrapLength !== null) { + $tagText = wordwrap($tagText, $wrapLength); + } + + $tagText = str_replace("\n", "\n{$indent} * ", $tagText); + + $comment .= "{$indent} * {$tagText}\n"; + } + + return $comment; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php new file mode 100644 index 0000000..5a8143c --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php @@ -0,0 +1,319 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod; +use phpDocumentor\Reflection\DocBlock\Tags\Generic; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Creates a Tag object given the contents of a tag. + * + * This Factory is capable of determining the appropriate class for a tag and instantiate it using its `create` + * factory method. The `create` factory method of a Tag can have a variable number of arguments; this way you can + * pass the dependencies that you need to construct a tag object. + * + * > Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise + * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to + * > verify that a dependency is actually passed. + * + * This Factory also features a Service Locator component that is used to pass the right dependencies to the + * `create` method of a tag; each dependency should be registered as a service or as a parameter. + * + * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass + * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface. + */ +final class StandardTagFactory implements TagFactory +{ + /** PCRE regular expression matching a tag name. */ + const REGEX_TAGNAME = '[\w\-\_\\\\]+'; + + /** + * @var string[] An array with a tag as a key, and an FQCN to a class that handles it as an array value. + */ + private $tagHandlerMappings = [ + 'author' => '\phpDocumentor\Reflection\DocBlock\Tags\Author', + 'covers' => '\phpDocumentor\Reflection\DocBlock\Tags\Covers', + 'deprecated' => '\phpDocumentor\Reflection\DocBlock\Tags\Deprecated', + // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', + 'link' => '\phpDocumentor\Reflection\DocBlock\Tags\Link', + 'method' => '\phpDocumentor\Reflection\DocBlock\Tags\Method', + 'param' => '\phpDocumentor\Reflection\DocBlock\Tags\Param', + 'property-read' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead', + 'property' => '\phpDocumentor\Reflection\DocBlock\Tags\Property', + 'property-write' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite', + 'return' => '\phpDocumentor\Reflection\DocBlock\Tags\Return_', + 'see' => '\phpDocumentor\Reflection\DocBlock\Tags\See', + 'since' => '\phpDocumentor\Reflection\DocBlock\Tags\Since', + 'source' => '\phpDocumentor\Reflection\DocBlock\Tags\Source', + 'throw' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws', + 'throws' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws', + 'uses' => '\phpDocumentor\Reflection\DocBlock\Tags\Uses', + 'var' => '\phpDocumentor\Reflection\DocBlock\Tags\Var_', + 'version' => '\phpDocumentor\Reflection\DocBlock\Tags\Version' + ]; + + /** + * @var \ReflectionParameter[][] a lazy-loading cache containing parameters for each tagHandler that has been used. + */ + private $tagHandlerParameterCache = []; + + /** + * @var FqsenResolver + */ + private $fqsenResolver; + + /** + * @var mixed[] an array representing a simple Service Locator where we can store parameters and + * services that can be inserted into the Factory Methods of Tag Handlers. + */ + private $serviceLocator = []; + + /** + * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers. + * + * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property + * is used. + * + * @param FqsenResolver $fqsenResolver + * @param string[] $tagHandlers + * + * @see self::registerTagHandler() to add a new tag handler to the existing default list. + */ + public function __construct(FqsenResolver $fqsenResolver, array $tagHandlers = null) + { + $this->fqsenResolver = $fqsenResolver; + if ($tagHandlers !== null) { + $this->tagHandlerMappings = $tagHandlers; + } + + $this->addService($fqsenResolver, FqsenResolver::class); + } + + /** + * {@inheritDoc} + */ + public function create($tagLine, TypeContext $context = null) + { + if (! $context) { + $context = new TypeContext(''); + } + + list($tagName, $tagBody) = $this->extractTagParts($tagLine); + + if ($tagBody !== '' && $tagBody[0] === '[') { + throw new \InvalidArgumentException( + 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors' + ); + } + + return $this->createTag($tagBody, $tagName, $context); + } + + /** + * {@inheritDoc} + */ + public function addParameter($name, $value) + { + $this->serviceLocator[$name] = $value; + } + + /** + * {@inheritDoc} + */ + public function addService($service, $alias = null) + { + $this->serviceLocator[$alias ?: get_class($service)] = $service; + } + + /** + * {@inheritDoc} + */ + public function registerTagHandler($tagName, $handler) + { + Assert::stringNotEmpty($tagName); + Assert::stringNotEmpty($handler); + Assert::classExists($handler); + Assert::implementsInterface($handler, StaticMethod::class); + + if (strpos($tagName, '\\') && $tagName[0] !== '\\') { + throw new \InvalidArgumentException( + 'A namespaced tag must have a leading backslash as it must be fully qualified' + ); + } + + $this->tagHandlerMappings[$tagName] = $handler; + } + + /** + * Extracts all components for a tag. + * + * @param string $tagLine + * + * @return string[] + */ + private function extractTagParts($tagLine) + { + $matches = []; + if (! preg_match('/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)/us', $tagLine, $matches)) { + throw new \InvalidArgumentException( + 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors' + ); + } + + if (count($matches) < 3) { + $matches[] = ''; + } + + return array_slice($matches, 1); + } + + /** + * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the + * body was invalid. + * + * @param string $body + * @param string $name + * @param TypeContext $context + * + * @return Tag|null + */ + private function createTag($body, $name, TypeContext $context) + { + $handlerClassName = $this->findHandlerClassName($name, $context); + $arguments = $this->getArgumentsForParametersFromWiring( + $this->fetchParametersForHandlerFactoryMethod($handlerClassName), + $this->getServiceLocatorWithDynamicParameters($context, $name, $body) + ); + + return call_user_func_array([$handlerClassName, 'create'], $arguments); + } + + /** + * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`). + * + * @param string $tagName + * @param TypeContext $context + * + * @return string + */ + private function findHandlerClassName($tagName, TypeContext $context) + { + $handlerClassName = Generic::class; + if (isset($this->tagHandlerMappings[$tagName])) { + $handlerClassName = $this->tagHandlerMappings[$tagName]; + } elseif ($this->isAnnotation($tagName)) { + // TODO: Annotation support is planned for a later stage and as such is disabled for now + // $tagName = (string)$this->fqsenResolver->resolve($tagName, $context); + // if (isset($this->annotationMappings[$tagName])) { + // $handlerClassName = $this->annotationMappings[$tagName]; + // } + } + + return $handlerClassName; + } + + /** + * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters. + * + * @param \ReflectionParameter[] $parameters + * @param mixed[] $locator + * + * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters + * is provided with this method. + */ + private function getArgumentsForParametersFromWiring($parameters, $locator) + { + $arguments = []; + foreach ($parameters as $index => $parameter) { + $typeHint = $parameter->getClass() ? $parameter->getClass()->getName() : null; + if (isset($locator[$typeHint])) { + $arguments[] = $locator[$typeHint]; + continue; + } + + $parameterName = $parameter->getName(); + if (isset($locator[$parameterName])) { + $arguments[] = $locator[$parameterName]; + continue; + } + + $arguments[] = null; + } + + return $arguments; + } + + /** + * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given + * tag handler class name. + * + * @param string $handlerClassName + * + * @return \ReflectionParameter[] + */ + private function fetchParametersForHandlerFactoryMethod($handlerClassName) + { + if (! isset($this->tagHandlerParameterCache[$handlerClassName])) { + $methodReflection = new \ReflectionMethod($handlerClassName, 'create'); + $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters(); + } + + return $this->tagHandlerParameterCache[$handlerClassName]; + } + + /** + * Returns a copy of this class' Service Locator with added dynamic parameters, such as the tag's name, body and + * Context. + * + * @param TypeContext $context The Context (namespace and aliasses) that may be passed and is used to resolve FQSENs. + * @param string $tagName The name of the tag that may be passed onto the factory method of the Tag class. + * @param string $tagBody The body of the tag that may be passed onto the factory method of the Tag class. + * + * @return mixed[] + */ + private function getServiceLocatorWithDynamicParameters(TypeContext $context, $tagName, $tagBody) + { + $locator = array_merge( + $this->serviceLocator, + [ + 'name' => $tagName, + 'body' => $tagBody, + TypeContext::class => $context + ] + ); + + return $locator; + } + + /** + * Returns whether the given tag belongs to an annotation. + * + * @param string $tagContent + * + * @todo this method should be populated once we implement Annotation notation support. + * + * @return bool + */ + private function isAnnotation($tagContent) + { + // 1. Contains a namespace separator + // 2. Contains parenthesis + // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part + // of the annotation class name matches the found tag name + + return false; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php new file mode 100644 index 0000000..e765367 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php @@ -0,0 +1,26 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +interface Tag +{ + public function getName(); + + public static function create($body); + + public function render(Formatter $formatter = null); + + public function __toString(); +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php new file mode 100644 index 0000000..3c1d113 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php @@ -0,0 +1,93 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\Types\Context as TypeContext; + +interface TagFactory +{ + /** + * Adds a parameter to the service locator that can be injected in a tag's factory method. + * + * When calling a tag's "create" method we always check the signature for dependencies to inject. One way is to + * typehint a parameter in the signature so that we can use that interface or class name to inject a dependency + * (see {@see addService()} for more information on that). + * + * Another way is to check the name of the argument against the names in the Service Locator. With this method + * you can add a variable that will be inserted when a tag's create method is not typehinted and has a matching + * name. + * + * Be aware that there are two reserved names: + * + * - name, representing the name of the tag. + * - body, representing the complete body of the tag. + * + * These parameters are injected at the last moment and will override any existing parameter with those names. + * + * @param string $name + * @param mixed $value + * + * @return void + */ + public function addParameter($name, $value); + + /** + * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided. + * + * When calling a tag's "create" method we always check the signature for dependencies to inject. If a parameter + * has a typehint then the ServiceLocator is queried to see if a Service is registered for that typehint. + * + * Because interfaces are regularly used as type-hints this method provides an alias parameter; if the FQCN of the + * interface is passed as alias then every time that interface is requested the provided service will be returned. + * + * @param object $service + * @param string $alias + * + * @return void + */ + public function addService($service); + + /** + * Factory method responsible for instantiating the correct sub type. + * + * @param string $tagLine The text for this tag, including description. + * @param TypeContext $context + * + * @throws \InvalidArgumentException if an invalid tag line was presented. + * + * @return Tag A new tag object. + */ + public function create($tagLine, TypeContext $context = null); + + /** + * Registers a handler for tags. + * + * If you want to use your own tags then you can use this method to instruct the TagFactory to register the name + * of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement the {@see Tag} interface (and thus + * the create method). + * + * @param string $tagName Name of tag to register a handler for. When registering a namespaced tag, the full + * name, along with a prefixing slash MUST be provided. + * @param string $handler FQCN of handler. + * + * @throws \InvalidArgumentException if the tag name is not a string + * @throws \InvalidArgumentException if the tag name is namespaced (contains backslashes) but does not start with + * a backslash + * @throws \InvalidArgumentException if the handler is not a string + * @throws \InvalidArgumentException if the handler is not an existing class + * @throws \InvalidArgumentException if the handler does not implement the {@see Tag} interface + * + * @return void + */ + public function registerTagHandler($tagName, $handler); +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php new file mode 100644 index 0000000..29d7f1d --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php @@ -0,0 +1,100 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use Webmozart\Assert\Assert; + +/** + * Reflection class for an {@}author tag in a Docblock. + */ +final class Author extends BaseTag implements Factory\StaticMethod +{ + /** @var string register that this is the author tag. */ + protected $name = 'author'; + + /** @var string The name of the author */ + private $authorName = ''; + + /** @var string The email of the author */ + private $authorEmail = ''; + + /** + * Initializes this tag with the author name and e-mail. + * + * @param string $authorName + * @param string $authorEmail + */ + public function __construct($authorName, $authorEmail) + { + Assert::string($authorName); + Assert::string($authorEmail); + if ($authorEmail && !filter_var($authorEmail, FILTER_VALIDATE_EMAIL)) { + throw new \InvalidArgumentException('The author tag does not have a valid e-mail address'); + } + + $this->authorName = $authorName; + $this->authorEmail = $authorEmail; + } + + /** + * Gets the author's name. + * + * @return string The author's name. + */ + public function getAuthorName() + { + return $this->authorName; + } + + /** + * Returns the author's email. + * + * @return string The author's email. + */ + public function getEmail() + { + return $this->authorEmail; + } + + /** + * Returns this tag in string form. + * + * @return string + */ + public function __toString() + { + return $this->authorName . (strlen($this->authorEmail) ? ' <' . $this->authorEmail . '>' : ''); + } + + /** + * Attempts to create a new Author object based on †he tag body. + * + * @param string $body + * + * @return static + */ + public static function create($body) + { + Assert::string($body); + + $splitTagContent = preg_match('/^([^\<]*)(?:\<([^\>]*)\>)?$/u', $body, $matches); + if (!$splitTagContent) { + return null; + } + + $authorName = trim($matches[1]); + $email = isset($matches[2]) ? trim($matches[2]) : ''; + + return new static($authorName, $email); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php new file mode 100644 index 0000000..14bb717 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php @@ -0,0 +1,52 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock; +use phpDocumentor\Reflection\DocBlock\Description; + +/** + * Parses a tag definition for a DocBlock. + */ +abstract class BaseTag implements DocBlock\Tag +{ + /** @var string Name of the tag */ + protected $name = ''; + + /** @var Description|null Description of the tag. */ + protected $description; + + /** + * Gets the name of this tag. + * + * @return string The name of this tag. + */ + public function getName() + { + return $this->name; + } + + public function getDescription() + { + return $this->description; + } + + public function render(Formatter $formatter = null) + { + if ($formatter === null) { + $formatter = new Formatter\PassthroughFormatter(); + } + + return $formatter->format($this); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php new file mode 100644 index 0000000..8d65403 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php @@ -0,0 +1,83 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a @covers tag in a Docblock. + */ +final class Covers extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'covers'; + + /** @var Fqsen */ + private $refers = null; + + /** + * Initializes this tag. + * + * @param Fqsen $refers + * @param Description $description + */ + public function __construct(Fqsen $refers, Description $description = null) + { + $this->refers = $refers; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + DescriptionFactory $descriptionFactory = null, + FqsenResolver $resolver = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::notEmpty($body); + + $parts = preg_split('/\s+/Su', $body, 2); + + return new static( + $resolver->resolve($parts[0], $context), + $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context) + ); + } + + /** + * Returns the structural element this tag refers to. + * + * @return Fqsen + */ + public function getReference() + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + * + * @return string + */ + public function __toString() + { + return $this->refers . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php new file mode 100644 index 0000000..822c305 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php @@ -0,0 +1,97 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}deprecated tag in a Docblock. + */ +final class Deprecated extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'deprecated'; + + /** + * PCRE regular expression matching a version vector. + * Assumes the "x" modifier. + */ + const REGEX_VECTOR = '(?: + # Normal release vectors. + \d\S* + | + # VCS version vectors. Per PHPCS, they are expected to + # follow the form of the VCS name, followed by ":", followed + # by the version vector itself. + # By convention, popular VCSes like CVS, SVN and GIT use "$" + # around the actual version vector. + [^\s\:]+\:\s*\$[^\$]+\$ + )'; + + /** @var string The version vector. */ + private $version = ''; + + public function __construct($version = null, Description $description = null) + { + Assert::nullOrStringNotEmpty($version); + + $this->version = $version; + $this->description = $description; + } + + /** + * @return static + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::nullOrString($body); + if (empty($body)) { + return new static(); + } + + $matches = []; + if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return new static( + null, + null !== $descriptionFactory ? $descriptionFactory->create($body, $context) : null + ); + } + + return new static( + $matches[1], + $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) + ); + } + + /** + * Gets the version section of the tag. + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->version . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php new file mode 100644 index 0000000..ecb199b --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php @@ -0,0 +1,176 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\Tag; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}example tag in a Docblock. + */ +final class Example extends BaseTag +{ + /** + * @var string Path to a file to use as an example. May also be an absolute URI. + */ + private $filePath; + + /** + * @var bool Whether the file path component represents an URI. This determines how the file portion + * appears at {@link getContent()}. + */ + private $isURI = false; + + /** + * @var int + */ + private $startingLine; + + /** + * @var int + */ + private $lineCount; + + public function __construct($filePath, $isURI, $startingLine, $lineCount, $description) + { + Assert::notEmpty($filePath); + Assert::integer($startingLine); + Assert::greaterThanEq($startingLine, 0); + + $this->filePath = $filePath; + $this->startingLine = $startingLine; + $this->lineCount = $lineCount; + $this->name = 'example'; + if ($description !== null) { + $this->description = trim($description); + } + + $this->isURI = $isURI; + } + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->description) { + $filePath = '"' . $this->filePath . '"'; + if ($this->isURI) { + $filePath = $this->isUriRelative($this->filePath) + ? str_replace('%2F', '/', rawurlencode($this->filePath)) + :$this->filePath; + } + + return trim($filePath . ' ' . parent::getDescription()); + } + + return $this->description; + } + + /** + * {@inheritdoc} + */ + public static function create($body) + { + // File component: File path in quotes or File URI / Source information + if (! preg_match('/^(?:\"([^\"]+)\"|(\S+))(?:\s+(.*))?$/sux', $body, $matches)) { + return null; + } + + $filePath = null; + $fileUri = null; + if ('' !== $matches[1]) { + $filePath = $matches[1]; + } else { + $fileUri = $matches[2]; + } + + $startingLine = 1; + $lineCount = null; + $description = null; + + if (array_key_exists(3, $matches)) { + $description = $matches[3]; + + // Starting line / Number of lines / Description + if (preg_match('/^([1-9]\d*)(?:\s+((?1))\s*)?(.*)$/sux', $matches[3], $contentMatches)) { + $startingLine = (int)$contentMatches[1]; + if (isset($contentMatches[2]) && $contentMatches[2] !== '') { + $lineCount = (int)$contentMatches[2]; + } + + if (array_key_exists(3, $contentMatches)) { + $description = $contentMatches[3]; + } + } + } + + return new static( + $filePath !== null?$filePath:$fileUri, + $fileUri !== null, + $startingLine, + $lineCount, + $description + ); + } + + /** + * Returns the file path. + * + * @return string Path to a file to use as an example. + * May also be an absolute URI. + */ + public function getFilePath() + { + return $this->filePath; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->filePath . ($this->description ? ' ' . $this->description : ''); + } + + /** + * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute). + * + * @param string $uri + * + * @return bool + */ + private function isUriRelative($uri) + { + return false === strpos($uri, ':'); + } + + /** + * @return int + */ + public function getStartingLine() + { + return $this->startingLine; + } + + /** + * @return int + */ + public function getLineCount() + { + return $this->lineCount; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php new file mode 100644 index 0000000..98aea45 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php @@ -0,0 +1,18 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; + +interface StaticMethod +{ + public static function create($body); +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php new file mode 100644 index 0000000..b9ca0b8 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php @@ -0,0 +1,18 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; + +interface Strategy +{ + public function create($body); +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php new file mode 100644 index 0000000..64b2c60 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php @@ -0,0 +1,27 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Tag; + +interface Formatter +{ + /** + * Formats a tag into a string representation according to a specific format, such as Markdown. + * + * @param Tag $tag + * + * @return string + */ + public function format(Tag $tag); +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php new file mode 100644 index 0000000..ceb40cc --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php @@ -0,0 +1,47 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @author Jan Schneider <jan@horde.org> + * @copyright 2017 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +class AlignFormatter implements Formatter +{ + /** @var int The maximum tag name length. */ + protected $maxLen = 0; + + /** + * Constructor. + * + * @param Tag[] $tags All tags that should later be aligned with the formatter. + */ + public function __construct(array $tags) + { + foreach ($tags as $tag) { + $this->maxLen = max($this->maxLen, strlen($tag->getName())); + } + } + + /** + * Formats the given tag to return a simple plain text version. + * + * @param Tag $tag + * + * @return string + */ + public function format(Tag $tag) + { + return '@' . $tag->getName() . str_repeat(' ', $this->maxLen - strlen($tag->getName()) + 1) . (string)$tag; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php new file mode 100644 index 0000000..4e2c576 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php @@ -0,0 +1,31 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Tags\Formatter; + +class PassthroughFormatter implements Formatter +{ + /** + * Formats the given tag to return a simple plain text version. + * + * @param Tag $tag + * + * @return string + */ + public function format(Tag $tag) + { + return trim('@' . $tag->getName() . ' ' . (string)$tag); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php new file mode 100644 index 0000000..e4c53e0 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php @@ -0,0 +1,91 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\StandardTagFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Parses a tag definition for a DocBlock. + */ +class Generic extends BaseTag implements Factory\StaticMethod +{ + /** + * Parses a tag and populates the member variables. + * + * @param string $name Name of the tag. + * @param Description $description The contents of the given tag. + */ + public function __construct($name, Description $description = null) + { + $this->validateTagName($name); + + $this->name = $name; + $this->description = $description; + } + + /** + * Creates a new tag that represents any unknown tag type. + * + * @param string $body + * @param string $name + * @param DescriptionFactory $descriptionFactory + * @param TypeContext $context + * + * @return static + */ + public static function create( + $body, + $name = '', + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::stringNotEmpty($name); + Assert::notNull($descriptionFactory); + + $description = $descriptionFactory && $body ? $descriptionFactory->create($body, $context) : null; + + return new static($name, $description); + } + + /** + * Returns the tag as a serialized string + * + * @return string + */ + public function __toString() + { + return ($this->description ? $this->description->render() : ''); + } + + /** + * Validates if the tag name matches the expected format, otherwise throws an exception. + * + * @param string $name + * + * @return void + */ + private function validateTagName($name) + { + if (! preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) { + throw new \InvalidArgumentException( + 'The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, ' + . 'hyphens and backslashes.' + ); + } + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php new file mode 100644 index 0000000..9c0e367 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php @@ -0,0 +1,77 @@ +<?php +/** + * phpDocumentor + * + * PHP Version 5.3 + * + * @author Ben Selby <benmatselby@gmail.com> + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a @link tag in a Docblock. + */ +final class Link extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'link'; + + /** @var string */ + private $link = ''; + + /** + * Initializes a link to a URL. + * + * @param string $link + * @param Description $description + */ + public function __construct($link, Description $description = null) + { + Assert::string($link); + + $this->link = $link; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::string($body); + Assert::notNull($descriptionFactory); + + $parts = preg_split('/\s+/Su', $body, 2); + $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; + + return new static($parts[0], $description); + } + + /** + * Gets the link + * + * @return string + */ + public function getLink() + { + return $this->link; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->link . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php new file mode 100644 index 0000000..7522529 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php @@ -0,0 +1,242 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use phpDocumentor\Reflection\Types\Void_; +use Webmozart\Assert\Assert; + +/** + * Reflection class for an {@}method in a Docblock. + */ +final class Method extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'method'; + + /** @var string */ + private $methodName = ''; + + /** @var string[] */ + private $arguments = []; + + /** @var bool */ + private $isStatic = false; + + /** @var Type */ + private $returnType; + + public function __construct( + $methodName, + array $arguments = [], + Type $returnType = null, + $static = false, + Description $description = null + ) { + Assert::stringNotEmpty($methodName); + Assert::boolean($static); + + if ($returnType === null) { + $returnType = new Void_(); + } + + $this->methodName = $methodName; + $this->arguments = $this->filterArguments($arguments); + $this->returnType = $returnType; + $this->isStatic = $static; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([ $typeResolver, $descriptionFactory ]); + + // 1. none or more whitespace + // 2. optionally the keyword "static" followed by whitespace + // 3. optionally a word with underscores followed by whitespace : as + // type for the return value + // 4. then optionally a word with underscores followed by () and + // whitespace : as method name as used by phpDocumentor + // 5. then a word with underscores, followed by ( and any character + // until a ) and whitespace : as method name with signature + // 6. any remaining text : as description + if (!preg_match( + '/^ + # Static keyword + # Declares a static method ONLY if type is also present + (?: + (static) + \s+ + )? + # Return type + (?: + ( + (?:[\w\|_\\\\]*\$this[\w\|_\\\\]*) + | + (?: + (?:[\w\|_\\\\]+) + # array notation + (?:\[\])* + )* + ) + \s+ + )? + # Legacy method name (not captured) + (?: + [\w_]+\(\)\s+ + )? + # Method name + ([\w\|_\\\\]+) + # Arguments + (?: + \(([^\)]*)\) + )? + \s* + # Description + (.*) + $/sux', + $body, + $matches + )) { + return null; + } + + list(, $static, $returnType, $methodName, $arguments, $description) = $matches; + + $static = $static === 'static'; + + if ($returnType === '') { + $returnType = 'void'; + } + + $returnType = $typeResolver->resolve($returnType, $context); + $description = $descriptionFactory->create($description, $context); + + if (is_string($arguments) && strlen($arguments) > 0) { + $arguments = explode(',', $arguments); + foreach ($arguments as &$argument) { + $argument = explode(' ', self::stripRestArg(trim($argument)), 2); + if ($argument[0][0] === '$') { + $argumentName = substr($argument[0], 1); + $argumentType = new Void_(); + } else { + $argumentType = $typeResolver->resolve($argument[0], $context); + $argumentName = ''; + if (isset($argument[1])) { + $argument[1] = self::stripRestArg($argument[1]); + $argumentName = substr($argument[1], 1); + } + } + + $argument = [ 'name' => $argumentName, 'type' => $argumentType]; + } + } else { + $arguments = []; + } + + return new static($methodName, $arguments, $returnType, $static, $description); + } + + /** + * Retrieves the method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * @return string[] + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Checks whether the method tag describes a static method or not. + * + * @return bool TRUE if the method declaration is for a static method, FALSE otherwise. + */ + public function isStatic() + { + return $this->isStatic; + } + + /** + * @return Type + */ + public function getReturnType() + { + return $this->returnType; + } + + public function __toString() + { + $arguments = []; + foreach ($this->arguments as $argument) { + $arguments[] = $argument['type'] . ' $' . $argument['name']; + } + + return trim(($this->isStatic() ? 'static ' : '') + . (string)$this->returnType . ' ' + . $this->methodName + . '(' . implode(', ', $arguments) . ')' + . ($this->description ? ' ' . $this->description->render() : '')); + } + + private function filterArguments($arguments) + { + foreach ($arguments as &$argument) { + if (is_string($argument)) { + $argument = [ 'name' => $argument ]; + } + + if (! isset($argument['type'])) { + $argument['type'] = new Void_(); + } + + $keys = array_keys($argument); + sort($keys); + if ($keys !== [ 'name', 'type' ]) { + throw new \InvalidArgumentException( + 'Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, true) + ); + } + } + + return $arguments; + } + + private static function stripRestArg($argument) + { + if (strpos($argument, '...') === 0) { + $argument = trim(substr($argument, 3)); + } + + return $argument; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php new file mode 100644 index 0000000..7d699d8 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php @@ -0,0 +1,141 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for the {@}param tag in a Docblock. + */ +final class Param extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'param'; + + /** @var Type */ + private $type; + + /** @var string */ + private $variableName = ''; + + /** @var bool determines whether this is a variadic argument */ + private $isVariadic = false; + + /** + * @param string $variableName + * @param Type $type + * @param bool $isVariadic + * @param Description $description + */ + public function __construct($variableName, Type $type = null, $isVariadic = false, Description $description = null) + { + Assert::string($variableName); + Assert::boolean($isVariadic); + + $this->variableName = $variableName; + $this->type = $type; + $this->isVariadic = $isVariadic; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + $isVariadic = false; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$' || substr($parts[0], 0, 4) === '...$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 3) === '...') { + $isVariadic = true; + $variableName = substr($variableName, 3); + } + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $isVariadic, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns whether this tag is variadic. + * + * @return boolean + */ + public function isVariadic() + { + return $this->isVariadic; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . ($this->isVariadic() ? '...' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php new file mode 100644 index 0000000..f0ef7c0 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php @@ -0,0 +1,118 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}property tag in a Docblock. + */ +class Property extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'property'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php new file mode 100644 index 0000000..e41c0c1 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php @@ -0,0 +1,118 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}property-read tag in a Docblock. + */ +class PropertyRead extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'property-read'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php new file mode 100644 index 0000000..cfdb0ed --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php @@ -0,0 +1,118 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}property-write tag in a Docblock. + */ +class PropertyWrite extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'property-write'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . '$' . $this->variableName + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php new file mode 100644 index 0000000..dc7b8b6 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php @@ -0,0 +1,42 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; + +use phpDocumentor\Reflection\Fqsen as RealFqsen; + +/** + * Fqsen reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See} + */ +final class Fqsen implements Reference +{ + /** + * @var RealFqsen + */ + private $fqsen; + + /** + * Fqsen constructor. + */ + public function __construct(RealFqsen $fqsen) + { + $this->fqsen = $fqsen; + } + + /** + * @return string string representation of the referenced fqsen + */ + public function __toString() + { + return (string)$this->fqsen; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php new file mode 100644 index 0000000..a3ffd24 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php @@ -0,0 +1,21 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; + +/** + * Interface for references in {@see phpDocumentor\Reflection\DocBlock\Tags\See} + */ +interface Reference +{ + public function __toString(); +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php new file mode 100644 index 0000000..2671d5e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php @@ -0,0 +1,40 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; + +use Webmozart\Assert\Assert; + +/** + * Url reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See} + */ +final class Url implements Reference +{ + /** + * @var string + */ + private $uri; + + /** + * Url constructor. + */ + public function __construct($uri) + { + Assert::stringNotEmpty($uri); + $this->uri = $uri; + } + + public function __toString() + { + return $this->uri; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php new file mode 100644 index 0000000..ca5bda7 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php @@ -0,0 +1,72 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}return tag in a Docblock. + */ +final class Return_ extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'return'; + + /** @var Type */ + private $type; + + public function __construct(Type $type, Description $description = null) + { + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + + $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context); + $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context); + + return new static($type, $description); + } + + /** + * Returns the type section of the variable. + * + * @return Type + */ + public function getType() + { + return $this->type; + } + + public function __toString() + { + return $this->type . ' ' . $this->description; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php new file mode 100644 index 0000000..9e9e723 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php @@ -0,0 +1,88 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for an {@}see tag in a Docblock. + */ +class See extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'see'; + + /** @var Reference */ + protected $refers = null; + + /** + * Initializes this tag. + * + * @param Reference $refers + * @param Description $description + */ + public function __construct(Reference $refers, Description $description = null) + { + $this->refers = $refers; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + FqsenResolver $resolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::allNotNull([$resolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; + + // https://tools.ietf.org/html/rfc2396#section-3 + if (preg_match('/\w:\/\/\w/i', $parts[0])) { + return new static(new Url($parts[0]), $description); + } + + return new static(new FqsenRef($resolver->resolve($parts[0], $context)), $description); + } + + /** + * Returns the ref of this tag. + * + * @return Reference + */ + public function getReference() + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + * + * @return string + */ + public function __toString() + { + return $this->refers . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php new file mode 100644 index 0000000..835fb0d --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php @@ -0,0 +1,94 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}since tag in a Docblock. + */ +final class Since extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'since'; + + /** + * PCRE regular expression matching a version vector. + * Assumes the "x" modifier. + */ + const REGEX_VECTOR = '(?: + # Normal release vectors. + \d\S* + | + # VCS version vectors. Per PHPCS, they are expected to + # follow the form of the VCS name, followed by ":", followed + # by the version vector itself. + # By convention, popular VCSes like CVS, SVN and GIT use "$" + # around the actual version vector. + [^\s\:]+\:\s*\$[^\$]+\$ + )'; + + /** @var string The version vector. */ + private $version = ''; + + public function __construct($version = null, Description $description = null) + { + Assert::nullOrStringNotEmpty($version); + + $this->version = $version; + $this->description = $description; + } + + /** + * @return static + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::nullOrString($body); + if (empty($body)) { + return new static(); + } + + $matches = []; + if (! preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return null; + } + + return new static( + $matches[1], + $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) + ); + } + + /** + * Gets the version section of the tag. + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->version . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php new file mode 100644 index 0000000..247b1b3 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php @@ -0,0 +1,97 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}source tag in a Docblock. + */ +final class Source extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'source'; + + /** @var int The starting line, relative to the structural element's location. */ + private $startingLine = 1; + + /** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */ + private $lineCount = null; + + public function __construct($startingLine, $lineCount = null, Description $description = null) + { + Assert::integerish($startingLine); + Assert::nullOrIntegerish($lineCount); + + $this->startingLine = (int)$startingLine; + $this->lineCount = $lineCount !== null ? (int)$lineCount : null; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::stringNotEmpty($body); + Assert::notNull($descriptionFactory); + + $startingLine = 1; + $lineCount = null; + $description = null; + + // Starting line / Number of lines / Description + if (preg_match('/^([1-9]\d*)\s*(?:((?1))\s+)?(.*)$/sux', $body, $matches)) { + $startingLine = (int)$matches[1]; + if (isset($matches[2]) && $matches[2] !== '') { + $lineCount = (int)$matches[2]; + } + + $description = $matches[3]; + } + + return new static($startingLine, $lineCount, $descriptionFactory->create($description, $context)); + } + + /** + * Gets the starting line. + * + * @return int The starting line, relative to the structural element's + * location. + */ + public function getStartingLine() + { + return $this->startingLine; + } + + /** + * Returns the number of lines. + * + * @return int|null The number of lines, relative to the starting line. NULL + * means "to the end". + */ + public function getLineCount() + { + return $this->lineCount; + } + + public function __toString() + { + return $this->startingLine + . ($this->lineCount !== null ? ' ' . $this->lineCount : '') + . ($this->description ? ' ' . $this->description->render() : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php new file mode 100644 index 0000000..349e773 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php @@ -0,0 +1,72 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}throws tag in a Docblock. + */ +final class Throws extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'throws'; + + /** @var Type */ + private $type; + + public function __construct(Type $type, Description $description = null) + { + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + + $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context); + $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context); + + return new static($type, $description); + } + + /** + * Returns the type section of the variable. + * + * @return Type + */ + public function getType() + { + return $this->type; + } + + public function __toString() + { + return $this->type . ' ' . $this->description; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php new file mode 100644 index 0000000..00dc3e3 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php @@ -0,0 +1,83 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}uses tag in a Docblock. + */ +final class Uses extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'uses'; + + /** @var Fqsen */ + protected $refers = null; + + /** + * Initializes this tag. + * + * @param Fqsen $refers + * @param Description $description + */ + public function __construct(Fqsen $refers, Description $description = null) + { + $this->refers = $refers; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + FqsenResolver $resolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::string($body); + Assert::allNotNull([$resolver, $descriptionFactory]); + + $parts = preg_split('/\s+/Su', $body, 2); + + return new static( + $resolver->resolve($parts[0], $context), + $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context) + ); + } + + /** + * Returns the structural element this tag refers to. + * + * @return Fqsen + */ + public function getReference() + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + * + * @return string + */ + public function __toString() + { + return $this->refers . ' ' . $this->description->render(); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php new file mode 100644 index 0000000..8907c95 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php @@ -0,0 +1,118 @@ +<?php +/** + * This file is part of phpDocumentor. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}var tag in a Docblock. + */ +class Var_ extends BaseTag implements Factory\StaticMethod +{ + /** @var string */ + protected $name = 'var'; + + /** @var Type */ + private $type; + + /** @var string */ + protected $variableName = ''; + + /** + * @param string $variableName + * @param Type $type + * @param Description $description + */ + public function __construct($variableName, Type $type = null, Description $description = null) + { + Assert::string($variableName); + + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public static function create( + $body, + TypeResolver $typeResolver = null, + DescriptionFactory $descriptionFactory = null, + TypeContext $context = null + ) { + Assert::stringNotEmpty($body); + Assert::allNotNull([$typeResolver, $descriptionFactory]); + + $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) { + $type = $typeResolver->resolve(array_shift($parts), $context); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) { + $variableName = array_shift($parts); + array_shift($parts); + + if (substr($variableName, 0, 1) === '$') { + $variableName = substr($variableName, 1); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Returns the variable's type or null if unknown. + * + * @return Type|null + */ + public function getType() + { + return $this->type; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return ($this->type ? $this->type . ' ' : '') + . (empty($this->variableName) ? null : ('$' . $this->variableName)) + . ($this->description ? ' ' . $this->description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php new file mode 100644 index 0000000..7bb0420 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php @@ -0,0 +1,94 @@ +<?php +/** + * phpDocumentor + * + * PHP Version 5.3 + * + * @author Vasil Rangelov <boen.robot@gmail.com> + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags; + +use phpDocumentor\Reflection\DocBlock\Description; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Types\Context as TypeContext; +use Webmozart\Assert\Assert; + +/** + * Reflection class for a {@}version tag in a Docblock. + */ +final class Version extends BaseTag implements Factory\StaticMethod +{ + protected $name = 'version'; + + /** + * PCRE regular expression matching a version vector. + * Assumes the "x" modifier. + */ + const REGEX_VECTOR = '(?: + # Normal release vectors. + \d\S* + | + # VCS version vectors. Per PHPCS, they are expected to + # follow the form of the VCS name, followed by ":", followed + # by the version vector itself. + # By convention, popular VCSes like CVS, SVN and GIT use "$" + # around the actual version vector. + [^\s\:]+\:\s*\$[^\$]+\$ + )'; + + /** @var string The version vector. */ + private $version = ''; + + public function __construct($version = null, Description $description = null) + { + Assert::nullOrStringNotEmpty($version); + + $this->version = $version; + $this->description = $description; + } + + /** + * @return static + */ + public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null) + { + Assert::nullOrString($body); + if (empty($body)) { + return new static(); + } + + $matches = []; + if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return null; + } + + return new static( + $matches[1], + $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context) + ); + } + + /** + * Gets the version section of the tag. + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + * + * @return string + */ + public function __toString() + { + return $this->version . ($this->description ? ' ' . $this->description->render() : ''); + } +} |