Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt typed throws where possible #5922

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ 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)
}
Expand All @@ -56,18 +56,18 @@ struct DeploymentTargetConfiguration: SeverityBasedRuleConfiguration {
platform.configurationKey
}

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
}

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:
Expand Down Expand Up @@ -122,9 +122,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 {
Expand All @@ -148,14 +148,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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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)
}
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
48 changes: 25 additions & 23 deletions Source/SwiftLintCore/Models/RuleConfigurationDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand All @@ -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.
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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
}
Expand All @@ -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
}
Expand All @@ -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
}
Expand All @@ -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)
}
}
}

Expand All @@ -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))
}
}
Expand All @@ -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
}
Expand All @@ -622,9 +624,9 @@ extension Double: AcceptableByConfigurationElement {
.float(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
}
Expand All @@ -635,11 +637,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)
}
}

Expand All @@ -657,12 +659,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")
}
}

Expand Down
5 changes: 3 additions & 2 deletions Source/SwiftLintCore/Models/RuleList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading