8000 bug #27618 [PropertyInfo] added handling of nullable types in PhpDoc … · symfony/symfony@1aae233 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1aae233

Browse files
committed
bug #27618 [PropertyInfo] added handling of nullable types in PhpDoc (oxan)
This PR was merged into the 3.4 branch. Discussion ---------- [PropertyInfo] added handling of nullable types in PhpDoc While not specified in PSR-5, PhpDocumentor does support parsing nullable types in the PHP 7.1 syntax (i.e. `?string`), and returns those in a `Nullable` wrapper type. We currently don't handle this and neither throw an error, which results in all kind of weird breakage when this syntax is used (e.g. "class string|int not found"). Correctly parse this syntax into a nullable type. | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a Commits ------- 38b369b [PropertyInfo] added handling of nullable types in PhpDoc
2 parents 52b91bb + 38b369b commit 1aae233

File tree

6 files changed

+44
-5
lines changed

6 files changed

+44
-5
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
},
105105
"conflict": {
106106
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
107-
"phpdocumentor/type-resolver": "<0.2.1",
107+
"phpdocumentor/type-resolver": "<0.3.0",
108108
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
109109
},
110110
"provide": {

src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ public function typesProvider()
9494
array('e', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_RESOURCE))), null, null),
9595
array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime'))), null, null),
9696
array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null),
97+
array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null),
98+
array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null),
99+
array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null),
97100
array('donotexist', null, null, null),
98101
array('staticGetter', null, null, null),
99102
array('staticSetter', null, null, null),
@@ -130,6 +133,9 @@ public function typesWithCustomPrefixesProvider()
130133
array('e', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_RESOURCE))), null, null),
131134
array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime'))), null, null),
132135
array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null),
136+
array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null),
137+
array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null),
138+
array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null),
133139
array('donotexist', null, null, null),
134140
array('staticGetter', null, null, null),
135141
array('staticSetter', null, null, null),
@@ -165,6 +171,9 @@ public function typesWithNoPrefixesProvider()
165171
array('e', null, null, null),
166172
array('f', null, null, null),
167173
array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null),
174+
array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null),
175+
array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null),
176+
array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null),
168177
array('donotexist', null, null, null),
169178
array('staticGetter', null, null, null),
170179
array('staticSetter', null, null, null),

src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public function testGetProperties()
4141
'B',
4242
'Guid',
4343
'g',
44+
'h',
45+
'i',
46+
'j',
4447
'emptyVar',
4548
'foo',
4649
'foo2',
@@ -77,6 +80,9 @@ public function testGetPropertiesWithCustomPrefixes()
7780
'B',
7881
'Guid',
7982
'g',
83+
'h',
84+
'i',
85+
'j',
8086
'emptyVar',
8187
'foo',
8288
'foo2',
@@ -105,6 +111,9 @@ public function testGetPropertiesWithNoPrefixes()
105111
'B',
106112
'Guid',
107113
'g',
114+
'h',
115+
'i',
116+
'j',
108117
'emptyVar',
109118
'foo',
110119
'foo2',

src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ class Dummy extends ParentDummy
6868
*/
6969
public $g;
7070

71+
/**
72+
* @var ?string
73+
*/
74+
public $h;
75+
76+
/**
77+
* @var ?string|int
78+
*/
79+
public $i;
80+
81+
/**
82+
* @var ?\DateTime
83+
*/
84+
public $j;
85+
7186
/**
7287
* This should not be removed.
7388
*

src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use phpDocumentor\Reflection\Type as DocType;
1515
use phpDocumentor\Reflection\Types\Compound;
1616
use phpDocumentor\Reflection\Types\Null_;
17+
use phpDocumentor\Reflection\Types\Nullable;
1718
use Symfony\Component\PropertyInfo\Type;
1819

1920
/**
@@ -27,13 +28,18 @@ final class PhpDocTypeHelper
2728
/**
2829
* Creates a {@see Type} from a PHPDoc type.
2930
*
30-
* @return Type
31+
* @return Type[]
3132
*/
3233
public function getTypes(DocType $varType)
3334
{
3435
$types = array();
3536
$nullable = false;
3637

38+
if ($varType instanceof Nullable) {
39+
$nullable = true;
40+
$varType = $varType->getActualType();
41+
}
42+
3743
if (!$varType instanceof Compound) {
3844
if ($varType instanceof Null_) {
3945
$nullable = true;
@@ -54,10 +60,10 @@ public function getTypes(DocType $varType)
5460

5561
// If null is present, all types are nullable
5662
$nullKey = array_search(Type::BUILTIN_TYPE_NULL, $varTypes);
57-
$nullable = false !== $nullKey;
63+
$nullable = $nullable || false !== $nullKey;
5864

5965
// Remove the null type from the type if other types are defined
60-
if ($nullable && count($varTypes) > 1) {
66+
if ($nullable && false !== $nullKey && count($varTypes) > 1) {
6167
unset($varTypes[$nullKey]);
6268
}
6369

src/Symfony/Component/PropertyInfo/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
},
3636
"conflict": {
3737
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
38-
"phpdocumentor/type-resolver": "<0.2.1",
38+
"phpdocumentor/type-resolver": "<0.3.0",
3939
"symfony/dependency-injection": "<3.3"
4040
},
4141
"suggest": {

0 commit comments

Comments
 (0)
0