Skip to content

Commit

Permalink
Fix crash caused by cyclic inherited type references. Closes #364 (#365)
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch authored Jun 30, 2021
1 parent 79fb2c9 commit fae4ccf
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 3 deletions.
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 crash caused by cyclic inherited type references.

## 2.7.0 (2021-06-29)

Expand Down
9 changes: 7 additions & 2 deletions Sources/PeripheryKit/Indexer/SourceGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,19 @@ public final class SourceGraph {
try visitor.make(graph: self).visit()
}

func inheritedTypeReferences(of decl: Declaration) -> [Reference] {
func inheritedTypeReferences(of decl: Declaration, seenDeclarations: Set<Declaration> = []) -> [Reference] {
var references: [Reference] = []

for reference in decl.immediateInheritedTypeReferences {
references.append(reference)

if let inheritedDecl = explicitDeclaration(withUsr: reference.usr) {
references = inheritedTypeReferences(of: inheritedDecl) + references
// Detect circular references. The following is valid Swift.
// class SomeClass {}
// extension SomeClass: SomeProtocol {}
// protocol SomeProtocol: SomeClass {}
guard !seenDeclarations.contains(inheritedDecl) else { continue }
references = inheritedTypeReferences(of: inheritedDecl, seenDeclarations: seenDeclarations.union([decl])) + references
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

class FixtureClass211 {}
extension FixtureClass211: FixtureProtocol211 {}
protocol FixtureProtocol211: FixtureClass211 {}
7 changes: 7 additions & 0 deletions Tests/PeripheryTests/RetentionTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,13 @@ final class RetentionTest: SourceGraphTestCase {
}
}

func testCircularTypeInheritance() {
analyze {
// Intentionally blank.
// Fixture contains a circular reference that shouldn't cause a stack overflow.
}
}

// MARK: - Objective-C

#if os(macOS)
Expand Down

0 comments on commit fae4ccf

Please sign in to comment.