Require multiline parameters and arguments to start on a new line after the opening parenthesis

Viewed 161

I'm configuring SwiftLint for a project, and one of our standards that I would like to enforce is this: when a function is declared or called, and its parameters or arguments are broken over multiple lines, then the first parameter should always be on the line after the function name.

In other words, it should always look like this:

func foo(
  bar: Int,
  baz: Int
  ...

foo(
  bar: 0,
  baz: 1

and never like this:

func foo(bar: Int
         baz: Int
         ...

foo(bar: 0,
    baz: 1
    ...

I've looked for a rule like this in among the predefined rules, but I couldn't find one. I'm really hoping I just missed it, because this seems like a rule that could be auto-applied with --fix quite easily.

If no such rule exists, I suppose it wouldn't be too hard to create a custom rule, but then (to my understanding) setting it up to be auto-applied is out of the question. Or am I wrong?

1 Answers

To answer my own question:

  1. No, this rule doesn't seem to be supported out of the box. The closest that seems to exist is multiline_parameters, which is perfectly happy with the snippet that I would want to consider a violation
  2. No, SwiftLint doesn't support autocorrecting custom rules
  3. My custom rule still needs a lot of love, but here is what I've got so far, which at least doesn't seem to trigger false positives:
# Triggered when a multi-line parameter or argument list starts on the same line as the opening bracket
# func foo(x: Int,
#      y: Int...
# ---OR---
# foo(x: 1,
#     y: 2...
    multi_line_args_start_on_same_line:
        name: "Multi-line args format"
        message: "Multi-line arguments or parameters should start on a new line"
        included: ".*\\.swift"
        # Line-by-line:
        # - start of function with opening bracket; e.g. `foo(`
        # - A parameter name, then a colon, and then whitespace; e.g. `x: `
        # - A parameter value or type, followed by a comma and newline,
        #   e.g. `Int,\n` or `10,\n`
        # - Anything, to account for subsequent parameters or args
        # - A closing bracket at the end
        regex: "\
        [\\w\\d]+\\(\
        [\\w\\d]+:\\s*\
        [\\w\\d]+,\\n\
        .*\
        \\)$"
        severity: error 
Related