11
11
12
12
namespace Symfony \Component \PropertyInfo \Extractor ;
13
13
14
- use phpDocumentor \Reflection \ClassReflector ;
15
14
use 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_ ;
17
19
use Symfony \Component \PropertyInfo \PropertyDescriptionExtractorInterface ;
18
20
use Symfony \Component \PropertyInfo \PropertyTypeExtractorInterface ;
19
21
use Symfony \Component \PropertyInfo \Type ;
@@ -30,35 +32,48 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
30
32
const MUTATOR = 2 ;
31
33
32
34
/**
33
- * @var FileReflector []
35
+ * @var DocBlock []
34
36
*/
35
- private $ fileReflectors = array ();
37
+ private $ docBlocks = array ();
36
38
37
39
/**
38
- * @var DocBlock[]
40
+ * @var DocBlockFactory
39
41
*/
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
+ }
41
54
42
55
/**
43
56
* {@inheritdoc}
44
57
*/
45
58
public function getShortDescription ($ class , $ property , array $ context = array ())
46
59
{
60
+ /** @var $docBlock DocBlock */
47
61
list ($ docBlock ) = $ this ->getDocBlock ($ class , $ property );
48
62
if (!$ docBlock ) {
49
63
return ;
50
64
}
51
65
52
- $ shortDescription = $ docBlock ->getShortDescription ();
53
- if ($ shortDescription ) {
66
+ $ shortDescription = $ docBlock ->getSummary ();
67
+
68
+ if (!empty ($ shortDescription )) {
54
69
return $ shortDescription ;
55
70
}
56
71
57
72
foreach ($ docBlock ->getTagsByName ('var ' ) as $ var ) {
58
- $ parsedDescription = $ var ->getParsedDescription ();
73
+ $ varDescription = $ var ->getDescription ()-> render ();
59
74
60
- if (isset ( $ parsedDescription [ 0 ]) && '' !== $ parsedDescription [ 0 ] ) {
61
- return $ parsedDescription [ 0 ] ;
75
+ if (! empty ( $ varDescription ) ) {
76
+ return $ varDescription ;
62
77
}
63
78
}
64
79
}
@@ -68,12 +83,13 @@ public function getShortDescription($class, $property, array $context = array())
68
83
*/
69
84
public function getLongDescription ($ class , $ property , array $ context = array ())
70
85
{
86
+ /** @var $docBlock DocBlock */
71
87
list ($ docBlock ) = $ this ->getDocBlock ($ class , $ property );
72
88
if (!$ docBlock ) {
73
89
return ;
74
90
}
75
91
76
- $ contents = $ docBlock ->getLongDescription ()->getContents ();
92
+ $ contents = $ docBlock ->getDescription ()->render ();
77
93
78
94
return '' === $ contents ? null : $ contents ;
79
95
}
@@ -83,6 +99,7 @@ public function getLongDescription($class, $property, array $context = array())
83
99
*/
84
100
public function getTypes ($ class , $ property , array $ context = array ())
85
101
{
102
+ /** @var $docBlock DocBlock */
86
103
list ($ docBlock , $ source , $ prefix ) = $ this ->getDocBlock ($ class , $ property );
87
104
if (!$ docBlock ) {
88
105
return ;
@@ -103,8 +120,31 @@ public function getTypes($class, $property, array $context = array())
103
120
}
104
121
105
122
$ types = array ();
123
+ /** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */
106
124
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 ((string ) $ varType , $ nullable );
134
+
135
+ if (null !== $ type ) {
136
+ $ types [] = $ type ;
137
+ }
138
+
139
+ continue ;
140
+ }
141
+
142
+ $ typeIndex = 0 ;
143
+ $ varTypes = array ();
144
+ while ($ varType ->has ($ typeIndex )) {
145
+ $ varTypes [] = (string ) $ varType ->get ($ typeIndex );
146
+ ++$ typeIndex ;
147
+ }
108
148
109
149
// If null is present, all types are nullable
110
150
$ nullKey = array_search (Type::BUILTIN_TYPE_NULL , $ varTypes );
@@ -134,29 +174,6 @@ public function getTypes($class, $property, array $context = array())
134
174
return array (new Type (Type::BUILTIN_TYPE_ARRAY , false , null , true , new Type (Type::BUILTIN_TYPE_INT ), $ types [0 ]));
135
175
}
136
176
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
-
160
177
/**
161
178
* Gets the DocBlock for this property.
162
179
*
@@ -212,27 +229,7 @@ private function getDocBlockFromProperty($class, $property)
212
229
return ;
213
230
}
214
231
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 ));
236
233
}
237
234
238
235
/**
@@ -242,11 +239,12 @@ private function getDocBlockFromProperty($class, $property)
242
239
* @param string $ucFirstProperty
243
240
* @param int $type
244
241
*
245
- * @return DocBlock|null
242
+ * @return array
246
243
*/
247
244
private function getDocBlockFromMethod ($ class , $ ucFirstProperty , $ type )
248
245
{
249
246
$ prefixes = $ type === self ::ACCESSOR ? ReflectionExtractor::$ accessorPrefixes : ReflectionExtractor::$ mutatorPrefixes ;
247
+ $ prefix = null ;
250
248
251
249
foreach ($ prefixes as $ prefix ) {
252
250
$ methodName = $ prefix .$ ucFirstProperty ;
@@ -269,39 +267,7 @@ private function getDocBlockFromMethod($class, $ucFirstProperty, $type)
269
267
return ;
270
268
}
271
269
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 ;
270
+ return array ($ this ->docBlockFactory ->create ($ reflectionMethod , $ this ->contextFactory ->createFromReflector ($ reflectionMethod )), $ prefix );
305
271
}
306
272
307
273
/**
0 commit comments