From 28087e7de7c61bec27d39c1e61f4c7967e963cb1 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Mon, 29 Jul 2019 22:23:19 +0100 Subject: [PATCH] Fix `void` rule inside generic parameters --- Sources/Rules.swift | 25 ++++++++++++++++--------- Tests/RulesTests.swift | 13 ++++++++++--- Tests/XCTestManifests.swift | 1 + 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Sources/Rules.swift b/Sources/Rules.swift index 84bf7c56a..b913a84fa 100644 --- a/Sources/Rules.swift +++ b/Sources/Rules.swift @@ -3276,16 +3276,23 @@ public struct _FormatRules { formatter.insertToken(.startOfScope("("), at: i) } } - if formatter.options.useVoid { - formatter.forEach(.startOfScope("(")) { i, _ in - if formatter.last(.nonSpaceOrCommentOrLinebreak, before: i) == .operator("->", .infix), - let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: i, if: { - $0 == .endOfScope(")") - }), !isArgumentToken(at: nextIndex) { - // Replace with Void - formatter.replaceTokens(inRange: i ... nextIndex, with: [.identifier("Void")]) - } + guard formatter.options.useVoid else { + return + } + formatter.forEach(.startOfScope("(")) { i, _ in + guard let endIndex = formatter.index(of: .nonSpaceOrLinebreak, after: i, if: { + $0 == .endOfScope(")") + }), let prevToken = formatter.last(.nonSpaceOrCommentOrLinebreak, before: i), + !isArgumentToken(at: endIndex) else { + return + } + if formatter.last(.nonSpaceOrCommentOrLinebreak, before: i) == .operator("->", .infix) { + formatter.replaceTokens(inRange: i ... endIndex, with: [.identifier("Void")]) + } else if prevToken == .startOfScope("<") || + (prevToken == .delimiter(",") && formatter.currentScope(at: i) == .startOfScope("<")) { + formatter.replaceTokens(inRange: i ... endIndex, with: [.identifier("Void")]) } + // TODO: other cases } } diff --git a/Tests/RulesTests.swift b/Tests/RulesTests.swift index 627341361..a6532053f 100644 --- a/Tests/RulesTests.swift +++ b/Tests/RulesTests.swift @@ -3864,6 +3864,13 @@ class RulesTests: XCTestCase { XCTAssertEqual(try format(input, rules: [FormatRules.void]), output) } + func testEmptyParensInGenericsConvertedToVoid() { + let input = "Foo<(), ()>" + let output = "Foo" + XCTAssertEqual(try format(input, rules: [FormatRules.void]), output) + XCTAssertEqual(try format(input + "\n", rules: FormatRules.all), output + "\n") + } + // useVoid = false func testUseVoidOptionFalse() { @@ -4701,21 +4708,21 @@ class RulesTests: XCTestCase { let input = "let foo = Foo" let output = input XCTAssertEqual(try format(input, rules: [FormatRules.redundantParens]), output) - XCTAssertEqual(try format(input + "\n", rules: FormatRules.all), output + "\n") + XCTAssertEqual(try format(input + "\n", rules: FormatRules.all(except: ["void"])), output + "\n") } func testParensNotRemovedAroundTupleGenerics() { let input = "let foo = Foo" let output = input XCTAssertEqual(try format(input, rules: [FormatRules.redundantParens]), output) - XCTAssertEqual(try format(input + "\n", rules: FormatRules.all), output + "\n") + XCTAssertEqual(try format(input + "\n", rules: FormatRules.all(except: ["void"])), output + "\n") } func testParensNotRemovedAroundLabeledTupleGenerics() { let input = "let foo = Foo" let output = input XCTAssertEqual(try format(input, rules: [FormatRules.redundantParens]), output) - XCTAssertEqual(try format(input + "\n", rules: FormatRules.all), output + "\n") + XCTAssertEqual(try format(input + "\n", rules: FormatRules.all(except: ["void"])), output + "\n") } // after indexed tuple diff --git a/Tests/XCTestManifests.swift b/Tests/XCTestManifests.swift index 17476f762..00df60c2f 100644 --- a/Tests/XCTestManifests.swift +++ b/Tests/XCTestManifests.swift @@ -485,6 +485,7 @@ extension RulesTests { ("testEmptyClosureArgsNotMangled", testEmptyClosureArgsNotMangled), ("testEmptyClosureArgsNotUnwrapped", testEmptyClosureArgsNotUnwrapped), ("testEmptyClosureReturnValueConvertedToVoid", testEmptyClosureReturnValueConvertedToVoid), + ("testEmptyParensInGenericsConvertedToVoid", testEmptyParensInGenericsConvertedToVoid), ("testEmptyParensReturnValueConvertedToVoid", testEmptyParensReturnValueConvertedToVoid), ("testEnumCaseIndenting", testEnumCaseIndenting), ("testEnumCaseIndentingCommas", testEnumCaseIndentingCommas),