rector/rules/DeadCode/NodeManipulator/LivingCodeManipulator.php

120 lines
5.1 KiB
PHP
Raw Normal View History

<?php
declare (strict_types=1);
namespace Rector\DeadCode\NodeManipulator;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\BinaryOp\Coalesce;
use PhpParser\Node\Expr\BinaryOp\LogicalAnd;
use PhpParser\Node\Expr\BinaryOp\LogicalOr;
use PhpParser\Node\Expr\BitwiseNot;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\Clone_;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\Empty_;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Expr\Isset_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\UnaryMinus;
use PhpParser\Node\Expr\UnaryPlus;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt\Expression;
use Rector\PostRector\Collector\NodesToAddCollector;
final class LivingCodeManipulator
{
/**
* @var \Rector\PostRector\Collector\NodesToAddCollector
*/
private $nodesToAddCollector;
public function __construct(\Rector\PostRector\Collector\NodesToAddCollector $nodesToAddCollector)
{
$this->nodesToAddCollector = $nodesToAddCollector;
}
public function addLivingCodeBeforeNode(\PhpParser\Node\Expr $expr, \PhpParser\Node $addBeforeThisNode) : void
{
$livinExprs = $this->keepLivingCodeFromExpr($expr);
[Naming] Register RenameForeachValueVariableToMatchExprVariableRector to naming config set (#5696) * [Naming] Register RenameForeachValueVariableToMatchExprVariableRector to naming config set * fix property fetch not from this * [ci-review] Rector Rectify * [ci-review] Rector Rectify * [ci-review] Rector Rectify * fix * [ci-review] Rector Rectify * [ci-review] Rector Rectify * fixture fix * phpstan * [ci-review] Rector Rectify * phpstan * extract to separate method for collect assigns by name * adding InflectorSingularResolver service * skip single prefix and length >= 40 * add failing fixture to skip plural camel case * use regex to get camel cases * implemented singularize camel cased * [ci-review] Rector Rectify * [ci-review] Rector Rectify * [ci-review] Rector Rectify * phpstan * handle singular verb news -> new * [ci-review] Rector Rectify * fixture fix * handle has * [ci-review] Rector Rectify * [ci-review] Rector Rectify * [ci-review] Rector Rectify * phpstan * phpstan * handle left side By * [ci-review] Rector Rectify * re-use resolve call * [ci-review] Rector Rectify * phpstan * [ci-review] Rector Rectify * final touch * final touch * [ci-review] Rector Rectify * [ci-review] Rector Rectify * use previous By in the middle * update $childClassReflection->hasProperty($propertyName) * [ci-review] Rector Rectify * catchKeys * regex fix * fixture * [ci-review] Rector Rectify * try use check array * Revert "try use check array" This reverts commit adb9f767f20ea2544e5ccfc9cfe361ecc929912a. * use files Co-authored-by: kaizen-ci <info@kaizen-ci.org>
2021-03-05 17:55:40 +07:00
foreach ($livinExprs as $livinExpr) {
$this->nodesToAddCollector->addNodeBeforeNode(new \PhpParser\Node\Stmt\Expression($livinExpr), $addBeforeThisNode);
}
}
/**
* @return Expr[]|mixed[]
* @param \PhpParser\Node|int|string|null $expr
*/
public function keepLivingCodeFromExpr($expr) : array
{
if (!$expr instanceof \PhpParser\Node\Expr) {
2020-07-27 08:56:25 +02:00
return [];
}
if ($expr instanceof \PhpParser\Node\Expr\Closure || $expr instanceof \PhpParser\Node\Scalar || $expr instanceof \PhpParser\Node\Expr\ConstFetch) {
return [];
}
if ($this->isNestedExpr($expr)) {
return $this->keepLivingCodeFromExpr($expr->expr);
}
if ($expr instanceof \PhpParser\Node\Expr\Variable) {
return $this->keepLivingCodeFromExpr($expr->name);
}
if ($expr instanceof \PhpParser\Node\Expr\PropertyFetch) {
return \array_merge($this->keepLivingCodeFromExpr($expr->var), $this->keepLivingCodeFromExpr($expr->name));
}
if ($expr instanceof \PhpParser\Node\Expr\ArrayDimFetch) {
return \array_merge($this->keepLivingCodeFromExpr($expr->var), $this->keepLivingCodeFromExpr($expr->dim));
}
if ($expr instanceof \PhpParser\Node\Expr\ClassConstFetch || $expr instanceof \PhpParser\Node\Expr\StaticPropertyFetch) {
return \array_merge($this->keepLivingCodeFromExpr($expr->class), $this->keepLivingCodeFromExpr($expr->name));
}
if ($this->isBinaryOpWithoutChange($expr)) {
2020-07-27 08:56:25 +02:00
/** @var BinaryOp $binaryOp */
$binaryOp = $expr;
return $this->processBinary($binaryOp);
}
if ($expr instanceof \PhpParser\Node\Expr\Instanceof_) {
return \array_merge($this->keepLivingCodeFromExpr($expr->expr), $this->keepLivingCodeFromExpr($expr->class));
}
if ($expr instanceof \PhpParser\Node\Expr\Isset_) {
2020-07-27 08:56:25 +02:00
return $this->processIsset($expr);
}
return [$expr];
}
private function isNestedExpr(\PhpParser\Node\Expr $expr) : bool
{
return $expr instanceof \PhpParser\Node\Expr\Cast || $expr instanceof \PhpParser\Node\Expr\Empty_ || $expr instanceof \PhpParser\Node\Expr\UnaryMinus || $expr instanceof \PhpParser\Node\Expr\UnaryPlus || $expr instanceof \PhpParser\Node\Expr\BitwiseNot || $expr instanceof \PhpParser\Node\Expr\BooleanNot || $expr instanceof \PhpParser\Node\Expr\Clone_;
}
private function isBinaryOpWithoutChange(\PhpParser\Node\Expr $expr) : bool
{
if (!$expr instanceof \PhpParser\Node\Expr\BinaryOp) {
return \false;
2020-07-27 08:56:25 +02:00
}
return !($expr instanceof \PhpParser\Node\Expr\BinaryOp\LogicalAnd || $expr instanceof \PhpParser\Node\Expr\BinaryOp\BooleanAnd || $expr instanceof \PhpParser\Node\Expr\BinaryOp\LogicalOr || $expr instanceof \PhpParser\Node\Expr\BinaryOp\BooleanOr || $expr instanceof \PhpParser\Node\Expr\BinaryOp\Coalesce);
2020-07-27 08:56:25 +02:00
}
/**
2020-08-29 11:03:40 +02:00
* @return Expr[]
*/
private function processBinary(\PhpParser\Node\Expr\BinaryOp $binaryOp) : array
2020-07-27 08:56:25 +02:00
{
return \array_merge($this->keepLivingCodeFromExpr($binaryOp->left), $this->keepLivingCodeFromExpr($binaryOp->right));
}
/**
* @return mixed[]
*/
private function processIsset(\PhpParser\Node\Expr\Isset_ $isset) : array
{
$livingExprs = [];
foreach ($isset->vars as $expr) {
$livingExprs = \array_merge($livingExprs, $this->keepLivingCodeFromExpr($expr));
}
return $livingExprs;
}
}