mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
TypeNameRule
This commit is contained in:
@@ -47,7 +47,7 @@ extension File {
|
||||
let kindString = subDict["key.kind"] as? String,
|
||||
let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) {
|
||||
violations.extend(self.astViolationsInDictionary(subDict))
|
||||
violations.extend(self.validateTypeName(kind, dict: subDict))
|
||||
violations.extend(TypeNameRule.validateFile(self, kind: kind, dictionary: subDict))
|
||||
violations.extend(self.validateVariableName(kind, dict: subDict))
|
||||
violations.extend(TypeBodyLengthRule.validateFile(self, kind: kind, dictionary: subDict))
|
||||
violations.extend(FunctionBodyLengthRule.validateFile(self, kind: kind, dictionary: subDict))
|
||||
@@ -57,40 +57,6 @@ extension File {
|
||||
}
|
||||
}
|
||||
|
||||
func validateTypeName(kind: SwiftDeclarationKind, dict: XPCDictionary) -> [StyleViolation] {
|
||||
let typeKinds: [SwiftDeclarationKind] = [
|
||||
.Class,
|
||||
.Struct,
|
||||
.Typealias,
|
||||
.Enum,
|
||||
.Enumelement
|
||||
]
|
||||
if !contains(typeKinds, kind) {
|
||||
return []
|
||||
}
|
||||
var violations = [StyleViolation]()
|
||||
if let name = dict["key.name"] as? String,
|
||||
let offset = flatMap(dict["key.offset"] as? Int64, { Int($0) }) {
|
||||
let location = Location(file: self, offset: offset)
|
||||
let nameCharacterSet = NSCharacterSet(charactersInString: name)
|
||||
if !NSCharacterSet.alphanumericCharacterSet().isSupersetOfSet(nameCharacterSet) {
|
||||
violations.append(StyleViolation(type: .NameFormat,
|
||||
location: location,
|
||||
reason: "Type name should only contain alphanumeric characters: '\(name)'"))
|
||||
} else if !name.substringToIndex(name.startIndex.successor()).isUppercase() {
|
||||
violations.append(StyleViolation(type: .NameFormat,
|
||||
location: location,
|
||||
reason: "Type name should start with an uppercase character: '\(name)'"))
|
||||
} else if count(name) < 3 || count(name) > 40 {
|
||||
violations.append(StyleViolation(type: .NameFormat,
|
||||
location: location,
|
||||
reason: "Type name should be between 3 and 40 characters in length: " +
|
||||
"'\(name)'"))
|
||||
}
|
||||
}
|
||||
return violations
|
||||
}
|
||||
|
||||
func validateVariableName(kind: SwiftDeclarationKind, dict: XPCDictionary) -> [StyleViolation] {
|
||||
let variableKinds: [SwiftDeclarationKind] = [
|
||||
.VarClass,
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// TypeNameRule.swift
|
||||
// SwiftLint
|
||||
//
|
||||
// Created by JP Simard on 5/18/15.
|
||||
// Copyright (c) 2015 Realm. All rights reserved.
|
||||
//
|
||||
|
||||
import SourceKittenFramework
|
||||
import SwiftXPC
|
||||
|
||||
struct TypeNameRule: Rule {
|
||||
static let identifier = "type_name"
|
||||
static let parameters = [RuleParameter<Void>]()
|
||||
|
||||
static func validateFile(file: File) -> [StyleViolation] {
|
||||
return self.validateFile(file, dictionary: Structure(file: file).dictionary)
|
||||
}
|
||||
|
||||
static func validateFile(file: File, dictionary: XPCDictionary) -> [StyleViolation] {
|
||||
return (dictionary["key.substructure"] as? XPCArray ?? []).flatMap { subItem in
|
||||
var violations = [StyleViolation]()
|
||||
if let subDict = subItem as? XPCDictionary,
|
||||
let kindString = subDict["key.kind"] as? String,
|
||||
let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) {
|
||||
violations.extend(self.validateFile(file, dictionary: subDict))
|
||||
violations.extend(self.validateFile(file, kind: kind, dictionary: subDict))
|
||||
}
|
||||
return violations
|
||||
}
|
||||
}
|
||||
|
||||
static func validateFile(file: File,
|
||||
kind: SwiftDeclarationKind,
|
||||
dictionary: XPCDictionary) -> [StyleViolation] {
|
||||
let typeKinds: [SwiftDeclarationKind] = [
|
||||
.Class,
|
||||
.Struct,
|
||||
.Typealias,
|
||||
.Enum,
|
||||
.Enumelement
|
||||
]
|
||||
if !contains(typeKinds, kind) {
|
||||
return []
|
||||
}
|
||||
var violations = [StyleViolation]()
|
||||
if let name = dictionary["key.name"] as? String,
|
||||
let offset = flatMap(dictionary["key.offset"] as? Int64, { Int($0) }) {
|
||||
let location = Location(file: file, offset: offset)
|
||||
let nameCharacterSet = NSCharacterSet(charactersInString: name)
|
||||
if !NSCharacterSet.alphanumericCharacterSet().isSupersetOfSet(nameCharacterSet) {
|
||||
violations.append(StyleViolation(type: .NameFormat,
|
||||
location: location,
|
||||
severity: .Medium,
|
||||
reason: "Type name should only contain alphanumeric characters: '\(name)'"))
|
||||
} else if !name.substringToIndex(name.startIndex.successor()).isUppercase() {
|
||||
violations.append(StyleViolation(type: .NameFormat,
|
||||
location: location,
|
||||
severity: .High,
|
||||
reason: "Type name should start with an uppercase character: '\(name)'"))
|
||||
} else if count(name) < 3 || count(name) > 40 {
|
||||
violations.append(StyleViolation(type: .NameFormat,
|
||||
location: location,
|
||||
severity: .Medium,
|
||||
reason: "Type name should be between 3 and 40 characters in length: " +
|
||||
"'\(name)'"))
|
||||
}
|
||||
}
|
||||
return violations
|
||||
}
|
||||
}
|
||||
@@ -25,14 +25,17 @@ class LinterTests: XCTestCase {
|
||||
|
||||
XCTAssertEqual(violations("\(kind) Ab_ {}\n"), [StyleViolation(type: .NameFormat,
|
||||
location: Location(file: nil, line: 1),
|
||||
severity: .Medium,
|
||||
reason: "Type name should only contain alphanumeric characters: 'Ab_'")])
|
||||
|
||||
XCTAssertEqual(violations("\(kind) abc {}\n"), [StyleViolation(type: .NameFormat,
|
||||
location: Location(file: nil, line: 1),
|
||||
severity: .High,
|
||||
reason: "Type name should start with an uppercase character: 'abc'")])
|
||||
|
||||
XCTAssertEqual(violations("\(kind) Ab {}\n"), [StyleViolation(type: .NameFormat,
|
||||
location: Location(file: nil, line: 1),
|
||||
severity: .Medium,
|
||||
reason: "Type name should be between 3 and 40 characters in length: 'Ab'")])
|
||||
|
||||
let longName = join("", Array(count: 40, repeatedValue: "A"))
|
||||
@@ -41,6 +44,7 @@ class LinterTests: XCTestCase {
|
||||
XCTAssertEqual(violations("\(kind) \(longerName) {}\n"), [
|
||||
StyleViolation(type: .NameFormat,
|
||||
location: Location(file: nil, line: 1),
|
||||
severity: .Medium,
|
||||
reason: "Type name should be between 3 and 40 characters in length: " +
|
||||
"'\(longerName)'")
|
||||
])
|
||||
@@ -66,6 +70,7 @@ class LinterTests: XCTestCase {
|
||||
[
|
||||
StyleViolation(type: .NameFormat,
|
||||
location: Location(file: nil, line: 2),
|
||||
severity: .High,
|
||||
reason: "Type name should start with an uppercase character: 'def'")
|
||||
])
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
E88DEA8C1B0999A000A66CB0 /* ASTRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA8B1B0999A000A66CB0 /* ASTRule.swift */; };
|
||||
E88DEA8E1B0999CD00A66CB0 /* TypeBodyLengthRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA8D1B0999CD00A66CB0 /* TypeBodyLengthRule.swift */; };
|
||||
E88DEA901B099A3100A66CB0 /* FunctionBodyLengthRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA8F1B099A3100A66CB0 /* FunctionBodyLengthRule.swift */; };
|
||||
E88DEA921B099B1F00A66CB0 /* TypeNameRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA911B099B1F00A66CB0 /* TypeNameRule.swift */; };
|
||||
E8AB1A2E1A649F2100452012 /* libclang.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E8AB1A2D1A649F2100452012 /* libclang.dylib */; };
|
||||
E8BA7E111B07A3EC003E02D0 /* Commandant.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E101B07A3EC003E02D0 /* Commandant.framework */; };
|
||||
E8BA7E131B07A3F3003E02D0 /* LlamaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E121B07A3F3003E02D0 /* LlamaKit.framework */; };
|
||||
@@ -148,6 +149,7 @@
|
||||
E88DEA8B1B0999A000A66CB0 /* ASTRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASTRule.swift; sourceTree = "<group>"; };
|
||||
E88DEA8D1B0999CD00A66CB0 /* TypeBodyLengthRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeBodyLengthRule.swift; sourceTree = "<group>"; };
|
||||
E88DEA8F1B099A3100A66CB0 /* FunctionBodyLengthRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FunctionBodyLengthRule.swift; sourceTree = "<group>"; };
|
||||
E88DEA911B099B1F00A66CB0 /* TypeNameRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeNameRule.swift; sourceTree = "<group>"; };
|
||||
E8AB1A2D1A649F2100452012 /* libclang.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libclang.dylib; path = Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib; sourceTree = DEVELOPER_DIR; };
|
||||
E8BA7E101B07A3EC003E02D0 /* Commandant.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Commandant.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E8BA7E121B07A3F3003E02D0 /* LlamaKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = LlamaKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -364,6 +366,7 @@
|
||||
E88DEA891B0992B300A66CB0 /* FileLengthRule.swift */,
|
||||
E88DEA8D1B0999CD00A66CB0 /* TypeBodyLengthRule.swift */,
|
||||
E88DEA8F1B099A3100A66CB0 /* FunctionBodyLengthRule.swift */,
|
||||
E88DEA911B099B1F00A66CB0 /* TypeNameRule.swift */,
|
||||
);
|
||||
path = Rules;
|
||||
sourceTree = "<group>";
|
||||
@@ -528,6 +531,7 @@
|
||||
E88DEA771B098D0C00A66CB0 /* Rule.swift in Sources */,
|
||||
E88DEA7C1B098D7D00A66CB0 /* LineLengthRule.swift in Sources */,
|
||||
E88DEA801B09903300A66CB0 /* ForceCastRule.swift in Sources */,
|
||||
E88DEA921B099B1F00A66CB0 /* TypeNameRule.swift in Sources */,
|
||||
E88DEA711B09847500A66CB0 /* ViolationSeverity.swift in Sources */,
|
||||
E88DEA8C1B0999A000A66CB0 /* ASTRule.swift in Sources */,
|
||||
E88DEA821B0990A700A66CB0 /* TodoRule.swift in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user