Annotation.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /*
  3. * This file is part of PHP CS Fixer.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. namespace Symfony\CS\DocBlock;
  12. /**
  13. * This represents an entire annotation from a docblock.
  14. *
  15. * @author Graham Campbell <graham@alt-three.com>
  16. */
  17. class Annotation
  18. {
  19. /**
  20. * All the annotation tag names with types.
  21. *
  22. * @var string[]
  23. */
  24. private static $tags = array(
  25. 'method',
  26. 'param',
  27. 'property',
  28. 'property-read',
  29. 'property-write',
  30. 'return',
  31. 'throws',
  32. 'type',
  33. 'var',
  34. );
  35. /**
  36. * The lines that make up the annotation.
  37. *
  38. * @var Line[]
  39. */
  40. private $lines;
  41. /**
  42. * The position of the first line of the annotation in the docblock.
  43. *
  44. * @var int
  45. */
  46. private $start;
  47. /**
  48. * The position of the last line of the annotation in the docblock.
  49. *
  50. * @var int
  51. */
  52. private $end;
  53. /**
  54. * The associated tag.
  55. *
  56. * @var Tag|null
  57. */
  58. private $tag;
  59. /**
  60. * The cached types content.
  61. *
  62. * @var string|null
  63. */
  64. private $typesContent;
  65. /**
  66. * Create a new line instance.
  67. *
  68. * @param Line[] $lines
  69. */
  70. public function __construct(array $lines)
  71. {
  72. $this->lines = array_values($lines);
  73. $keys = array_keys($lines);
  74. $this->start = $keys[0];
  75. $this->end = end($keys);
  76. }
  77. /**
  78. * Get all the annotation tag names with types.
  79. *
  80. * @return string[]
  81. */
  82. public static function getTagsWithTypes()
  83. {
  84. return self::$tags;
  85. }
  86. /**
  87. * Get the start position of this annotation.
  88. *
  89. * @return int
  90. */
  91. public function getStart()
  92. {
  93. return $this->start;
  94. }
  95. /**
  96. * Get the end position of this annotation.
  97. *
  98. * @return int
  99. */
  100. public function getEnd()
  101. {
  102. return $this->end;
  103. }
  104. /**
  105. * Get the associated tag.
  106. *
  107. * @return Tag
  108. */
  109. public function getTag()
  110. {
  111. if (null === $this->tag) {
  112. $values = array_values($this->lines);
  113. $this->tag = new Tag($values[0]->getContent());
  114. }
  115. return $this->tag;
  116. }
  117. /**
  118. * Get the current types content.
  119. *
  120. * Be careful modifying the underlying line as that won't flush the cache.
  121. *
  122. * @return string
  123. */
  124. private function getTypesContent()
  125. {
  126. if (null === $this->typesContent) {
  127. $name = $this->getTag()->getName();
  128. if (!in_array($name, self::$tags, true)) {
  129. throw new \RuntimeException('This tag does not support types');
  130. }
  131. $tagSplit = preg_split('/\s*\@'.$name.'\s*/', $this->lines[0]->getContent(), 2);
  132. $spaceSplit = preg_split('/\s/', $tagSplit[1], 2);
  133. $this->typesContent = $spaceSplit[0];
  134. }
  135. return $this->typesContent;
  136. }
  137. /**
  138. * Get the types associated with this annotation.
  139. *
  140. * @return string[]
  141. */
  142. public function getTypes()
  143. {
  144. return explode('|', $this->getTypesContent());
  145. }
  146. /**
  147. * Set the types associated with this annotation.
  148. *
  149. * @param string[] $types
  150. */
  151. public function setTypes(array $types)
  152. {
  153. $pattern = '/'.preg_quote($this->getTypesContent()).'/';
  154. $this->lines[0]->setContent(preg_replace($pattern, implode('|', $types), $this->lines[0]->getContent(), 1));
  155. $this->typesContent = null;
  156. }
  157. /**
  158. * Remove this annotation by removing all its lines.
  159. */
  160. public function remove()
  161. {
  162. foreach ($this->lines as $line) {
  163. $line->remove();
  164. }
  165. }
  166. /**
  167. * Get the annotation content.
  168. *
  169. * @return string
  170. */
  171. public function getContent()
  172. {
  173. return implode($this->lines);
  174. }
  175. /**
  176. * Get the string representation of object.
  177. *
  178. * @return string
  179. */
  180. public function __toString()
  181. {
  182. return $this->getContent();
  183. }
  184. }