[FIR] Simplify FirCyclicTypeBoundsChecker and replace PersistentList with MutableList

This commit is contained in:
Ivan Kochurkin
2021-06-03 19:44:32 +03:00
parent 1e430b7b03
commit ce4e60afd3
@@ -5,8 +5,6 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
@@ -24,22 +22,28 @@ object FirCyclicTypeBoundsChecker : FirMemberDeclarationChecker() {
val processed = mutableSetOf<Name>() val processed = mutableSetOf<Name>()
val cycles = mutableSetOf<Name>() val cycles = mutableSetOf<Name>()
val graph = declaration.typeParameters.map { param -> val graph = declaration.typeParameters.associate { param ->
param.symbol.name to param.symbol.fir.bounds.flatMap { extractTypeParamNames(it) }.toSet() param.symbol.name to param.symbol.fir.bounds.flatMap { extractTypeParamNames(it) }.toSet()
}.toMap() }
val graphFunc = { name: Name -> graph.getOrDefault(name, emptySet()) }
val path = mutableListOf<Name>()
declaration.typeParameters.forEach { param -> fun findCycles(
if (!processed.contains(param.symbol.name)) { node: Name
findCycles( ) {
persistentListOf(), if (processed.add(node)) {
param.symbol.name, path.add(node)
processed, graphFunc(node).forEach { nextNode ->
mutableSetOf(), findCycles(nextNode)
cycles }
) { name -> graph.getOrDefault(name, emptySet()) } path.removeAt(path.size - 1)
} else {
cycles.addAll(path.dropWhile { it != node })
} }
} }
declaration.typeParameters.forEach { param -> findCycles(param.symbol.name) }
if (cycles.isNotEmpty()) { if (cycles.isNotEmpty()) {
declaration.typeParameters declaration.typeParameters
.filter { cycles.contains(it.symbol.name) } .filter { cycles.contains(it.symbol.name) }
@@ -72,24 +76,4 @@ object FirCyclicTypeBoundsChecker : FirMemberDeclarationChecker() {
ref.unwrapBound().mapNotNull { extractTypeParamName(it.coneType) }.toSet() ref.unwrapBound().mapNotNull { extractTypeParamName(it.coneType) }.toSet()
private fun extractTypeParamName(type: ConeKotlinType): Name? = type.safeAs<ConeTypeParameterType>()?.lookupTag?.name private fun extractTypeParamName(type: ConeKotlinType): Name? = type.safeAs<ConeTypeParameterType>()?.lookupTag?.name
private fun findCycles(
path: PersistentList<Name>,
node: Name,
processed: MutableSet<Name>,
visited: MutableSet<Name>,
cycles: MutableSet<Name>,
graph: (Name) -> Set<Name>
) {
processed.add(node)
if (visited.add(node)) {
val newPath = path.add(node)
graph(node).forEach { nextNode ->
findCycles(newPath, nextNode, processed, visited, cycles, graph)
}
} else {
cycles.addAll(path.dropWhile { it != node })
}
}
} }