%PDF- %PDF-
Direktori : /home/vacivi36/vacivitta.com.br/vendor/friendsofphp/php-cs-fixer/src/DocBlock/ |
Current File : /home/vacivi36/vacivitta.com.br/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Annotation.php |
<?php declare(strict_types=1); /* * This file is part of PHP CS Fixer. * * (c) Fabien Potencier <fabien@symfony.com> * Dariusz Rumiński <dariusz.ruminski@gmail.com> * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace PhpCsFixer\DocBlock; use PhpCsFixer\Preg; use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceAnalysis; use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceUseAnalysis; /** * This represents an entire annotation from a docblock. * * @author Graham Campbell <hello@gjcampbell.co.uk> * @author Dariusz Rumiński <dariusz.ruminski@gmail.com> */ final class Annotation { /** * All the annotation tag names with types. * * @var string[] */ private static $tags = [ 'method', 'param', 'property', 'property-read', 'property-write', 'return', 'throws', 'type', 'var', ]; /** * The lines that make up the annotation. * * @var Line[] */ private $lines; /** * The position of the first line of the annotation in the docblock. * * @var int */ private $start; /** * The position of the last line of the annotation in the docblock. * * @var int */ private $end; /** * The associated tag. * * @var null|Tag */ private $tag; /** * Lazy loaded, cached types content. * * @var null|string */ private $typesContent; /** * The cached types. * * @var null|string[] */ private $types; /** * @var null|NamespaceAnalysis */ private $namespace; /** * @var NamespaceUseAnalysis[] */ private $namespaceUses; /** * Create a new line instance. * * @param Line[] $lines * @param null|NamespaceAnalysis $namespace * @param NamespaceUseAnalysis[] $namespaceUses */ public function __construct(array $lines, $namespace = null, array $namespaceUses = []) { $this->lines = array_values($lines); $this->namespace = $namespace; $this->namespaceUses = $namespaceUses; $keys = array_keys($lines); $this->start = $keys[0]; $this->end = end($keys); } /** * Get the string representation of object. */ public function __toString(): string { return $this->getContent(); } /** * Get all the annotation tag names with types. * * @return string[] */ public static function getTagsWithTypes(): array { return self::$tags; } /** * Get the start position of this annotation. */ public function getStart(): int { return $this->start; } /** * Get the end position of this annotation. */ public function getEnd(): int { return $this->end; } /** * Get the associated tag. */ public function getTag(): Tag { if (null === $this->tag) { $this->tag = new Tag($this->lines[0]); } return $this->tag; } /** * @internal */ public function getTypeExpression(): TypeExpression { return new TypeExpression($this->getTypesContent(), $this->namespace, $this->namespaceUses); } /** * @return null|string * * @internal */ public function getVariableName() { $type = preg_quote($this->getTypesContent(), '/'); $regex = "/@{$this->tag->getName()}\\s+{$type}\\s+(?<variable>\\$.+?)(?:[\\s*]|$)/"; if (Preg::match($regex, $this->lines[0]->getContent(), $matches)) { return $matches['variable']; } return null; } /** * Get the types associated with this annotation. * * @return string[] */ public function getTypes(): array { if (null === $this->types) { $this->types = $this->getTypeExpression()->getTypes(); } return $this->types; } /** * Set the types associated with this annotation. * * @param string[] $types */ public function setTypes(array $types): void { $pattern = '/'.preg_quote($this->getTypesContent(), '/').'/'; $this->lines[0]->setContent(Preg::replace($pattern, implode('|', $types), $this->lines[0]->getContent(), 1)); $this->clearCache(); } /** * Get the normalized types associated with this annotation, so they can easily be compared. * * @return string[] */ public function getNormalizedTypes(): array { $normalized = array_map(static function (string $type): string { return strtolower($type); }, $this->getTypes()); sort($normalized); return $normalized; } /** * Remove this annotation by removing all its lines. */ public function remove(): void { foreach ($this->lines as $line) { if ($line->isTheStart() && $line->isTheEnd()) { // Single line doc block, remove entirely $line->remove(); } elseif ($line->isTheStart()) { // Multi line doc block, but start is on the same line as the first annotation, keep only the start $content = Preg::replace('#(\s*/\*\*).*#', '$1', $line->getContent()); $line->setContent($content); } elseif ($line->isTheEnd()) { // Multi line doc block, but end is on the same line as the last annotation, keep only the end $content = Preg::replace('#(\s*)\S.*(\*/.*)#', '$1$2', $line->getContent()); $line->setContent($content); } else { // Multi line doc block, neither start nor end on this line, can be removed safely $line->remove(); } } $this->clearCache(); } /** * Get the annotation content. */ public function getContent(): string { return implode('', $this->lines); } public function supportTypes(): bool { return \in_array($this->getTag()->getName(), self::$tags, true); } /** * Get the current types content. * * Be careful modifying the underlying line as that won't flush the cache. */ private function getTypesContent(): string { if (null === $this->typesContent) { $name = $this->getTag()->getName(); if (!$this->supportTypes()) { throw new \RuntimeException('This tag does not support types.'); } $matchingResult = Preg::match( '{^(?:\s*\*|/\*\*)\s*@'.$name.'\s+'.TypeExpression::REGEX_TYPES.'(?:[*\h\v].*)?\r?$}sx', $this->lines[0]->getContent(), $matches ); $this->typesContent = 1 === $matchingResult ? $matches['types'] : ''; } return $this->typesContent; } private function clearCache(): void { $this->types = null; $this->typesContent = null; } }