diff --git a/Sources/SwiftFormat/Rules/NoEmptyTrailingClosureParentheses.swift b/Sources/SwiftFormat/Rules/NoEmptyTrailingClosureParentheses.swift index d3c17eed..80dba8bc 100644 --- a/Sources/SwiftFormat/Rules/NoEmptyTrailingClosureParentheses.swift +++ b/Sources/SwiftFormat/Rules/NoEmptyTrailingClosureParentheses.swift @@ -38,6 +38,15 @@ public final class NoEmptyTrailingClosureParentheses: SyntaxFormatRule { return super.visit(node) } + // Keep the empty parentheses when in a curried call to avoid the trailing closure + // getting associated with the called call expression. + guard + !node.calledExpression.is(FunctionCallExprSyntax.self) + && !node.calledExpression.is(SubscriptCallExprSyntax.self) + else { + return super.visit(node) + } + diagnose(.removeEmptyTrailingParentheses(name: "\(name.trimmedDescription)"), on: leftParen) // Need to visit `calledExpression` before creating a new node so that the location data (column diff --git a/Tests/SwiftFormatTests/Rules/NoEmptyTrailingClosureParenthesesTests.swift b/Tests/SwiftFormatTests/Rules/NoEmptyTrailingClosureParenthesesTests.swift index f828fd7c..f6a8e7f0 100644 --- a/Tests/SwiftFormatTests/Rules/NoEmptyTrailingClosureParenthesesTests.swift +++ b/Tests/SwiftFormatTests/Rules/NoEmptyTrailingClosureParenthesesTests.swift @@ -46,7 +46,7 @@ final class NoEmptyTrailingClosureParenthesesTests: LintOrFormatRuleTestCase { greetEnthusiastically8️⃣() { "Willis" } } } - foo(bar🔟() { baz })9️⃣() { blah } + foo(bar9️⃣() { baz }) { blah } """, expected: """ func greetEnthusiastically(_ nameProvider: () -> String) { @@ -89,8 +89,7 @@ final class NoEmptyTrailingClosureParenthesesTests: LintOrFormatRuleTestCase { FindingSpec("6️⃣", message: "remove the empty parentheses following 'async'"), FindingSpec("7️⃣", message: "remove the empty parentheses following 'greetEnthusiastically'"), FindingSpec("8️⃣", message: "remove the empty parentheses following 'greetEnthusiastically'"), - FindingSpec("9️⃣", message: "remove the empty parentheses following ')'"), - FindingSpec("🔟", message: "remove the empty parentheses following 'bar'"), + FindingSpec("9️⃣", message: "remove the empty parentheses following 'bar'"), ] ) } @@ -119,4 +118,21 @@ final class NoEmptyTrailingClosureParenthesesTests: LintOrFormatRuleTestCase { findings: [] ) } + + func testDoNotRemoveParensInCurriedCalls() { + assertFormatting( + NoEmptyTrailingClosureParentheses.self, + input: """ + perform()() { foo } + Executor.execute(executor)() { bar } + withSubscript[baz]() { blah } + """, + expected: """ + perform()() { foo } + Executor.execute(executor)() { bar } + withSubscript[baz]() { blah } + """, + findings: [] + ) + } }