Skip to content

Commit d10b178

Browse files
authored
Exclude wrapped properties from assign-only analysis (#1004)
1 parent 96ec760 commit d10b178

File tree

4 files changed

+20
-3
lines changed

4 files changed

+20
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
##### Enhancements
88

9-
- None.
9+
- Exclude wrapped properties from assign-only analysis, as Periphery cannot observe the behavior of the property wrapper.
1010

1111
##### Bug Fixes
1212

Sources/SourceGraph/Mutators/AssignOnlyPropertyReferenceEliminator.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ final class AssignOnlyPropertyReferenceEliminator: SourceGraphMutator {
77
private let configuration: Configuration
88
private let retainAssignOnlyPropertyTypes: [String]
99
private let defaultRetainedTypes = ["AnyCancellable", "Set<AnyCancellable>", "[AnyCancellable]", "NSKeyValueObservation"]
10-
private let retainedAttributes = ["State", "Binding"]
1110

1211
required init(graph: SourceGraph, configuration: Configuration, swiftVersion _: SwiftVersion) {
1312
self.graph = graph
@@ -24,7 +23,7 @@ final class AssignOnlyPropertyReferenceEliminator: SourceGraphMutator {
2423
guard let declaredType = property.declaredType,
2524
!retainAssignOnlyPropertyTypes.contains(declaredType),
2625
!graph.isRetained(property),
27-
property.attributes.isDisjoint(with: retainedAttributes),
26+
property.attributes.isEmpty,
2827
!property.isComplexProperty,
2928
// A protocol property can technically be assigned and never used when the protocol is used as an existential
3029
// type, however communicating that succinctly would be very tricky, and most likely just lead to confusion.

Tests/Fixtures/Sources/RetentionFixtures/testSimplePropertyAssignedButNeverRead.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public class FixtureClass70 {
2525
// periphery:ignore
2626
var ignoredSimpleUnreadVar: String
2727

28+
@Wrapped
29+
var wrappedProperty: String
30+
2831
init() {
2932
simpleUnreadVar = "Hello"
3033
simpleUnreadShadowedVar = "Hello"
@@ -33,6 +36,7 @@ public class FixtureClass70 {
3336
complexUnreadVar1 = "Hello"
3437
readVar = "Hello"
3538
ignoredSimpleUnreadVar = "Hello"
39+
wrappedProperty = "Hello"
3640
FixtureClass70.simpleStaticUnreadVar = "Hello"
3741
}
3842

@@ -44,3 +48,11 @@ public class FixtureClass70 {
4448
print(readVar)
4549
}
4650
}
51+
52+
@propertyWrapper
53+
struct Wrapped<Value> {
54+
var wrappedValue: Value
55+
init(wrappedValue: Value) {
56+
self.wrappedValue = wrappedValue
57+
}
58+
}

Tests/PeripheryTests/RetentionTest.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,9 @@ final class RetentionTest: FixtureSourceGraphTestCase {
12201220

12211221
self.assertReferenced(.varInstance("ignoredSimpleUnreadVar"))
12221222
self.assertNotAssignOnlyProperty(.varInstance("ignoredSimpleUnreadVar"))
1223+
1224+
self.assertReferenced(.varInstance("wrappedProperty"))
1225+
self.assertNotAssignOnlyProperty(.varInstance("wrappedProperty"))
12231226
}
12241227
}
12251228

@@ -1248,6 +1251,9 @@ final class RetentionTest: FixtureSourceGraphTestCase {
12481251

12491252
self.assertReferenced(.varInstance("ignoredSimpleUnreadVar"))
12501253
self.assertNotAssignOnlyProperty(.varInstance("ignoredSimpleUnreadVar"))
1254+
1255+
self.assertReferenced(.varInstance("wrappedProperty"))
1256+
self.assertNotAssignOnlyProperty(.varInstance("wrappedProperty"))
12511257
}
12521258
}
12531259
}

0 commit comments

Comments
 (0)