mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
Created ASTRule protocol and TypeBodyLengthRule
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// ASTRule.swift
|
||||
// SwiftLint
|
||||
//
|
||||
// Created by JP Simard on 2015-05-16.
|
||||
// Copyright (c) 2015 Realm. All rights reserved.
|
||||
//
|
||||
|
||||
import SourceKittenFramework
|
||||
import SwiftXPC
|
||||
|
||||
protocol ASTRule: Rule {
|
||||
static func validateFile(file: File, dictionary: XPCDictionary) -> [StyleViolation]
|
||||
|
||||
static func validateFile(file: File,
|
||||
kind: SwiftDeclarationKind,
|
||||
dictionary: XPCDictionary) -> [StyleViolation]
|
||||
}
|
||||
@@ -49,7 +49,7 @@ extension File {
|
||||
violations.extend(self.astViolationsInDictionary(subDict))
|
||||
violations.extend(self.validateTypeName(kind, dict: subDict))
|
||||
violations.extend(self.validateVariableName(kind, dict: subDict))
|
||||
violations.extend(self.validateTypeBodyLength(kind, dict: subDict))
|
||||
violations.extend(TypeBodyLengthRule.validateFile(self, kind: kind, dictionary: subDict))
|
||||
violations.extend(self.validateFunctionBodyLength(kind, dict: subDict))
|
||||
violations.extend(self.validateNesting(kind, dict: subDict))
|
||||
}
|
||||
@@ -57,34 +57,6 @@ extension File {
|
||||
}
|
||||
}
|
||||
|
||||
func validateTypeBodyLength(kind: SwiftDeclarationKind, dict: XPCDictionary) ->
|
||||
[StyleViolation] {
|
||||
let typeKinds: [SwiftDeclarationKind] = [
|
||||
.Class,
|
||||
.Struct,
|
||||
.Enum
|
||||
]
|
||||
if !contains(typeKinds, kind) {
|
||||
return []
|
||||
}
|
||||
var violations = [StyleViolation]()
|
||||
if let offset = flatMap(dict["key.offset"] as? Int64, { Int($0) }),
|
||||
let bodyOffset = flatMap(dict["key.bodyoffset"] as? Int64, { Int($0) }),
|
||||
let bodyLength = flatMap(dict["key.bodylength"] as? Int64, { Int($0) }) {
|
||||
let location = Location(file: self, offset: offset)
|
||||
let startLine = self.contents.lineAndCharacterForByteOffset(bodyOffset)
|
||||
let endLine = self.contents.lineAndCharacterForByteOffset(bodyOffset + bodyLength)
|
||||
if let startLine = startLine?.line, let endLine = endLine?.line
|
||||
where endLine - startLine > 200 {
|
||||
violations.append(StyleViolation(type: .Length,
|
||||
location: location,
|
||||
reason: "Type body should be span 200 lines or less: currently spans " +
|
||||
"\(endLine - startLine) lines"))
|
||||
}
|
||||
}
|
||||
return violations
|
||||
}
|
||||
|
||||
func validateFunctionBodyLength(kind: SwiftDeclarationKind, dict: XPCDictionary) ->
|
||||
[StyleViolation] {
|
||||
let functionKinds: [SwiftDeclarationKind] = [
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// TypeBodyLengthRule.swift
|
||||
// SwiftLint
|
||||
//
|
||||
// Created by JP Simard on 5/18/15.
|
||||
// Copyright (c) 2015 Realm. All rights reserved.
|
||||
//
|
||||
|
||||
import SourceKittenFramework
|
||||
import SwiftXPC
|
||||
|
||||
struct TypeBodyLengthRule: Rule {
|
||||
static let identifier = "type_body_length"
|
||||
static let parameters = [
|
||||
RuleParameter(severity: .VeryLow, value: 200),
|
||||
RuleParameter(severity: .Low, value: 250),
|
||||
RuleParameter(severity: .Medium, value: 300),
|
||||
RuleParameter(severity: .High, value: 350),
|
||||
RuleParameter(severity: .VeryHigh, value: 400)
|
||||
]
|
||||
|
||||
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,
|
||||
.Enum
|
||||
]
|
||||
if !contains(typeKinds, kind) {
|
||||
return []
|
||||
}
|
||||
var violations = [StyleViolation]()
|
||||
if let offset = flatMap(dictionary["key.offset"] as? Int64, { Int($0) }),
|
||||
let bodyOffset = flatMap(dictionary["key.bodyoffset"] as? Int64, { Int($0) }),
|
||||
let bodyLength = flatMap(dictionary["key.bodylength"] as? Int64, { Int($0) }) {
|
||||
let location = Location(file: file, offset: offset)
|
||||
let startLine = file.contents.lineAndCharacterForByteOffset(bodyOffset)
|
||||
let endLine = file.contents.lineAndCharacterForByteOffset(bodyOffset + bodyLength)
|
||||
for parameter in reverse(parameters) {
|
||||
if let startLine = startLine?.line, let endLine = endLine?.line
|
||||
where endLine - startLine > parameter.value {
|
||||
violations.append(StyleViolation(type: .Length,
|
||||
location: location,
|
||||
severity: parameter.severity,
|
||||
reason: "Type body should be span 200 lines or less: currently spans " +
|
||||
"\(endLine - startLine) lines"))
|
||||
}
|
||||
}
|
||||
}
|
||||
return violations
|
||||
}
|
||||
}
|
||||
@@ -137,6 +137,7 @@ class LinterTests: XCTestCase {
|
||||
"}\n"
|
||||
XCTAssertEqual(violations(longerTypeBody), [StyleViolation(type: .Length,
|
||||
location: Location(file: nil, line: 1),
|
||||
severity: .VeryLow,
|
||||
reason: "Type body should be span 200 lines or less: currently spans 201 lines")])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
E88DEA861B0991BF00A66CB0 /* TrailingWhitespaceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA851B0991BF00A66CB0 /* TrailingWhitespaceRule.swift */; };
|
||||
E88DEA881B09924C00A66CB0 /* TrailingNewlineRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA871B09924C00A66CB0 /* TrailingNewlineRule.swift */; };
|
||||
E88DEA8A1B0992B300A66CB0 /* FileLengthRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA891B0992B300A66CB0 /* FileLengthRule.swift */; };
|
||||
E88DEA8C1B0999A000A66CB0 /* ASTRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA8B1B0999A000A66CB0 /* ASTRule.swift */; };
|
||||
E88DEA8E1B0999CD00A66CB0 /* TypeBodyLengthRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA8D1B0999CD00A66CB0 /* TypeBodyLengthRule.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 */; };
|
||||
@@ -142,6 +144,8 @@
|
||||
E88DEA851B0991BF00A66CB0 /* TrailingWhitespaceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrailingWhitespaceRule.swift; sourceTree = "<group>"; };
|
||||
E88DEA871B09924C00A66CB0 /* TrailingNewlineRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrailingNewlineRule.swift; sourceTree = "<group>"; };
|
||||
E88DEA891B0992B300A66CB0 /* FileLengthRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileLengthRule.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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; };
|
||||
@@ -296,6 +300,7 @@
|
||||
children = (
|
||||
E88DEA7A1B098D7300A66CB0 /* Rules */,
|
||||
E88DEA741B09852000A66CB0 /* File+SwiftLint.swift */,
|
||||
E88DEA8B1B0999A000A66CB0 /* ASTRule.swift */,
|
||||
E88DEA761B098D0C00A66CB0 /* Rule.swift */,
|
||||
E88DEA781B098D4400A66CB0 /* RuleParameter.swift */,
|
||||
E812249B1B04FADC001783D2 /* Linter.swift */,
|
||||
@@ -355,6 +360,7 @@
|
||||
E88DEA851B0991BF00A66CB0 /* TrailingWhitespaceRule.swift */,
|
||||
E88DEA871B09924C00A66CB0 /* TrailingNewlineRule.swift */,
|
||||
E88DEA891B0992B300A66CB0 /* FileLengthRule.swift */,
|
||||
E88DEA8D1B0999CD00A66CB0 /* TypeBodyLengthRule.swift */,
|
||||
);
|
||||
path = Rules;
|
||||
sourceTree = "<group>";
|
||||
@@ -513,12 +519,14 @@
|
||||
E88DEA6D1B09842200A66CB0 /* StyleViolationType.swift in Sources */,
|
||||
E88DEA8A1B0992B300A66CB0 /* FileLengthRule.swift in Sources */,
|
||||
E88DEA751B09852000A66CB0 /* File+SwiftLint.swift in Sources */,
|
||||
E88DEA8E1B0999CD00A66CB0 /* TypeBodyLengthRule.swift in Sources */,
|
||||
E88DEA6F1B09843F00A66CB0 /* Location.swift in Sources */,
|
||||
E88DEA881B09924C00A66CB0 /* TrailingNewlineRule.swift in Sources */,
|
||||
E88DEA771B098D0C00A66CB0 /* Rule.swift in Sources */,
|
||||
E88DEA7C1B098D7D00A66CB0 /* LineLengthRule.swift in Sources */,
|
||||
E88DEA801B09903300A66CB0 /* ForceCastRule.swift in Sources */,
|
||||
E88DEA711B09847500A66CB0 /* ViolationSeverity.swift in Sources */,
|
||||
E88DEA8C1B0999A000A66CB0 /* ASTRule.swift in Sources */,
|
||||
E88DEA821B0990A700A66CB0 /* TodoRule.swift in Sources */,
|
||||
E88DEA6B1B0983FE00A66CB0 /* StyleViolation.swift in Sources */,
|
||||
E88DEA7E1B098F2A00A66CB0 /* LeadingWhitespaceRule.swift in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user