[TypeDeclaration] Do not add return type on parent Closure for deep closure has return type on ReturnTypeFromStrictTypedCallRector (#439)

* [TypeDeclaration] Do not add return type on parent Closure for deep closure has return type

* debug

* fixed 🎉

* ensure check deep closure parent has return

* fixture rename

* ensure check anonymous class method call inside

* check on any function like

* check on any function like

* any functionlike

* final touch: clean up
This commit is contained in:
Abdul Malik Ikhsan 2021-07-15 14:32:46 +07:00 committed by GitHub
parent 72b34a7d76
commit acabcfc456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 154 additions and 1 deletions

View File

@ -0,0 +1,65 @@
<?php
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture;
class App
{
public static function init(): App
{
return new App;
}
}
function () {
function () {
return App::init();
};
function foo() {
return App::init();
};
new class {
public function run()
{
return App::init();
}
};
};
?>
-----
<?php
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture;
class App
{
public static function init(): App
{
return new App;
}
}
function () {
function (): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture\App {
return App::init();
};
function foo(): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture\App {
return App::init();
};
new class {
public function run(): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture\App
{
return App::init();
}
};
};
?>

View File

@ -0,0 +1,69 @@
<?php
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture;
class App
{
public static function init(): App
{
return new App;
}
}
function () {
function () {
return App::init();
};
function foo() {
return App::init();
};
new class {
public function run()
{
return App::init();
}
};
return App::init();
};
?>
-----
<?php
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture;
class App
{
public static function init(): App
{
return new App;
}
}
function (): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture\App {
function (): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture\App {
return App::init();
};
function foo(): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture\App {
return App::init();
};
new class {
public function run(): \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\Fixture\App
{
return App::init();
}
};
return App::init();
};
?>

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
@ -95,7 +96,25 @@ CODE_SAMPLE
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstanceOf((array) $node->stmts, Return_::class);
$returns = $this->betterNodeFinder->find((array) $node->stmts, function (Node $n) use ($node) {
$currentFunctionLike = $this->betterNodeFinder->findParentType($n, FunctionLike::class);
if ($currentFunctionLike === $node) {
return $n instanceof Return_;
}
$currentReturn = $this->betterNodeFinder->findParentType($n, Return_::class);
if (! $currentReturn instanceof Return_) {
return false;
}
$currentFunctionLike = $this->betterNodeFinder->findParentType($currentReturn, FunctionLike::class);
if ($currentFunctionLike !== $node) {
return false;
}
return $n instanceof Return_;
});
$returnedStrictTypes = $this->collectStrictReturnTypes($returns);
if ($returnedStrictTypes === []) {