Skip to content

Commit

Permalink
Workaround incorrect location of generic protocol extensions. Closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch committed Sep 26, 2023
1 parent ae01b91 commit 74927d2
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

##### Bug Fixes

- None.
- Fix retaining members of public generic protocol extensions with `--retain-public`.

## 2.15.1 (2023-09-17)

Expand Down
5 changes: 5 additions & 0 deletions Sources/PeripheryKit/Syntax/DeclarationSyntaxVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ final class DeclarationSyntaxVisitor: PeripherySyntaxVisitor {

if let memberType = node.extendedType.as(MemberTypeSyntax.self) {
position = memberType.name.positionAfterSkippingLeadingTrivia
} else if let genericArgumentClause = node.extendedType.as(IdentifierTypeSyntax.self)?.genericArgumentClause {
// Generic protocol extensions in the form `extension Foo<Type>` have incorrect locations in the index store.
// This results in syntax metadata not being applied to the declaration due to the location mismatch. To
// workaround this, parse this node with the incorrect location.
position = genericArgumentClause.rightAngle.positionAfterSkippingLeadingTrivia
}

parse(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
public protocol FixtureProtocol38<Value> {
associatedtype Value
}

public extension FixtureProtocol38<Int> {
func someFunc() {}
}

public protocol FixtureProtocol39<Value, Value2> {
associatedtype Value
associatedtype Value2
}

public extension FixtureProtocol39<Int, Int> {
func someFunc() {}
}

public protocol FixtureProtocol40<Value, Value2> {
associatedtype Value
associatedtype Value2
}

public extension FixtureProtocol40 where Value == Int, Value2 == Int {
func someFunc() {}
}
19 changes: 19 additions & 0 deletions Tests/PeripheryTests/RetentionTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,25 @@ final class RetentionTest: FixtureSourceGraphTestCase {
}
}

func testRetainsGenericProtocolExtensionMembers() {
analyze(retainPublic: true) {
assertReferenced(.protocol("FixtureProtocol38"))
assertReferenced(.extensionProtocol("FixtureProtocol38")) {
self.assertReferenced(.functionMethodInstance("someFunc()"))
}

assertReferenced(.protocol("FixtureProtocol39"))
assertReferenced(.extensionProtocol("FixtureProtocol39")) {
self.assertReferenced(.functionMethodInstance("someFunc()"))
}

assertReferenced(.protocol("FixtureProtocol40"))
assertReferenced(.extensionProtocol("FixtureProtocol40")) {
self.assertReferenced(.functionMethodInstance("someFunc()"))
}
}
}

func testUnusedTypealias() {
analyze() {
assertNotReferenced(.typealias("UnusedAlias"))
Expand Down

0 comments on commit 74927d2

Please sign in to comment.