From 3c90e25cb4d2019fdf444b61f5a32c0accffceda Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 11 Jun 2020 22:39:25 +0200 Subject: [PATCH] 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. --- .../jetbrains/kotlin/ir/types/IrTypeUtils.kt | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt index 7083e1c3d92..fc317d0720f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt @@ -11,15 +11,11 @@ import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol 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.render import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeCheckerContext -import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.DFS fun IrClassifierSymbol.superTypes() = when (this) { @@ -80,22 +76,16 @@ fun Collection.commonSupertype(irBuiltIns: IrBuiltIns): IrType { } } -fun IrType.isNullable(): Boolean = DFS.ifAny( - listOf(this), - { - when (val classifier = it.classifierOrNull) { - is IrTypeParameterSymbol -> classifier.owner.superTypes - is IrClassSymbol -> emptyList() - null -> emptyList() +fun IrType.isNullable(): Boolean = + when (this) { + is IrSimpleType -> when (val classifier = classifier) { + is IrClassSymbol -> hasQuestionMark + is IrTypeParameterSymbol -> hasQuestionMark || classifier.owner.superTypes.any(IrType::isNullable) else -> error("Unsupported classifier: $classifier") } - }, { - when (it) { - is IrSimpleType -> it.hasQuestionMark - else -> it is IrDynamicType - } + is IrDynamicType -> true + else -> false } -) val IrType.isBoxedArray: Boolean get() = classOrNull?.owner?.fqNameWhenAvailable == KotlinBuiltIns.FQ_NAMES.array.toSafe()