followedByCommaAnalyzer = $followedByCommaAnalyzer; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Remove trailing commas in param or use list', [new CodeSample(<<<'CODE_SAMPLE' class SomeClass { public function __construct(string $value1, string $value2,) { function (string $value1, string $value2,) { }; function () use ($value1, $value2,) { }; } } function inFunction(string $value1, string $value2,) { } CODE_SAMPLE , <<<'CODE_SAMPLE' class SomeClass { public function __construct(string $value1, string $value2) { function (string $value1, string $value2) { }; function () use ($value1, $value2) { }; } } function inFunction(string $value1, string $value2) { } CODE_SAMPLE )]); } /** * @return array> */ public function getNodeTypes() : array { return [ClassMethod::class, Function_::class, Closure::class]; } /** * @param ClassMethod|Function_|Closure $node */ public function refactor(Node $node) : ?Node { if ($node instanceof Closure) { $this->processUses($node); } return $this->processParams($node); } private function processUses(Closure $node) : ?Node { if ($node->uses === []) { return null; } return $this->cleanTrailingComma($node, $node->uses); } /** * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $node */ private function processParams($node) : ?Node { if ($node->params === []) { return null; } return $this->cleanTrailingComma($node, $node->params); } /** * @param ClosureUse[]|Param[] $array * @param \PhpParser\Node\Expr\Closure|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node */ private function cleanTrailingComma($node, array $array) : ?Node { \end($array); $lastPosition = \key($array); \reset($array); $last = $array[$lastPosition]; if (!$this->followedByCommaAnalyzer->isFollowed($this->file, $last)) { return null; } $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); $last->setAttribute(AttributeKey::FUNC_ARGS_TRAILING_COMMA, \false); return $node; } }