Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 28bb402

Browse files
committed
[PropertyInfo] Extract the logic converting a php doc to a Type
in PhpDocTypeHelperTrait
1 parent ad85c79 commit 28bb402

File tree

2 files changed

+173
-127
lines changed

2 files changed

+173
-127
lines changed

src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php

Lines changed: 3 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
use phpDocumentor\Reflection\DocBlock;
1515
use phpDocumentor\Reflection\DocBlockFactory;
1616
use phpDocumentor\Reflection\DocBlockFactoryInterface;
17-
use phpDocumentor\Reflection\Types\Compound;
1817
use phpDocumentor\Reflection\Types\ContextFactory;
19-
use phpDocumentor\Reflection\Types\Null_;
2018
use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
2119
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
2220
use Symfony\Component\PropertyInfo\Type;
@@ -28,6 +26,8 @@
2826
*/
2927
class PhpDocExtractor implements PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface
3028
{
29+
use PhpDocTypeHelperTrait;
30+
3131
const PROPERTY = 0;
3232
const ACCESSOR = 1;
3333
const MUTATOR = 2;
@@ -123,45 +123,7 @@ public function getTypes($class, $property, array $context = array())
123123
$types = array();
124124
/** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */
125125
foreach ($docBlock->getTagsByName($tag) as $tag) {
126-
$varType = $tag->getType();
127-
$nullable = false;
128-
129-
if (!$varType instanceof Compound) {
130-
if ($varType instanceof Null_) {
131-
$nullable = true;
132-
}
133-
134-
$type = $this->createType((string) $varType, $nullable);
135-
136-
if (null !== $type) {
137-
$types[] = $type;
138-
}
139-
140-
continue;
141-
}
142-
143-
$typeIndex = 0;
144-
$varTypes = array();
145-
while ($varType->has($typeIndex)) {
146-
$varTypes[] = (string) $varType->get($typeIndex);
147-
++$typeIndex;
148-
}
149-
150-
// If null is present, all types are nullable
151-
$nullKey = array_search(Type::BUILTIN_TYPE_NULL, $varTypes);
152-
$nullable = false !== $nullKey;
153-
154-
// Remove the null type from the type if other types are defined
155-
if ($nullable && count($varTypes) > 1) {
156-
unset($varTypes[$nullKey]);
157-
}
158-
159-
foreach ($varTypes as $varType) {
160-
$type = $this->createType($varType, $nullable);
161-
if (null !== $type) {
162-
$types[] = $type;
163-
}
164-
}
126+
$types = array_merge($types, $this->getTypesFromTag($tag));
165127
}
166128

167129
if (!isset($types[0])) {
@@ -274,90 +236,4 @@ private function getDocBlockFromMethod($class, $ucFirstProperty, $type)
274236

275237
return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix);
276238
}
277-
278-
/**
279-
* Creates a {@see Type} from a PHPDoc type.
280-
*
281-
* @param string $docType
282-
* @param bool $nullable
283-
*
284-
* @return Type|null
285-
*/
286-
private function createType($docType, $nullable)
287-
{
288-
// Cannot guess
289-
if (!$docType || 'mixed' === $docType) {
290-
return;
291-
}
292-
293-
if ($collection = '[]' === substr($docType, -2)) {
294-
$docType = substr($docType, 0, -2);
295-
}
296-
297-
$docType = $this->normalizeType($docType);
298-
list($phpType, $class) = $this->getPhpTypeAndClass($docType);
299-
300-
$array = 'array' === $docType;
301-
302-
if ($collection || $array) {
303-
if ($array || 'mixed' === $docType) {
304-
$collectionKeyType = null;
305-
$collectionValueType = null;
306-
} else {
307-
$collectionKeyType = new Type(Type::BUILTIN_TYPE_INT);
308-
$collectionValueType = new Type($phpType, false, $class);
309-
}
310-
311-
return new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, $collectionKeyType, $collectionValueType);
312-
}
313-
314-
return new Type($phpType, $nullable, $class);
315-
}
316-
317-
/**
318-
* Normalizes the type.
319-
*
320-
* @param string $docType
321-
*
322-
* @return string
323-
*/
324-
private function normalizeType($docType)
325-
{
326-
switch ($docType) {
327-
case 'integer':
328-
return 'int';
329-
330-
case 'boolean':
331-
return 'bool';
332-
333-
// real is not part of the PHPDoc standard, so we ignore it
334-
case 'double':
335-
return 'float';
336-
337-
case 'callback':
338-
return 'callable';
339-
340-
case 'void':
341-
return 'null';
342-
343-
default:
344-
return $docType;
345-
}
346-
}
347-
348-
/**
349-
* Gets an array containing the PHP type and the class.
350-
*
351-
* @param string $docType
352-
*
353-
* @return array
354-
*/
355-
private function getPhpTypeAndClass($docType)
356-
{
357-
if (in_array($docType, Type::$builtinTypes)) {
358-
return array($docType, null);
359-
}
360-
361-
return array('object', substr($docType, 1));
362-
}
363239
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyInfo\Extractor;
13+
14+
use phpDocumentor\Reflection\DocBlock\Tags\Param;
15+
use phpDocumentor\Reflection\DocBlock\Tags\Return_;
16+
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
17+
use phpDocumentor\Reflection\Types\Compound;
18+
use phpDocumentor\Reflection\Types\Null_;
19+
use Symfony\Component\PropertyInfo\Type;
20+
21+
/**
22+
* Transforms a php doc type to a {@link Type} instance.
23+
*
24+
* @author Kévin Dunglas <[email protected]>
25+
* @author Guilhem N. <[email protected]>
26+
*/
27+
trait PhpDocTypeHelperTrait
28+
{
29+
/**
30+
* Creates a {@see Type} from a PHPDoc tag.
31+
*
32+
* @param Var_|Return_|Param $tag
33+
*
34+
* @return Type
35+
*/
36+
private function getTypesFromTag($tag)
37+
{
38+
$types = array();
39+
$varType = $tag->getType();
40+
$nullable = false;
41+
42+
if (!$varType instanceof Compound) {
43+
if ($varType instanceof Null_) {
44+
$nullable = true;
45+
}
46+
47+
$type = $this->createType((string) $varType, $nullable);
48+
if (null !== $type) {
49+
$types[] = $type;
50+
}
51+
52+
return $types;
53+
}
54+
55+
$varTypes = array();
56+
for ($typeIndex = 0; $varType->has($typeIndex); ++$typeIndex) {
57+
$varTypes[] = (string) $varType->get($typeIndex);
58+
}
59+
60+
// If null is present, all types are nullable
61+
$nullKey = array_search(Type::BUILTIN_TYPE_NULL, $varTypes);
62+
$nullable = false !== $nullKey;
63+
64+
// Remove the null type from the type if other types are defined
65+
if ($nullable && count($varTypes) > 1) {
66+
unset($varTypes[$nullKey]);
67+
}
68+
69+
foreach ($varTypes as $varType) {
70+
$type = $this->createType($varType, $nullable);
71+
if (null !== $type) {
72+
$types[] = $type;
73+
}
74+
}
75+
76+
return $types;
77+
}
78+
79+
/**
80+
* Creates a {@see Type} from a PHPDoc type.
81+
*
82+
* @param string $docType
83+
* @param bool $nullable
84+
*
85+
* @return Type|null
86+
*
87+
* @internal
88+
*/
89+
private function createType($docType, $nullable)
90+
{
91+
// Cannot guess
92+
if (!$docType || 'mixed' === $docType) {
93+
return;
94+
}
95+
96+
if ($collection = '[]' === substr($docType, -2)) {
97+
$docType = substr($docType, 0, -2);
98+
}
99+
100+
$docType = $this->normalizeType($docType);
101+
list($phpType, $class) = $this->getPhpTypeAndClass($docType);
102+
103+
$array = 'array' === $docType;
104+
105+
if ($collection || $array) {
106+
if ($array || 'mixed' === $docType) {
107+
$collectionKeyType = null;
108+
$collectionValueType = null;
109+
} else {
110+
$collectionKeyType = new Type(Type::BUILTIN_TYPE_INT);
111+
$collectionValueType = new Type($phpType, false, $class);
112+
}
113+
114+
return new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, $collectionKeyType, $collectionValueType);
115+
}
116+
117+
return new Type($phpType, $nullable, $class);
118+
}
119+
120+
/**
121+
* Normalizes the type.
122+
*
123+
* @param string $docType
124+
*
125+
* @return string
126+
*
127+
* @internal
128+
*/
129+
private function normalizeType($docType)
130+
{
131+
switch ($docType) {
132+
case 'integer':
133+
return 'int';
134+
135+
case 'boolean':
136+
return 'bool';
137+
138+
// real is not part of the PHPDoc standard, so we ignore it
139+
case 'double':
140+
return 'float';
141+
142+
case 'callback':
143+
return 'callable';
144+
145+
case 'void':
146+
return 'null';
147+
148+
default:
149+
return $docType;
150+
}
151+
}
152+
153+
/**
154+
* Gets an array containing the PHP type and the class.
155+
*
156+
* @param string $docType
157+
*
158+
* @return array
159+
*
160+
* @internal
161+
*/
162+
private function getPhpTypeAndClass($docType)
163+
{
164+
if (in_array($docType, Type::$builtinTypes)) {
165+
return array($docType, null);
166+
}
167+
168+
return array('object', substr($docType, 1));
169+
}
170+
}

0 commit comments

Comments
 (0)