Skip to content

Commit c04f702

Browse files
authored
Retain static @_dynamicReplacement members (#924)
1 parent ff1082d commit c04f702

File tree

5 files changed

+13
-5
lines changed

5 files changed

+13
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
- Fix slow baseline filtering for large projects with many results.
2525
- Fix inconsistent unused parameter results when the function is declared in a file that is a member of multiple targets.
2626
- Fix inconsistent results caused by identical extensions declared in different modules.
27+
- Static `@_dynamicReplacement` members are now retained.
2728

2829
## 3.1.0 (2025-04-05)
2930

Sources/SourceGraph/Elements/Declaration.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public final class Declaration {
4949
Set(Kind.allCases.filter(\.isFunctionKind))
5050
}
5151

52+
static var variableKinds: Set<Kind> {
53+
Set(Kind.allCases.filter(\.isVariableKind))
54+
}
55+
5256
static var protocolMemberKinds: [Kind] {
5357
let functionKinds: [Kind] = [.functionMethodInstance, .functionMethodStatic, .functionSubscript, .functionOperator, .functionOperatorInfix, .functionOperatorPostfix, .functionOperatorPrefix, .functionConstructor]
5458
let variableKinds: [Kind] = [.varInstance, .varStatic]
@@ -73,10 +77,6 @@ public final class Declaration {
7377
rawValue.hasPrefix("function")
7478
}
7579

76-
static var variableKinds: Set<Kind> {
77-
Set(Kind.allCases.filter(\.isVariableKind))
78-
}
79-
8080
public var isVariableKind: Bool {
8181
rawValue.hasPrefix("var")
8282
}

Sources/SourceGraph/Mutators/DynamicMemberRetainer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class DynamicMemberRetainer: SourceGraphMutator {
1616
}
1717
}
1818

19-
for decl in graph.declarations(ofKinds: [.functionSubscript, .varInstance, .functionMethodInstance]) {
19+
for decl in graph.declarations(ofKinds: Declaration.Kind.functionKinds.union(Declaration.Kind.variableKinds)) {
2020
if decl.attributes.contains("_dynamicReplacement") {
2121
graph.markRetained(decl)
2222
}

Tests/Fixtures/Sources/RetentionFixtures/testRetainsDynamicReplacement.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ struct FixtureStruct8 {
66
}
77

88
extension FixtureStruct8 {
9+
@_dynamicReplacement(for: originalStaticMethod)
10+
static func replacementStaticMethod() {}
11+
912
@_dynamicReplacement(for: originalMethod)
1013
func replacementMethod() {}
1114

@@ -18,6 +21,7 @@ extension FixtureStruct8 {
1821

1922
public struct FixtureStruct8Retainer {
2023
public func retain() {
24+
_ = FixtureStruct8.originalStaticMethod()
2125
let strct = FixtureStruct8()
2226
strct.originalMethod()
2327
_ = strct.originalProperty

Tests/PeripheryTests/RetentionTest.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,9 @@ final class RetentionTest: FixtureSourceGraphTestCase {
10351035
func testRetainsDynamicReplacement() {
10361036
analyze(retainPublic: true) {
10371037
assertReferenced(.struct("FixtureStruct8")) {
1038+
self.assertReferenced(.functionMethodStatic("originalStaticMethod()"))
1039+
self.assertReferenced(.functionMethodStatic("replacementStaticMethod()"))
1040+
10381041
self.assertReferenced(.functionMethodInstance("originalMethod()"))
10391042
self.assertReferenced(.functionMethodInstance("replacementMethod()"))
10401043

0 commit comments

Comments
 (0)