diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector/Fixture/same_variable_return_nested.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector/Fixture/same_variable_return_nested.php.inc new file mode 100644 index 00000000000..4446e752088 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector/Fixture/same_variable_return_nested.php.inc @@ -0,0 +1,51 @@ +setBody('... some body content'); + + return $response; + } + + return $response; + } +} + +?> +----- +setBody('... some body content'); + + return $response; + } + + return $response; + } +} + +?> diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector/Fixture/skip_two_variables_return_nested.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector/Fixture/skip_two_variables_return_nested.php.inc new file mode 100644 index 00000000000..9137e45cbe4 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector/Fixture/skip_two_variables_return_nested.php.inc @@ -0,0 +1,24 @@ +setBody('... some body content'); + + return $response; + } + + return $anotherResponse; + } +} diff --git a/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php b/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php index 037483a349b..07202f9f165 100644 --- a/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php +++ b/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php @@ -40,36 +40,43 @@ public function matchAlwaysReturnVariableNew(ClassMethod|Function_ $functionLike return null; } - if (count($returns) !== 1) { - return null; - } + // in case of more returns, we need to check if they all return the same variable - // exact one return of variable - $onlyReturn = $returns[0]; - if (! $onlyReturn->expr instanceof Variable) { - return null; - } + $createdVariablesToTypes = $this->resolveCreatedVariablesToTypes($functionLike); - $returnType = $this->nodeTypeResolver->getType($onlyReturn->expr); + $alwaysReturnedClassNames = []; - if (! $returnType instanceof ObjectType) { - return null; - } + foreach ($returns as $return) { + // exact one return of variable + if (! $return->expr instanceof Variable) { + return null; + } - $createdVariablesToTypes = $this->resolveCreatedVariablesToTypes($functionLike); + $returnType = $this->nodeTypeResolver->getType($return->expr); + if (! $returnType instanceof ObjectType) { + return null; + } + + $returnedVariableName = $this->nodeNameResolver->getName($return->expr); + + $className = $createdVariablesToTypes[$returnedVariableName] ?? null; + if (! is_string($className)) { + return null; + } - $returnedVariableName = $this->nodeNameResolver->getName($onlyReturn->expr); + if ($returnType->getClassName() !== $className) { + return null; + } - $className = $createdVariablesToTypes[$returnedVariableName] ?? null; - if (! is_string($className)) { - return $className; + $alwaysReturnedClassNames[] = $className; } - if ($returnType->getClassName() === $className) { - return $className; + $uniqueAlwaysReturnedClasses = array_unique($alwaysReturnedClassNames); + if (count($uniqueAlwaysReturnedClasses) !== 1) { + return null; } - return null; + return $uniqueAlwaysReturnedClasses[0]; } /** diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php index 5637a34c4e6..0b06c01b11b 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php @@ -118,6 +118,7 @@ public function refactor(Node $node): ?Node } $returnedNewClassName = $this->strictReturnNewAnalyzer->matchAlwaysReturnVariableNew($node); + if (is_string($returnedNewClassName)) { $node->returnType = new FullyQualified($returnedNewClassName);