AssignBitwiseOr::class, BitwiseAnd::class => AssignBitwiseAnd::class, BitwiseXor::class => AssignBitwiseXor::class, Plus::class => AssignPlus::class, Div::class => AssignDiv::class, Mul::class => AssignMul::class, Minus::class => AssignMinus::class, Concat::class => AssignConcat::class, Pow::class => AssignPow::class, Mod::class => AssignMod::class, ShiftLeft::class => AssignShiftLeft::class, ShiftRight::class => AssignShiftRight::class, ]; /** * @var BetterStandardPrinter */ private $betterStandardPrinter; public function __construct(BetterStandardPrinter $betterStandardPrinter) { $this->betterStandardPrinter = $betterStandardPrinter; } public function getDefinition(): RectorDefinition { return new RectorDefinition( 'Simplify $value = $value + 5; assignments to shorter ones', [new CodeSample('$value = $value + 5;', '$value += 5;')] ); } /** * @return string[] */ public function getNodeTypes(): array { return [Assign::class]; } /** * @param Assign $assignNode */ public function refactor(Node $assignNode): ?Node { if (! $assignNode->expr instanceof BinaryOp) { return $assignNode; } /** @var BinaryOp $binaryNode */ $binaryNode = $assignNode->expr; if (! $this->areNodesEqual($assignNode->var, $binaryNode->left)) { return $assignNode; } $binaryNodeClass = get_class($binaryNode); if (! isset($this->binaryOpClassToAssignOpClass[$binaryNodeClass])) { return $assignNode; } $newAssignNodeClass = $this->binaryOpClassToAssignOpClass[$binaryNodeClass]; /** @var AssignOp $newAssignNodeClass */ return new $newAssignNodeClass($assignNode->var, $binaryNode->right); } private function areNodesEqual(Node $firstNode, Node $secondNode): bool { return $this->betterStandardPrinter->prettyPrint([$firstNode]) === $this->betterStandardPrinter->prettyPrint( [$secondNode] ); } }