1111
1212namespace Symfony \Component \PropertyInfo \Extractor ;
1313
14- use phpDocumentor \Reflection \ClassReflector ;
1514use phpDocumentor \Reflection \DocBlock ;
16- use phpDocumentor \Reflection \FileReflector ;
15+ use phpDocumentor \Reflection \DocBlockFactory ;
16+ use phpDocumentor \Reflection \Types \Compound ;
17+ use phpDocumentor \Reflection \Types \ContextFactory ;
18+ use phpDocumentor \Reflection \Types \Null_ ;
1719use Symfony \Component \PropertyInfo \PropertyDescriptionExtractorInterface ;
1820use Symfony \Component \PropertyInfo \PropertyTypeExtractorInterface ;
1921use Symfony \Component \PropertyInfo \Type ;
@@ -30,35 +32,48 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
3032 const MUTATOR = 2 ;
3133
3234 /**
33- * @var FileReflector []
35+ * @var DocBlock []
3436 */
35- private $ fileReflectors = array ();
37+ private $ docBlocks = array ();
3638
3739 /**
38- * @var DocBlock[]
40+ * @var DocBlockFactory
3941 */
40- private $ docBlocks = array ();
42+ private $ docBlockFactory ;
43+
44+ /**
45+ * @var ContextFactory
46+ */
47+ private $ contextFactory ;
48+
49+ public function __construct ()
50+ {
51+ $ this ->docBlockFactory = DocBlockFactory::createInstance ();
52+ $ this ->contextFactory = new ContextFactory ();
53+ }
4154
4255 /**
4356 * {@inheritdoc}
4457 */
4558 public function getShortDescription ($ class , $ property , array $ context = array ())
4659 {
60+ /** @var $docBlock DocBlock */
4761 list ($ docBlock ) = $ this ->getDocBlock ($ class , $ property );
4862 if (!$ docBlock ) {
4963 return ;
5064 }
5165
52- $ shortDescription = $ docBlock ->getShortDescription ();
53- if ($ shortDescription ) {
66+ $ shortDescription = $ docBlock ->getSummary ();
67+
68+ if (!empty ($ shortDescription )) {
5469 return $ shortDescription ;
5570 }
5671
5772 foreach ($ docBlock ->getTagsByName ('var ' ) as $ var ) {
58- $ parsedDescription = $ var ->getParsedDescription ();
73+ $ varDescription = $ var ->getDescription ()-> render ();
5974
60- if (isset ( $ parsedDescription [ 0 ]) && '' !== $ parsedDescription [ 0 ] ) {
61- return $ parsedDescription [ 0 ] ;
75+ if (! empty ( $ varDescription ) ) {
76+ return $ varDescription ;
6277 }
6378 }
6479 }
@@ -68,12 +83,13 @@ public function getShortDescription($class, $property, array $context = array())
6883 */
6984 public function getLongDescription ($ class , $ property , array $ context = array ())
7085 {
86+ /** @var $docBlock DocBlock */
7187 list ($ docBlock ) = $ this ->getDocBlock ($ class , $ property );
7288 if (!$ docBlock ) {
7389 return ;
7490 }
7591
76- $ contents = $ docBlock ->getLongDescription ()->getContents ();
92+ $ contents = $ docBlock ->getDescription ()->render ();
7793
7894 return '' === $ contents ? null : $ contents ;
7995 }
@@ -83,6 +99,7 @@ public function getLongDescription($class, $property, array $context = array())
8399 */
84100 public function getTypes ($ class , $ property , array $ context = array ())
85101 {
102+ /** @var $docBlock DocBlock */
86103 list ($ docBlock , $ source , $ prefix ) = $ this ->getDocBlock ($ class , $ property );
87104 if (!$ docBlock ) {
88105 return ;
@@ -103,8 +120,31 @@ public function getTypes($class, $property, array $context = array())
103120 }
104121
105122 $ types = array ();
123+ /** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */
106124 foreach ($ docBlock ->getTagsByName ($ tag ) as $ tag ) {
107- $ varTypes = $ tag ->getTypes ();
125+ $ varType = $ tag ->getType ();
126+ $ nullable = false ;
127+
128+ if (!($ varType instanceof Compound)) {
129+ if ($ varType instanceof Null_) {
130+ $ nullable = true ;
131+ }
132+
133+ $ type = $ this ->createType ($ varType ->__toString (), $ nullable );
134+
135+ if (null !== $ type ) {
136+ $ types [] = $ type ;
137+ }
138+
139+ continue ;
140+ }
141+
142+ $ typeIndex = 0 ;
143+ $ varTypes = [];
144+ while ($ varType ->has ($ typeIndex )) {
145+ $ varTypes [] = $ varType ->get ($ typeIndex )->__toString ();
146+ ++$ typeIndex ;
147+ }
108148
109149 // If null is present, all types are nullable
110150 $ nullKey = array_search (Type::BUILTIN_TYPE_NULL , $ varTypes );
@@ -134,29 +174,6 @@ public function getTypes($class, $property, array $context = array())
134174 return array (new Type (Type::BUILTIN_TYPE_ARRAY , false , null , true , new Type (Type::BUILTIN_TYPE_INT ), $ types [0 ]));
135175 }
136176
137- /**
138- * Gets the FileReflector associated with the class.
139- *
140- * @param \ReflectionClass $reflectionClass
141- *
142- * @return FileReflector|null
143- */
144- private function getFileReflector (\ReflectionClass $ reflectionClass )
145- {
146- if (!($ fileName = $ reflectionClass ->getFileName ()) || 'hh ' === pathinfo ($ fileName , PATHINFO_EXTENSION )) {
147- return ;
148- }
149-
150- if (isset ($ this ->fileReflectors [$ fileName ])) {
151- return $ this ->fileReflectors [$ fileName ];
152- }
153-
154- $ this ->fileReflectors [$ fileName ] = new FileReflector ($ fileName );
155- $ this ->fileReflectors [$ fileName ]->process ();
156-
157- return $ this ->fileReflectors [$ fileName ];
158- }
159-
160177 /**
161178 * Gets the DocBlock for this property.
162179 *
@@ -212,27 +229,7 @@ private function getDocBlockFromProperty($class, $property)
212229 return ;
213230 }
214231
215- $ reflectionCLass = $ reflectionProperty ->getDeclaringClass ();
216-
217- $ fileReflector = $ this ->getFileReflector ($ reflectionCLass );
218- if (!$ fileReflector ) {
219- return ;
220- }
221-
222- foreach ($ fileReflector ->getClasses () as $ classReflector ) {
223- $ className = $ this ->getClassName ($ classReflector );
224-
225- if ($ className === $ reflectionCLass ->name ) {
226- foreach ($ classReflector ->getProperties () as $ propertyReflector ) {
227- // strip the $ prefix
228- $ propertyName = substr ($ propertyReflector ->getName (), 1 );
229-
230- if ($ propertyName === $ property ) {
231- return $ propertyReflector ->getDocBlock ();
232- }
233- }
234- }
235- }
232+ return $ this ->docBlockFactory ->create ($ reflectionProperty , $ this ->contextFactory ->createFromReflector ($ reflectionProperty ));
236233 }
237234
238235 /**
@@ -269,39 +266,7 @@ private function getDocBlockFromMethod($class, $ucFirstProperty, $type)
269266 return ;
270267 }
271268
272- $ reflectionClass = $ reflectionMethod ->getDeclaringClass ();
273- $ fileReflector = $ this ->getFileReflector ($ reflectionClass );
274-
275- if (!$ fileReflector ) {
276- return ;
277- }
278-
279- foreach ($ fileReflector ->getClasses () as $ classReflector ) {
280- $ className = $ this ->getClassName ($ classReflector );
281-
282- if ($ className === $ reflectionClass ->name ) {
283- if ($ methodReflector = $ classReflector ->getMethod ($ methodName )) {
284- return array ($ methodReflector ->getDocBlock (), $ prefix );
285- }
286- }
287- }
288- }
289-
290- /**
291- * Gets the normalized class name (without trailing backslash).
292- *
293- * @param ClassReflector $classReflector
294- *
295- * @return string
296- */
297- private function getClassName (ClassReflector $ classReflector )
298- {
299- $ className = $ classReflector ->getName ();
300- if ('\\' === $ className [0 ]) {
301- return substr ($ className , 1 );
302- }
303-
304- return $ className ;
269+ return [$ this ->docBlockFactory ->create ($ reflectionMethod , $ this ->contextFactory ->createFromReflector ($ reflectionMethod )), $ prefix ];
305270 }
306271
307272 /**
0 commit comments