mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
fcf848608e
* 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.
82 lines
2.9 KiB
Swift
82 lines
2.9 KiB
Swift
import SourceKittenFramework
|
|
|
|
public struct EnumCaseAssociatedValuesLengthRule: ASTRule, OptInRule, ConfigurationProviderRule, AutomaticTestableRule {
|
|
public var configuration = SeverityLevelsConfiguration(warning: 5, error: 6)
|
|
|
|
public init() {}
|
|
|
|
public static let description = RuleDescription(
|
|
identifier: "enum_case_associated_values_count",
|
|
name: "Enum Case Associated Values Count",
|
|
description: "Number of associated values in an enum case should be low",
|
|
kind: .metrics,
|
|
nonTriggeringExamples: [
|
|
Example("""
|
|
enum Employee {
|
|
case fullTime(name: String, retirement: Date, designation: String, contactNumber: Int)
|
|
case partTime(name: String, age: Int, contractEndDate: Date)
|
|
}
|
|
"""),
|
|
Example("""
|
|
enum Barcode {
|
|
case upc(Int, Int, Int, Int)
|
|
}
|
|
""")
|
|
],
|
|
triggeringExamples: [
|
|
Example("""
|
|
enum Employee {
|
|
case ↓fullTime(name: String, retirement: Date, age: Int, designation: String, contactNumber: Int)
|
|
case ↓partTime(name: String, contractEndDate: Date, age: Int, designation: String, contactNumber: Int)
|
|
}
|
|
"""),
|
|
Example("""
|
|
enum Barcode {
|
|
case ↓upc(Int, Int, Int, Int, Int, Int)
|
|
}
|
|
""")
|
|
]
|
|
)
|
|
|
|
public func validate(
|
|
file: SwiftLintFile,
|
|
kind: SwiftDeclarationKind,
|
|
dictionary: SourceKittenDictionary
|
|
) -> [StyleViolation] {
|
|
guard kind == .enumelement,
|
|
let keyOffset = dictionary.offset,
|
|
let keyName = dictionary.name,
|
|
let caseNameWithoutParams = keyName.split(separator: "(").first else {
|
|
return []
|
|
}
|
|
|
|
var violations: [StyleViolation] = []
|
|
|
|
let enumCaseAssociatedValueCount = keyName.split(separator: ":").count - 1
|
|
|
|
if enumCaseAssociatedValueCount >= configuration.warning {
|
|
let violationSeverity: ViolationSeverity
|
|
|
|
if let errorConfig = configuration.error,
|
|
enumCaseAssociatedValueCount >= errorConfig {
|
|
violationSeverity = .error
|
|
} else {
|
|
violationSeverity = .warning
|
|
}
|
|
|
|
let reason = "Enum case \(caseNameWithoutParams) should contain "
|
|
+ "less than \(configuration.warning) associated values: "
|
|
+ "currently contains \(enumCaseAssociatedValueCount)"
|
|
violations.append(
|
|
StyleViolation(
|
|
ruleDescription: type(of: self).description,
|
|
severity: violationSeverity,
|
|
location: Location(file: file, byteOffset: keyOffset),
|
|
reason: reason
|
|
)
|
|
)
|
|
}
|
|
return violations
|
|
}
|
|
}
|