Skip to content

Commit e117134

Browse files
authored
Merge pull request #131 from unsignedapps/equatable-computed-properties
Don't generate Equatable checking for computed properties
2 parents d5d55a1 + dd72229 commit e117134

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

Sources/VexilMacros/FlagContainerMacro.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ extension FlagContainerMacro: ExtensionMacro {
146146
extendedType: type,
147147
inheritanceClause: .init(inheritedTypes: [ .init(type: TypeSyntax(stringLiteral: "Equatable")) ])
148148
) {
149-
var variables = declaration.memberBlock.variables
149+
var variables = declaration.memberBlock.storedVariables
150150
if variables.isEmpty == false {
151151
try FunctionDeclSyntax("func ==(lhs: \(type), rhs: \(type)) -> Bool") {
152152
if let lastBinding = variables.removeLast().bindings.first?.pattern {

Sources/VexilMacros/Utilities/SimpleVariables.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,29 @@ extension MemberBlockSyntax {
2222
}
2323
}
2424

25+
var storedVariables: [VariableDeclSyntax] {
26+
variables.filter { variable in
27+
// Only simple properties
28+
guard variable.bindings.count == 1, let binding = variable.bindings.first else {
29+
return false
30+
}
31+
32+
// If it has no accessor block it's stored
33+
guard let accessorBlock = binding.accessorBlock else {
34+
return true
35+
}
36+
37+
// If there is any kind of getter then its computed
38+
switch accessorBlock.accessors {
39+
case .getter:
40+
return false
41+
42+
case let .accessors(accessors):
43+
return accessors.allSatisfy { $0.accessorSpecifier.tokenKind != .keyword(.get) }
44+
}
45+
}
46+
}
47+
2548
}
2649

2750
extension VariableDeclSyntax {

Tests/VexilMacroTests/EquatableFlagContainerMacroTests.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@ final class EquatableFlagContainerMacroTests: XCTestCase {
6464
struct TestFlags {
6565
@Flag(default: false, description: "Some Flag")
6666
var someFlag: Bool
67+
68+
var someComputedNotEquatableProperty: (any Error)? {
69+
nil
70+
}
71+
72+
var someComputedPropertyWithAGetter: (any Error)? {
73+
get { fatalError() }
74+
set { fatalError() }
75+
}
76+
77+
var otherStoredProperty: Int {
78+
didSet { fatalError() }
79+
}
6780
}
6881
""",
6982
expandedSource: """
@@ -86,6 +99,19 @@ final class EquatableFlagContainerMacroTests: XCTestCase {
8699
)
87100
}
88101
102+
var someComputedNotEquatableProperty: (any Error)? {
103+
nil
104+
}
105+
106+
var someComputedPropertyWithAGetter: (any Error)? {
107+
get { fatalError() }
108+
set { fatalError() }
109+
}
110+
111+
var otherStoredProperty: Int {
112+
didSet { fatalError() }
113+
}
114+
89115
fileprivate let _flagKeyPath: FlagKeyPath
90116
91117
fileprivate let _flagLookup: any FlagLookup
@@ -120,7 +146,8 @@ final class EquatableFlagContainerMacroTests: XCTestCase {
120146
121147
extension TestFlags: Equatable {
122148
static func ==(lhs: TestFlags, rhs: TestFlags) -> Bool {
123-
lhs.someFlag == rhs.someFlag
149+
lhs.someFlag == rhs.someFlag &&
150+
lhs.otherStoredProperty == rhs.otherStoredProperty
124151
}
125152
}
126153
""",

0 commit comments

Comments
 (0)