From a4fbb6622b77cd3f7db70ca1e1012b79c4a81720 Mon Sep 17 00:00:00 2001 From: Blake <> Date: Thu, 13 Feb 2020 01:30:27 -0600 Subject: [PATCH] Adding Legacy ObjC Type Rule #2758 --- CHANGELOG.md | 8 +++ .../Models/PrimaryRuleList.swift | 1 + .../Rules/Idiomatic/LegacyObjcTypeRule.swift | 63 +++++++++++++++++++ Tests/LinuxMain.swift | 7 +++ .../AutomaticRuleTests.generated.swift | 6 ++ 5 files changed, 85 insertions(+) create mode 100644 Source/SwiftLintFramework/Rules/Idiomatic/LegacyObjcTypeRule.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 49d2c7f76d..9b8a779136 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,14 @@ explicitly referenced by other code. [JP Simard](https://github.com/jpsim) +* Make `strong_iboutlet` rule correctable. + [MaxHaertwig](https://github.com/maxhaertwig) + +* Add `legacy_objc_type` opt-in rule to warn against using + bridged Objective-C reference types instead of Swift value types. + [Blake](https://github.com/72A12F4E) + [#2758](https://github.com/realm/SwiftLint/issues/2758) + #### Bug Fixes * Fix typos in configuration options for `file_name` rule. diff --git a/Source/SwiftLintFramework/Models/PrimaryRuleList.swift b/Source/SwiftLintFramework/Models/PrimaryRuleList.swift index 27ad435a07..0864a76da9 100644 --- a/Source/SwiftLintFramework/Models/PrimaryRuleList.swift +++ b/Source/SwiftLintFramework/Models/PrimaryRuleList.swift @@ -91,6 +91,7 @@ public let primaryRuleList = RuleList(rules: [ LegacyHashingRule.self, LegacyMultipleRule.self, LegacyNSGeometryFunctionsRule.self, + LegacyObjcTypeRule.self, LegacyRandomRule.self, LetVarWhitespaceRule.self, LineLengthRule.self, diff --git a/Source/SwiftLintFramework/Rules/Idiomatic/LegacyObjcTypeRule.swift b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyObjcTypeRule.swift new file mode 100644 index 0000000000..cd298914ed --- /dev/null +++ b/Source/SwiftLintFramework/Rules/Idiomatic/LegacyObjcTypeRule.swift @@ -0,0 +1,63 @@ +import Foundation +import SourceKittenFramework + +private let legacyObjcTypes = [ + "NSAffineTransform", + "NSArray", + "NSCalendar", + "NSCharacterSet", + "NSData", + "NSDateComponents", + "NSDateInterval", + "NSDate", + "NSDecimalNumber", + "NSDictionary", + "NSIndexPath", + "NSIndexSet", + "NSLocale", + "NSMeasurement", + "NSNotification", + "NSNumber", + "NSPersonNameComponents", + "NSSet", + "NSString", + "NSTimeZone", + "NSURL", + "NSURLComponents", + "NSURLQueryItem", + "NSURLRequest", + "NSUUID" +] + +public struct LegacyObjcTypeRule: OptInRule, ConfigurationProviderRule, AutomaticTestableRule { + public var configuration = SeverityConfiguration(.warning) + + public init() {} + + public static let description = RuleDescription( + identifier: "legacy_objc_type", + name: "Legacy Objective-C Reference Type", + description: "Prefer Swift value types to bridged Objective-C reference types", + kind: .idiomatic, + nonTriggeringExamples: [ + Example("var array = Array()\n"), + Example("var calendar: Calendar? = nil") + ], + triggeringExamples: [ + Example("var array = NSArray()"), + Example("var calendar: NSCalendar? = nil") + ] + ) + + private let pattern = legacyObjcTypes.joined(separator: "|") + + public func validate(file: SwiftLintFile) -> [StyleViolation] { + return file.match(pattern: pattern) + .filter { !Set($0.1).isDisjoint(with: [.typeidentifier, .identifier]) } + .map { + StyleViolation(ruleDescription: Self.description, + severity: configuration.severity, + location: Location(file: file, characterOffset: $0.0.location)) + } + } +} diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 6c111536f1..c4febefede 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -858,6 +858,12 @@ extension LegacyNSGeometryFunctionsRuleTests { ] } +extension LegacyObjcTypeRuleTests { + static var allTests: [(String, (LegacyObjcTypeRuleTests) -> () throws -> Void)] = [ + ("testWithDefaultConfiguration", testWithDefaultConfiguration) + ] +} + extension LegacyRandomRuleTests { static var allTests: [(String, (LegacyRandomRuleTests) -> () throws -> Void)] = [ ("testWithDefaultConfiguration", testWithDefaultConfiguration) @@ -1878,6 +1884,7 @@ XCTMain([ testCase(LegacyHashingRuleTests.allTests), testCase(LegacyMultipleRuleTests.allTests), testCase(LegacyNSGeometryFunctionsRuleTests.allTests), + testCase(LegacyObjcTypeRuleTests.allTests), testCase(LegacyRandomRuleTests.allTests), testCase(LetVarWhitespaceRuleTests.allTests), testCase(LineEndingTests.allTests), diff --git a/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift b/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift index 937db6c1b1..3f44064e21 100644 --- a/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift +++ b/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift @@ -360,6 +360,12 @@ class LegacyNSGeometryFunctionsRuleTests: XCTestCase { } } +class LegacyObjcTypeRuleTests: XCTestCase { + func testWithDefaultConfiguration() { + verifyRule(LegacyObjcTypeRule.description) + } +} + class LegacyRandomRuleTests: XCTestCase { func testWithDefaultConfiguration() { verifyRule(LegacyRandomRule.description)