FIR: make "collectSuperTypes" recursion-resistant

This commit is contained in:
Denis Zharkov
2019-08-27 19:13:16 +03:00
parent 1f23184db9
commit 7f5c4d90fd
@@ -27,7 +27,7 @@ fun lookupSuperTypes(
useSiteSession: FirSession useSiteSession: FirSession
): List<ConeClassLikeType> { ): List<ConeClassLikeType> {
return mutableListOf<ConeClassLikeType>().also { return mutableListOf<ConeClassLikeType>().also {
klass.symbol.collectSuperTypes(it, deep, lookupInterfaces, useSiteSession) klass.symbol.collectSuperTypes(it, mutableSetOf(), deep, lookupInterfaces, useSiteSession)
} }
} }
@@ -110,10 +110,12 @@ private tailrec fun ConeClassLikeType.computePartialExpansion(useSiteSession: Fi
private fun ConeClassifierSymbol.collectSuperTypes( private fun ConeClassifierSymbol.collectSuperTypes(
list: MutableList<ConeClassLikeType>, list: MutableList<ConeClassLikeType>,
visitedSymbols: MutableSet<ConeClassifierSymbol>,
deep: Boolean, deep: Boolean,
lookupInterfaces: Boolean, lookupInterfaces: Boolean,
useSiteSession: FirSession useSiteSession: FirSession
) { ) {
if (!visitedSymbols.add(this)) return
when (this) { when (this) {
is FirClassSymbol -> { is FirClassSymbol -> {
val superClassTypes = val superClassTypes =
@@ -125,13 +127,19 @@ private fun ConeClassifierSymbol.collectSuperTypes(
if (deep) if (deep)
superClassTypes.forEach { superClassTypes.forEach {
if (it !is ConeClassErrorType) { if (it !is ConeClassErrorType) {
it.lookupTag.toSymbol(useSiteSession)?.collectSuperTypes(list, deep, lookupInterfaces, useSiteSession) it.lookupTag.toSymbol(useSiteSession)?.collectSuperTypes(
list,
visitedSymbols,
deep,
lookupInterfaces,
useSiteSession
)
} }
} }
} }
is FirTypeAliasSymbol -> { is FirTypeAliasSymbol -> {
val expansion = fir.expandedConeType?.computePartialExpansion(useSiteSession) ?: return val expansion = fir.expandedConeType?.computePartialExpansion(useSiteSession) ?: return
expansion.lookupTag.toSymbol(useSiteSession)?.collectSuperTypes(list, deep, lookupInterfaces, useSiteSession) expansion.lookupTag.toSymbol(useSiteSession)?.collectSuperTypes(list, visitedSymbols, deep, lookupInterfaces, useSiteSession)
} }
else -> error("?!id:1") else -> error("?!id:1")
} }