Swiftlint: Multiline Brackets: consistent style with other bracket conventions

Created on 23 Jul 2018  路  1Comment  路  Source: realm/SwiftLint

Rationale

When trying to enforce the same code style amongst all team members one issue that often arises is the question, how multi-line literals should be styled. What I mean by multi-line literals is arrays and dictionaries, which are written very differently by every team member if no style is enforced. While one might opt to accept all styles so long as other style rules are not violated, this rule should enforce a clear style which is oriented by the community-accepted style for other multi-line bracket based code like classes and method calls. For those we already have clear conventions:

class SomeType {
    let x: Int
    let y: Int

    func sum() -> Int {
        return x = y
    }

    func viewDidLoad() {
        print("x: \(x)")
        print("x: \(x)")
        let sum = sum()

        let evenNums = [x, y].filter { $0 % 2 == 0 }.map { num in
            // some multi-line code
            // some multi-line code
            // some multi-line code
        }
    }
}

While there's of course different styles, one standard widely accepted by the community is to either keep everything in one line including the brackets (like in [x, y].filter { $0 % 2 == 0 } or to put the opening bracket and closing bracket into their own line (like for the class body, the body of the function sum, the body of the function viewDidLoad and the body of the map call).

The same rationale can be applied to function parameters and function arguments as well to enforce a unified multiline style.

Example

The requested opt-in rule requires array and dictionary literals to be styled according to the same rules, to be consistent with other multi-line bracket structure style, for example:

            let trio = ["harry",
                        "ronald",
                        "hermione"]

            let houseCup = ["gryffinder": 460,
                            "hufflepuff": 370,
                            "ravenclaw": 410,
                            "slytherin": 450]

This code is not bad per se, but it could lead to line-length problems when the name of the variable is relatively long. Also renaming the variable in one branch and changing the value of the first literal entry in another branch would lead to a merge conflict. To fix these problems and at the same time be consistent with other brackets, here's the style to be enforced by the new rule:

            let trio = [
                "harry",
                "ronald",
                "hermione"
            ]

            let houseCup = [
                "gryffinder": 460,
                "hufflepuff": 370,
                "ravenclaw": 410,
                "slytherin": 450
            ]

This fixes the line-length problem, prevents merge-conflicts when both the first literal object and the literal variable name are changed in different branches and is consistent with other bracket rules as it puts the opening and closing braces into their own line, just like usually done with { and }.

rule-request

Most helpful comment

an autocorrect for this rule would be amazing, even if it only autocorrected a limited number of situations to be conservative from mistakes!

>All comments

an autocorrect for this rule would be amazing, even if it only autocorrected a limited number of situations to be conservative from mistakes!

Was this page helpful?
0 / 5 - 0 ratings