diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt index 661c7d62b98..9a51416d962 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.fir.types.builder.* import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import java.util.* +import kotlin.collections.ArrayList // TODO: rewrite fun FirBlock.returnExpressions(): List = listOfNotNull(statements.lastOrNull() as? FirExpression) @@ -143,7 +145,7 @@ inline fun withFileAnalysisExceptionWrapping(file: FirFile, block: () -> R): } @JvmInline -value class MutableOrEmptyList(val list: MutableList?) : List { +value class MutableOrEmptyList(internal val list: MutableList<@UnsafeVariance T>?) : List { private constructor(list: Nothing?) : this(list as MutableList?) @@ -159,42 +161,52 @@ value class MutableOrEmptyList(val list: MutableList?) : List { } override fun iterator(): Iterator { - return list?.iterator() ?: emptyList().iterator() + return list?.iterator() ?: EMPTY_LIST_STUB_ITERATOR } override fun listIterator(): ListIterator { - return list?.listIterator() ?: emptyList().listIterator() + return list?.listIterator() ?: EMPTY_LIST_STUB_LIST_ITERATOR } override fun listIterator(index: Int): ListIterator { - return list?.listIterator(index) ?: emptyList().listIterator(index) + return list?.listIterator(index) ?: EMPTY_LIST_STUB_LIST_ITERATOR } - override fun subList(fromIndex: Int, toIndex: Int): MutableList { + override fun subList(fromIndex: Int, toIndex: Int): List { + if (list == null && fromIndex == 0 && toIndex == 0) return this return list!!.subList(fromIndex, toIndex) } - override fun lastIndexOf(element: T): Int { + override fun lastIndexOf(element: @UnsafeVariance T): Int { return list?.lastIndexOf(element) ?: -1 } - override fun indexOf(element: T): Int { + override fun indexOf(element: @UnsafeVariance T): Int { return list?.indexOf(element) ?: -1 } - override fun containsAll(elements: Collection): Boolean { + override fun containsAll(elements: Collection<@UnsafeVariance T>): Boolean { return list?.containsAll(elements) ?: elements.isEmpty() } - override fun contains(element: T): Boolean { + override fun contains(element: @UnsafeVariance T): Boolean { return list?.contains(element) ?: false } + override fun toString(): String { + return list?.joinToString(prefix = "[", postfix = "]") ?: "[]" + } + companion object { private val EMPTY = MutableOrEmptyList(null) - @Suppress("UNCHECKED_CAST") - fun empty(): MutableOrEmptyList = EMPTY as MutableOrEmptyList + private val EMPTY_LIST_STUB = emptyList() + + private val EMPTY_LIST_STUB_ITERATOR = EMPTY_LIST_STUB.iterator() + + private val EMPTY_LIST_STUB_LIST_ITERATOR = EMPTY_LIST_STUB.listIterator() + + fun empty(): MutableOrEmptyList = EMPTY } }