1919class Annotation
2020{
2121 /**
22- * The lines that make up the annotation .
22+ * All the annotation tag names with types .
2323 *
24- * Note that the array indexes represent the position in the docblock.
24+ * @var string[]
25+ */
26+ private static $ tags = array (
27+ 'method ' ,
28+ 'param ' ,
29+ 'property ' ,
30+ 'property-read ' ,
31+ 'property-write ' ,
32+ 'return ' ,
33+ 'throws ' ,
34+ 'type ' ,
35+ 'var ' ,
36+ );
37+
38+ /**
39+ * The lines that make up the annotation.
2540 *
2641 * @var Line[]
2742 */
2843 private $ lines ;
2944
45+ /**
46+ * The position of the first line of the annotation in the docblock.
47+ *
48+ * @var int
49+ */
50+ private $ start ;
51+
52+ /**
53+ * The position of the last line of the annotation in the docblock.
54+ *
55+ * @var int
56+ */
57+ private $ end ;
58+
3059 /**
3160 * The associated tag.
3261 *
3362 * @var Tag|null
3463 */
3564 private $ tag ;
3665
66+ /**
67+ * The cached types content.
68+ *
69+ * @var string|null
70+ */
71+ private $ typesContent ;
72+
3773 /**
3874 * Create a new line instance.
3975 *
4076 * @param Line[] $lines
4177 */
4278 public function __construct (array $ lines )
4379 {
44- $ this ->lines = $ lines ;
80+ $ this ->lines = array_values ($ lines );
81+
82+ $ keys = array_keys ($ lines );
83+
84+ $ this ->start = $ keys [0 ];
85+ $ this ->end = end ($ keys );
86+ }
87+
88+ /**
89+ * Get all the annotation tag names with types.
90+ *
91+ * @var string[]
92+ */
93+ public static function getTagsWithTypes ()
94+ {
95+ return self ::$ tags ;
4596 }
4697
4798 /**
@@ -51,9 +102,7 @@ public function __construct(array $lines)
51102 */
52103 public function getStart ()
53104 {
54- $ keys = array_keys ($ this ->lines );
55-
56- return $ keys [0 ];
105+ return $ this ->start ;
57106 }
58107
59108 /**
@@ -63,9 +112,7 @@ public function getStart()
63112 */
64113 public function getEnd ()
65114 {
66- $ keys = array_keys ($ this ->lines );
67-
68- return end ($ keys );
115+ return $ this ->end ;
69116 }
70117
71118 /**
@@ -83,6 +130,55 @@ public function getTag()
83130 return $ this ->tag ;
84131 }
85132
133+ /**
134+ * Get the current types content.
135+ *
136+ * Be careful modifying the underlying line as that won't flush the cache.
137+ *
138+ * @return string
139+ */
140+ private function getTypesContent ()
141+ {
142+ if (null === $ this ->typesContent ) {
143+ $ name = $ this ->getTag ()->getName ();
144+
145+ if (!in_array ($ name , self ::$ tags , true )) {
146+ throw new \RuntimeException ('This tag does not support types ' );
147+ }
148+
149+ $ tagSplit = preg_split ('/\s*\@ ' .$ name .'\s*/ ' , $ this ->lines [0 ]->getContent (), 2 );
150+ $ spaceSplit = preg_split ('/\s/ ' , $ tagSplit [1 ], 2 );
151+
152+ $ this ->typesContent = $ spaceSplit [0 ];
153+ }
154+
155+ return $ this ->typesContent ;
156+ }
157+
158+ /**
159+ * Get the types associated with this annotation.
160+ *
161+ * @return string[]
162+ */
163+ public function getTypes ()
164+ {
165+ return explode ('| ' , $ this ->getTypesContent ());
166+ }
167+
168+ /**
169+ * Set the types associated with this annotation.
170+ *
171+ * @param string[] $types
172+ */
173+ public function setTypes (array $ types )
174+ {
175+ $ pattern = '/ ' .preg_quote ($ this ->getTypesContent ()).'/ ' ;
176+
177+ $ this ->lines [0 ]->setContent (preg_replace ($ pattern , implode ('| ' , $ types ), $ this ->lines [0 ]->getContent (), 1 ));
178+
179+ $ this ->typesContent = null ;
180+ }
181+
86182 /**
87183 * Remove this annotation by removing all its lines.
88184 */
0 commit comments