Skip to content

Commit 0e23e81

Browse files
authored
[type-coverage] Add support for same returned object in ReturnTypeFromReturnNewRector (#7096)
* add missing fixture for ReturnTypeFromReturnNewRector * implement
1 parent 6e3122c commit 0e23e81

File tree

4 files changed

+103
-20
lines changed

4 files changed

+103
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector\Fixture;
6+
7+
use Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector\Source\SomeResponse;
8+
9+
final class SameVariableReturnNested
10+
{
11+
public function action()
12+
{
13+
$response = new SomeResponse();
14+
15+
if (mt_rand(0, 1)) {
16+
$response->setBody('... some body content');
17+
18+
return $response;
19+
}
20+
21+
return $response;
22+
}
23+
}
24+
25+
?>
26+
-----
27+
<?php
28+
29+
declare(strict_types=1);
30+
31+
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector\Fixture;
32+
33+
use Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector\Source\SomeResponse;
34+
35+
final class SameVariableReturnNested
36+
{
37+
public function action(): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector\Source\SomeResponse
38+
{
39+
$response = new SomeResponse();
40+
41+
if (mt_rand(0, 1)) {
42+
$response->setBody('... some body content');
43+
44+
return $response;
45+
}
46+
47+
return $response;
48+
}
49+
}
50+
51+
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector\Fixture;
6+
7+
use Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector\Source\SomeResponse;
8+
9+
final class SkipTwoVariablesReturnNested
10+
{
11+
public function action()
12+
{
13+
$response = new SomeResponse();
14+
$anotherResponse = new \stdClass();
15+
16+
if (mt_rand(0, 1)) {
17+
$response->setBody('... some body content');
18+
19+
return $response;
20+
}
21+
22+
return $anotherResponse;
23+
}
24+
}

rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,43 @@ public function matchAlwaysReturnVariableNew(ClassMethod|Function_ $functionLike
4040
return null;
4141
}
4242

43-
if (count($returns) !== 1) {
44-
return null;
45-
}
43+
// in case of more returns, we need to check if they all return the same variable
4644

47-
// exact one return of variable
48-
$onlyReturn = $returns[0];
49-
if (! $onlyReturn->expr instanceof Variable) {
50-
return null;
51-
}
45+
$createdVariablesToTypes = $this->resolveCreatedVariablesToTypes($functionLike);
5246

53-
$returnType = $this->nodeTypeResolver->getType($onlyReturn->expr);
47+
$alwaysReturnedClassNames = [];
5448

55-
if (! $returnType instanceof ObjectType) {
56-
return null;
57-
}
49+
foreach ($returns as $return) {
50+
// exact one return of variable
51+
if (! $return->expr instanceof Variable) {
52+
return null;
53+
}
5854

59-
$createdVariablesToTypes = $this->resolveCreatedVariablesToTypes($functionLike);
55+
$returnType = $this->nodeTypeResolver->getType($return->expr);
56+
if (! $returnType instanceof ObjectType) {
57+
return null;
58+
}
59+
60+
$returnedVariableName = $this->nodeNameResolver->getName($return->expr);
61+
62+
$className = $createdVariablesToTypes[$returnedVariableName] ?? null;
63+
if (! is_string($className)) {
64+
return null;
65+
}
6066

61-
$returnedVariableName = $this->nodeNameResolver->getName($onlyReturn->expr);
67+
if ($returnType->getClassName() !== $className) {
68+
return null;
69+
}
6270

63-
$className = $createdVariablesToTypes[$returnedVariableName] ?? null;
64-
if (! is_string($className)) {
65-
return $className;
71+
$alwaysReturnedClassNames[] = $className;
6672
}
6773

68-
if ($returnType->getClassName() === $className) {
69-
return $className;
74+
$uniqueAlwaysReturnedClasses = array_unique($alwaysReturnedClassNames);
75+
if (count($uniqueAlwaysReturnedClasses) !== 1) {
76+
return null;
7077
}
7178

72-
return null;
79+
return $uniqueAlwaysReturnedClasses[0];
7380
}
7481

7582
/**

rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public function refactor(Node $node): ?Node
118118
}
119119

120120
$returnedNewClassName = $this->strictReturnNewAnalyzer->matchAlwaysReturnVariableNew($node);
121+
121122
if (is_string($returnedNewClassName)) {
122123
$node->returnType = new FullyQualified($returnedNewClassName);
123124

0 commit comments

Comments
 (0)