Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ConditionalBindingCascadeRule #327

Closed
wants to merge 10 commits into from
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
* Improve performance of `LineLengthRule`.
[Norio Nomura](https://github.com/norio-nomura)

* Add ConditionalBindingCascadeRule.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing the two trailing spaces as described in CONTRIBUTING.md.

[Aaron McTavish](https://github.com/aamctustwo)
[#202](https://github.com/realm/SwiftLint/issues/202)


##### Bug Fixes

* AutoCorrect for TrailingNewlineRule only removes at most one line.
Expand Down
1 change: 1 addition & 0 deletions Source/SwiftLintFramework/Models/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ public struct Configuration: Equatable {
ClosingBraceRule(),
ColonRule(),
CommaRule(),
ConditionalBindingCascadeRule(),
ControlStatementRule(),
ForceCastRule(),
ForceTryRule(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// ConditionalBindingCascadeRule.swift
// SwiftLint
//
// Created by Aaron McTavish on 08/01/2016.
// Copyright © 2016 Realm. All rights reserved.
//

import SourceKittenFramework

public struct ConditionalBindingCascadeRule: Rule {
public static let description = RuleDescription(
identifier: "conditional_binding_cascade",
name: "Conditional Binding Cascade",
description: "Repeated `let` statements in conditional binding cascade should be avoided.",
nonTriggeringExamples: [
"if let a = b, c = d {",
"if let a = b, \n c = d {",
"if let a = b, \n c = d \n {",
"if let a = b { if let c = d {",
"if let a = b { let c = d({ foo in ... })",
"guard let a = b, c = d else {"
],
triggeringExamples: [
"if let a = b, let c = d {",
"if let a = b, \n let c = d {",
"if let a = b, c = d, let e = f {",
"if let a = b, let c = d \n {",
"if \n let a = b, let c = d {",
"if let a = b, c = d.indexOf({$0 == e}), let f = g {",
"guard let a = b, let c = d else {"
]
)

public func validateFile(file: File) -> [StyleViolation] {
let conditionalBindingKeywords = ["if", "guard"]
let pattern = "^(" +
conditionalBindingKeywords.joinWithSeparator("|") +
")(\\s*?)let((.|\\s)*?),(\\s*?)let((.|\\s)*?)\\{"
return file.matchPattern(pattern,
excludingSyntaxKinds: SyntaxKind.commentAndStringKinds()).map {
StyleViolation(ruleDescription: self.dynamicType.description,
location: Location(file: file, characterOffset: $0.location))
}
}
}
4 changes: 4 additions & 0 deletions Source/SwiftLintFrameworkTests/StringRuleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,8 @@ class StringRuleTests: XCTestCase {
func testLegacyConstructor() {
verifyRule(LegacyConstructorRule.description)
}

func testConditionalBindingCascade() {
verifyRule(ConditionalBindingCascadeRule.description)
}
}
4 changes: 4 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
00970C751C3FC3A0007C4A83 /* ConditionalBindingCascadeRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00970C741C3FC3A0007C4A83 /* ConditionalBindingCascadeRule.swift */; };
02FD8AEF1BFC18D60014BFFB /* ExtendedNSStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02FD8AEE1BFC18D60014BFFB /* ExtendedNSStringTests.swift */; };
1F11B3CF1C252F23002E8FA8 /* ClosingBraceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F11B3CE1C252F23002E8FA8 /* ClosingBraceRule.swift */; };
24E17F721B14BB3F008195BE /* File+Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E17F701B1481FF008195BE /* File+Cache.swift */; };
Expand Down Expand Up @@ -142,6 +143,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
00970C741C3FC3A0007C4A83 /* ConditionalBindingCascadeRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConditionalBindingCascadeRule.swift; sourceTree = "<group>"; };
02FD8AEE1BFC18D60014BFFB /* ExtendedNSStringTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtendedNSStringTests.swift; sourceTree = "<group>"; };
1F11B3CE1C252F23002E8FA8 /* ClosingBraceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClosingBraceRule.swift; sourceTree = "<group>"; };
24E17F701B1481FF008195BE /* File+Cache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "File+Cache.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -480,6 +482,7 @@
1F11B3CE1C252F23002E8FA8 /* ClosingBraceRule.swift */,
E88DEA831B0990F500A66CB0 /* ColonRule.swift */,
695BE9CE1BDFD92B0071E985 /* CommaRule.swift */,
00970C741C3FC3A0007C4A83 /* ConditionalBindingCascadeRule.swift */,
65454F451B14D73800319A6C /* ControlStatementRule.swift */,
E88DEA891B0992B300A66CB0 /* FileLengthRule.swift */,
E88DEA7F1B09903300A66CB0 /* ForceCastRule.swift */,
Expand Down Expand Up @@ -747,6 +750,7 @@
E816194E1BFBFEAB00946723 /* ForceTryRule.swift in Sources */,
E88198541BEA945100333A11 /* CommaRule.swift in Sources */,
E88198601BEA98F000333A11 /* VariableNameRule.swift in Sources */,
00970C751C3FC3A0007C4A83 /* ConditionalBindingCascadeRule.swift in Sources */,
E88DEA791B098D4400A66CB0 /* RuleParameter.swift in Sources */,
E86396CB1BADB519002C9E88 /* CSVReporter.swift in Sources */,
E88198561BEA94D800333A11 /* FileLengthRule.swift in Sources */,
Expand Down