From afcdcf8217883360889fb012d9c097e3cc2a0c42 Mon Sep 17 00:00:00 2001 From: romanart Date: Fri, 24 Aug 2018 20:31:22 +0300 Subject: [PATCH] Partially reimplement KotlinType based util using IrType --- .../common/utils/kotlinTypeBasedUtils.kt | 15 ---- .../jetbrains/kotlin/ir/util/IrTypeUtils.kt | 75 ++++++++++++++----- .../js/lower/IntrinsicifyCallsLowering.kt | 1 - .../backend/js/lower/TypeOperatorLowering.kt | 4 + 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/utils/kotlinTypeBasedUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/utils/kotlinTypeBasedUtils.kt index ec48e8ab634..8ef1b374788 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/utils/kotlinTypeBasedUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/utils/kotlinTypeBasedUtils.kt @@ -21,24 +21,12 @@ import org.jetbrains.kotlin.types.typeUtil.isTypeParameter // TODO: implement pure Ir-based function (see IrTypeUtils.kt) -@Deprecated("Use pure Ir helper") -fun IrType.isNullable() = toKotlinType().isNullable() - -@Deprecated("Use pure Ir helper") -fun IrType.isInterface() = toKotlinType().isInterface() - @Deprecated("Use pure Ir helper") fun IrType.isPrimitiveArray() = KotlinBuiltIns.isPrimitiveArray(toKotlinType()) @Deprecated("Use pure Ir helper") fun IrType.getPrimitiveArrayElementType() = KotlinBuiltIns.getPrimitiveArrayElementType(toKotlinType()) -@Deprecated("Use pure Ir helper") -fun IrType.isTypeParameter() = toKotlinType().isTypeParameter() - -@Deprecated("Use pure Ir helper") -fun IrType.isFunctionOrKFunction() = toKotlinType().isFunctionOrKFunctionType - @Deprecated("Use pure Ir helper") fun List.commonSupertype() = CommonSupertypes.commonSupertype(map(IrType::toKotlinType)).toIrType()!! @@ -47,6 +35,3 @@ fun IrType.isSubtypeOf(superType: IrType) = toKotlinType().isSubtypeOf(superType @Deprecated("Use pure Ir helper") fun IrType.isSubtypeOfClass(superClass: IrClassSymbol) = DescriptorUtils.isSubtypeOfClass(toKotlinType(), superClass.descriptor) - -@Deprecated("Use pure Ir helper") -fun IrType.isBuiltinFunctionalTypeOrSubtype() = toKotlinType().isBuiltinFunctionalTypeOrSubtype \ No newline at end of file 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 1cc9889c60a..08ceb54b5b9 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 @@ -5,37 +5,72 @@ package org.jetbrains.kotlin.ir.util +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.ir.declarations.IrTypeParameter -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classifierOrNull +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.DFS +val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin")) +val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflection")) -fun IrType.isFunctionTypeOrSubtype(): Boolean { +fun IrType.isFunction(): Boolean { + val classifier = classifierOrNull ?: return false + val name = classifier.descriptor.name.asString() + if (!name.startsWith("Function")) return false + val declaration = classifier.owner as IrDeclaration + val parent = declaration.parent as? IrPackageFragment ?: return false - val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin")) - fun checkType(irType: IrType): Boolean { - val classifier = irType.classifierOrNull ?: return false - val name = classifier.descriptor.name.asString() - if (!name.startsWith("Function")) return false - val declaration = classifier.owner as IrDeclaration - val parent = declaration.parent as? IrPackageFragment ?: return false + return parent.fqName == kotlinPackageFqn +} - return parent.fqName == kotlinPackageFqn + +fun IrType.isKFunction(): Boolean { + val classifier = classifierOrNull ?: return false + val name = classifier.descriptor.name.asString() + if (!name.startsWith("KFunction")) return false + val declaration = classifier.owner as IrDeclaration + val parent = declaration.parent as? IrPackageFragment ?: return false + + return parent.fqName == kotlinReflectionPackageFqn +} + + +fun IrType.superTypes(): List { + val classifier = classifierOrNull?.owner ?: return emptyList() + return when(classifier) { + is IrClass -> classifier.superTypes + is IrTypeParameter -> classifier.superTypes + else -> throw IllegalStateException() } +} - fun superTypes(irType: IrType): List { - val classifier = irType.classifierOrNull?.owner ?: return emptyList() - return when(classifier) { - is IrClass -> classifier.superTypes - is IrTypeParameter -> classifier.superTypes - else -> throw IllegalStateException() - } +fun IrType.typeParameterSuperTypes(): List { + val classifier = classifierOrNull ?: return emptyList() + return when(classifier) { + is IrTypeParameterSymbol -> classifier.owner.superTypes + is IrClassSymbol -> emptyList() + else -> throw IllegalStateException() } +} - return DFS.ifAny(listOf(this), ::superTypes, ::checkType) -} \ No newline at end of file +fun IrType.isFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), { it.superTypes() }, { it.isFunction() }) + +fun IrType.isTypeParameter() = classifierOrNull is IrTypeParameterSymbol + +fun IrType.isInterface() = (classifierOrNull?.owner as? IrClass)?.kind == ClassKind.INTERFACE + +fun IrType.isFunctionOrKFunction() = isFunction() || isKFunction() + +fun IrType.isNullable(): Boolean = DFS.ifAny(listOf(this), { it.typeParameterSuperTypes() }, { + when (it) { + is IrSimpleType -> it.hasQuestionMark + else -> it is IrDynamicType + } +}) \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt index 616fe675ece..787318ace05 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/IntrinsicifyCallsLowering.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.utils.isNullable import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf import org.jetbrains.kotlin.backend.common.utils.isSubtypeOfClass import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt index 73a18d617ad..2293dffc117 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt @@ -22,6 +22,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction +import org.jetbrains.kotlin.ir.util.isInterface +import org.jetbrains.kotlin.ir.util.isNullable +import org.jetbrains.kotlin.ir.util.isTypeParameter import org.jetbrains.kotlin.ir.visitors.IrElementTransformer class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {