diff --git a/CHANGELOG.md b/CHANGELOG.md index d00eb00f2..97ee7e3c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -114,6 +114,11 @@ #### Bug Fixes +* Fixes an issue with `control_statement` where commas in clauses prevent the + rule from applying. + [Allen Wu](https://github.com/allewun) + [#2170](https://github.com/realm/SwiftLint/pull/2170) + * Update `LowerACLThanParent` rule to not lint extensions. [Keith Smiley](https://github.com/keith) [#2164](https://github.com/realm/SwiftLint/pull/2164) diff --git a/Rules.md b/Rules.md index 1efc1f4e6..adc35fefd 100644 --- a/Rules.md +++ b/Rules.md @@ -1758,7 +1758,7 @@ Identifier | Enabled by default | Supports autocorrection | Kind | Minimum Swift --- | --- | --- | --- | --- `control_statement` | Enabled | No | style | 3.0.0 -if,for,while,do,catch statements shouldn't wrap their conditionals or arguments in parentheses. +`if`, `for`, `guard`, `switch`, `while`, and `catch` statements shouldn't unnecessarily wrap their conditionals or arguments in parentheses. ### Examples @@ -1850,6 +1850,16 @@ do { foo().catch(all: true) {} ``` +```swift +if max(a, b) < c { + +``` + +```swift +switch (lhs, rhs) { + +``` +
Triggering Examples @@ -1864,6 +1874,11 @@ foo().catch(all: true) {} ``` +```swift +↓if (condition == endIndex) { + +``` + ```swift ↓if ((a || b) && (c || d)) { @@ -1940,6 +1955,11 @@ do { } ``` +```swift +↓if (max(a, b) < c) { + +``` +
diff --git a/Source/SwiftLintFramework/Rules/ControlStatementRule.swift b/Source/SwiftLintFramework/Rules/ControlStatementRule.swift index 6f65a3beb..71d574fe0 100644 --- a/Source/SwiftLintFramework/Rules/ControlStatementRule.swift +++ b/Source/SwiftLintFramework/Rules/ControlStatementRule.swift @@ -10,7 +10,8 @@ public struct ControlStatementRule: ConfigurationProviderRule { identifier: "control_statement", name: "Control Statement", description: - "if,for,while,do,catch statements shouldn't wrap their conditionals or arguments in parentheses.", + "`if`, `for`, `guard`, `switch`, `while`, and `catch` statements shouldn't unnecessarily wrap their " + + "conditionals or arguments in parentheses.", kind: .style, nonTriggeringExamples: [ "if condition {\n", @@ -29,11 +30,14 @@ public struct ControlStatementRule: ConfigurationProviderRule { "do { ; } while condition {\n", "switch foo {\n", "do {\n} catch let error as NSError {\n}", - "foo().catch(all: true) {}" + "foo().catch(all: true) {}", + "if max(a, b) < c {\n", + "switch (lhs, rhs) {\n" ], triggeringExamples: [ "↓if (condition) {\n", "↓if(condition) {\n", + "↓if (condition == endIndex) {\n", "↓if ((a || b) && (c || d)) {\n", "↓if ((min...max).contains(value)) {\n", "↓for (item in collection) {\n", @@ -48,7 +52,8 @@ public struct ControlStatementRule: ConfigurationProviderRule { "do { ; } ↓while(condition) {\n", "do { ; } ↓while (condition) {\n", "↓switch (foo) {\n", - "do {\n} ↓catch(let error as NSError) {\n}" + "do {\n} ↓catch(let error as NSError) {\n}", + "↓if (max(a, b) < c) {\n" ] ) @@ -56,8 +61,10 @@ public struct ControlStatementRule: ConfigurationProviderRule { let statements = ["if", "for", "guard", "switch", "while", "catch"] let statementPatterns: [String] = statements.map { statement -> String in let isGuard = statement == "guard" + let isSwitch = statement == "switch" let elsePattern = isGuard ? "else\\s*" : "" - return "\(statement)\\s*\\([^,{]*\\)\\s*\(elsePattern)\\{" + let clausePattern = isSwitch ? "[^,{]*" : "[^{]*" + return "\(statement)\\s*\\(\(clausePattern)\\)\\s*\(elsePattern)\\{" } return statementPatterns.flatMap { pattern -> [StyleViolation] in return file.match(pattern: pattern)