Skip to content

Commit

Permalink
Adds opt-in discouraged_object_literal rule
Browse files Browse the repository at this point in the history
Implements realm#1987.
  • Loading branch information
ornithocoder committed Jan 2, 2018
1 parent e574f1f commit 690340f
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,11 @@
[Daniel Metzing](https://github.com/dirtydanee)
[#1924](https://github.com/realm/SwiftLint/issues/1924)

* Add `discouraged_object_literal` opt-in rule which encourages initializers
over object literals.
[Ornithologist Coder](https://github.com/ornithocoder)
[#1987](https://github.com/realm/SwiftLint/issues/1987)

##### Bug Fixes

* Fix false positives in `control_statement` rule when methods with keyword
Expand Down
54 changes: 54 additions & 0 deletions Rules.md
Expand Up @@ -19,6 +19,7 @@
* [Cyclomatic Complexity](#cyclomatic-complexity)
* [Discarded Notification Center Observer](#discarded-notification-center-observer)
* [Discouraged Direct Initialization](#discouraged-direct-initialization)
* [Discouraged Object Literal](#discouraged-object-literal)
* [Dynamic Inline](#dynamic-inline)
* [Empty Count](#empty-count)
* [Empty Enum Arguments](#empty-enum-arguments)
Expand Down Expand Up @@ -2066,6 +2067,59 @@ let foo = bar(bundle: ↓Bundle.init(), device: ↓UIDevice.init())



## Discouraged Object Literal

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

Prefer initializers over object literals.

### Examples

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

```swift
let image = UIImage(named: aVariable)
```

```swift
let image = UIImage(named: "interpolated \(variable)")
```

```swift
let color = UIColor(red: value, green: value, blue: value, alpha: 1)
```

```swift
let image = NSImage(named: aVariable)
```

```swift
let image = NSImage(named: "interpolated \(variable)")
```

```swift
let color = NSColor(red: value, green: value, blue: value, alpha: 1)
```

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

```swift
let image = ↓#imageLiteral(resourceName: "image.jpg")
```

```swift
let color = ↓#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)
```

</details>



## Dynamic Inline

Identifier | Enabled by default | Supports autocorrection | Kind
Expand Down
1 change: 1 addition & 0 deletions Source/SwiftLintFramework/Models/MasterRuleList.swift
Expand Up @@ -27,6 +27,7 @@ public let masterRuleList = RuleList(rules: [
CyclomaticComplexityRule.self,
DiscardedNotificationCenterObserverRule.self,
DiscouragedDirectInitRule.self,
DiscouragedObjectLiteralRule.self,
DynamicInlineRule.self,
EmptyCountRule.self,
EmptyEnumArgumentsRule.self,
Expand Down
45 changes: 45 additions & 0 deletions Source/SwiftLintFramework/Rules/DiscouragedObjectLiteralRule.swift
@@ -0,0 +1,45 @@
//
// DiscouragedObjectLiteralRule.swift
// SwiftLint
//
// Created by Ornithologist Coder on 1/3/18.
// Copyright © 2018 Realm. All rights reserved.
//

import Foundation
import SourceKittenFramework

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

public init() {}

public static let description = RuleDescription(
identifier: "discouraged_object_literal",
name: "Discouraged Object Literal",
description: "Prefer initializers over object literals.",
kind: .idiomatic,
nonTriggeringExamples: [
"let image = UIImage(named: aVariable)",
"let image = UIImage(named: \"interpolated \\(variable)\")",
"let color = UIColor(red: value, green: value, blue: value, alpha: 1)",
"let image = NSImage(named: aVariable)",
"let image = NSImage(named: \"interpolated \\(variable)\")",
"let color = NSColor(red: value, green: value, blue: value, alpha: 1)"
],
triggeringExamples: [
"let image = ↓#imageLiteral(resourceName: \"image.jpg\")",
"let color = ↓#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)"
]
)

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

return [StyleViolation(ruleDescription: type(of: self).description,
severity: configuration.severity,
location: Location(file: file, byteOffset: offset))]
}
}
4 changes: 4 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Expand Up @@ -75,6 +75,7 @@
623E36F01F3DB1B1002E5B71 /* QuickDiscouragedCallRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 623E36EF1F3DB1B1002E5B71 /* QuickDiscouragedCallRule.swift */; };
623E36F21F3DB988002E5B71 /* QuickDiscouragedCallRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 623E36F11F3DB988002E5B71 /* QuickDiscouragedCallRuleExamples.swift */; };
6250D32A1ED4DFEB00735129 /* MultilineParametersRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6238AE411ED4D734006C3601 /* MultilineParametersRule.swift */; };
6258783B1FFC458100AC34F2 /* DiscouragedObjectLiteralRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6258783A1FFC458100AC34F2 /* DiscouragedObjectLiteralRule.swift */; };
62622F6B1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62622F6A1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift */; };
626C16E21F948EBC00BB7475 /* QuickDiscouragedFocusedTestRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 626C16E01F948E1C00BB7475 /* QuickDiscouragedFocusedTestRuleExamples.swift */; };
626D02971F31CBCC0054788D /* XCTFailMessageRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 626D02961F31CBCC0054788D /* XCTFailMessageRule.swift */; };
Expand Down Expand Up @@ -417,6 +418,7 @@
6238AE411ED4D734006C3601 /* MultilineParametersRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultilineParametersRule.swift; sourceTree = "<group>"; };
623E36EF1F3DB1B1002E5B71 /* QuickDiscouragedCallRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickDiscouragedCallRule.swift; sourceTree = "<group>"; };
623E36F11F3DB988002E5B71 /* QuickDiscouragedCallRuleExamples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickDiscouragedCallRuleExamples.swift; sourceTree = "<group>"; };
6258783A1FFC458100AC34F2 /* DiscouragedObjectLiteralRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedObjectLiteralRule.swift; sourceTree = "<group>"; };
62622F6A1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedDirectInitRule.swift; sourceTree = "<group>"; };
626C16E01F948E1C00BB7475 /* QuickDiscouragedFocusedTestRuleExamples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickDiscouragedFocusedTestRuleExamples.swift; sourceTree = "<group>"; };
626D02961F31CBCC0054788D /* XCTFailMessageRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTFailMessageRule.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1017,6 +1019,7 @@
2E02005E1C54BF680024D09D /* CyclomaticComplexityRule.swift */,
D4DABFD21E29B4A5009617B6 /* DiscardedNotificationCenterObserverRule.swift */,
62622F6A1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift */,
6258783A1FFC458100AC34F2 /* DiscouragedObjectLiteralRule.swift */,
E315B83B1DFA4BC500621B44 /* DynamicInlineRule.swift */,
E847F0A81BFBBABD00EA9363 /* EmptyCountRule.swift */,
D4470D581EB6B4D1008A1B2E /* EmptyEnumArgumentsRule.swift */,
Expand Down Expand Up @@ -1473,6 +1476,7 @@
BFF028AE1CBCF8A500B38A9D /* TrailingWhitespaceConfiguration.swift in Sources */,
3B034B6E1E0BE549005D49A9 /* LineLengthConfiguration.swift in Sources */,
B25DCD0C1F7E9FA20028A199 /* MultilineArgumentsRule.swift in Sources */,
6258783B1FFC458100AC34F2 /* DiscouragedObjectLiteralRule.swift in Sources */,
D4C4A34C1DEA4FF000E0E04C /* AttributesConfiguration.swift in Sources */,
83D71E281B131ECE000395DE /* RuleDescription.swift in Sources */,
D4470D571EB69225008A1B2E /* ImplicitReturnRule.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Tests/LinuxMain.swift
Expand Up @@ -371,6 +371,7 @@ extension RulesTests {
("testControlStatement", testControlStatement),
("testCyclomaticComplexity", testCyclomaticComplexity),
("testDiscardedNotificationCenterObserver", testDiscardedNotificationCenterObserver),
("testDiscouragedObjectLiteralRule", testDiscouragedObjectLiteralRule),
("testDynamicInline", testDynamicInline),
("testEmptyCount", testEmptyCount),
("testEmptyEnumArguments", testEmptyEnumArguments),
Expand Down
4 changes: 4 additions & 0 deletions Tests/SwiftLintFrameworkTests/RulesTests.swift
Expand Up @@ -70,6 +70,10 @@ class RulesTests: XCTestCase {
verifyRule(DiscardedNotificationCenterObserverRule.description)
}

func testDiscouragedObjectLiteralRule() {
verifyRule(DiscouragedObjectLiteralRule.description)
}

func testDynamicInline() {
verifyRule(DynamicInlineRule.description)
}
Expand Down

0 comments on commit 690340f

Please sign in to comment.