mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
2bcea4b04d
* Add LintableFilesVisitor * Move LintCommand logic into LintOrAnalyzeCommand to prepare for the upcoming analyze command * Add AnalyzeCommand (not fully implemented yet in SwiftLintFramework) * Add analyzerRules configuration member * Add AnalyzerRule protocol * Pass compiler arguments to validate/correct * Add requiresFileOnDisk member to RuleDescription This will be used by AnalyzerRules because they need a file on disk to pass in the compiler arguments to SourceKit. * Exclusively run AnalyzerRules when the Linter has compiler arguments * Enable testing AnalyzerRules in TestHelpers * Add ExplicitSelfRule * Update documentation * Fix `analyze --autocorrect` * Improve performance of CompilerArgumentsExtractor * Fix lint command actually running analyze * Move File operations in TestHelpers into a private extension * Add analyzer column to rules command and markdown documentation * Use a Set literal * Make AnalyzerRule inherit from OptInRule * Mention analyzer_rules in readme * Mention that analyzer rules are slow
92 lines
2.6 KiB
Swift
92 lines
2.6 KiB
Swift
import SourceKittenFramework
|
|
|
|
public protocol Rule {
|
|
static var description: RuleDescription { get }
|
|
var configurationDescription: String { get }
|
|
|
|
init() // Rules need to be able to be initialized with default values
|
|
init(configuration: Any) throws
|
|
|
|
func validate(file: File, compilerArguments: [String]) -> [StyleViolation]
|
|
func validate(file: File) -> [StyleViolation]
|
|
func isEqualTo(_ rule: Rule) -> Bool
|
|
}
|
|
|
|
extension Rule {
|
|
public func validate(file: File, compilerArguments: [String]) -> [StyleViolation] {
|
|
return validate(file: file)
|
|
}
|
|
|
|
public func isEqualTo(_ rule: Rule) -> Bool {
|
|
return type(of: self).description == type(of: rule).description
|
|
}
|
|
|
|
internal var cacheDescription: String {
|
|
return (self as? CacheDescriptionProvider)?.cacheDescription ?? configurationDescription
|
|
}
|
|
}
|
|
|
|
public protocol OptInRule: Rule {}
|
|
|
|
public protocol AutomaticTestableRule: Rule {}
|
|
|
|
public protocol ConfigurationProviderRule: Rule {
|
|
associatedtype ConfigurationType: RuleConfiguration
|
|
|
|
var configuration: ConfigurationType { get set }
|
|
}
|
|
|
|
public protocol CorrectableRule: Rule {
|
|
func correct(file: File, compilerArguments: [String]) -> [Correction]
|
|
func correct(file: File) -> [Correction]
|
|
}
|
|
|
|
public extension CorrectableRule {
|
|
func correct(file: File, compilerArguments: [String]) -> [Correction] {
|
|
return correct(file: file)
|
|
}
|
|
}
|
|
|
|
public protocol SourceKitFreeRule: Rule {}
|
|
|
|
public protocol AnalyzerRule: OptInRule {}
|
|
|
|
public extension AnalyzerRule {
|
|
func validate(file: File) -> [StyleViolation] {
|
|
queuedFatalError("Must call `validate(file:compilerArguments:)` for AnalyzerRule")
|
|
}
|
|
}
|
|
|
|
public extension AnalyzerRule where Self: CorrectableRule {
|
|
func correct(file: File) -> [Correction] {
|
|
queuedFatalError("Must call `correct(file:compilerArguments:)` for AnalyzerRule")
|
|
}
|
|
}
|
|
|
|
// MARK: - ConfigurationProviderRule conformance to Configurable
|
|
|
|
public extension ConfigurationProviderRule {
|
|
init(configuration: Any) throws {
|
|
self.init()
|
|
try self.configuration.apply(configuration: configuration)
|
|
}
|
|
|
|
func isEqualTo(_ rule: Rule) -> Bool {
|
|
if let rule = rule as? Self {
|
|
return configuration.isEqualTo(rule.configuration)
|
|
}
|
|
return false
|
|
}
|
|
|
|
var configurationDescription: String {
|
|
return configuration.consoleDescription
|
|
}
|
|
}
|
|
|
|
// MARK: - == Implementations
|
|
|
|
public func == (lhs: [Rule], rhs: [Rule]) -> Bool {
|
|
if lhs.count != rhs.count { return false }
|
|
return !zip(lhs, rhs).contains { !$0.0.isEqualTo($0.1) }
|
|
}
|