Merge pull request #1091 from marcelofabri/uppercase-enums-swift-2.3

type_name rule validates enum values with Swift 2.3
This commit is contained in:
JP Simard
2016-12-30 11:32:58 -08:00
committed by GitHub
6 changed files with 106 additions and 53 deletions
+5
View File
@@ -42,6 +42,11 @@
[Scott Berrevoets](https://github.com/sberrevoets)
[#900](https://github.com/realm/SwiftLint/issues/900)
* `type_name` rule forces enum values to be UpperCamelCase again
when used with Swift 2.3.
[Marcelo Fabri](https://github.com/marcelofabri)
[#1090](https://github.com/realm/SwiftLint/issues/1090)
* Make `weak_delegate` rule ignore computed properties.
[Rafael Machado](https://github.com/rakaramos/)
[#1089](https://github.com/realm/SwiftLint/issues/1089)
@@ -18,59 +18,25 @@ public struct TypeNameRule: ASTRule, ConfigurationProviderRule {
public init() {}
private static func nonTriggeringExamples() -> [String] {
let types = ["class", "struct", "enum"]
let typeExamples: [String] = types.flatMap { (type: String) -> [String] in
[
"\(type) MyType {}",
"private \(type) _MyType {}",
"enum MyType {\ncase value\n}",
"\(type) \(repeatElement("A", count: 40).joined()) {}"
]
}
let typeAliasAndAssociatedTypeExamples = [
"typealias Foo = Void",
"private typealias Foo = Void",
"protocol Foo {\n associatedtype Bar\n }",
"protocol Foo {\n associatedtype Bar: Equatable\n }"
]
return typeExamples + typeAliasAndAssociatedTypeExamples
}
private static func triggeringExamples() -> [String] {
let types = ["class", "struct", "enum"]
let typeExamples: [String] = types.flatMap { (type: String) -> [String] in
[
"↓\(type) myType {}",
"↓\(type) _MyType {}",
"private ↓\(type) MyType_ {}",
"↓\(type) My {}",
"↓\(type) \(repeatElement("A", count: 41).joined()) {}"
]
}
let typeAliasAndAssociatedTypeExamples: [String] = [
"typealias ↓X = Void",
"private typealias ↓Foo_Bar = Void",
"private typealias ↓foo = Void",
"typealias ↓\(repeatElement("A", count: 41).joined()) = Void",
"protocol Foo {\n associatedtype ↓X\n }",
"protocol Foo {\n associatedtype ↓Foo_Bar: Equatable\n }",
"protocol Foo {\n associatedtype ↓\(repeatElement("A", count: 41).joined())\n }"
]
return typeExamples + typeAliasAndAssociatedTypeExamples
}
public static let description = RuleDescription(
identifier: "type_name",
name: "Type Name",
description: "Type name should only contain alphanumeric characters, start with an " +
"uppercase character and span between 3 and 40 characters in length.",
nonTriggeringExamples: TypeNameRule.nonTriggeringExamples(),
triggeringExamples: TypeNameRule.triggeringExamples()
nonTriggeringExamples: TypeNameRuleExamples.swift3NonTriggeringExamples,
triggeringExamples: TypeNameRuleExamples.swift3TriggeringExamples
)
private let typeKinds: [SwiftDeclarationKind] = {
let common = SwiftDeclarationKind.typeKinds()
switch SwiftVersion.current {
case .two:
return common + [.enumelement]
case .three:
return common
}
}()
public func validateFile(_ file: File) -> [StyleViolation] {
return validateTypeAliasesAndAssociatedTypes(file) +
validateFile(file, dictionary: file.structure.dictionary)
@@ -80,7 +46,7 @@ public struct TypeNameRule: ASTRule, ConfigurationProviderRule {
kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) -> [StyleViolation] {
guard SwiftDeclarationKind.typeKinds().contains(kind),
guard typeKinds.contains(kind),
let name = dictionary["key.name"] as? String,
let offset = (dictionary["key.offset"] as? Int64).flatMap({ Int($0) }) else {
return []
@@ -0,0 +1,63 @@
//
// TypeNameRuleExamples.swift
// SwiftLint
//
// Created by Marcelo Fabri on 30/12/16.
// Copyright © 2016 Realm. All rights reserved.
//
import Foundation
internal struct TypeNameRuleExamples {
static let swift2NonTriggeringExamples = commonNonTriggeringExamples + ["enum MyType {\ncase Value\n}"]
static let swift3NonTriggeringExamples = commonNonTriggeringExamples + ["enum MyType {\ncase value\n}"]
static let swift2TriggeringExamples = commonTriggeringExamples + ["enum MyType {\ncase ↓value\n}"]
static let swift3TriggeringExamples = commonTriggeringExamples
private static let types = ["class", "struct", "enum"]
private static let commonNonTriggeringExamples: [String] = {
let typeExamples: [String] = types.flatMap { (type: String) -> [String] in
[
"\(type) MyType {}",
"private \(type) _MyType {}",
"\(type) \(repeatElement("A", count: 40).joined()) {}"
]
}
let typeAliasAndAssociatedTypeExamples = [
"typealias Foo = Void",
"private typealias Foo = Void",
"protocol Foo {\n associatedtype Bar\n }",
"protocol Foo {\n associatedtype Bar: Equatable\n }"
]
return typeExamples + typeAliasAndAssociatedTypeExamples
}()
private static let commonTriggeringExamples: [String] = {
let typeExamples: [String] = types.flatMap { (type: String) -> [String] in
[
"↓\(type) myType {}",
"↓\(type) _MyType {}",
"private ↓\(type) MyType_ {}",
"↓\(type) My {}",
"↓\(type) \(repeatElement("A", count: 41).joined()) {}"
]
}
let typeAliasAndAssociatedTypeExamples: [String] = [
"typealias ↓X = Void",
"private typealias ↓Foo_Bar = Void",
"private typealias ↓foo = Void",
"typealias ↓\(repeatElement("A", count: 41).joined()) = Void",
"protocol Foo {\n associatedtype ↓X\n }",
"protocol Foo {\n associatedtype ↓Foo_Bar: Equatable\n }",
"protocol Foo {\n associatedtype ↓\(repeatElement("A", count: 41).joined())\n }"
]
return typeExamples + typeAliasAndAssociatedTypeExamples
}()
}
+4
View File
@@ -87,6 +87,7 @@
D286EC021E02DF6F0003CF72 /* SortedImportsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D286EC001E02DA190003CF72 /* SortedImportsRule.swift */; };
D40AD08A1E032F9700F48C30 /* UnusedClosureParameterRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D40AD0891E032F9700F48C30 /* UnusedClosureParameterRule.swift */; };
D40F83881DE9179200524C62 /* TrailingCommaConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D40F83871DE9179200524C62 /* TrailingCommaConfiguration.swift */; };
D4130D991E16CC1300242361 /* TypeNameRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4130D981E16CC1300242361 /* TypeNameRuleExamples.swift */; };
D41E7E0B1DF9DABB0065259A /* RedundantStringEnumValueRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41E7E0A1DF9DABB0065259A /* RedundantStringEnumValueRule.swift */; };
D42D2B381E09CC0D00CD7A2E /* FirstWhereRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42D2B371E09CC0D00CD7A2E /* FirstWhereRule.swift */; };
D4348EEA1C46122C007707FB /* FunctionBodyLengthRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4348EE91C46122C007707FB /* FunctionBodyLengthRuleTests.swift */; };
@@ -335,6 +336,7 @@
D286EC001E02DA190003CF72 /* SortedImportsRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SortedImportsRule.swift; sourceTree = "<group>"; };
D40AD0891E032F9700F48C30 /* UnusedClosureParameterRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnusedClosureParameterRule.swift; sourceTree = "<group>"; };
D40F83871DE9179200524C62 /* TrailingCommaConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrailingCommaConfiguration.swift; sourceTree = "<group>"; };
D4130D981E16CC1300242361 /* TypeNameRuleExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeNameRuleExamples.swift; sourceTree = "<group>"; };
D41E7E0A1DF9DABB0065259A /* RedundantStringEnumValueRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RedundantStringEnumValueRule.swift; sourceTree = "<group>"; };
D42D2B371E09CC0D00CD7A2E /* FirstWhereRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirstWhereRule.swift; sourceTree = "<group>"; };
D4348EE91C46122C007707FB /* FunctionBodyLengthRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FunctionBodyLengthRuleTests.swift; sourceTree = "<group>"; };
@@ -797,6 +799,7 @@
E88DEA851B0991BF00A66CB0 /* TrailingWhitespaceRule.swift */,
E88DEA8D1B0999CD00A66CB0 /* TypeBodyLengthRule.swift */,
E88DEA911B099B1F00A66CB0 /* TypeNameRule.swift */,
D4130D981E16CC1300242361 /* TypeNameRuleExamples.swift */,
D40AD0891E032F9700F48C30 /* UnusedClosureParameterRule.swift */,
D43B04631E0620AB004016AF /* UnusedEnumeratedRule.swift */,
E81CDE701C00FEAA00B430F6 /* ValidDocsRule.swift */,
@@ -1136,6 +1139,7 @@
1EC163521D5992D900DD2928 /* VerticalWhitespaceRule.swift in Sources */,
57ED827B1CF656E3002B3513 /* JUnitReporter.swift in Sources */,
D43B04691E072291004016AF /* ColonConfiguration.swift in Sources */,
D4130D991E16CC1300242361 /* TypeNameRuleExamples.swift in Sources */,
24E17F721B14BB3F008195BE /* File+Cache.swift in Sources */,
009E09281DFEE4C200B588A7 /* ProhibitedSuperRule.swift in Sources */,
E80E018F1B92C1350078EB70 /* Region.swift in Sources */,
@@ -48,6 +48,9 @@
<Test
Identifier = "RulesTests/testNumberSeparator()">
</Test>
<Test
Identifier = "RulesTests/testTypeName()">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
@@ -12,6 +12,18 @@ import XCTest
#if !SWIFT_PACKAGE
class Swift2RulesTests: XCTestCase {
func testAttributes() {
let description = RuleDescription(
identifier: AttributesRule.description.identifier,
name: AttributesRule.description.name,
description: AttributesRule.description.description,
nonTriggeringExamples: AttributesRuleExamples.swift2NonTriggeringExamples,
triggeringExamples: AttributesRuleExamples.swift2TriggeringExamples
)
verifyRule(description)
}
func testNumberSeparator() {
let description = RuleDescription(
identifier: NumberSeparatorRule.description.identifier,
@@ -25,13 +37,13 @@ class Swift2RulesTests: XCTestCase {
verifyRule(description)
}
func testAttributes() {
func testTypeName() {
let description = RuleDescription(
identifier: AttributesRule.description.identifier,
name: AttributesRule.description.name,
description: AttributesRule.description.description,
nonTriggeringExamples: AttributesRuleExamples.swift2NonTriggeringExamples,
triggeringExamples: AttributesRuleExamples.swift2TriggeringExamples
identifier: TypeNameRule.description.identifier,
name: TypeNameRule.description.name,
description: TypeNameRule.description.description,
nonTriggeringExamples: TypeNameRuleExamples.swift2NonTriggeringExamples,
triggeringExamples: TypeNameRuleExamples.swift2TriggeringExamples
)
verifyRule(description)