mirror of
https://github.com/rectorphp/rector.git
synced 2024-07-01 07:03:32 +00:00
cover return array method
This commit is contained in:
parent
87fa3a25e4
commit
59dbe98883
|
@ -1,4 +1,4 @@
|
|||
# All 512 Rectors Overview
|
||||
# All 513 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
- [General](#general)
|
||||
|
@ -26,7 +26,7 @@
|
|||
- [MagicDisclosure](#magicdisclosure) (5)
|
||||
- [MockistaToMockery](#mockistatomockery) (2)
|
||||
- [MysqlToMysqli](#mysqltomysqli) (4)
|
||||
- [Naming](#naming) (1)
|
||||
- [Naming](#naming) (2)
|
||||
- [Nette](#nette) (12)
|
||||
- [NetteCodeQuality](#nettecodequality) (1)
|
||||
- [NetteKdyby](#nettekdyby) (4)
|
||||
|
@ -4812,6 +4812,28 @@ Rename property and method param to match its type
|
|||
|
||||
<br><br>
|
||||
|
||||
### `RenameVariableToMatchNewTypeRector`
|
||||
|
||||
- class: [`Rector\Naming\Rector\ClassMethod\RenameVariableToMatchNewTypeRector`](/../master/rules/naming/src/Rector/ClassMethod/RenameVariableToMatchNewTypeRector.php)
|
||||
- [test fixtures](/../master/rules/naming/tests/Rector/ClassMethod/RenameVariableToMatchNewTypeRector/Fixture)
|
||||
|
||||
Rename variable to match new ClassType
|
||||
|
||||
```diff
|
||||
final class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
- $search = new DreamSearch();
|
||||
- $search->advance();
|
||||
+ $dreamSearch = new DreamSearch();
|
||||
+ $dreamSearch->advance();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
## Nette
|
||||
|
||||
### `AddDatePickerToDateControlRector`
|
||||
|
@ -10383,7 +10405,7 @@ Turns `@Template` annotation to explicit method call in Controller of FrameworkE
|
|||
- */
|
||||
public function indexAction()
|
||||
{
|
||||
+ return $this->render("index.html.twig");
|
||||
+ return $this->render('index.html.twig');
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Rector\Sensio\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
|
@ -13,9 +14,11 @@ use PhpParser\Node\Expr\Variable;
|
|||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Sensio\SensioTemplateTagValueNode;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\Sensio\Helper\TemplateGuesser;
|
||||
|
||||
final class ThisRenderFactory
|
||||
|
@ -40,16 +43,23 @@ final class ThisRenderFactory
|
|||
*/
|
||||
private $arrayFromCompactFactory;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
public function __construct(
|
||||
NodeFactory $nodeFactory,
|
||||
TemplateGuesser $templateGuesser,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
ArrayFromCompactFactory $arrayFromCompactFactory
|
||||
ArrayFromCompactFactory $arrayFromCompactFactory,
|
||||
NodeTypeResolver $nodeTypeResolver
|
||||
) {
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->templateGuesser = $templateGuesser;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->arrayFromCompactFactory = $arrayFromCompactFactory;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
public function create(
|
||||
|
@ -71,21 +81,10 @@ final class ThisRenderFactory
|
|||
SensioTemplateTagValueNode $sensioTemplateTagValueNode
|
||||
): array {
|
||||
$arguments = [$this->resolveTemplateName($classMethod, $sensioTemplateTagValueNode)];
|
||||
if ($return === null) {
|
||||
return $this->nodeFactory->createArgs($arguments);
|
||||
}
|
||||
|
||||
if ($return->expr instanceof Array_ && count($return->expr->items)) {
|
||||
$arguments[] = $return->expr;
|
||||
} elseif ($return->expr instanceof FuncCall && $this->nodeNameResolver->isName($return->expr, 'compact')) {
|
||||
/** @var FuncCall $compactFunCall */
|
||||
$compactFunCall = $return->expr;
|
||||
|
||||
$array = $this->arrayFromCompactFactory->createArrayFromCompactFuncCall($compactFunCall);
|
||||
$arguments[1] = new Arg($array);
|
||||
} elseif ($sensioTemplateTagValueNode->getVars() !== []) {
|
||||
$variableList = $this->createArrayFromVars($sensioTemplateTagValueNode->getVars());
|
||||
$arguments[1] = new Arg($variableList);
|
||||
$parametersExpr = $this->resolveParametersExpr($return, $sensioTemplateTagValueNode);
|
||||
if ($parametersExpr !== null) {
|
||||
$arguments[] = new Arg($parametersExpr);
|
||||
}
|
||||
|
||||
return $this->nodeFactory->createArgs($arguments);
|
||||
|
@ -114,4 +113,36 @@ final class ThisRenderFactory
|
|||
|
||||
return new Array_($arrayItems);
|
||||
}
|
||||
|
||||
private function resolveParametersExpr(
|
||||
?Return_ $return,
|
||||
SensioTemplateTagValueNode $sensioTemplateTagValueNode
|
||||
): ?Expr {
|
||||
if ($return === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($return->expr instanceof Array_ && count($return->expr->items)) {
|
||||
return $return->expr;
|
||||
}
|
||||
|
||||
if ($return->expr instanceof MethodCall) {
|
||||
$returnStaticType = $this->nodeTypeResolver->getStaticType($return->expr);
|
||||
if ($returnStaticType instanceof ArrayType) {
|
||||
return $return->expr;
|
||||
}
|
||||
}
|
||||
|
||||
if ($return->expr instanceof FuncCall && $this->nodeNameResolver->isName($return->expr, 'compact')) {
|
||||
/** @var FuncCall $compactFunCall */
|
||||
$compactFunCall = $return->expr;
|
||||
return $this->arrayFromCompactFactory->createArrayFromCompactFuncCall($compactFunCall);
|
||||
}
|
||||
|
||||
if ($sensioTemplateTagValueNode->getVars() !== []) {
|
||||
return $this->createArrayFromVars($sensioTemplateTagValueNode->getVars());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use PhpParser\Node\Stmt\Class_;
|
|||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\If_;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Sensio\SensioTemplateTagValueNode;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
|
@ -81,7 +82,7 @@ PHP
|
|||
<<<'PHP'
|
||||
public function indexAction()
|
||||
{
|
||||
return $this->render("index.html.twig");
|
||||
return $this->render('index.html.twig');
|
||||
}
|
||||
PHP
|
||||
),
|
||||
|
@ -162,9 +163,11 @@ PHP
|
|||
/** @var Return_|null $lastReturn */
|
||||
$lastReturn = $this->betterNodeFinder->findLastInstanceOf((array) $classMethod->stmts, Return_::class);
|
||||
|
||||
if ($lastReturn === null) {
|
||||
$this->processClassMethodWithoutReturn($classMethod, $sensioTemplateTagValueNode);
|
||||
} elseif ($lastReturn->expr !== null) {
|
||||
// nothing we can do
|
||||
if ($lastReturn !== null && $lastReturn->expr === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// create "$this->render('template.file.twig.html', ['key' => 'value']);" method call
|
||||
$thisRenderMethodCall = $this->thisRenderFactory->create(
|
||||
$classMethod,
|
||||
|
@ -172,36 +175,23 @@ PHP
|
|||
$sensioTemplateTagValueNode
|
||||
);
|
||||
|
||||
$returnStaticType = $this->getStaticType($lastReturn->expr);
|
||||
|
||||
if (! $lastReturn->expr instanceof MethodCall) {
|
||||
if (! $hasThisRenderOrReturnsResponse) {
|
||||
$lastReturn->expr = $thisRenderMethodCall;
|
||||
}
|
||||
} elseif ($returnStaticType instanceof MixedType) {
|
||||
if ($lastReturn === null) {
|
||||
$this->refactorNoReturn($classMethod, $thisRenderMethodCall);
|
||||
return;
|
||||
}
|
||||
|
||||
$isArrayOrResponseType = $this->arrayUnionResponseTypeAnalyzer->isArrayUnionResponseType(
|
||||
$returnStaticType,
|
||||
self::RESPONSE_CLASS
|
||||
$this->refactorReturnWithValue(
|
||||
$lastReturn,
|
||||
$hasThisRenderOrReturnsResponse,
|
||||
$thisRenderMethodCall,
|
||||
$classMethod
|
||||
);
|
||||
|
||||
if ($isArrayOrResponseType) {
|
||||
$this->processIsArrayOrResponseType($lastReturn, $lastReturn->expr, $thisRenderMethodCall);
|
||||
}
|
||||
}
|
||||
|
||||
$this->returnTypeDeclarationUpdater->updateClassMethod($classMethod, self::RESPONSE_CLASS);
|
||||
$this->removePhpDocTagValueNode($classMethod, SensioTemplateTagValueNode::class);
|
||||
}
|
||||
|
||||
private function processClassMethodWithoutReturn(
|
||||
ClassMethod $classMethod,
|
||||
SensioTemplateTagValueNode $sensioTemplateTagValueNode
|
||||
MethodCall $thisRenderMethodCall
|
||||
): void {
|
||||
// create "$this->render('template.file.twig.html', ['key' => 'value']);" method call
|
||||
$thisRenderMethodCall = $this->thisRenderFactory->create($classMethod, null, $sensioTemplateTagValueNode);
|
||||
$classMethod->stmts[] = new Return_($thisRenderMethodCall);
|
||||
}
|
||||
|
||||
|
@ -234,4 +224,48 @@ PHP
|
|||
|
||||
return $this->isReturnOfObjectType($lastReturn, self::RESPONSE_CLASS);
|
||||
}
|
||||
|
||||
private function refactorNoReturn(ClassMethod $classMethod, MethodCall $thisRenderMethodCall): void
|
||||
{
|
||||
$this->processClassMethodWithoutReturn($classMethod, $thisRenderMethodCall);
|
||||
|
||||
$this->returnTypeDeclarationUpdater->updateClassMethod($classMethod, self::RESPONSE_CLASS);
|
||||
|
||||
$this->removePhpDocTagValueNode($classMethod, SensioTemplateTagValueNode::class);
|
||||
}
|
||||
|
||||
private function refactorReturnWithValue(
|
||||
Return_ $lastReturn,
|
||||
bool $hasThisRenderOrReturnsResponse,
|
||||
MethodCall $thisRenderMethodCall,
|
||||
ClassMethod $classMethod
|
||||
): void {
|
||||
/** @var Expr $lastReturnExpr */
|
||||
$lastReturnExpr = $lastReturn->expr;
|
||||
|
||||
$returnStaticType = $this->getStaticType($lastReturnExpr);
|
||||
|
||||
if (! $lastReturn->expr instanceof MethodCall) {
|
||||
if (! $hasThisRenderOrReturnsResponse) {
|
||||
$lastReturn->expr = $thisRenderMethodCall;
|
||||
}
|
||||
} elseif ($returnStaticType instanceof ArrayType) {
|
||||
$lastReturn->expr = $thisRenderMethodCall;
|
||||
} elseif ($returnStaticType instanceof MixedType) {
|
||||
// nothing we can do
|
||||
return;
|
||||
}
|
||||
|
||||
$isArrayOrResponseType = $this->arrayUnionResponseTypeAnalyzer->isArrayUnionResponseType(
|
||||
$returnStaticType,
|
||||
self::RESPONSE_CLASS
|
||||
);
|
||||
|
||||
if ($isArrayOrResponseType) {
|
||||
$this->processIsArrayOrResponseType($lastReturn, $lastReturnExpr, $thisRenderMethodCall);
|
||||
}
|
||||
|
||||
$this->returnTypeDeclarationUpdater->updateClassMethod($classMethod, self::RESPONSE_CLASS);
|
||||
$this->removePhpDocTagValueNode($classMethod, SensioTemplateTagValueNode::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<?php declare (strict_types=1);
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
final class ClassWithNestedArrayController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @Template("with_some_template.twig")
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
return $this->handleStuff();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function handleStuff()
|
||||
{
|
||||
return [
|
||||
'hello' => 'world'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php declare (strict_types=1);
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
final class ClassWithNestedArrayController extends AbstractController
|
||||
{
|
||||
public function indexAction(): \Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
return $this->render('with_some_template.twig', $this->handleStuff());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function handleStuff()
|
||||
{
|
||||
return [
|
||||
'hello' => 'world'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
Loading…
Reference in New Issue
Block a user