Skip to content

Commit 71b6b50

Browse files
Merge pull request #1446 from krzysztofzablocki/eh/fix-typealias-cycle
Break out of typealias cycles
2 parents b703710 + 48f428b commit 71b6b50

2 files changed

Lines changed: 22 additions & 0 deletions

File tree

SourceryRuntime/Sources/Common/Composer/ParserResultsComposed.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,15 @@ internal struct ParserResultsComposed {
237237
typealiasesByNames.forEach { _, alias in
238238
var aliasNamesToReplace = [alias.name]
239239
var finalAlias = alias
240+
var visitedAliasNames = Set<String>()
241+
visitedAliasNames.insert(alias.name)
240242
while let targetAlias = typealiasesByNames[finalAlias.typeName.name] {
243+
if visitedAliasNames.contains(targetAlias.name) {
244+
Log.astWarning("Detected typealias cycle while resolving '\(alias.name)' -> '\(targetAlias.name)' (type name: \(finalAlias.typeName.name)).")
245+
break
246+
}
241247
aliasNamesToReplace.append(targetAlias.name)
248+
visitedAliasNames.insert(targetAlias.name)
242249
finalAlias = targetAlias
243250
}
244251

SourceryTests/Parsing/ComposerSpec.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,21 @@ class ParserComposerSpec: QuickSpec {
11731173
}
11741174
}
11751175

1176+
it("does not loop forever when typealiases form a cycle") {
1177+
let code = """
1178+
typealias Foo = Bar
1179+
typealias Bar = Foo
1180+
"""
1181+
1182+
guard let parserResult = try? makeParser(for: code).parse() else {
1183+
fail("Failed to parse typealias cycle fixture")
1184+
return
1185+
}
1186+
1187+
let composed = ParserResultsComposed(parserResult: parserResult)
1188+
expect(composed.resolvedTypealiases.keys).to(contain("Foo", "Bar"))
1189+
}
1190+
11761191
xit("follows through typealias contained in other types") {
11771192
let code =
11781193
"""

0 commit comments

Comments
 (0)