nodesToAddCollector = $nodesToAddCollector; } public function addLivingCodeBeforeNode(\PhpParser\Node\Expr $expr, \PhpParser\Node $addBeforeThisNode) : void { $livinExprs = $this->keepLivingCodeFromExpr($expr); foreach ($livinExprs as $livinExpr) { $this->nodesToAddCollector->addNodeBeforeNode(new \PhpParser\Node\Stmt\Expression($livinExpr), $addBeforeThisNode); } } /** * @param Node|int|string|null $expr * @return Expr[]|mixed[] */ public function keepLivingCodeFromExpr($expr) : array { if (!$expr instanceof \PhpParser\Node\Expr) { 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)) { /** @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_) { 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; } 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); } /** * @return Expr[] */ private function processBinary(\PhpParser\Node\Expr\BinaryOp $binaryOp) : array { 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; } }