mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
generalized rules and split off LineLengthRule
This commit is contained in:
@@ -12,15 +12,6 @@ import SwiftXPC
|
||||
typealias Line = (index: Int, content: String)
|
||||
|
||||
extension File {
|
||||
func lineLengthViolations(lines: [Line]) -> [StyleViolation] {
|
||||
return lines.filter({ count($0.content) > 100 }).map {
|
||||
return StyleViolation(type: .Length,
|
||||
location: Location(file: self.path, line: $0.index),
|
||||
reason: "Line #\($0.index) should be 100 characters or less: " +
|
||||
"currently \(count($0.content)) characters")
|
||||
}
|
||||
}
|
||||
|
||||
func leadingWhitespaceViolations(contents: String) -> [StyleViolation] {
|
||||
let countOfLeadingWhitespace = contents.countOfLeadingCharactersInSet(
|
||||
NSCharacterSet.whitespaceAndNewlineCharacterSet()
|
||||
@@ -323,7 +314,7 @@ extension File {
|
||||
let lines = contents.lines()
|
||||
// FIXME: Using '+' to concatenate these arrays would be nicer,
|
||||
// but slows the compiler to a crawl.
|
||||
var violations = lineLengthViolations(lines)
|
||||
var violations = LineLengthRule.validateFile(self)
|
||||
violations.extend(leadingWhitespaceViolations(contents))
|
||||
violations.extend(trailingLineWhitespaceViolations(lines))
|
||||
violations.extend(trailingNewlineViolations(contents))
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Rule.swift
|
||||
// SwiftLint
|
||||
//
|
||||
// Created by JP Simard on 2015-05-16.
|
||||
// Copyright (c) 2015 Realm. All rights reserved.
|
||||
//
|
||||
|
||||
import SourceKittenFramework
|
||||
|
||||
protocol Rule {
|
||||
typealias ParameterType
|
||||
|
||||
static var identifier: String { get }
|
||||
static var parameters: [RuleParameter<ParameterType>] { get }
|
||||
|
||||
static func validateFile(file: File) -> [StyleViolation]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// RuleParameter.swift
|
||||
// SwiftLint
|
||||
//
|
||||
// Created by JP Simard on 2015-05-16.
|
||||
// Copyright (c) 2015 Realm. All rights reserved.
|
||||
//
|
||||
|
||||
struct RuleParameter<T> {
|
||||
let severity: ViolationSeverity
|
||||
let value: T
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// LineLengthRule.swift
|
||||
// SwiftLint
|
||||
//
|
||||
// Created by JP Simard on 2015-05-16.
|
||||
// Copyright (c) 2015 Realm. All rights reserved.
|
||||
//
|
||||
|
||||
import SourceKittenFramework
|
||||
|
||||
struct LineLengthRule: Rule {
|
||||
static let identifier = "line_length"
|
||||
static let parameters = [
|
||||
RuleParameter(severity: .VeryLow, value: 100),
|
||||
RuleParameter(severity: .Low, value: 120),
|
||||
RuleParameter(severity: .Medium, value: 150),
|
||||
RuleParameter(severity: .High, value: 200),
|
||||
RuleParameter(severity: .VeryHigh, value: 250)
|
||||
]
|
||||
|
||||
static func validateFile(file: File) -> [StyleViolation] {
|
||||
return compact(file.contents.lines().map { line in
|
||||
for parameter in reverse(self.parameters) {
|
||||
if count(line.content) > parameter.value {
|
||||
return StyleViolation(type: .Length,
|
||||
location: Location(file: file.path, line: line.index),
|
||||
severity: parameter.severity,
|
||||
reason: "Line should be 100 characters or less: currently " +
|
||||
"\(count(line.content)) characters")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,11 @@ public struct StyleViolation: Printable, Equatable {
|
||||
}
|
||||
|
||||
public init(type: StyleViolationType, location: Location, reason: String? = nil) {
|
||||
severity = .Low
|
||||
self.init(type: type, location: location, severity: .Low, reason: reason)
|
||||
}
|
||||
|
||||
public init(type: StyleViolationType, location: Location, severity: ViolationSeverity, reason: String? = nil) {
|
||||
self.severity = severity
|
||||
self.type = type
|
||||
self.location = location
|
||||
self.reason = reason
|
||||
@@ -40,5 +44,6 @@ Returns true if `lhs` StyleViolation is equal to `rhs` StyleViolation.
|
||||
public func ==(lhs: StyleViolation, rhs: StyleViolation) -> Bool {
|
||||
return lhs.type == rhs.type &&
|
||||
lhs.location == rhs.location &&
|
||||
lhs.severity == rhs.severity &&
|
||||
lhs.reason == rhs.reason
|
||||
}
|
||||
|
||||
@@ -210,11 +210,21 @@ class LinterTests: XCTestCase {
|
||||
// MARK: String Violations
|
||||
|
||||
func testLineLengths() {
|
||||
let longLine = join("", Array(count: 100, repeatedValue: "/"))
|
||||
XCTAssertEqual(violations(longLine + "\n"), [])
|
||||
XCTAssertEqual(violations(longLine + "/\n"), [StyleViolation(type: .Length,
|
||||
location: Location(file: nil, line: 1),
|
||||
reason: "Line #1 should be 100 characters or less: currently 101 characters")])
|
||||
let longLine = join("", Array(count: 100, repeatedValue: "/")) + "\n"
|
||||
XCTAssertEqual(violations(longLine), [])
|
||||
let testCases: [(String, Int, ViolationSeverity)] = [
|
||||
("/", 101, .VeryLow),
|
||||
(join("", Array(count: 21, repeatedValue: "/")), 121, .Low),
|
||||
(join("", Array(count: 51, repeatedValue: "/")), 151, .Medium),
|
||||
(join("", Array(count: 101, repeatedValue: "/")), 201, .High),
|
||||
(join("", Array(count: 151, repeatedValue: "/")), 251, .VeryHigh)
|
||||
]
|
||||
for testCase in testCases {
|
||||
XCTAssertEqual(violations(testCase.0 + longLine), [StyleViolation(type: .Length,
|
||||
location: Location(file: nil, line: 1),
|
||||
severity: testCase.2,
|
||||
reason: "Line should be 100 characters or less: currently \(testCase.1) characters")])
|
||||
}
|
||||
}
|
||||
|
||||
func testTrailingNewlineAtEndOfFile() {
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
E88DEA711B09847500A66CB0 /* ViolationSeverity.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA701B09847500A66CB0 /* ViolationSeverity.swift */; };
|
||||
E88DEA731B0984C400A66CB0 /* String+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA721B0984C400A66CB0 /* String+SwiftLint.swift */; };
|
||||
E88DEA751B09852000A66CB0 /* File+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA741B09852000A66CB0 /* File+SwiftLint.swift */; };
|
||||
E88DEA771B098D0C00A66CB0 /* Rule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA761B098D0C00A66CB0 /* Rule.swift */; };
|
||||
E88DEA791B098D4400A66CB0 /* RuleParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA781B098D4400A66CB0 /* RuleParameter.swift */; };
|
||||
E88DEA7C1B098D7D00A66CB0 /* LineLengthRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA7B1B098D7D00A66CB0 /* LineLengthRule.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 */; };
|
||||
@@ -122,6 +125,9 @@
|
||||
E88DEA701B09847500A66CB0 /* ViolationSeverity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViolationSeverity.swift; sourceTree = "<group>"; };
|
||||
E88DEA721B0984C400A66CB0 /* String+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SwiftLint.swift"; sourceTree = "<group>"; };
|
||||
E88DEA741B09852000A66CB0 /* File+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "File+SwiftLint.swift"; sourceTree = "<group>"; };
|
||||
E88DEA761B098D0C00A66CB0 /* Rule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Rule.swift; sourceTree = "<group>"; };
|
||||
E88DEA781B098D4400A66CB0 /* RuleParameter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleParameter.swift; sourceTree = "<group>"; };
|
||||
E88DEA7B1B098D7D00A66CB0 /* LineLengthRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineLengthRule.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; };
|
||||
@@ -274,7 +280,10 @@
|
||||
D0D1216E19E87B05005E4BAA /* SwiftLintFramework */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E88DEA7A1B098D7300A66CB0 /* Rules */,
|
||||
E88DEA741B09852000A66CB0 /* File+SwiftLint.swift */,
|
||||
E88DEA761B098D0C00A66CB0 /* Rule.swift */,
|
||||
E88DEA781B098D4400A66CB0 /* RuleParameter.swift */,
|
||||
E812249B1B04FADC001783D2 /* Linter.swift */,
|
||||
E88DEA6E1B09843F00A66CB0 /* Location.swift */,
|
||||
E88DEA721B0984C400A66CB0 /* String+SwiftLint.swift */,
|
||||
@@ -321,6 +330,14 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E88DEA7A1B098D7300A66CB0 /* Rules */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E88DEA7B1B098D7D00A66CB0 /* LineLengthRule.swift */,
|
||||
);
|
||||
path = Rules;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
@@ -468,10 +485,13 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E812249C1B04FADC001783D2 /* Linter.swift in Sources */,
|
||||
E88DEA791B098D4400A66CB0 /* RuleParameter.swift in Sources */,
|
||||
E88DEA731B0984C400A66CB0 /* String+SwiftLint.swift in Sources */,
|
||||
E88DEA6D1B09842200A66CB0 /* StyleViolationType.swift in Sources */,
|
||||
E88DEA751B09852000A66CB0 /* File+SwiftLint.swift in Sources */,
|
||||
E88DEA6F1B09843F00A66CB0 /* Location.swift in Sources */,
|
||||
E88DEA771B098D0C00A66CB0 /* Rule.swift in Sources */,
|
||||
E88DEA7C1B098D7D00A66CB0 /* LineLengthRule.swift in Sources */,
|
||||
E88DEA711B09847500A66CB0 /* ViolationSeverity.swift in Sources */,
|
||||
E88DEA6B1B0983FE00A66CB0 /* StyleViolation.swift in Sources */,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user