Skip to content

Commit

Permalink
Refactor EquatableMacroInfo type
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklockwood committed Nov 26, 2024
1 parent 6e36f09 commit f36187b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 24 deletions.
4 changes: 2 additions & 2 deletions Sources/OptionDescriptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1247,11 +1247,11 @@ struct _Descriptors {
help: "Sort SwiftUI props: none, alphabetize, first-appearance-sort",
keyPath: \.swiftUIPropertiesSortMode
)
let equatableMacroInfo = OptionDescriptor(
let equatableMacro = OptionDescriptor(
argumentName: "equatablemacro",
displayName: "The name and module of an Equatable conformance macro",
help: "For example: \"@Equatable,EquatableMacroLib\"",
keyPath: \.equatableMacroInfo
keyPath: \.equatableMacro
)
let preferFileMacro = OptionDescriptor(
argumentName: "filemacro",
Expand Down
37 changes: 25 additions & 12 deletions Sources/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -590,21 +590,34 @@ public enum SwiftUIPropertiesSortMode: String, CaseIterable {
case firstAppearanceSort = "first-appearance-sort"
}

public struct EquatableMacroInfo: RawRepresentable {
/// The name of this macro, e.g. `@Equatable`
let macro: String
/// The name of the module defining this macro, e.g. `EquatableMacroLib`
let moduleName: String
public enum EquatableMacro: Equatable, RawRepresentable, CustomStringConvertible {
/// No equatable macro
case none
/// The name and the module for the macro, e.g. `@Equatable,EquatableMacroLib`
case macro(String, module: String)

public init?(rawValue: String) {
let components = rawValue.components(separatedBy: ",")
guard components.count == 2 else { return nil }
macro = components[0]
moduleName = components[1]
if components.count == 2 {
self = .macro(components[0], module: components[1])
} else if rawValue == "none" {
self = .none
} else {
return nil
}
}

public var rawValue: String {
"\(macro),\(moduleName)"
switch self {
case .none:
return "none"
case let .macro(name, module: module):
return "\(name),\(module)"
}
}

public var description: String {
rawValue
}
}

Expand Down Expand Up @@ -718,7 +731,7 @@ public struct FormatOptions: CustomStringConvertible {
public var timeZone: FormatTimeZone
public var nilInit: NilInitType
public var preservedPrivateDeclarations: Set<String>
public var equatableMacroInfo: EquatableMacroInfo?
public var equatableMacro: EquatableMacro
public var preferFileMacro: Bool

/// Deprecated
Expand Down Expand Up @@ -846,7 +859,7 @@ public struct FormatOptions: CustomStringConvertible {
timeZone: FormatTimeZone = .system,
nilInit: NilInitType = .remove,
preservedPrivateDeclarations: Set<String> = [],
equatableMacroInfo: EquatableMacroInfo? = nil,
equatableMacro: EquatableMacro = .none,
preferFileMacro: Bool = true,
// Doesn't really belong here, but hard to put elsewhere
fragment: Bool = false,
Expand Down Expand Up @@ -964,7 +977,7 @@ public struct FormatOptions: CustomStringConvertible {
self.timeZone = timeZone
self.nilInit = nilInit
self.preservedPrivateDeclarations = preservedPrivateDeclarations
self.equatableMacroInfo = equatableMacroInfo
self.equatableMacro = equatableMacro
self.preferFileMacro = preferFileMacro
// Doesn't really belong here, but hard to put elsewhere
self.fragment = fragment
Expand Down
8 changes: 4 additions & 4 deletions Sources/Rules/RedundantEquatable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public extension FormatRule {
isEligibleForAutoEquatableConformance = true
case "class":
// Projects can define an `@Equatable` macro that generates the Equatable implementation for classes
isEligibleForAutoEquatableConformance = formatter.options.equatableMacroInfo != nil
isEligibleForAutoEquatableConformance = formatter.options.equatableMacro != .none
default:
// This rule doesn't support other kinds of types.
isEligibleForAutoEquatableConformance = false
Expand Down Expand Up @@ -49,7 +49,7 @@ public extension FormatRule {

// In projects using an `@Equatable` macro, the Equatable implementation
// can be generated by that macro instead of written manually.
else if let equatableMacroInfo = formatter.options.equatableMacroInfo {
else if case let .macro(macro, module: module) = formatter.options.equatableMacro {
let declarationWithEquatableConformance = equatableType.declarationWithEquatableConformance

guard let equatableConformance = formatter.parseConformancesOfType(atKeywordIndex: declarationWithEquatableConformance.keywordIndex).first(where: { $0.conformance == "Equatable" || $0.conformance == "Hashable" })
Expand All @@ -74,12 +74,12 @@ public extension FormatRule {

// Add the `@Equatable` macro
formatter.insert(
[.keyword(equatableMacroInfo.macro), .space(" ")],
[.keyword(macro), .space(" ")],
at: equatableType.typeDeclaration.startOfModifiersIndex
)

// Import the module that defines the `@Equatable` macro if needed
formatter.addImports([equatableMacroInfo.moduleName])
formatter.addImports([module])
}
}
} examples: {
Expand Down
15 changes: 9 additions & 6 deletions Tests/Rules/RedundantEquatableTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ final class RedundantEquatableTests: XCTestCase {

let options = FormatOptions(
typeAttributes: .prevLine,
equatableMacroInfo: EquatableMacroInfo(rawValue: "@Equatable,MyEquatableMacroLib")
equatableMacro: .macro("@Equatable", module: "MyEquatableMacroLib")
)

testFormatting(
Expand Down Expand Up @@ -248,7 +248,7 @@ final class RedundantEquatableTests: XCTestCase {

let options = FormatOptions(
typeAttributes: .prevLine,
equatableMacroInfo: EquatableMacroInfo(rawValue: "@Equatable,MyEquatableMacroLib")
equatableMacro: .macro("@Equatable", module: "MyEquatableMacroLib")
)

testFormatting(for: input, rule: .redundantEquatable, options: options)
Expand Down Expand Up @@ -286,7 +286,10 @@ final class RedundantEquatableTests: XCTestCase {
}
"""

let options = FormatOptions(typeAttributes: .prevLine, equatableMacroInfo: EquatableMacroInfo(rawValue: "@Equatable,MyEquatableMacroLib"))
let options = FormatOptions(
typeAttributes: .prevLine,
equatableMacro: .macro("@Equatable", module: "MyEquatableMacroLib")
)
testFormatting(for: input, [output], rules: [.redundantEquatable, .blankLinesAtEndOfScope, .wrapAttributes], options: options)
}

Expand Down Expand Up @@ -321,7 +324,7 @@ final class RedundantEquatableTests: XCTestCase {

let options = FormatOptions(
typeAttributes: .prevLine,
equatableMacroInfo: EquatableMacroInfo(rawValue: "@Equatable,MyEquatableMacroLib")
equatableMacro: .macro("@Equatable", module: "MyEquatableMacroLib")
)

testFormatting(
Expand Down Expand Up @@ -367,7 +370,7 @@ final class RedundantEquatableTests: XCTestCase {

let options = FormatOptions(
typeAttributes: .prevLine,
equatableMacroInfo: EquatableMacroInfo(rawValue: "@Equatable,MyEquatableMacroLib")
equatableMacro: .macro("@Equatable", module: "MyEquatableMacroLib")
)

testFormatting(
Expand Down Expand Up @@ -510,7 +513,7 @@ final class RedundantEquatableTests: XCTestCase {

let options = FormatOptions(
typeAttributes: .prevLine,
equatableMacroInfo: EquatableMacroInfo(rawValue: "@Equatable,MyEquatableMacroLib")
equatableMacro: .macro("@Equatable", module: "MyEquatableMacroLib")
)

testFormatting(for: input, [output], rules: [.redundantEquatable, .emptyBraces, .wrapAttributes, .emptyExtensions, .consecutiveBlankLines], options: options)
Expand Down

0 comments on commit f36187b

Please sign in to comment.