mirror of
https://github.com/realm/SwiftLint.git
synced 2026-05-07 20:12:49 +00:00
Adopt typed throws where possible (#5922)
This commit is contained in:
@@ -39,8 +39,6 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- macOS: '14'
|
||||
xcode: '15.4'
|
||||
- macOS: '15'
|
||||
xcode: '16.4'
|
||||
- macOS: '26'
|
||||
|
||||
+9
-9
@@ -47,15 +47,15 @@ struct DeploymentTargetConfiguration: SeverityBasedRuleConfiguration {
|
||||
self.patch = patch
|
||||
}
|
||||
|
||||
init(platform: Platform, value: Any) throws {
|
||||
init(platform: Platform, value: Any) throws(Issue) {
|
||||
let (major, minor, patch) = try Self.parseVersion(string: String(describing: value))
|
||||
self.init(platform: platform, major: major, minor: minor, patch: patch)
|
||||
}
|
||||
|
||||
private static func parseVersion(string: String) throws -> (Int, Int, Int) {
|
||||
func parseNumber(_ string: String) throws -> Int {
|
||||
private static func parseVersion(string: String) throws(Issue) -> (Int, Int, Int) {
|
||||
func parseNumber(_ string: String) throws(Issue) -> Int {
|
||||
guard let number = Int(string) else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
return number
|
||||
}
|
||||
@@ -63,7 +63,7 @@ struct DeploymentTargetConfiguration: SeverityBasedRuleConfiguration {
|
||||
let parts = string.components(separatedBy: ".")
|
||||
switch parts.count {
|
||||
case 0:
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
case 1:
|
||||
return (try parseNumber(parts[0]), 0, 0)
|
||||
case 2:
|
||||
@@ -118,9 +118,9 @@ struct DeploymentTargetConfiguration: SeverityBasedRuleConfiguration {
|
||||
}
|
||||
|
||||
// swiftlint:disable:next cyclomatic_complexity
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configuration = configuration as? [String: Any] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
for (key, value) in configuration {
|
||||
if key == "severity", let value = value as? String {
|
||||
@@ -144,14 +144,14 @@ struct DeploymentTargetConfiguration: SeverityBasedRuleConfiguration {
|
||||
try apply(value: value, to: \.tvOSDeploymentTarget, from: configuration)
|
||||
case tvOSAppExtensionDeploymentTarget.platform.configurationKey:
|
||||
tvOSAppExtensionDeploymentTarget = try Version(platform: .tvOSApplicationExtension, value: value)
|
||||
default: throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
default: throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private mutating func apply(value: Any,
|
||||
to target: WritableKeyPath<Self, Version>,
|
||||
from configuration: [String: Any]) throws {
|
||||
from configuration: [String: Any]) throws(Issue) {
|
||||
let platform = self[keyPath: target].platform
|
||||
self[keyPath: target] = try Version(platform: platform, value: value)
|
||||
if let counterpart = platform.appExtensionCounterpart,
|
||||
|
||||
+2
-2
@@ -11,11 +11,11 @@ struct ExpiringTodoConfiguration: RuleConfiguration {
|
||||
fileprivate(set) var opening: String
|
||||
fileprivate(set) var closing: String
|
||||
|
||||
init(fromAny value: Any, context ruleID: String) throws {
|
||||
init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
guard let dateDelimiters = value as? [String: String],
|
||||
let openingDelimiter = dateDelimiters["opening"],
|
||||
let closingDelimiter = dateDelimiters["closing"] else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
self.init(opening: openingDelimiter, closing: closingDelimiter)
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ struct FileHeaderConfiguration: SeverityBasedRuleConfiguration {
|
||||
|
||||
private static let defaultRegex = regex("\\bCopyright\\b", options: [.caseInsensitive])
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configuration = configuration as? [String: String] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
|
||||
// Cache the created regexes if possible.
|
||||
|
||||
+6
-6
@@ -31,9 +31,9 @@ struct MissingDocsConfiguration: RuleConfiguration {
|
||||
$evaluateEffectiveAccessControlLevel.key => .flag(evaluateEffectiveAccessControlLevel)
|
||||
}
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let dict = configuration as? [String: Any] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
|
||||
if let shouldExcludeExtensions = dict[$excludesExtensions.key] as? Bool {
|
||||
@@ -57,7 +57,7 @@ struct MissingDocsConfiguration: RuleConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private func parameters(from dict: [String: Any]) throws -> [RuleParameter<AccessControlLevel>]? {
|
||||
private func parameters(from dict: [String: Any]) throws(Issue) -> [RuleParameter<AccessControlLevel>]? {
|
||||
var parameters: [RuleParameter<AccessControlLevel>] = []
|
||||
|
||||
for (key, value) in dict {
|
||||
@@ -67,9 +67,9 @@ struct MissingDocsConfiguration: RuleConfiguration {
|
||||
|
||||
if let array = [String].array(of: value) {
|
||||
let rules: [RuleParameter<AccessControlLevel>] = try array
|
||||
.map { val -> RuleParameter<AccessControlLevel> in
|
||||
.map { val throws(Issue) -> RuleParameter<AccessControlLevel> in
|
||||
guard let acl = AccessControlLevel(description: val) else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
return RuleParameter<AccessControlLevel>(severity: severity, value: acl)
|
||||
}
|
||||
@@ -83,7 +83,7 @@ struct MissingDocsConfiguration: RuleConfiguration {
|
||||
}
|
||||
|
||||
guard parameters.count == parameters.map(\.value).unique.count else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
|
||||
return parameters.isNotEmpty ? parameters : nil
|
||||
|
||||
+2
-2
@@ -24,11 +24,11 @@ struct ModifierOrderConfiguration: SeverityBasedRuleConfiguration {
|
||||
}
|
||||
|
||||
extension SwiftDeclarationAttributeKind.ModifierGroup: AcceptableByConfigurationElement {
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
if let value = value as? String, let newSelf = Self(rawValue: value), newSelf != .atPrefixed {
|
||||
self = newSelf
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ struct MultilineParametersConfiguration: SeverityBasedRuleConfiguration {
|
||||
@ConfigurationElement(key: "max_number_of_single_line_parameters")
|
||||
private(set) var maxNumberOfSingleLineParameters: Int?
|
||||
|
||||
func validate() throws {
|
||||
func validate() throws(Issue) {
|
||||
guard let maxNumberOfSingleLineParameters else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -49,9 +49,9 @@ struct NameConfiguration<Parent: Rule>: RuleConfiguration, InlinableOptionType {
|
||||
self.validatesStartWithLowercase = validatesStartWithLowercase
|
||||
}
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configurationDict = configuration as? [String: Any] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
|
||||
if let minLengthConfiguration = configurationDict[$minLength.key] {
|
||||
|
||||
+2
-2
@@ -12,11 +12,11 @@ struct NumberSeparatorConfiguration: SeverityBasedRuleConfiguration {
|
||||
.symbol("\(min) ..< \(max)")
|
||||
}
|
||||
|
||||
init(fromAny value: Any, context ruleID: String) throws {
|
||||
init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
guard let values = value as? [String: Any],
|
||||
let min = values["min"] as? Double,
|
||||
let max = values["max"] as? Double else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
self.min = min
|
||||
self.max = max
|
||||
|
||||
+2
-2
@@ -30,9 +30,9 @@ struct RequiredEnumCaseConfiguration: RuleConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let config = configuration as? [String: [String: String]] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
|
||||
register(protocols: config)
|
||||
|
||||
+2
-2
@@ -8,13 +8,13 @@ struct TransitiveModuleConfiguration<Parent: Rule>: Equatable, AcceptableByConfi
|
||||
/// The set of modules that can be transitively imported by `importedModule`.
|
||||
let transitivelyImportedModules: [String]
|
||||
|
||||
init(fromAny configuration: Any, context _: String) throws {
|
||||
init(fromAny configuration: Any, context _: String) throws(Issue) {
|
||||
guard let configurationDict = configuration as? [String: Any],
|
||||
Set(configurationDict.keys) == ["module", "allowed_transitive_imports"],
|
||||
let importedModule = configurationDict["module"] as? String,
|
||||
let transitivelyImportedModules = configurationDict["allowed_transitive_imports"] as? [String]
|
||||
else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
self.importedModule = importedModule
|
||||
self.transitivelyImportedModules = transitivelyImportedModules
|
||||
|
||||
@@ -33,11 +33,11 @@ public struct RegularExpression: Hashable, Comparable, ExpressibleByStringLitera
|
||||
/// - Returns: A `RegularExpression` instance.
|
||||
public static func from(pattern: String,
|
||||
options: NSRegularExpression.Options? = nil,
|
||||
for ruleID: String) throws -> Self {
|
||||
for ruleID: String) throws(Issue) -> Self {
|
||||
do {
|
||||
return try Self(pattern: pattern, options: options)
|
||||
} catch {
|
||||
throw Issue.invalidRegexPattern(ruleID: ruleID, pattern: pattern)
|
||||
throw .invalidRegexPattern(ruleID: ruleID, pattern: pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,10 @@ public struct ChildOptionSeverityConfiguration<Parent: Rule>: RuleConfiguration,
|
||||
ViolationSeverity(rawValue: optionSeverity.rawValue)
|
||||
}
|
||||
|
||||
public mutating func apply(configuration: Any) throws {
|
||||
public mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configString = configuration as? String,
|
||||
let optionSeverity = ChildOptionSeverity(rawValue: configString.lowercased()) else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
self.optionSeverity = optionSeverity
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ public protocol AcceptableByConfigurationElement {
|
||||
/// - Parameters:
|
||||
/// - value: Value from a configuration.
|
||||
/// - ruleID: The rule's identifier in which context the configuration parsing runs.
|
||||
init(fromAny value: Any, context ruleID: String) throws
|
||||
init(fromAny value: Any, context ruleID: String) throws(Issue)
|
||||
|
||||
/// Make the object an option.
|
||||
///
|
||||
@@ -337,7 +337,7 @@ public protocol AcceptableByConfigurationElement {
|
||||
/// - Parameters:
|
||||
/// - value: New underlying data for the object.
|
||||
/// - ruleID: The rule's identifier in which context the configuration parsing runs.
|
||||
mutating func apply(_ value: Any, ruleID: String) throws
|
||||
mutating func apply(_ value: Any, ruleID: String) throws(Issue)
|
||||
}
|
||||
|
||||
/// Default implementations which are shortcuts applicable for most of the types conforming to the protocol.
|
||||
@@ -346,7 +346,7 @@ public extension AcceptableByConfigurationElement {
|
||||
RuleConfigurationDescription(options: [key => asOption()])
|
||||
}
|
||||
|
||||
mutating func apply(_ value: Any, ruleID: String) throws {
|
||||
mutating func apply(_ value: Any, ruleID: String) throws(Issue) {
|
||||
self = try Self(fromAny: value, context: ruleID)
|
||||
}
|
||||
}
|
||||
@@ -537,7 +537,7 @@ extension Optional: AcceptableByConfigurationElement where Wrapped: AcceptableBy
|
||||
self?.asOption() ?? .empty
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
self = try Wrapped(fromAny: value, context: ruleID)
|
||||
}
|
||||
}
|
||||
@@ -549,9 +549,9 @@ struct Symbol: Equatable, AcceptableByConfigurationElement {
|
||||
.symbol(value)
|
||||
}
|
||||
|
||||
init(fromAny value: Any, context ruleID: String) throws {
|
||||
init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
guard let value = value as? String else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
self.value = value
|
||||
}
|
||||
@@ -562,9 +562,9 @@ extension Bool: AcceptableByConfigurationElement {
|
||||
.flag(self)
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
guard let value = value as? Self else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
self = value
|
||||
}
|
||||
@@ -575,9 +575,9 @@ extension String: AcceptableByConfigurationElement {
|
||||
.string(self)
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
guard let value = value as? Self else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
self = value
|
||||
}
|
||||
@@ -588,9 +588,11 @@ extension Array: AcceptableByConfigurationElement where Element: AcceptableByCon
|
||||
.list(map { $0.asOption() })
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
let values = value as? [Any] ?? [value]
|
||||
self = try values.map { try Element(fromAny: $0, context: ruleID) }
|
||||
self = try values.map { value throws(Issue) in
|
||||
try Element(fromAny: value, context: ruleID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,7 +601,7 @@ extension Set: AcceptableByConfigurationElement where Element: AcceptableByConfi
|
||||
sorted().asOption()
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
self = Set(try [Element].init(fromAny: value, context: ruleID))
|
||||
}
|
||||
}
|
||||
@@ -609,9 +611,9 @@ extension Int: AcceptableByConfigurationElement {
|
||||
.integer(self)
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
guard let value = value as? Self else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
self = value
|
||||
}
|
||||
@@ -622,13 +624,13 @@ extension Double: AcceptableByConfigurationElement {
|
||||
.float(self)
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
if let value = value as? Self {
|
||||
self = value
|
||||
} else if let value = value as? Int {
|
||||
self = Double(value)
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -638,11 +640,11 @@ extension RegularExpression: AcceptableByConfigurationElement {
|
||||
.string(pattern)
|
||||
}
|
||||
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
guard let value = value as? String else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
self = try Self(pattern: value)
|
||||
self = try .from(pattern: value, for: ruleID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,12 +662,12 @@ public extension AcceptableByConfigurationElement where Self: RuleConfiguration
|
||||
return RuleConfigurationDescription(options: [key => asOption()])
|
||||
}
|
||||
|
||||
mutating func apply(_ value: Any, ruleID _: String) throws {
|
||||
mutating func apply(_ value: Any, ruleID _: String) throws(Issue) {
|
||||
try apply(configuration: value)
|
||||
}
|
||||
|
||||
init(fromAny _: Any, context _: String) throws {
|
||||
throw Issue.genericError("Do not call this initializer")
|
||||
init(fromAny _: Any, context _: String) throws(Issue) {
|
||||
throw .genericError("Do not call this initializer")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,13 +40,14 @@ public struct RuleList {
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
package func allRulesWrapped(configurationDict: [String: Any] = [:]) throws -> [ConfigurationRuleWrapper] {
|
||||
package func allRulesWrapped(configurationDict: [String: Any] = [:])
|
||||
throws(RuleListError) -> [ConfigurationRuleWrapper] {
|
||||
var rules = [String: ConfigurationRuleWrapper]()
|
||||
|
||||
// Add rules where configuration exists
|
||||
for (key, configuration) in configurationDict {
|
||||
guard let identifier = identifier(for: key), let ruleType = list[identifier] else { continue }
|
||||
guard rules[identifier] == nil else { throw RuleListError.duplicatedConfigurations(rule: ruleType) }
|
||||
guard rules[identifier] == nil else { throw .duplicatedConfigurations(rule: ruleType) }
|
||||
do {
|
||||
let configuredRule = try ruleType.init(configuration: configuration)
|
||||
let isConfigured = (configuration as? [String: Any])?.isEmpty == false
|
||||
|
||||
@@ -19,17 +19,17 @@ public struct SeverityConfiguration<Parent: Rule>: SeverityBasedRuleConfiguratio
|
||||
self.severity = severity
|
||||
}
|
||||
|
||||
public mutating func apply(configuration: Any) throws {
|
||||
public mutating func apply(configuration: Any) throws(Issue) {
|
||||
let configString = configuration as? String
|
||||
let configDict = configuration as? [String: Any]
|
||||
if let severityString: String = configString ?? configDict?[$severity.key] as? String {
|
||||
if let severity = ViolationSeverity(rawValue: severityString.lowercased()) {
|
||||
self.severity = severity
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
} else {
|
||||
throw Issue.nothingApplied(ruleID: Parent.identifier)
|
||||
throw .nothingApplied(ruleID: Parent.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ public protocol RuleConfiguration: Equatable, Sendable {
|
||||
/// - parameter configuration: The untyped configuration value to apply.
|
||||
///
|
||||
/// - throws: Throws if the configuration is not in the expected format.
|
||||
mutating func apply(configuration: Any) throws
|
||||
mutating func apply(configuration: Any) throws(Issue)
|
||||
|
||||
/// Run a sanity check on the configuration, perform optional postprocessing steps and/or warn about potential
|
||||
/// issues.
|
||||
mutating func validate() throws
|
||||
mutating func validate() throws(Issue)
|
||||
}
|
||||
|
||||
/// A configuration for a rule that allows to configure at least the severity.
|
||||
@@ -35,7 +35,7 @@ public extension SeverityBasedRuleConfiguration {
|
||||
public extension RuleConfiguration {
|
||||
var parameterDescription: RuleConfigurationDescription? { nil }
|
||||
|
||||
func validate() throws {
|
||||
func validate() throws(Issue) {
|
||||
// Do nothing by default.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,10 +70,10 @@ public struct RegexConfiguration<Parent: Rule>: SeverityBasedRuleConfiguration,
|
||||
}
|
||||
|
||||
// swiftlint:disable:next cyclomatic_complexity
|
||||
public mutating func apply(configuration: Any) throws {
|
||||
public mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configurationDict = configuration as? [String: Any],
|
||||
let regexString = configurationDict[$regex.key] as? String else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
|
||||
regex = try .from(pattern: regexString, for: Parent.identifier)
|
||||
@@ -81,7 +81,7 @@ public struct RegexConfiguration<Parent: Rule>: SeverityBasedRuleConfiguration,
|
||||
if let includedString = configurationDict["included"] as? String {
|
||||
included = [try .from(pattern: includedString, for: Parent.identifier)]
|
||||
} else if let includedArray = configurationDict["included"] as? [String] {
|
||||
included = try includedArray.map { pattern in
|
||||
included = try includedArray.map { pattern throws(Issue) in
|
||||
try .from(pattern: pattern, for: Parent.identifier)
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public struct RegexConfiguration<Parent: Rule>: SeverityBasedRuleConfiguration,
|
||||
if let excludedString = configurationDict["excluded"] as? String {
|
||||
excluded = [try .from(pattern: excludedString, for: Parent.identifier)]
|
||||
} else if let excludedArray = configurationDict["excluded"] as? [String] {
|
||||
excluded = try excludedArray.map { pattern in
|
||||
excluded = try excludedArray.map { pattern throws(Issue) in
|
||||
try .from(pattern: pattern, for: Parent.identifier)
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ public struct RegexConfiguration<Parent: Rule>: SeverityBasedRuleConfiguration,
|
||||
}
|
||||
if let captureGroup = configurationDict["capture_group"] as? Int {
|
||||
guard (0 ... regex.numberOfCaptureGroups).contains(captureGroup) else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
self.captureGroup = captureGroup
|
||||
}
|
||||
@@ -140,7 +140,7 @@ public struct RegexConfiguration<Parent: Rule>: SeverityBasedRuleConfiguration,
|
||||
}
|
||||
}
|
||||
|
||||
private func excludedMatchKinds(from configurationDict: [String: Any]) throws -> Set<SyntaxKind> {
|
||||
private func excludedMatchKinds(from configurationDict: [String: Any]) throws(Issue) -> Set<SyntaxKind> {
|
||||
let matchKinds = [String].array(of: configurationDict["match_kinds"])
|
||||
let excludedMatchKinds = [String].array(of: configurationDict["excluded_match_kinds"])
|
||||
|
||||
@@ -152,18 +152,18 @@ public struct RegexConfiguration<Parent: Rule>: SeverityBasedRuleConfiguration,
|
||||
case (nil, nil):
|
||||
return .init()
|
||||
case (.some, .some):
|
||||
throw Issue.genericWarning(
|
||||
throw .genericWarning(
|
||||
"The configuration keys 'match_kinds' and 'excluded_match_kinds' cannot appear at the same time."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func toSyntaxKinds(_ names: [String]) throws -> Set<SyntaxKind> {
|
||||
let kinds = try names.map {
|
||||
if let kind = SyntaxKind(shortName: $0) {
|
||||
private func toSyntaxKinds(_ names: [String]) throws(Issue) -> Set<SyntaxKind> {
|
||||
let kinds = try names.map { name throws(Issue) in
|
||||
if let kind = SyntaxKind(shortName: name) {
|
||||
return kind
|
||||
}
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
return Set(kinds)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public struct SeverityLevelsConfiguration<Parent: Rule>: RuleConfiguration, Inli
|
||||
return [RuleParameter(severity: .warning, value: warning)]
|
||||
}
|
||||
|
||||
public mutating func apply(configuration: Any) throws {
|
||||
public mutating func apply(configuration: Any) throws(Issue) {
|
||||
if let configurationArray = [Int].array(of: configuration), configurationArray.isNotEmpty {
|
||||
warning = configurationArray[0]
|
||||
error = (configurationArray.count > 1) ? configurationArray[1] : nil
|
||||
@@ -37,7 +37,7 @@ public struct SeverityLevelsConfiguration<Parent: Rule>: RuleConfiguration, Inli
|
||||
if let warning = warningValue as? Int {
|
||||
self.warning = warning
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
}
|
||||
if let errorValue = configDict[$error.key] {
|
||||
@@ -46,13 +46,13 @@ public struct SeverityLevelsConfiguration<Parent: Rule>: RuleConfiguration, Inli
|
||||
} else if let error = errorValue as? Int {
|
||||
self.error = error
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
} else if warningValue != nil {
|
||||
self.error = nil
|
||||
}
|
||||
} else {
|
||||
throw Issue.nothingApplied(ruleID: Parent.identifier)
|
||||
throw .nothingApplied(ruleID: Parent.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ enum AutoConfigParser: MemberMacro {
|
||||
}
|
||||
}
|
||||
return [
|
||||
DeclSyntax(try FunctionDeclSyntax("mutating func apply(configuration: Any) throws") {
|
||||
DeclSyntax(try FunctionDeclSyntax("mutating func apply(configuration: Any) throws(Issue)") {
|
||||
for option in nonInlinedOptions {
|
||||
"""
|
||||
if $\(raw: option).key.isEmpty {
|
||||
@@ -61,7 +61,7 @@ enum AutoConfigParser: MemberMacro {
|
||||
"""
|
||||
do {
|
||||
try \(raw: option).apply(configuration, ruleID: Parent.identifier)
|
||||
} catch let issue as Issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
} catch let issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
// Acceptable. Continue.
|
||||
}
|
||||
"""
|
||||
@@ -69,7 +69,7 @@ enum AutoConfigParser: MemberMacro {
|
||||
"""
|
||||
guard let configuration = configuration as? [String: Any] else {
|
||||
\(raw: inlinedOptions.isEmpty
|
||||
? "throw Issue.invalidConfiguration(ruleID: Parent.identifier)"
|
||||
? "throw .invalidConfiguration(ruleID: Parent.identifier)"
|
||||
: "return")
|
||||
}
|
||||
"""
|
||||
@@ -115,11 +115,11 @@ enum AcceptableByConfigurationElement: ExtensionMacro {
|
||||
try ExtensionDeclSyntax("""
|
||||
extension \(type): AcceptableByConfigurationElement {
|
||||
\(raw: accessLevel)func asOption() -> OptionType { .symbol(rawValue) }
|
||||
\(raw: accessLevel)init(fromAny value: Any, context ruleID: String) throws {
|
||||
\(raw: accessLevel)init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
if let value = value as? String, let newSelf = Self(rawValue: value) {
|
||||
self = newSelf
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ private actor CounterActor {
|
||||
}
|
||||
}
|
||||
|
||||
private func readFilesFromScriptInputFiles() throws -> [SwiftLintFile] {
|
||||
private func readFilesFromScriptInputFiles() throws(SwiftLintError) -> [SwiftLintFile] {
|
||||
let count = try fileCount(from: "SCRIPT_INPUT_FILE_COUNT")
|
||||
return (0..<count).compactMap { fileNumber in
|
||||
do {
|
||||
@@ -31,7 +31,7 @@ private func readFilesFromScriptInputFiles() throws -> [SwiftLintFile] {
|
||||
}
|
||||
}
|
||||
|
||||
private func readFilesFromScriptInputFileLists() throws -> [SwiftLintFile] {
|
||||
private func readFilesFromScriptInputFileLists() throws(SwiftLintError) -> [SwiftLintFile] {
|
||||
let count = try fileCount(from: "SCRIPT_INPUT_FILE_LIST_COUNT")
|
||||
return (0..<count).flatMap { fileNumber in
|
||||
var filesToLint: [SwiftLintFile] = []
|
||||
@@ -59,12 +59,12 @@ private func readFilesFromScriptInputFileLists() throws -> [SwiftLintFile] {
|
||||
}
|
||||
}
|
||||
|
||||
private func fileCount(from envVar: String) throws -> Int {
|
||||
private func fileCount(from envVar: String) throws(SwiftLintError) -> Int {
|
||||
guard let countString = ProcessInfo.processInfo.environment[envVar] else {
|
||||
throw SwiftLintError.usageError(description: "\(envVar) variable not set")
|
||||
throw .usageError(description: "\(envVar) variable not set")
|
||||
}
|
||||
guard let count = Int(countString) else {
|
||||
throw SwiftLintError.usageError(description: "\(envVar) did not specify a number")
|
||||
throw .usageError(description: "\(envVar) did not specify a number")
|
||||
}
|
||||
return count
|
||||
}
|
||||
@@ -103,10 +103,10 @@ extension Configuration {
|
||||
return result.flatMap { $0 }
|
||||
}
|
||||
|
||||
private func groupFiles(_ files: [SwiftLintFile], visitor: LintableFilesVisitor) throws
|
||||
private func groupFiles(_ files: [SwiftLintFile], visitor: LintableFilesVisitor) throws(SwiftLintError)
|
||||
-> [Configuration: [SwiftLintFile]] {
|
||||
if files.isEmpty, !visitor.allowZeroLintableFiles {
|
||||
throw SwiftLintError.usageError(
|
||||
throw .usageError(
|
||||
description: "No lintable files found at paths: '\(visitor.options.paths.joined(separator: ", "))'"
|
||||
)
|
||||
}
|
||||
@@ -236,14 +236,14 @@ extension Configuration {
|
||||
linters.asyncMap(visit)
|
||||
}
|
||||
|
||||
fileprivate func getFiles(with visitor: LintableFilesVisitor) throws -> [SwiftLintFile] {
|
||||
fileprivate func getFiles(with visitor: LintableFilesVisitor) throws(SwiftLintError) -> [SwiftLintFile] {
|
||||
let options = visitor.options
|
||||
if options.useSTDIN {
|
||||
let stdinData = FileHandle.standardInput.readDataToEndOfFile()
|
||||
if let stdinString = String(data: stdinData, encoding: .utf8) {
|
||||
return [SwiftLintFile(contents: stdinString)]
|
||||
}
|
||||
throw SwiftLintError.usageError(description: "stdin isn't a UTF8-encoded string")
|
||||
throw .usageError(description: "stdin isn't a UTF8-encoded string")
|
||||
}
|
||||
if options.useScriptInputFiles || options.useScriptInputFileLists {
|
||||
let files = try options.useScriptInputFiles
|
||||
|
||||
@@ -119,10 +119,11 @@ struct LintableFilesVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static func loadCompilerInvocations(_ options: LintOrAnalyzeOptions) throws -> CompilerInvocations {
|
||||
private static func loadCompilerInvocations(_ options: LintOrAnalyzeOptions)
|
||||
throws(SwiftLintError) -> CompilerInvocations {
|
||||
if let path = options.compilerLogPath {
|
||||
guard let compilerInvocations = self.loadLogCompilerInvocations(path) else {
|
||||
throw SwiftLintError.usageError(description: "Could not read compiler log at path: '\(path)'")
|
||||
throw .usageError(description: "Could not read compiler log at path: '\(path)'")
|
||||
}
|
||||
|
||||
return .buildLog(compilerInvocations: compilerInvocations)
|
||||
@@ -131,13 +132,13 @@ struct LintableFilesVisitor {
|
||||
do {
|
||||
return .compilationDatabase(compileCommands: try self.loadCompileCommands(path))
|
||||
} catch {
|
||||
throw SwiftLintError.usageError(
|
||||
throw .usageError(
|
||||
description: "Could not read compilation database at path: '\(path)' \(error.localizedDescription)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
throw SwiftLintError.usageError(description: "Could not read compiler invocations")
|
||||
throw .usageError(description: "Could not read compiler invocations")
|
||||
}
|
||||
|
||||
private static func loadLogCompilerInvocations(_ path: String) -> [[String]]? {
|
||||
|
||||
@@ -20,9 +20,9 @@ struct CustomRulesConfiguration: RuleConfiguration, CacheDescriptionProvider {
|
||||
var customRuleConfigurations = [RegexConfiguration<Parent>]()
|
||||
var defaultExecutionMode: RegexConfiguration<Parent>.ExecutionMode?
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configurationDict = configuration as? [String: Any] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
|
||||
// Parse default execution mode if present
|
||||
|
||||
@@ -22,11 +22,11 @@ extension SwiftLint {
|
||||
@Argument(help: "The rule identifier to display description for")
|
||||
var ruleID: String?
|
||||
|
||||
func run() throws {
|
||||
func run() throws(SwiftLintError) {
|
||||
let configuration = Configuration(configurationFiles: [config].compactMap({ $0 }))
|
||||
if let ruleID {
|
||||
guard let rule = RuleRegistry.shared.rule(forID: ruleID) else {
|
||||
throw SwiftLintError.usageError(description: "No rule with identifier: \(ruleID)")
|
||||
throw .usageError(description: "No rule with identifier: \(ruleID)")
|
||||
}
|
||||
printDescription(for: rule, with: configuration)
|
||||
return
|
||||
|
||||
@@ -233,7 +233,7 @@ final class RuleConfigurationDescriptionTests: SwiftLintTestCase {
|
||||
@ConfigurationElement(key: "invisible")
|
||||
var invisible = true
|
||||
|
||||
mutating func apply(configuration _: Any) throws { /* conformance for test */ }
|
||||
mutating func apply(configuration _: Any) throws(Issue) { /* conformance for test */ }
|
||||
|
||||
func isEqualTo(_: some RuleConfiguration) -> Bool { false }
|
||||
}
|
||||
|
||||
@@ -59,11 +59,11 @@ final class AcceptableByConfigurationElementTests: XCTestCase {
|
||||
private func asOption() -> OptionType {
|
||||
.symbol(rawValue)
|
||||
}
|
||||
private init(fromAny value: Any, context ruleID: String) throws {
|
||||
private init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
if let value = value as? String, let newSelf = Self(rawValue: value) {
|
||||
self = newSelf
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,11 +87,11 @@ final class AcceptableByConfigurationElementTests: XCTestCase {
|
||||
public func asOption() -> OptionType {
|
||||
.symbol(rawValue)
|
||||
}
|
||||
public init(fromAny value: Any, context ruleID: String) throws {
|
||||
public init(fromAny value: Any, context ruleID: String) throws(Issue) {
|
||||
if let value = value as? String, let newSelf = Self(rawValue: value) {
|
||||
self = newSelf
|
||||
} else {
|
||||
throw Issue.invalidConfiguration(ruleID: ruleID)
|
||||
throw .invalidConfiguration(ruleID: ruleID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
"""
|
||||
struct S {
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configuration = configuration as? [String: Any] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
if !supportedKeys.isSuperset(of: configuration.keys) {
|
||||
let unknownKeys = Set(configuration.keys).subtracting(supportedKeys)
|
||||
@@ -71,7 +71,7 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
@ConfigurationElement(key: "name")
|
||||
var eB = 2
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
if $eA.key.isEmpty {
|
||||
$eA.key = "e_a"
|
||||
}
|
||||
@@ -79,7 +79,7 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
$eB.key = "e_b"
|
||||
}
|
||||
guard let configuration = configuration as? [String: Any] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
if let value = configuration[$eA.key] {
|
||||
try eA.apply(value, ruleID: Parent.identifier)
|
||||
@@ -122,7 +122,7 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
@ConfigurationElement(inline: false)
|
||||
var eC = 3
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
if $eA.key.isEmpty {
|
||||
$eA.key = "e_a"
|
||||
}
|
||||
@@ -131,7 +131,7 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
try eB.apply(configuration, ruleID: Parent.identifier)
|
||||
} catch let issue as Issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
} catch let issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
// Acceptable. Continue.
|
||||
}
|
||||
guard let configuration = configuration as? [String: Any] else {
|
||||
@@ -166,9 +166,9 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
"""
|
||||
struct S: SeverityBasedRuleConfiguration {
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
guard let configuration = configuration as? [String: Any] else {
|
||||
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
|
||||
throw .invalidConfiguration(ruleID: Parent.identifier)
|
||||
}
|
||||
if !supportedKeys.isSuperset(of: configuration.keys) {
|
||||
let unknownKeys = Set(configuration.keys).subtracting(supportedKeys)
|
||||
@@ -207,7 +207,7 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
@ConfigurationElement
|
||||
var foo = 2
|
||||
|
||||
mutating func apply(configuration: Any) throws {
|
||||
mutating func apply(configuration: Any) throws(Issue) {
|
||||
if $severityConfiguration.key.isEmpty {
|
||||
$severityConfiguration.key = "severity_configuration"
|
||||
}
|
||||
@@ -216,7 +216,7 @@ final class AutoConfigParserTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
try severityConfiguration.apply(configuration, ruleID: Parent.identifier)
|
||||
} catch let issue as Issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
} catch let issue where issue == Issue.nothingApplied(ruleID: Parent.identifier) {
|
||||
// Acceptable. Continue.
|
||||
}
|
||||
guard let configuration = configuration as? [String: Any] else {
|
||||
|
||||
Reference in New Issue
Block a user