2020-02-09 12:31:31 +01:00
|
|
|
<?php
|
|
|
|
|
2021-05-09 20:15:43 +00:00
|
|
|
declare (strict_types=1);
|
2020-02-09 12:31:31 +01:00
|
|
|
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;
|
2020-11-16 17:50:38 +00:00
|
|
|
use PhpParser\Node\Stmt\Expression;
|
|
|
|
use Rector\PostRector\Collector\NodesToAddCollector;
|
2020-02-09 12:31:31 +01:00
|
|
|
final class LivingCodeManipulator
|
|
|
|
{
|
2020-11-16 17:50:38 +00:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\PostRector\Collector\NodesToAddCollector
|
2020-11-16 17:50:38 +00:00
|
|
|
*/
|
|
|
|
private $nodesToAddCollector;
|
2021-05-10 22:23:08 +00:00
|
|
|
public function __construct(\Rector\PostRector\Collector\NodesToAddCollector $nodesToAddCollector)
|
2020-11-16 17:50:38 +00:00
|
|
|
{
|
|
|
|
$this->nodesToAddCollector = $nodesToAddCollector;
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
public function addLivingCodeBeforeNode(\PhpParser\Node\Expr $expr, \PhpParser\Node $addBeforeThisNode) : void
|
2020-11-16 17:50:38 +00:00
|
|
|
{
|
2020-11-16 23:32:24 +00:00
|
|
|
$livinExprs = $this->keepLivingCodeFromExpr($expr);
|
2021-03-05 17:55:40 +07:00
|
|
|
foreach ($livinExprs as $livinExpr) {
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->nodesToAddCollector->addNodeBeforeNode(new \PhpParser\Node\Stmt\Expression($livinExpr), $addBeforeThisNode);
|
2020-11-16 17:50:38 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-09 12:31:31 +01:00
|
|
|
/**
|
2020-11-01 16:39:04 +01:00
|
|
|
* @return Expr[]|mixed[]
|
2021-07-04 13:13:54 +00:00
|
|
|
* @param \PhpParser\Node|int|string|null $expr
|
2020-02-09 12:31:31 +01:00
|
|
|
*/
|
2021-05-09 20:15:43 +00:00
|
|
|
public function keepLivingCodeFromExpr($expr) : array
|
2020-02-09 12:31:31 +01:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
if (!$expr instanceof \PhpParser\Node\Expr) {
|
2020-07-27 08:56:25 +02:00
|
|
|
return [];
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($expr instanceof \PhpParser\Node\Expr\Closure || $expr instanceof \PhpParser\Node\Scalar || $expr instanceof \PhpParser\Node\Expr\ConstFetch) {
|
2020-02-09 12:31:31 +01:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
if ($this->isNestedExpr($expr)) {
|
|
|
|
return $this->keepLivingCodeFromExpr($expr->expr);
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($expr instanceof \PhpParser\Node\Expr\Variable) {
|
2020-02-09 12:31:31 +01:00
|
|
|
return $this->keepLivingCodeFromExpr($expr->name);
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($expr instanceof \PhpParser\Node\Expr\PropertyFetch) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \array_merge($this->keepLivingCodeFromExpr($expr->var), $this->keepLivingCodeFromExpr($expr->name));
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($expr instanceof \PhpParser\Node\Expr\ArrayDimFetch) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \array_merge($this->keepLivingCodeFromExpr($expr->var), $this->keepLivingCodeFromExpr($expr->dim));
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($expr instanceof \PhpParser\Node\Expr\ClassConstFetch || $expr instanceof \PhpParser\Node\Expr\StaticPropertyFetch) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \array_merge($this->keepLivingCodeFromExpr($expr->class), $this->keepLivingCodeFromExpr($expr->name));
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|
|
|
|
if ($this->isBinaryOpWithoutChange($expr)) {
|
2020-07-27 08:56:25 +02:00
|
|
|
/** @var BinaryOp $binaryOp */
|
|
|
|
$binaryOp = $expr;
|
|
|
|
return $this->processBinary($binaryOp);
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($expr instanceof \PhpParser\Node\Expr\Instanceof_) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \array_merge($this->keepLivingCodeFromExpr($expr->expr), $this->keepLivingCodeFromExpr($expr->class));
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($expr instanceof \PhpParser\Node\Expr\Isset_) {
|
2020-07-27 08:56:25 +02:00
|
|
|
return $this->processIsset($expr);
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|
|
|
|
return [$expr];
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
private function isNestedExpr(\PhpParser\Node\Expr $expr) : bool
|
2020-04-26 02:57:47 +02:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
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_;
|
2020-04-26 02:57:47 +02:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
private function isBinaryOpWithoutChange(\PhpParser\Node\Expr $expr) : bool
|
2020-02-09 12:31:31 +01:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
if (!$expr instanceof \PhpParser\Node\Expr\BinaryOp) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \false;
|
2020-07-27 08:56:25 +02:00
|
|
|
}
|
2021-05-10 22:23:08 +00: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-11 12:59:04 +02:00
|
|
|
/**
|
2020-08-29 11:03:40 +02:00
|
|
|
* @return Expr[]
|
2020-08-11 12:59:04 +02:00
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private function processBinary(\PhpParser\Node\Expr\BinaryOp $binaryOp) : array
|
2020-07-27 08:56:25 +02:00
|
|
|
{
|
2021-05-09 20:15:43 +00:00
|
|
|
return \array_merge($this->keepLivingCodeFromExpr($binaryOp->left), $this->keepLivingCodeFromExpr($binaryOp->right));
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|
2020-08-11 12:59:04 +02:00
|
|
|
/**
|
|
|
|
* @return mixed[]
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private function processIsset(\PhpParser\Node\Expr\Isset_ $isset) : array
|
2020-08-05 22:45:36 +02:00
|
|
|
{
|
2020-11-16 17:50:38 +00:00
|
|
|
$livingExprs = [];
|
|
|
|
foreach ($isset->vars as $expr) {
|
2021-05-09 20:15:43 +00:00
|
|
|
$livingExprs = \array_merge($livingExprs, $this->keepLivingCodeFromExpr($expr));
|
2020-11-16 17:50:38 +00:00
|
|
|
}
|
|
|
|
return $livingExprs;
|
2020-08-05 22:45:36 +02:00
|
|
|
}
|
2020-02-09 12:31:31 +01:00
|
|
|
}
|