diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt index 4268f2d15f6..2394af9b076 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt @@ -23,27 +23,14 @@ import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.ir.types.isNullable as irTreeTypeUtils_isNullable val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin")) -val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect")) -val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier("coroutines")) +private val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect")) +private val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier("coroutines")) +fun IrType.isFunction(): Boolean = this.isClassWithNamePrefix("Function", kotlinPackageFqn) +fun IrType.isKFunction(): Boolean = this.isClassWithNamePrefix("KFunction", kotlinReflectionPackageFqn) +fun IrType.isSuspendFunction(): Boolean = this.isClassWithNamePrefix("SuspendFunction", kotlinCoroutinesPackageFqn) -fun IrType.isFunction() = this.isNameInPackage("Function", kotlinPackageFqn) -fun IrType.isKClass() = this.isNameInPackage("KClass", kotlinReflectionPackageFqn) -fun IrType.isKFunction() = this.isNameInPackage("KFunction", kotlinReflectionPackageFqn) -fun IrType.isSuspendFunction() = this.isNameInPackage("SuspendFunction", kotlinCoroutinesPackageFqn) - -fun IrType.isKotlinResult(): Boolean = isNameInPackage("Result", kotlinPackageFqn) -fun IrType.isContinuation(): Boolean = isNameInPackage("Continuation", kotlinCoroutinesPackageFqn) -fun IrType.isNullableContinuation(): Boolean = isContinuation() && this is IrSimpleType && hasQuestionMark - -fun IrType.isKClassArray(): Boolean { - if (!isNonPrimitiveArray()) return false - val argument = (this as? IrSimpleType)?.arguments?.singleOrNull() ?: return false - val argumentType = (argument as? IrTypeProjection)?.type ?: return false - return argumentType.isKClass() -} - -fun IrType.isNameInPackage(prefix: String, packageFqName: FqName): Boolean { +private fun IrType.isClassWithNamePrefix(prefix: String, packageFqName: FqName): Boolean { val classifier = classifierOrNull ?: return false val name = classifier.descriptor.name.asString() if (!name.startsWith(prefix)) return false @@ -51,13 +38,12 @@ fun IrType.isNameInPackage(prefix: String, packageFqName: FqName): Boolean { val parent = declaration.parent as? IrPackageFragment ?: return false return parent.fqName == packageFqName - } -fun IrType.superTypes() = classifierOrNull?.superTypes() ?: emptyList() +private fun IrType.superTypes(): List = classifierOrNull?.superTypes() ?: emptyList() -fun IrType.isFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), { it.superTypes() }, { it.isFunction() }) -fun IrType.isSuspendFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), { it.superTypes() }, { it.isSuspendFunction() }) +fun IrType.isFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isFunction) +fun IrType.isSuspendFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isSuspendFunction) fun IrType.isTypeParameter() = classifierOrNull is IrTypeParameterSymbol @@ -75,7 +61,7 @@ fun IrType.isNullable(): Boolean = this.irTreeTypeUtils_isNullable() fun IrType.isThrowable(): Boolean = isTypeFromKotlinPackage { name -> name.asString() == "Throwable" } -fun IrType.isThrowableTypeOrSubtype() = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isThrowable) +fun IrType.isThrowableTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isThrowable) fun IrType.isUnsigned(): Boolean = isTypeFromKotlinPackage { name -> UnsignedTypes.isShortNameOfUnsignedType(name) } @@ -94,14 +80,9 @@ fun IrType.getPrimitiveArrayElementType() = (this as? IrSimpleType)?.let { (it.classifier.owner as? IrClass)?.fqNameWhenAvailable?.toUnsafe()?.let { fqn -> FQ_NAMES.arrayClassFqNameToPrimitiveType[fqn] } } -fun IrType.isNonPrimitiveArray() = - (this.isArray() || this.isNullableArray()) && !this.isPrimitiveArray() - - fun IrType.substitute(params: List, arguments: List): IrType = substitute(params.map { it.symbol }.zip(arguments).toMap()) - fun IrType.substitute(substitutionMap: Map): IrType { if (this !is IrSimpleType) return this @@ -138,7 +119,7 @@ private fun collectAllSupertypes(irClass: IrClass, result: MutableSet { collectAllSupertypes(irClass, result) return result -} \ No newline at end of file +} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt index a6aa4ff8353..58a2455e934 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt @@ -10,11 +10,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.StackValue -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classOrNull -import org.jetbrains.kotlin.ir.types.toKotlinType -import org.jetbrains.kotlin.ir.util.isKClass -import org.jetbrains.kotlin.ir.util.isKClassArray +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Label @@ -123,7 +119,7 @@ fun PromisedValue.coerce(target: Type, irTarget: IrType): PromisedValue { AsmUtil.wrapJavaClassIntoKClass(mv) } } - type == AsmTypes.JAVA_CLASS_ARRAY_TYPE && target == AsmTypes.K_CLASS_ARRAY_TYPE && irType.isKClassArray() -> + type == AsmTypes.JAVA_CLASS_ARRAY_TYPE && target == AsmTypes.K_CLASS_ARRAY_TYPE && irType.isArrayOfKClass() -> object : PromisedValue(codegen, target, irTarget) { override fun materialize() { this@coerce.materialize() @@ -173,3 +169,8 @@ fun ExpressionCodegen.defaultValue(irType: IrType): PromisedValue = StackValue.coerce(Type.VOID_TYPE, type, codegen.mv) } } + +private fun IrType.isArrayOfKClass(): Boolean = + isArray() && this is IrSimpleType && arguments.singleOrNull().let { argument -> + argument is IrTypeProjection && argument.type.isKClass() + } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index 88a67bc3f9e..4871df64686 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -34,12 +34,9 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl -import org.jetbrains.kotlin.ir.types.IrSimpleType -import org.jetbrains.kotlin.ir.types.createType +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection -import org.jetbrains.kotlin.ir.types.isInt -import org.jetbrains.kotlin.ir.types.isNullableAny import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.load.java.JavaVisibilities diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt index 0316eabe355..230342b7483 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.name.FqNameUnsafe +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName private fun IrType.isNotNullClassType(fqName: FqNameUnsafe) = isClassType(fqName, hasQuestionMark = false) @@ -45,6 +46,7 @@ fun IrType.isArray(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.array fun IrType.isNullableArray(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES.array) fun IrType.isCollection(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.collection.toUnsafe()) fun IrType.isNothing(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.nothing) +fun IrType.isKClass(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.kClass) fun IrType.isPrimitiveType(): Boolean = KotlinBuiltIns.FQ_NAMES.fqNameToPrimitiveType.keys.any { isNotNullClassType(it) } fun IrType.isNullablePrimitiveType(): Boolean = KotlinBuiltIns.FQ_NAMES.fqNameToPrimitiveType.keys.any { isNullableClassType(it) } @@ -84,3 +86,7 @@ fun IrType.isDoubleArray(): Boolean = isNotNullClassType(FqNameUnsafe("kotlin.Do fun IrType.isNullableBoolean(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES._boolean) fun IrType.isNullableLong(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES._long) fun IrType.isNullableChar(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES._char) + +fun IrType.isKotlinResult(): Boolean = isNotNullClassType(DescriptorUtils.RESULT_FQ_NAME.toUnsafe()) +fun IrType.isContinuation(): Boolean = isNotNullClassType(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE.toUnsafe()) +fun IrType.isNullableContinuation(): Boolean = isNullableClassType(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE.toUnsafe())