Skip to content

Commit

Permalink
Add rule for multiline switch cases (#691)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklockwood committed Aug 14, 2020
1 parent 587bacb commit 4027942
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
5 changes: 5 additions & 0 deletions Rules.md
Expand Up @@ -21,6 +21,7 @@
* [linebreaks](#linebreaks)
* [modifierOrder](#modifierOrder)
* [multilineEnumCases](#multilineEnumCases)
* [multilineSwitchCases](#multilineSwitchCases)
* [numberFormatting](#numberFormatting)
* [preferKeyPath](#preferKeyPath)
* [ranges *(deprecated)*](#ranges)
Expand Down Expand Up @@ -615,6 +616,10 @@ Option | Description

Writes one enum case per line.

## multilineSwitchCases

Writes one switch case per line.

## numberFormatting

Use consistent grouping for numeric literals. Groups will be separated by `_`
Expand Down
24 changes: 23 additions & 1 deletion Sources/Rules.swift
Expand Up @@ -3471,6 +3471,29 @@ public struct _FormatRules {
}
}

/// Writes one switch case per line
public let multilineSwitchCases = FormatRule(
help: "Writes one switch case per line.",
options: [],
sharedOptions: ["linebreaks", "tabwidth", "indent", "smarttabs"]
) { formatter in
formatter.forEach(.endOfScope("case")) { idx, _ in
guard let colonIndex = formatter.index(of: .startOfScope(":"), after: idx) else { return }

var startIndex = idx
while let delimiterIndex = formatter.index(of: .delimiter(","), after: startIndex),
let nextCaseIndex = formatter.index(of: .operator(".", .prefix), after: delimiterIndex)
{
if formatter.index(of: .linebreak, in: delimiterIndex ..< nextCaseIndex) == nil {
formatter.insertLinebreak(at: delimiterIndex + 1)
formatter.insertSpace(formatter.spaceEquivalentToWidth(5), at: delimiterIndex + 2)
}

startIndex = nextCaseIndex
}
}
}

/// Normalize the use of void in closure arguments and return values
public let void = FormatRule(
help: "Use `Void` for type declarations and `()` for values.",
Expand Down Expand Up @@ -3571,7 +3594,6 @@ public struct _FormatRules {
// TODO: other cases
}
}

/// Standardize formatting of numeric literals
public let numberFormatting = FormatRule(
help: """
Expand Down
32 changes: 30 additions & 2 deletions Tests/RulesTests.swift
Expand Up @@ -4708,6 +4708,30 @@ class RulesTests: XCTestCase {
testFormatting(for: input, output, rule: FormatRules.multilineEnumCases)
}

// MARK: multilineSwitchCases

func testMultilineSwitchCases() {
let input = """
switch enum1 {
case .a(_), .b, .c:
print("")
case .d:
print("")
}
"""
let output = """
switch enum1 {
case .a(_),
.b,
.c:
print("")
case .d:
print("")
}
"""
testFormatting(for: input, output, rule: FormatRules.multilineSwitchCases)
}

// MARK: - void

func testEmptyParensReturnValueConvertedToVoid() {
Expand Down Expand Up @@ -8384,7 +8408,7 @@ class RulesTests: XCTestCase {
func testHoistCommaSeparatedSwitchCaseLets() {
let input = "switch foo {\ncase .foo(let bar), .bar(let bar):\n}"
let output = "switch foo {\ncase let .foo(bar), let .bar(bar):\n}"
testFormatting(for: input, output, rule: FormatRules.hoistPatternLet)
testFormatting(for: input, output, rule: FormatRules.hoistPatternLet, exclude: ["multilineSwitchCases"])
}

func testHoistCatchLet() {
Expand Down Expand Up @@ -8507,7 +8531,11 @@ class RulesTests: XCTestCase {
let input = "switch foo {\ncase let .foo(bar), let .bar(bar):\n}"
let output = "switch foo {\ncase .foo(let bar), .bar(let bar):\n}"
let options = FormatOptions(hoistPatternLet: false)
testFormatting(for: input, output, rule: FormatRules.hoistPatternLet, options: options)
testFormatting(for: input,
output,
rule: FormatRules.hoistPatternLet,
options: options,
exclude: ["multilineSwitchCases"])
}

func testUnhoistCommaSeparatedSwitchCaseLets2() {
Expand Down
1 change: 1 addition & 0 deletions Tests/XCTestManifests.swift
Expand Up @@ -919,6 +919,7 @@ extension RulesTests {
("testMultilineInitBraceOnNextLine", testMultilineInitBraceOnNextLine),
("testMultilineMapPropertyToKeyPath", testMultilineMapPropertyToKeyPath),
("testMultilineStringWithEscapedLinebreak", testMultilineStringWithEscapedLinebreak),
("testMultilineSwitchCases", testMultilineSwitchCases),
("testMultipleAttributesNotSeparated", testMultipleAttributesNotSeparated),
("testMultipleClosureArgumentUnwrapped", testMultipleClosureArgumentUnwrapped),
("testMultipleNestedClosures", testMultipleNestedClosures),
Expand Down

0 comments on commit 4027942

Please sign in to comment.