mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
40828dff03
* master: (41 commits) Fix formatting in CHANGELOG.md release 0.13.0 Update CHANGELOG.md Fix check for trailing whitespace to return early Fix checks for some inline comments Replace check for comments to use SyntaxKind Add configuration for trailing_whitespace to ignore comments Unwanted space removed - Lint issues fixed Updated HTML Reporter PR feedback Add check on autocorrect for disabled range Use `utf8.count` instead of `utf16.count` to byte range Re-write `ExplicitInitRule` to `ASTRule` added ExplicitInitRule Updated CHANGELOG HTML Reporter added HTML Reporter added Adds information about SwiftLint plugin for AppCode into README.md added reasons why a new rule should be opt in ... # Conflicts: # Source/SwiftLintFramework/Extensions/File+SwiftLint.swift # Source/SwiftLintFramework/Extensions/Structure+SwiftLint.swift # Source/SwiftLintFramework/Rules/ColonRule.swift # Source/SwiftLintFramework/Rules/CommaRule.swift # Source/SwiftLintFramework/Rules/LegacyCGGeometryFunctionsRule.swift # Source/SwiftLintFramework/Rules/LegacyConstantRule.swift # Source/SwiftLintFramework/Rules/LegacyConstructorRule.swift # Source/SwiftLintFramework/Rules/LegacyNSGeometryFunctionsRule.swift # Source/SwiftLintFramework/Rules/LineLengthRule.swift # Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift # Source/SwiftLintFramework/Rules/ReturnArrowWhitespaceRule.swift # Source/SwiftLintFramework/Rules/RuleConfigurations/StatementPositionConfiguration.swift # Source/SwiftLintFramework/Rules/StatementPositionRule.swift # Source/SwiftLintFramework/Rules/TrailingWhitespaceRule.swift # Tests/SwiftLintFramework/RuleConfigurationTests.swift
91 lines
3.9 KiB
Swift
91 lines
3.9 KiB
Swift
//
|
|
// LineLengthRule.swift
|
|
// SwiftLint
|
|
//
|
|
// Created by JP Simard on 2015-05-16.
|
|
// Copyright (c) 2015 Realm. All rights reserved.
|
|
//
|
|
|
|
import SourceKittenFramework
|
|
|
|
public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule {
|
|
public var configuration = SeverityLevelsConfiguration(warning: 100, error: 200)
|
|
|
|
public init() {}
|
|
|
|
public static let description = RuleDescription(
|
|
identifier: "line_length",
|
|
name: "Line Length",
|
|
description: "Lines should not span too many characters.",
|
|
nonTriggeringExamples: [
|
|
String(repeating: "/", count: 100) + "\n",
|
|
String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 100) + "\n",
|
|
String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 100) + "\n",
|
|
],
|
|
triggeringExamples: [
|
|
String(repeating: "/", count: 101) + "\n",
|
|
String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 101) + "\n",
|
|
String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 101) + "\n",
|
|
]
|
|
)
|
|
|
|
public func validateFile(_ file: File) -> [StyleViolation] {
|
|
let minValue = configuration.params.map({ $0.value }).min(by: <)
|
|
return file.lines.flatMap { line in
|
|
// `line.content.characters.count` <= `line.range.length` is true.
|
|
// So, `check line.range.length` is larger than minimum parameter value.
|
|
// for avoiding using heavy `line.content.characters.count`.
|
|
if line.range.length < minValue! {
|
|
return nil
|
|
}
|
|
|
|
var strippedString = line.content
|
|
strippedString = stripLiterals(fromSourceString: strippedString,
|
|
withDelimiter: "#colorLiteral")
|
|
strippedString = stripLiterals(fromSourceString: strippedString,
|
|
withDelimiter: "#imageLiteral")
|
|
|
|
let length = strippedString.characters.count
|
|
|
|
for param in configuration.params where length > param.value {
|
|
return StyleViolation(ruleDescription: type(of: self).description,
|
|
severity: param.severity,
|
|
location: Location(file: file.path, line: line.index),
|
|
reason: "Line should be \(configuration.warning) characters or less: " +
|
|
"currently \(length) characters")
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
/// Takes a string and replaces any literals specified by the `delimiter` parameter with `#`
|
|
///
|
|
/// - parameter sourceString: Original string, possibly containing literals
|
|
/// - parameter delimiter: Delimiter of the literal
|
|
/// (characters before the parentheses, e.g. `#colorLiteral`)
|
|
///
|
|
/// - returns: sourceString with the given literals replaced by `#`
|
|
private func stripLiterals(fromSourceString sourceString: String,
|
|
withDelimiter delimiter: String) -> String {
|
|
var modifiedString = sourceString
|
|
|
|
// While copy of content contains literal, replace with a single character
|
|
while modifiedString.contains("\(delimiter)(") {
|
|
if let rangeStart = modifiedString.range(of: "\(delimiter)("),
|
|
let rangeEnd = modifiedString.range(of: ")",
|
|
options: .literal,
|
|
range:
|
|
rangeStart.lowerBound..<modifiedString.endIndex) {
|
|
modifiedString.replaceSubrange(rangeStart.lowerBound..<rangeEnd.upperBound,
|
|
with: "#")
|
|
|
|
} else { // Should never be the case, but break to avoid accidental infinity loop
|
|
break
|
|
}
|
|
}
|
|
|
|
return modifiedString
|
|
}
|
|
|
|
}
|