Skip to content

Commit

Permalink
Add joined_default_parameter opt-in rule
Browse files Browse the repository at this point in the history
to discourage explicit usage of the default separator. Implements realm#1093.
  • Loading branch information
ornithocoder committed Aug 3, 2017
1 parent 54d6199 commit da823f5
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
[Ornithologist Coder](https://github.com/ornithocoder)
[#1370](https://github.com/realm/SwiftLint/issues/1370)

* Add `joined_default_parameter` opt-in rule to discourage
explicit usage of the default separator.
[Ornithologist Coder](https://github.com/ornithocoder)
[#1093](https://github.com/realm/SwiftLint/issues/1093)

##### Bug Fixes

* Fix false positive on `force_unwrapping` rule when declaring
Expand Down
38 changes: 38 additions & 0 deletions Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* [Implicit Getter](#implicit-getter)
* [Implicit Return](#implicit-return)
* [Implicitly Unwrapped Optional](#implicitly-unwrapped-optional)
* [Joined Default Parameter](#joined-default-parameter)
* [Large Tuple](#large-tuple)
* [Leading Whitespace](#leading-whitespace)
* [Legacy CGGeometry Functions](#legacy-cggeometry-functions)
Expand Down Expand Up @@ -4819,6 +4820,43 @@ func foo(int: Int!) {}



## Joined Default Parameter

Identifier | Enabled by default | Supports autocorrection | Kind
--- | --- | --- | ---
`joined_default_parameter` | Disabled | No | idiomatic

Discouraged explicit usage of the default separator.

### Examples

<details>
<summary>Non Triggering Examples</summary>

```swift
let foo = bar.joined()
```

```swift
let foo = bar.joined(separator: ",")
```

```swift
let foo = bar.joined(separator: toto)
```

</details>
<details>
<summary>Triggering Examples</summary>

```swift
let foo = bar.joined(separator: "")
```

</details>



## Large Tuple

Identifier | Enabled by default | Supports autocorrection | Kind
Expand Down
1 change: 1 addition & 0 deletions Source/SwiftLintFramework/Models/MasterRuleList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public let masterRuleList = RuleList(rules: [
ImplicitGetterRule.self,
ImplicitReturnRule.self,
ImplicitlyUnwrappedOptionalRule.self,
JoinedDefaultParameterRule.self,
LargeTupleRule.self,
LeadingWhitespaceRule.self,
LegacyCGGeometryFunctionsRule.self,
Expand Down
58 changes: 58 additions & 0 deletions Source/SwiftLintFramework/Rules/JoinedDefaultRule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// JoinedDefaultRule.swift
// SwiftLint
//
// Created by Ornithologist Coder on 8/3/17.
// Copyright © 2017 Realm. All rights reserved.
//

import Foundation
import SourceKittenFramework

public struct JoinedDefaultParameterRule: ASTRule, ConfigurationProviderRule, OptInRule {
public var configuration = SeverityConfiguration(.warning)

public init() {}

public static let description = RuleDescription(
identifier: "joined_default_parameter",
name: "Joined Default Parameter",
description: "Discouraged explicit usage of the default separator.",
kind: .idiomatic,
nonTriggeringExamples: [
"let foo = bar.joined()",
"let foo = bar.joined(separator: \",\")",
"let foo = bar.joined(separator: toto)"
],
triggeringExamples: [
"let foo = bar.joined(separator: \"\")"
]
)

public func validate(file: File,
kind: SwiftExpressionKind,
dictionary: [String: SourceKitRepresentable]) -> [StyleViolation] {
guard
kind == .call,
let offset = dictionary.offset,
let name = dictionary.name,
name.hasSuffix(".joined"),
passesDefaultSeparator(dictionary: dictionary, file: file)
else {
return []
}

return [StyleViolation(ruleDescription: type(of: self).description,
severity: configuration.severity,
location: Location(file: file, byteOffset: offset))]
}

private func passesDefaultSeparator(dictionary: [String: SourceKitRepresentable], file: File) -> Bool {
guard
let bodyOffset = dictionary.bodyOffset,
let bodyLength = dictionary.bodyLength else { return false }

let body = file.contents.bridge().substringWithByteRange(start: bodyOffset, length: bodyLength)
return body == "separator: \"\""
}
}
4 changes: 4 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
62622F6B1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62622F6A1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift */; };
626D02971F31CBCC0054788D /* XCTFailMessageRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 626D02961F31CBCC0054788D /* XCTFailMessageRule.swift */; };
62A498561F306A7700D766E4 /* DiscouragedDirectInitConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A498551F306A7700D766E4 /* DiscouragedDirectInitConfiguration.swift */; };
62A6E7931F3317E3003A0479 /* JoinedDefaultRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A6E7911F3317E3003A0479 /* JoinedDefaultRule.swift */; };
67932E2D1E54AF4B00CB0629 /* CyclomaticComplexityConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67932E2C1E54AF4B00CB0629 /* CyclomaticComplexityConfigurationTests.swift */; };
67EB4DFA1E4CC111004E9ACD /* CyclomaticComplexityConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67EB4DF81E4CC101004E9ACD /* CyclomaticComplexityConfiguration.swift */; };
67EB4DFC1E4CD7F5004E9ACD /* CyclomaticComplexityRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67EB4DFB1E4CD7F5004E9ACD /* CyclomaticComplexityRuleTests.swift */; };
Expand Down Expand Up @@ -377,6 +378,7 @@
62622F6A1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedDirectInitRule.swift; sourceTree = "<group>"; };
626D02961F31CBCC0054788D /* XCTFailMessageRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTFailMessageRule.swift; sourceTree = "<group>"; };
62A498551F306A7700D766E4 /* DiscouragedDirectInitConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedDirectInitConfiguration.swift; sourceTree = "<group>"; };
62A6E7911F3317E3003A0479 /* JoinedDefaultRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinedDefaultRule.swift; sourceTree = "<group>"; };
62AF35D71F30B183009B11EE /* DiscouragedDirectInitRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedDirectInitRuleTests.swift; sourceTree = "<group>"; };
65454F451B14D73800319A6C /* ControlStatementRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlStatementRule.swift; sourceTree = "<group>"; };
67932E2C1E54AF4B00CB0629 /* CyclomaticComplexityConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CyclomaticComplexityConfigurationTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -964,6 +966,7 @@
D43DB1071DC573DA00281215 /* ImplicitGetterRule.swift */,
47FF3BDF1E7C745100187E6D /* ImplicitlyUnwrappedOptionalRule.swift */,
D4470D561EB69225008A1B2E /* ImplicitReturnRule.swift */,
62A6E7911F3317E3003A0479 /* JoinedDefaultRule.swift */,
D4DA1DF91E18D6200037413D /* LargeTupleRule.swift */,
E88DEA7D1B098F2A00A66CB0 /* LeadingWhitespaceRule.swift */,
4DB7815C1CAD690100BC4723 /* LegacyCGGeometryFunctionsRule.swift */,
Expand Down Expand Up @@ -1440,6 +1443,7 @@
C328A2F71E6759AE00A9E4D7 /* ExplicitTypeInterfaceRule.swift in Sources */,
93E0C3CE1D67BD7F007FA25D /* ConditionalReturnsOnNewlineRule.swift in Sources */,
D43DB1081DC573DA00281215 /* ImplicitGetterRule.swift in Sources */,
62A6E7931F3317E3003A0479 /* JoinedDefaultRule.swift in Sources */,
D4FD4C851F2A260A00DD8AA8 /* BlockBasedKVORule.swift in Sources */,
7C0C2E7A1D2866CB0076435A /* ExplicitInitRule.swift in Sources */,
E88DEA771B098D0C00A66CB0 /* Rule.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ extension RulesTests {
("testImplicitGetter", testImplicitGetter),
("testImplicitlyUnwrappedOptional", testImplicitlyUnwrappedOptional),
("testImplicitReturn", testImplicitReturn),
("testJoinedDefaultParameter", testJoinedDefaultParameter),
("testLargeTuple", testLargeTuple),
("testLeadingWhitespace", testLeadingWhitespace),
("testLegacyCGGeometryFunctions", testLegacyCGGeometryFunctions),
Expand Down
4 changes: 4 additions & 0 deletions Tests/SwiftLintFrameworkTests/RulesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ class RulesTests: XCTestCase {
verifyRule(ImplicitReturnRule.description)
}

func testJoinedDefaultParameter() {
verifyRule(JoinedDefaultParameterRule.description)
}

func testLargeTuple() {
verifyRule(LargeTupleRule.description)
}
Expand Down

0 comments on commit da823f5

Please sign in to comment.