Skip to content

Commit fb69bc6

Browse files
committed
Adds missing testcases and solves issue nullable
Nullable return types are an object type in php-parser this patch changes the logic to convert that to a return type of phpdocumentor
1 parent 3659ab8 commit fb69bc6

File tree

4 files changed

+115
-4
lines changed

4 files changed

+115
-4
lines changed

src/phpDocumentor/Reflection/Php/Factory/Function_.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use phpDocumentor\Reflection\TypeResolver;
2323
use phpDocumentor\Reflection\Types\Context;
2424
use PhpParser\Comment\Doc;
25+
use PhpParser\Node\NullableType;
2526
use PhpParser\Node\Stmt\Function_ as FunctionNode;
2627

2728
/**
@@ -59,9 +60,14 @@ protected function doCreate($object, StrategyContainer $strategies, Context $con
5960
$docBlock = $this->createDocBlock($strategies, $object->getDocComment(), $context);
6061

6162
$returnType = null;
62-
if ($object->returnType !== null) {
63+
if ($object->getReturnType() !== null) {
6364
$typeResolver = new TypeResolver();
64-
$returnType = $typeResolver->resolve($object->returnType, $context);
65+
if ($object->getReturnType() instanceof NullableType) {
66+
$typeString = '?' . $object->getReturnType()->type;
67+
} else {
68+
$typeString = (string)$object->getReturnType();
69+
}
70+
$returnType = $typeResolver->resolve($typeString, $context);
6571
}
6672

6773
$function = new FunctionDescriptor($object->fqsen, $docBlock, new Location($object->getLine()), $returnType);

src/phpDocumentor/Reflection/Php/Factory/Method.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use phpDocumentor\Reflection\TypeResolver;
2121
use phpDocumentor\Reflection\Types\Context;
2222
use phpDocumentor\Reflection\Types\Mixed_;
23+
use PhpParser\Node\NullableType;
2324
use PhpParser\Node\Stmt\ClassMethod;
2425

2526
/**
@@ -51,9 +52,14 @@ protected function doCreate($object, StrategyContainer $strategies, Context $con
5152
$docBlock = $this->createDocBlock($strategies, $object->getDocComment(), $context);
5253

5354
$returnType = null;
54-
if ($object->returnType !== null) {
55+
if ($object->getReturnType() !== null) {
5556
$typeResolver = new TypeResolver();
56-
$returnType = $typeResolver->resolve($object->returnType, $context);
57+
if ($object->getReturnType() instanceof NullableType) {
58+
$typeString = '?' . $object->getReturnType()->type;
59+
} else {
60+
$typeString = (string)$object->getReturnType();
61+
}
62+
$returnType = $typeResolver->resolve($typeString, $context);
5763
}
5864

5965
$method = new MethodDescriptor(

tests/unit/phpDocumentor/Reflection/Php/Factory/Function_Test.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
use Mockery as m;
2121
use phpDocumentor\Reflection\Php\StrategyContainer;
2222
use phpDocumentor\Reflection\Types\Context;
23+
use phpDocumentor\Reflection\Types\Integer;
24+
use phpDocumentor\Reflection\Types\Nullable;
2325
use PhpParser\Comment\Doc;
26+
use PhpParser\Node\NullableType;
2427

2528
/**
2629
* Test case for \phpDocumentor\Reflection\Php\Factory\Function_
@@ -55,6 +58,7 @@ public function testCreateWithoutParameters()
5558
$functionMock->params = [];
5659
$functionMock->shouldReceive('getDocComment')->andReturnNull();
5760
$functionMock->shouldReceive('getLine')->andReturn(1);
61+
$functionMock->shouldReceive('getReturnType')->andReturnNull();
5862

5963
$containerMock = m::mock(StrategyContainer::class);
6064
$containerMock->shouldReceive('findMatching')->never();
@@ -75,6 +79,7 @@ public function testCreateWithParameters()
7579
$functionMock->params = array('param1');
7680
$functionMock->shouldReceive('getDocComment')->andReturnNull();
7781
$functionMock->shouldReceive('getLine')->andReturn(1);
82+
$functionMock->shouldReceive('getReturnType')->andReturnNull();
7883

7984
$containerMock = m::mock(StrategyContainer::class);
8085
$containerMock->shouldReceive('findMatching->create')
@@ -88,6 +93,50 @@ public function testCreateWithParameters()
8893
$this->assertEquals('\SomeSpace::function()', (string)$function->getFqsen());
8994
}
9095

96+
/**
97+
* @covers ::create
98+
*/
99+
public function testReturnTypeResolving()
100+
{
101+
$functionMock = m::mock(\PhpParser\Node\Stmt\Function_::class);
102+
$functionMock->fqsen = new Fqsen('\SomeSpace::function()');
103+
$functionMock->params = [];
104+
$functionMock->shouldReceive('getDocComment')->andReturnNull();
105+
$functionMock->shouldReceive('getLine')->andReturn(1);
106+
$functionMock->shouldReceive('getReturnType')->times(3)->andReturn('int');
107+
108+
$containerMock = m::mock(StrategyContainer::class);
109+
$containerMock->shouldReceive('findMatching')->never();
110+
111+
112+
/** @var FunctionDescriptor $function */
113+
$function = $this->fixture->create($functionMock, $containerMock);
114+
115+
$this->assertEquals(new Integer(), $function->getReturnType());
116+
}
117+
118+
/**
119+
* @covers ::create
120+
*/
121+
public function testReturnTypeNullableResolving()
122+
{
123+
$functionMock = m::mock(\PhpParser\Node\Stmt\Function_::class);
124+
$functionMock->fqsen = new Fqsen('\SomeSpace::function()');
125+
$functionMock->params = [];
126+
$functionMock->shouldReceive('getDocComment')->andReturnNull();
127+
$functionMock->shouldReceive('getLine')->andReturn(1);
128+
$functionMock->shouldReceive('getReturnType')->times(3)->andReturn(new NullableType('int'));
129+
130+
$containerMock = m::mock(StrategyContainer::class);
131+
$containerMock->shouldReceive('findMatching')->never();
132+
133+
134+
/** @var FunctionDescriptor $method */
135+
$function = $this->fixture->create($functionMock, $containerMock);
136+
137+
$this->assertEquals(new Nullable(new Integer()), $function->getReturnType());
138+
}
139+
91140
/**
92141
* @covers ::create
93142
*/
@@ -99,6 +148,7 @@ public function testCreateWithDocBlock()
99148
$functionMock->params = [];
100149
$functionMock->shouldReceive('getDocComment')->andReturn($doc);
101150
$functionMock->shouldReceive('getLine')->andReturn(1);
151+
$functionMock->shouldReceive('getReturnType')->andReturnNull();
102152

103153
$docBlock = new DocBlockDescriptor('');
104154

tests/unit/phpDocumentor/Reflection/Php/Factory/MethodTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
use Mockery as m;
2020
use phpDocumentor\Reflection\Php\StrategyContainer;
2121
use phpDocumentor\Reflection\Types\Context;
22+
use phpDocumentor\Reflection\Types\Integer;
23+
use phpDocumentor\Reflection\Types\Nullable;
2224
use PhpParser\Comment\Doc;
25+
use PhpParser\Node\NullableType;
2326
use PhpParser\Node\Stmt\ClassMethod;
2427

2528
/**
@@ -53,6 +56,7 @@ public function testCreateWithoutParameters()
5356
$classMethodMock->shouldReceive('isPrivate')->once()->andReturn(false);
5457
$classMethodMock->shouldReceive('isProtected')->once()->andReturn(false);
5558
$classMethodMock->shouldReceive('getDocComment')->once()->andReturnNull();
59+
$classMethodMock->shouldReceive('getReturnType')->once()->andReturn(null);
5660

5761
$containerMock = m::mock(StrategyContainer::class);
5862
$containerMock->shouldReceive('findMatching')->never();
@@ -71,6 +75,7 @@ public function testCreateProtectedMethod()
7175
$classMethodMock->shouldReceive('isPrivate')->once()->andReturn(false);
7276
$classMethodMock->shouldReceive('isProtected')->once()->andReturn(true);
7377
$classMethodMock->shouldReceive('getDocComment')->once()->andReturnNull();
78+
$classMethodMock->shouldReceive('getReturnType')->once()->andReturn(null);
7479

7580
$containerMock = m::mock(StrategyContainer::class);
7681
$containerMock->shouldReceive('findMatching')->never();
@@ -91,6 +96,7 @@ public function testCreateWithParameters()
9196
$classMethodMock->params = array('param1');
9297
$classMethodMock->shouldReceive('isPrivate')->once()->andReturn(true);
9398
$classMethodMock->shouldReceive('getDocComment')->once()->andReturnNull();
99+
$classMethodMock->shouldReceive('getReturnType')->once()->andReturn(null);
94100

95101
$containerMock = m::mock(StrategyContainer::class);
96102
$containerMock->shouldReceive('findMatching->create')
@@ -108,6 +114,48 @@ public function testCreateWithParameters()
108114
$this->assertEquals('private', (string)$method->getVisibility());
109115
}
110116

117+
/**
118+
* @covers ::create
119+
*/
120+
public function testReturnTypeResolving()
121+
{
122+
$classMethodMock = $this->buildClassMethodMock();
123+
$classMethodMock->params = [];
124+
$classMethodMock->shouldReceive('isPrivate')->once()->andReturn(true);
125+
$classMethodMock->shouldReceive('getDocComment')->once()->andReturnNull();
126+
$classMethodMock->shouldReceive('getReturnType')->times(3)->andReturn('int');
127+
128+
$containerMock = m::mock(StrategyContainer::class);
129+
$containerMock->shouldReceive('findMatching')->never();
130+
131+
132+
/** @var MethodDescriptor $method */
133+
$method = $this->fixture->create($classMethodMock, $containerMock);
134+
135+
$this->assertEquals(new Integer(), $method->getReturnType());
136+
}
137+
138+
/**
139+
* @covers ::create
140+
*/
141+
public function testReturnTypeNullableResolving()
142+
{
143+
$classMethodMock = $this->buildClassMethodMock();
144+
$classMethodMock->params = [];
145+
$classMethodMock->shouldReceive('isPrivate')->once()->andReturn(true);
146+
$classMethodMock->shouldReceive('getDocComment')->once()->andReturnNull();
147+
$classMethodMock->shouldReceive('getReturnType')->times(3)->andReturn(new NullableType('int'));
148+
149+
$containerMock = m::mock(StrategyContainer::class);
150+
$containerMock->shouldReceive('findMatching')->never();
151+
152+
153+
/** @var MethodDescriptor $method */
154+
$method = $this->fixture->create($classMethodMock, $containerMock);
155+
156+
$this->assertEquals(new Nullable(new Integer()), $method->getReturnType());
157+
}
158+
111159
/**
112160
* @covers ::create
113161
*/
@@ -118,6 +166,7 @@ public function testCreateWithDocBlock()
118166
$classMethodMock->params = array();
119167
$classMethodMock->shouldReceive('isPrivate')->once()->andReturn(true);
120168
$classMethodMock->shouldReceive('getDocComment')->andReturn($doc);
169+
$classMethodMock->shouldReceive('getReturnType')->once()->andReturn(null);
121170

122171
$docBlock = new DocBlockDescriptor('');
123172

0 commit comments

Comments
 (0)