mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
* Add Example wrapper in order to display test failures inline when running in Xcode. * Stop using Swift 5.1-only features so we can compile on Xcode 10.2. * Wrap strings in Example. * Add Changelog entry. * Wrap all examples in Example struct. * Better and more complete capturing of line numbers. * Fix broken test. * Better test traceability. * Address or disable linting warnings. * Add documentation comments. * Disable linter for a few cases. * Limit mutability and add copy-and-mutate utility functions. * Limit scope of mutability.
52 lines
2.1 KiB
Swift
52 lines
2.1 KiB
Swift
import Foundation
|
|
import SourceKittenFramework
|
|
|
|
public struct LeadingWhitespaceRule: CorrectableRule, ConfigurationProviderRule, SourceKitFreeRule {
|
|
public var configuration = SeverityConfiguration(.warning)
|
|
|
|
public init() {}
|
|
|
|
public static let description = RuleDescription(
|
|
identifier: "leading_whitespace",
|
|
name: "Leading Whitespace",
|
|
description: "Files should not contain leading whitespace.",
|
|
kind: .style,
|
|
nonTriggeringExamples: [ Example("//\n") ],
|
|
triggeringExamples: [ Example("\n"), Example(" //\n") ],
|
|
corrections: [Example("\n //"): Example("//")]
|
|
)
|
|
|
|
public func validate(file: SwiftLintFile) -> [StyleViolation] {
|
|
let countOfLeadingWhitespace = file.contents.countOfLeadingCharacters(in: .whitespacesAndNewlines)
|
|
if countOfLeadingWhitespace == 0 {
|
|
return []
|
|
}
|
|
|
|
let reason = "File shouldn't start with whitespace: " +
|
|
"currently starts with \(countOfLeadingWhitespace) whitespace characters"
|
|
|
|
return [StyleViolation(ruleDescription: type(of: self).description,
|
|
severity: configuration.severity,
|
|
location: Location(file: file.path, line: 1),
|
|
reason: reason)]
|
|
}
|
|
|
|
public func correct(file: SwiftLintFile) -> [Correction] {
|
|
let whitespaceAndNewline = CharacterSet.whitespacesAndNewlines
|
|
let spaceCount = file.contents.countOfLeadingCharacters(in: whitespaceAndNewline)
|
|
guard spaceCount > 0,
|
|
let firstLineRange = file.lines.first?.range,
|
|
!file.ruleEnabled(violatingRanges: [firstLineRange], for: self).isEmpty else {
|
|
return []
|
|
}
|
|
|
|
let indexEnd = file.contents.index(
|
|
file.contents.startIndex,
|
|
offsetBy: spaceCount,
|
|
limitedBy: file.contents.endIndex) ?? file.contents.endIndex
|
|
file.write(String(file.contents[indexEnd...]))
|
|
let location = Location(file: file.path, line: max(file.lines.count, 1))
|
|
return [Correction(ruleDescription: type(of: self).description, location: location)]
|
|
}
|
|
}
|