From 1fec14180f42ae66ec9ce488e5766922c88a3eaf Mon Sep 17 00:00:00 2001 From: Marcelo Fabri Date: Sun, 29 Nov 2015 01:46:06 -0200 Subject: [PATCH 1/3] Adding LegacyConstructorRule --- .../Models/Configuration.swift | 1 + .../Rules/LegacyConstructorRule.swift | 50 +++++++++++++++++++ .../StringRuleTests.swift | 4 ++ SwiftLint.xcodeproj/project.pbxproj | 4 ++ 4 files changed, 59 insertions(+) create mode 100644 Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift diff --git a/Source/SwiftLintFramework/Models/Configuration.swift b/Source/SwiftLintFramework/Models/Configuration.swift index 75ee38bc3..8d93073af 100644 --- a/Source/SwiftLintFramework/Models/Configuration.swift +++ b/Source/SwiftLintFramework/Models/Configuration.swift @@ -128,6 +128,7 @@ public struct Configuration { ForceCastRule(), ForceTryRule(), LeadingWhitespaceRule(), + LegacyConstructorRule(), NestingRule(), OpeningBraceRule(), OperatorFunctionWhitespaceRule(), diff --git a/Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift b/Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift new file mode 100644 index 000000000..8f11b8ec7 --- /dev/null +++ b/Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift @@ -0,0 +1,50 @@ +// +// LegacyConstructorRule.swift +// SwiftLint +// +// Created by Marcelo Fabri on 29/11/15. +// Copyright © 2015 Realm. All rights reserved. +// + +import SourceKittenFramework +import SwiftXPC + +public struct LegacyConstructorRule: Rule { + public init() {} + + public static let description = RuleDescription( + identifier: "legacy_constructor", + name: "Legacy Constructor", + description: "Swift constructors are preferred over legacy convenience functions.", + nonTriggeringExamples: [ + "CGPoint(x: 10, y: 10)", + "CGSize(width: 10, height: 10)", + "CGRect(x: 0, y: 0, width: 10, height: 10)", + "CGVector(dx: 10, dy: 10)", + "NSRange(location: 10, length: 1)", + ], + triggeringExamples: [ + "CGPointMake(10, 10)", + "CGSizeMake(10, 10)", + "CGRectMake(0, 0, 10, 10)", + "CGVectorMake(10, 10)", + "NSMakeRange(10, 1)", + ] + ) + + public func validateFile(file: File) -> [StyleViolation] { + let constructors = ["CGRectMake", "CGPointMake", "CGSizeMake", "CGVectorMake", + "NSMakeRange"] + + return constructors.flatMap { constructor -> [StyleViolation] in + let pattern = "\\b(" + constructor + ")\\b" + let matches = file.matchPattern(pattern, + excludingSyntaxKinds: SyntaxKind.commentAndStringKinds()) + + return matches.flatMap { match -> StyleViolation in + return StyleViolation(ruleDescription: self.dynamicType.description, + location: Location(file: file, offset: match.location)) + } + } + } +} diff --git a/Source/SwiftLintFrameworkTests/StringRuleTests.swift b/Source/SwiftLintFrameworkTests/StringRuleTests.swift index 00b910dbf..bb4aa6658 100644 --- a/Source/SwiftLintFrameworkTests/StringRuleTests.swift +++ b/Source/SwiftLintFrameworkTests/StringRuleTests.swift @@ -97,4 +97,8 @@ class StringRuleTests: XCTestCase { func testTrailingSemicolon() { verifyRule(TrailingSemicolonRule.description) } + + func testLegacyConstructor() { + verifyRule(LegacyConstructorRule.description) + } } diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index d3f0cf802..3b664d9a1 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ D0D1217819E87B05005E4BAA /* SwiftLintFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D1216D19E87B05005E4BAA /* SwiftLintFramework.framework */; }; D0E7B65319E9C6AD00EDBA4D /* SwiftLintFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D1216D19E87B05005E4BAA /* SwiftLintFramework.framework */; }; D0E7B65619E9C76900EDBA4D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D1211B19E87861005E4BAA /* main.swift */; }; + D44AD2761C0AA5350048F7B0 /* LegacyConstructorRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44AD2741C0AA3730048F7B0 /* LegacyConstructorRule.swift */; }; E57B23C11B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E57B23C01B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift */; }; E809EDA11B8A71DF00399043 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E809EDA01B8A71DF00399043 /* Configuration.swift */; }; E809EDA31B8A73FB00399043 /* ConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E809EDA21B8A73FB00399043 /* ConfigurationTests.swift */; }; @@ -166,6 +167,7 @@ D0D1217719E87B05005E4BAA /* SwiftLintFrameworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftLintFrameworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D0D1217D19E87B05005E4BAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D0E7B63219E9C64500EDBA4D /* swiftlint.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = swiftlint.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D44AD2741C0AA3730048F7B0 /* LegacyConstructorRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyConstructorRule.swift; sourceTree = ""; }; E57B23C01B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReturnArrowWhitespaceRule.swift; sourceTree = ""; }; E5A167C81B25A0B000CF2D03 /* OperatorFunctionWhitespaceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorFunctionWhitespaceRule.swift; sourceTree = ""; }; E809EDA01B8A71DF00399043 /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; @@ -441,6 +443,7 @@ E816194D1BFBFEAB00946723 /* ForceTryRule.swift */, E88DEA8F1B099A3100A66CB0 /* FunctionBodyLengthRule.swift */, E88DEA7D1B098F2A00A66CB0 /* LeadingWhitespaceRule.swift */, + D44AD2741C0AA3730048F7B0 /* LegacyConstructorRule.swift */, E88DEA7B1B098D7D00A66CB0 /* LineLengthRule.swift */, E88DEA951B099CF200A66CB0 /* NestingRule.swift */, 692B1EB11BD7E00F00EAABFF /* OpeningBraceRule.swift */, @@ -667,6 +670,7 @@ 69F88BF71BDA38A6005E7CAE /* OpeningBraceRule.swift in Sources */, E80E018D1B92C0F60078EB70 /* Command.swift in Sources */, E88198571BEA953300333A11 /* ForceCastRule.swift in Sources */, + D44AD2761C0AA5350048F7B0 /* LegacyConstructorRule.swift in Sources */, 83D71E281B131ECE000395DE /* RuleDescription.swift in Sources */, E812249C1B04FADC001783D2 /* Linter.swift in Sources */, CAF900151BED8B17006A371D /* VariableNameMinLengthRule.swift in Sources */, From 63216c56cb71053f8d3cf4333284a88e2944c2e2 Mon Sep 17 00:00:00 2001 From: Marcelo Fabri Date: Sun, 29 Nov 2015 21:40:08 -0200 Subject: [PATCH 2/3] Refactoring LegacyConstructorRule --- .../Rules/LegacyConstructorRule.swift | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift b/Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift index 8f11b8ec7..d8fe91d14 100644 --- a/Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift +++ b/Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift @@ -7,7 +7,6 @@ // import SourceKittenFramework -import SwiftXPC public struct LegacyConstructorRule: Rule { public init() {} @@ -36,15 +35,11 @@ public struct LegacyConstructorRule: Rule { let constructors = ["CGRectMake", "CGPointMake", "CGSizeMake", "CGVectorMake", "NSMakeRange"] - return constructors.flatMap { constructor -> [StyleViolation] in - let pattern = "\\b(" + constructor + ")\\b" - let matches = file.matchPattern(pattern, - excludingSyntaxKinds: SyntaxKind.commentAndStringKinds()) + let pattern = "\\b(" + constructors.joinWithSeparator("|") + ")\\b" - return matches.flatMap { match -> StyleViolation in - return StyleViolation(ruleDescription: self.dynamicType.description, - location: Location(file: file, offset: match.location)) - } + return file.matchPattern(pattern, withSyntaxKinds: [.Identifier]).map { + StyleViolation(ruleDescription: self.dynamicType.description, + location: Location(file: file, offset: $0.location)) } } } From 8f04c56f20f1d8a01338f9f091e1d6fea7948a2d Mon Sep 17 00:00:00 2001 From: Marcelo Fabri Date: Sun, 29 Nov 2015 21:42:00 -0200 Subject: [PATCH 3/3] Adding legacy constructor rule to CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d631d48b7..c58af2a4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ##### Enhancements +* Add legacy constructor rule. + [Marcelo Fabri](https://github.com/marcelofabri) + [#202](https://github.com/realm/SwiftLint/issues/202) + * The `VariableNameRule` now allows variable names when the entire name is capitalized. This allows stylistic usage common in cases like `URL` and other acronyms.