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:
@@ -23,27 +23,14 @@ import org.jetbrains.kotlin.utils.DFS
|
|||||||
import org.jetbrains.kotlin.ir.types.isNullable as irTreeTypeUtils_isNullable
|
import org.jetbrains.kotlin.ir.types.isNullable as irTreeTypeUtils_isNullable
|
||||||
|
|
||||||
val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin"))
|
val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin"))
|
||||||
val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect"))
|
private val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect"))
|
||||||
val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier("coroutines"))
|
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)
|
private fun IrType.isClassWithNamePrefix(prefix: String, packageFqName: FqName): Boolean {
|
||||||
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 {
|
|
||||||
val classifier = classifierOrNull ?: return false
|
val classifier = classifierOrNull ?: return false
|
||||||
val name = classifier.descriptor.name.asString()
|
val name = classifier.descriptor.name.asString()
|
||||||
if (!name.startsWith(prefix)) return false
|
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
|
val parent = declaration.parent as? IrPackageFragment ?: return false
|
||||||
|
|
||||||
return parent.fqName == packageFqName
|
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.isFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isFunction)
|
||||||
fun IrType.isSuspendFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), { it.superTypes() }, { it.isSuspendFunction() })
|
fun IrType.isSuspendFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isSuspendFunction)
|
||||||
|
|
||||||
fun IrType.isTypeParameter() = classifierOrNull is IrTypeParameterSymbol
|
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.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) }
|
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] }
|
(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 =
|
fun IrType.substitute(params: List<IrTypeParameter>, arguments: List<IrType>): IrType =
|
||||||
substitute(params.map { it.symbol }.zip(arguments).toMap())
|
substitute(params.map { it.symbol }.zip(arguments).toMap())
|
||||||
|
|
||||||
|
|
||||||
fun IrType.substitute(substitutionMap: Map<IrTypeParameterSymbol, IrType>): IrType {
|
fun IrType.substitute(substitutionMap: Map<IrTypeParameterSymbol, IrType>): IrType {
|
||||||
if (this !is IrSimpleType) return this
|
if (this !is IrSimpleType) return this
|
||||||
|
|
||||||
@@ -138,7 +119,7 @@ private fun collectAllSupertypes(irClass: IrClass, result: MutableSet<IrSimpleTy
|
|||||||
val immediateSupertypes = getImmediateSupertypes(irClass)
|
val immediateSupertypes = getImmediateSupertypes(irClass)
|
||||||
result.addAll(immediateSupertypes)
|
result.addAll(immediateSupertypes)
|
||||||
for (supertype in 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)
|
collectAllSupertypes(irClass, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -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.backend.jvm.lower.inlineclasses.InlineClassAbi
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
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.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
@@ -123,7 +119,7 @@ fun PromisedValue.coerce(target: Type, irTarget: IrType): PromisedValue {
|
|||||||
AsmUtil.wrapJavaClassIntoKClass(mv)
|
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) {
|
object : PromisedValue(codegen, target, irTarget) {
|
||||||
override fun materialize() {
|
override fun materialize() {
|
||||||
this@coerce.materialize()
|
this@coerce.materialize()
|
||||||
@@ -173,3 +169,8 @@ fun ExpressionCodegen.defaultValue(irType: IrType): PromisedValue =
|
|||||||
StackValue.coerce(Type.VOID_TYPE, type, codegen.mv)
|
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()
|
||||||
|
}
|
||||||
|
|||||||
+1
-4
@@ -34,12 +34,9 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.createType
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
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.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.*
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
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.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName
|
||||||
|
|
||||||
private fun IrType.isNotNullClassType(fqName: FqNameUnsafe) = isClassType(fqName, hasQuestionMark = false)
|
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.isNullableArray(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES.array)
|
||||||
fun IrType.isCollection(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.collection.toUnsafe())
|
fun IrType.isCollection(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.collection.toUnsafe())
|
||||||
fun IrType.isNothing(): Boolean = isNotNullClassType(KotlinBuiltIns.FQ_NAMES.nothing)
|
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.isPrimitiveType(): Boolean = KotlinBuiltIns.FQ_NAMES.fqNameToPrimitiveType.keys.any { isNotNullClassType(it) }
|
||||||
fun IrType.isNullablePrimitiveType(): Boolean = KotlinBuiltIns.FQ_NAMES.fqNameToPrimitiveType.keys.any { isNullableClassType(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.isNullableBoolean(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES._boolean)
|
||||||
fun IrType.isNullableLong(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES._long)
|
fun IrType.isNullableLong(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES._long)
|
||||||
fun IrType.isNullableChar(): Boolean = isNullableClassType(KotlinBuiltIns.FQ_NAMES._char)
|
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())
|
||||||
|
|||||||
Reference in New Issue
Block a user