IR: move type utilities from IrTypeUtils.kt to irTypePredicates.kt

Multiple IrType extensions were incorrectly calling isNameInPackage
which actually checked if the name of the type's classifier _starts_
with the given string, not equals it. Move them to irTypePredicates,
which seems a more natural place for these extensions anyway. Move
isKClassArray to JVM backend utilities, since this is JVM-specific
behavior at the moment. Fix minor warnings/inspections
This commit is contained in:
Alexander Udalov
2019-07-01 17:00:44 +02:00
parent 7c6f48df39
commit 361c468c33
4 changed files with 26 additions and 41 deletions
@@ -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<IrType> = 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<IrTypeParameter>, arguments: List<IrType>): IrType =
substitute(params.map { it.symbol }.zip(arguments).toMap())
fun IrType.substitute(substitutionMap: Map<IrTypeParameterSymbol, IrType>): IrType {
if (this !is IrSimpleType) return this
@@ -138,7 +119,7 @@ private fun collectAllSupertypes(irClass: IrClass, result: MutableSet<IrSimpleTy
val immediateSupertypes = getImmediateSupertypes(irClass)
result.addAll(immediateSupertypes)
for (supertype in immediateSupertypes) {
supertype.classOrNull.let { collectAllSupertypes(it!!.owner, result) }
collectAllSupertypes(supertype.classOrNull!!.owner, result)
}
}
@@ -147,4 +128,4 @@ fun getAllSupertypes(irClass: IrClass): MutableSet<IrSimpleType> {
collectAllSupertypes(irClass, result)
return result
}
}
@@ -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()
}
@@ -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
@@ -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())