Files
SwiftLint/Source/SwiftLintFramework/Rules/RuleConfigurations/RegexConfiguration.swift
T
JP Simard 34f429b0a3 Fix caching on Linux
This has never worked for two reasons:

1. We've used dictionaries to represent cache descriptions, which
   don't guarantee stable ordering of keys across invocations.
   This is true both on Darwin and Linux, but in practice ordering
   varies significantly more on Linux.
2. Storing a `TimeInterval` value in a `[String: Any]` dictionary
   and retrieving it again will not be dynamically castable to
   `Double` or `TimeInterval` but will be castable to `Int`.
2017-10-26 12:23:13 -07:00

97 lines
3.3 KiB
Swift

//
// RegexConfiguration.swift
// SwiftLint
//
// Created by Scott Hoyt on 1/21/16.
// Copyright © 2016 Realm. All rights reserved.
//
import Foundation
import SourceKittenFramework
public struct RegexConfiguration: RuleConfiguration, Equatable, CacheDescriptionProvider {
public let identifier: String
public var name: String?
public var message = "Regex matched."
public var regex: NSRegularExpression!
public var included: NSRegularExpression?
public var excluded: NSRegularExpression?
public var matchKinds = SyntaxKind.allKinds
public var severityConfiguration = SeverityConfiguration(.warning)
public var severity: ViolationSeverity {
return severityConfiguration.severity
}
public var consoleDescription: String {
return "\(severity.rawValue): \(regex.pattern)"
}
internal var cacheDescription: String {
let jsonObject: [String] = [
identifier,
name ?? "",
message,
regex.pattern,
included?.pattern ?? "",
excluded?.pattern ?? "",
matchKinds.map({ $0.rawValue }).sorted(by: <).joined(separator: ","),
severityConfiguration.consoleDescription
]
if let jsonData = try? JSONSerialization.data(withJSONObject: jsonObject),
let jsonString = String(data: jsonData, encoding: .utf8) {
return jsonString
}
queuedFatalError("Could not serialize regex configuration for cache")
}
public var description: RuleDescription {
return RuleDescription(identifier: identifier, name: name ?? identifier,
description: "", kind: .style)
}
public init(identifier: String) {
self.identifier = identifier
}
public mutating func apply(configuration: Any) throws {
guard let configurationDict = configuration as? [String: Any],
let regexString = configurationDict["regex"] as? String else {
throw ConfigurationError.unknownConfiguration
}
regex = try .cached(pattern: regexString)
if let includedString = configurationDict["included"] as? String {
included = try .cached(pattern: includedString)
}
if let excludedString = configurationDict["excluded"] as? String {
excluded = try .cached(pattern: excludedString)
}
if let name = configurationDict["name"] as? String {
self.name = name
}
if let message = configurationDict["message"] as? String {
self.message = message
}
if let matchKinds = [String].array(of: configurationDict["match_kinds"]) {
self.matchKinds = Set(try matchKinds.map({ try SyntaxKind(shortName: $0) }))
}
if let severityString = configurationDict["severity"] as? String {
try severityConfiguration.apply(configuration: severityString)
}
}
}
public func == (lhs: RegexConfiguration, rhs: RegexConfiguration) -> Bool {
return lhs.identifier == rhs.identifier &&
lhs.message == rhs.message &&
lhs.regex == rhs.regex &&
lhs.included?.pattern == rhs.included?.pattern &&
lhs.excluded?.pattern == rhs.excluded?.pattern &&
lhs.matchKinds == rhs.matchKinds &&
lhs.severity == rhs.severity
}