IR: optimize IrType.isNullable, do not use DFS
DFS is not justified for type usages. In contrast to type hierarchies, traversing the type usage naively with recursion has linear, not exponential, complexity.
This commit is contained in:
@@ -11,15 +11,11 @@ import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeBuilder
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.buildTypeProjection
|
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
|
|
||||||
fun IrClassifierSymbol.superTypes() = when (this) {
|
fun IrClassifierSymbol.superTypes() = when (this) {
|
||||||
@@ -80,22 +76,16 @@ fun Collection<IrType>.commonSupertype(irBuiltIns: IrBuiltIns): IrType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrType.isNullable(): Boolean = DFS.ifAny(
|
fun IrType.isNullable(): Boolean =
|
||||||
listOf(this),
|
when (this) {
|
||||||
{
|
is IrSimpleType -> when (val classifier = classifier) {
|
||||||
when (val classifier = it.classifierOrNull) {
|
is IrClassSymbol -> hasQuestionMark
|
||||||
is IrTypeParameterSymbol -> classifier.owner.superTypes
|
is IrTypeParameterSymbol -> hasQuestionMark || classifier.owner.superTypes.any(IrType::isNullable)
|
||||||
is IrClassSymbol -> emptyList()
|
|
||||||
null -> emptyList()
|
|
||||||
else -> error("Unsupported classifier: $classifier")
|
else -> error("Unsupported classifier: $classifier")
|
||||||
}
|
}
|
||||||
}, {
|
is IrDynamicType -> true
|
||||||
when (it) {
|
else -> false
|
||||||
is IrSimpleType -> it.hasQuestionMark
|
|
||||||
else -> it is IrDynamicType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
val IrType.isBoxedArray: Boolean
|
val IrType.isBoxedArray: Boolean
|
||||||
get() = classOrNull?.owner?.fqNameWhenAvailable == KotlinBuiltIns.FQ_NAMES.array.toSafe()
|
get() = classOrNull?.owner?.fqNameWhenAvailable == KotlinBuiltIns.FQ_NAMES.array.toSafe()
|
||||||
|
|||||||
Reference in New Issue
Block a user