[K/N] Support kType generation as ConstantValue
This commit is contained in:
+3
-1
@@ -442,7 +442,6 @@ internal class KonanSymbols(
|
||||
return symbolTable.referenceEnumEntry(descriptor)
|
||||
}
|
||||
|
||||
val getClassTypeInfo = internalFunction("getClassTypeInfo")
|
||||
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
|
||||
val kClassImpl = internalClass("KClassImpl")
|
||||
val kClassImplConstructor by lazy { kClassImpl.constructors.single { it.descriptor.isPrimary } }
|
||||
@@ -453,6 +452,7 @@ internal class KonanSymbols(
|
||||
val kTypeImpl = internalClass("KTypeImpl")
|
||||
val kTypeImplIntrinsicConstructor by lazy { kTypeImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
||||
val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds")
|
||||
val kTypeProjectionList = internalClass("KTypeProjectionList")
|
||||
|
||||
val kTypeProjection = symbolTable.referenceClass(context.reflectionTypes.kTypeProjection)
|
||||
|
||||
@@ -484,6 +484,8 @@ internal class KonanSymbols(
|
||||
val listOf = irBuiltIns.findFunctions(Name.identifier("listOf"), "kotlin", "collections")
|
||||
.single { it.descriptor.valueParameters.size == 1 && it.descriptor.valueParameters[0].isVararg }
|
||||
|
||||
val arrayAsList = internalClass("ArrayAsList")
|
||||
|
||||
val threadLocal = symbolTable.referenceClass(
|
||||
context.builtIns.builtInsModule.findClassAcrossModuleDependencies(
|
||||
ClassId.topLevel(KonanFqNames.threadLocal))!!)
|
||||
|
||||
-15
@@ -61,7 +61,6 @@ internal enum class IntrinsicType {
|
||||
OBJC_INIT_BY,
|
||||
OBJC_GET_SELECTOR,
|
||||
// Other
|
||||
GET_CLASS_TYPE_INFO,
|
||||
CREATE_UNINITIALIZED_INSTANCE,
|
||||
IDENTITY,
|
||||
IMMUTABLE_BLOB,
|
||||
@@ -242,7 +241,6 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
IntrinsicType.OBJC_GET_MESSENGER_STRET -> emitObjCGetMessenger(args, isStret = true)
|
||||
IntrinsicType.OBJC_GET_OBJC_CLASS -> emitGetObjCClass(callSite)
|
||||
IntrinsicType.OBJC_CREATE_SUPER_STRUCT -> emitObjCCreateSuperStruct(args)
|
||||
IntrinsicType.GET_CLASS_TYPE_INFO -> emitGetClassTypeInfo(callSite)
|
||||
IntrinsicType.INTEROP_READ_BITS -> emitReadBits(args)
|
||||
IntrinsicType.INTEROP_WRITE_BITS -> emitWriteBits(args)
|
||||
IntrinsicType.INTEROP_READ_PRIMITIVE -> emitReadPrimitive(callSite, args)
|
||||
@@ -432,19 +430,6 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
TODO("Implement me")
|
||||
}
|
||||
|
||||
private fun FunctionGenerationContext.emitGetClassTypeInfo(callSite: IrCall): LLVMValueRef {
|
||||
val typeArgument = callSite.getTypeArgument(0)!!
|
||||
val typeArgumentClass = typeArgument.getClass()
|
||||
return if (typeArgumentClass == null) {
|
||||
// Should not happen anymore, but it is safer to handle this case.
|
||||
unreachable()
|
||||
kNullInt8Ptr
|
||||
} else {
|
||||
val typeInfo = codegen.typeInfoValue(typeArgumentClass)
|
||||
LLVMConstBitCast(typeInfo, kInt8Ptr)!!
|
||||
}
|
||||
}
|
||||
|
||||
private fun FunctionGenerationContext.emitObjCCreateSuperStruct(args: List<LLVMValueRef>): LLVMValueRef {
|
||||
assert(args.size == 2)
|
||||
val receiver = args[0]
|
||||
|
||||
+15
-7
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.lower.at
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.ConstantConstructorIntrinsicType
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.tryGetConstantConstructorIntrinsicType
|
||||
import org.jetbrains.kotlin.backend.konan.renderCompilerError
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
@@ -93,17 +95,23 @@ internal class PostInlineLowering(val context: Context) : BodyLoweringPass {
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.stringType,
|
||||
IrConstKind.String, builder.toString()))
|
||||
} else if (Symbols.isTypeOfIntrinsic(expression.symbol)) {
|
||||
// Inline functions themselves are not called (they have been inlined at all call sites),
|
||||
// so it is ok not to build exact type parameters for them.
|
||||
val needExactTypeParameters = (container as? IrSimpleFunction)?.isInline != true
|
||||
return with (KTypeGenerator(context, irFile, expression, needExactTypeParameters)) {
|
||||
data.at(expression).irKType(expression.getTypeArgument(0)!!, leaveReifiedForLater = false)
|
||||
}
|
||||
}
|
||||
|
||||
return expression
|
||||
}
|
||||
|
||||
override fun visitConstantObject(expression: IrConstantObject, data: IrBuilderWithScope): IrConstantValue {
|
||||
return if (tryGetConstantConstructorIntrinsicType(expression.constructor) == ConstantConstructorIntrinsicType.KTYPE_IMPL) {
|
||||
// Inline functions themselves are not called (they have been inlined at all call sites),
|
||||
// so it is ok not to build exact type parameters for them.
|
||||
val needExactTypeParameters = (container as? IrSimpleFunction)?.isInline != true
|
||||
with(KTypeGenerator(context, irFile, expression, needExactTypeParameters)) {
|
||||
data.at(expression).irKType(expression.typeArguments[0], leaveReifiedForLater = false)
|
||||
}
|
||||
} else
|
||||
super.visitConstantObject(expression, data)
|
||||
}
|
||||
|
||||
}, data = context.createIrBuilder((container as IrSymbolOwner).symbol, irBody.startOffset, irBody.endOffset))
|
||||
}
|
||||
}
|
||||
+86
-95
@@ -8,30 +8,26 @@ package org.jetbrains.kotlin.backend.konan.lower
|
||||
import org.jetbrains.kotlin.backend.konan.InteropFqNames
|
||||
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
|
||||
import org.jetbrains.kotlin.backend.konan.ir.typeWithStarProjections
|
||||
import org.jetbrains.kotlin.backend.konan.ir.typeWithoutArguments
|
||||
import org.jetbrains.kotlin.backend.konan.isObjCClass
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.computeFullName
|
||||
import org.jetbrains.kotlin.backend.konan.reportCompilationError
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
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.*
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
private fun IrBuilderWithScope.irConstantString(string: String) = irConstantPrimitive(irString(string))
|
||||
private fun IrBuilderWithScope.irConstantInt(int: Int) = irConstantPrimitive(irInt(int))
|
||||
private fun IrBuilderWithScope.irConstantBoolean(boolean: Boolean) = irConstantPrimitive(irBoolean(boolean))
|
||||
|
||||
internal class KTypeGenerator(
|
||||
val context: KonanBackendContext,
|
||||
val irFile: IrFile,
|
||||
@@ -49,15 +45,16 @@ internal class KTypeGenerator(
|
||||
type: IrType,
|
||||
leaveReifiedForLater: Boolean,
|
||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||
): IrExpression {
|
||||
): IrConstantValue {
|
||||
if (type !is IrSimpleType) {
|
||||
// Represent as non-denotable type:
|
||||
return irKTypeImpl(
|
||||
kClassifier = irNull(),
|
||||
irTypeArguments = emptyList(),
|
||||
isMarkedNullable = false,
|
||||
leaveReifiedForLater = leaveReifiedForLater,
|
||||
seenTypeParameters = seenTypeParameters
|
||||
kClassifier = irConstantPrimitive(irNull()),
|
||||
irTypeArguments = emptyList(),
|
||||
isMarkedNullable = false,
|
||||
leaveReifiedForLater = leaveReifiedForLater,
|
||||
seenTypeParameters = seenTypeParameters,
|
||||
type = type,
|
||||
)
|
||||
}
|
||||
try {
|
||||
@@ -66,7 +63,7 @@ internal class KTypeGenerator(
|
||||
is IrTypeParameterSymbol -> {
|
||||
if (classifier.owner.isReified && leaveReifiedForLater) {
|
||||
// Leave as is for reification.
|
||||
return irCall(symbols.typeOf).apply { putTypeArgument(0, type) }
|
||||
return irConstantObject(symbols.kTypeImplIntrinsicConstructor, emptyList(), listOf(type))
|
||||
}
|
||||
|
||||
// Leave upper bounds of non-reified type parameters as is, even if they are reified themselves.
|
||||
@@ -80,26 +77,28 @@ internal class KTypeGenerator(
|
||||
irTypeArguments = type.arguments,
|
||||
isMarkedNullable = type.hasQuestionMark,
|
||||
leaveReifiedForLater = leaveReifiedForLater,
|
||||
seenTypeParameters = seenTypeParameters
|
||||
seenTypeParameters = seenTypeParameters,
|
||||
type = type,
|
||||
)
|
||||
} catch (t: RecursiveBoundsException) {
|
||||
if (needExactTypeParameters)
|
||||
this@KTypeGenerator.context.reportCompilationError(t.message!!, irFile, irElement)
|
||||
return irCall(symbols.kTypeImplForTypeParametersWithRecursiveBounds.constructors.single())
|
||||
return irConstantObject(symbols.kTypeImplForTypeParametersWithRecursiveBounds.owner, emptyMap())
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irKTypeImpl(
|
||||
kClassifier: IrExpression,
|
||||
irTypeArguments: List<IrTypeArgument>,
|
||||
isMarkedNullable: Boolean,
|
||||
leaveReifiedForLater: Boolean,
|
||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||
): IrExpression = irCall(symbols.kTypeImpl.constructors.single()).apply {
|
||||
putValueArgument(0, kClassifier)
|
||||
putValueArgument(1, irKTypeProjectionsList(irTypeArguments, leaveReifiedForLater, seenTypeParameters))
|
||||
putValueArgument(2, irBoolean(isMarkedNullable))
|
||||
}
|
||||
kClassifier: IrConstantValue,
|
||||
irTypeArguments: List<IrTypeArgument>,
|
||||
isMarkedNullable: Boolean,
|
||||
leaveReifiedForLater: Boolean,
|
||||
seenTypeParameters: MutableSet<IrTypeParameter>,
|
||||
type: IrType,
|
||||
): IrConstantValue = irConstantObject(symbols.kTypeImpl.owner, mapOf(
|
||||
"classifier" to kClassifier,
|
||||
"arguments" to irKTypeProjectionsList(irTypeArguments, leaveReifiedForLater, seenTypeParameters),
|
||||
"isMarkedNullable" to irConstantPrimitive(irBoolean(isMarkedNullable)),
|
||||
), listOf(type))
|
||||
|
||||
private fun IrBuilderWithScope.irKClass(symbol: IrClassSymbol) = irKClass(this@KTypeGenerator.context, symbol)
|
||||
|
||||
@@ -107,86 +106,80 @@ internal class KTypeGenerator(
|
||||
typeParameter: IrTypeParameter,
|
||||
leaveReifiedForLater: Boolean,
|
||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||
): IrMemberAccessExpression<*> {
|
||||
): IrConstantValue {
|
||||
if (!seenTypeParameters.add(typeParameter))
|
||||
throw RecursiveBoundsException("Non-reified type parameters with recursive bounds are not supported yet: ${typeParameter.render()}")
|
||||
val result = irCall(symbols.kTypeParameterImpl.constructors.single()).apply {
|
||||
putValueArgument(0, irString(typeParameter.name.asString()))
|
||||
putValueArgument(1, irString(typeParameter.parentUniqueName))
|
||||
putValueArgument(2, irKTypeList(typeParameter.superTypes, leaveReifiedForLater, seenTypeParameters))
|
||||
putValueArgument(3, irKVariance(typeParameter.variance))
|
||||
putValueArgument(4, irBoolean(typeParameter.isReified))
|
||||
}
|
||||
val result = irConstantObject(symbols.kTypeParameterImpl.owner, mapOf(
|
||||
"name" to irConstantString(typeParameter.name.asString()),
|
||||
"containerFqName" to irConstantString(typeParameter.parentUniqueName),
|
||||
"upperBounds" to irKTypeList(typeParameter.superTypes, leaveReifiedForLater, seenTypeParameters),
|
||||
"varianceId" to irConstantInt(mapVariance(typeParameter.variance)),
|
||||
"isReified" to irConstantBoolean(typeParameter.isReified),
|
||||
))
|
||||
seenTypeParameters.remove(typeParameter)
|
||||
return result
|
||||
}
|
||||
|
||||
private val IrTypeParameter.parentUniqueName get() = when (val parent = parent) {
|
||||
is IrFunction -> parent.computeFullName()
|
||||
else -> parent.fqNameForIrSerialization.asString()
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irKVariance(variance: Variance) =
|
||||
IrGetEnumValueImpl(
|
||||
startOffset, endOffset,
|
||||
symbols.kVariance.defaultType,
|
||||
when (variance) {
|
||||
Variance.INVARIANT -> symbols.kVarianceInvariant
|
||||
Variance.IN_VARIANCE -> symbols.kVarianceIn
|
||||
Variance.OUT_VARIANCE -> symbols.kVarianceOut
|
||||
}
|
||||
)
|
||||
|
||||
private fun <T> IrBuilderWithScope.irKTypeLikeList(
|
||||
types: List<T>,
|
||||
itemType: IrType,
|
||||
itemBuilder: (T) -> IrExpression
|
||||
) = if (types.isEmpty()) {
|
||||
irCall(symbols.emptyList, listOf(itemType))
|
||||
} else {
|
||||
irCall(symbols.listOf, listOf(itemType)).apply {
|
||||
putValueArgument(0, IrVarargImpl(
|
||||
startOffset, endOffset,
|
||||
type = symbols.array.typeWith(itemType),
|
||||
varargElementType = itemType,
|
||||
elements = types.map { itemBuilder(it) }
|
||||
))
|
||||
private val IrTypeParameter.parentUniqueName
|
||||
get() = when (val parent = parent) {
|
||||
is IrFunction -> parent.computeFullName()
|
||||
else -> parent.fqNameForIrSerialization.asString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irKTypeList(
|
||||
types: List<IrType>,
|
||||
leaveReifiedForLater: Boolean,
|
||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||
) = irKTypeLikeList(types, symbols.kType.defaultType) { irKType(it, leaveReifiedForLater, seenTypeParameters) }
|
||||
): IrConstantValue {
|
||||
val itemType = symbols.kType.defaultType
|
||||
val elements = irConstantArray(symbols.array.typeWith(itemType),
|
||||
types.map { irKType(it, leaveReifiedForLater, seenTypeParameters) }
|
||||
)
|
||||
return irConstantObject(symbols.arrayAsList.owner, mapOf(
|
||||
"array" to elements
|
||||
))
|
||||
}
|
||||
|
||||
// this constants are copypasted from KVarianceMapper.Companion in KTypeImpl.kt
|
||||
private fun mapVariance(variance: Variance) = when (variance) {
|
||||
Variance.INVARIANT -> 0
|
||||
Variance.IN_VARIANCE -> 1
|
||||
Variance.OUT_VARIANCE -> 2
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irKTypeProjectionsList(
|
||||
irTypeArguments: List<IrTypeArgument>,
|
||||
leaveReifiedForLater: Boolean,
|
||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||
) = irKTypeLikeList(irTypeArguments, symbols.kTypeProjection.typeWithoutArguments) {
|
||||
irKTypeProjection(it, leaveReifiedForLater, seenTypeParameters)
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irKTypeProjection(
|
||||
argument: IrTypeArgument,
|
||||
leaveReifiedForLater: Boolean,
|
||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||
) = when (argument) {
|
||||
is IrTypeProjection -> irCall(symbols.kTypeProjectionFactories.getValue(argument.variance)).apply {
|
||||
dispatchReceiver = irGetObject(symbols.kTypeProjectionCompanion)
|
||||
putValueArgument(0, irKType(argument.type, leaveReifiedForLater, seenTypeParameters))
|
||||
}
|
||||
|
||||
is IrStarProjection -> irCall(symbols.kTypeProjectionStar.owner.getter!!).apply {
|
||||
dispatchReceiver = irGetObject(symbols.kTypeProjectionCompanion)
|
||||
}
|
||||
|
||||
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
|
||||
): IrConstantValue {
|
||||
val variance = irConstantArray(
|
||||
symbols.intArrayType,
|
||||
irTypeArguments.map { argument ->
|
||||
when (argument) {
|
||||
is IrStarProjection -> irConstantInt(-1)
|
||||
is IrTypeProjection -> irConstantInt(mapVariance(argument.variance))
|
||||
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
|
||||
}
|
||||
})
|
||||
val type = irConstantArray(
|
||||
symbols.array.typeWith(symbols.kType.defaultType.makeNullable()),
|
||||
irTypeArguments.map { argument ->
|
||||
when (argument) {
|
||||
is IrStarProjection -> irConstantPrimitive(irNull())
|
||||
is IrTypeProjection -> irKType(argument.type, leaveReifiedForLater, seenTypeParameters)
|
||||
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
|
||||
}
|
||||
})
|
||||
return irConstantObject(
|
||||
symbols.kTypeProjectionList.owner,
|
||||
mapOf(
|
||||
"variance" to variance,
|
||||
"type" to type
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun IrBuilderWithScope.irKClass(context: KonanBackendContext, symbol: IrClassSymbol): IrExpression {
|
||||
internal fun IrBuilderWithScope.irKClass(context: KonanBackendContext, symbol: IrClassSymbol): IrConstantValue {
|
||||
val symbols = context.ir.symbols
|
||||
return when {
|
||||
symbol.descriptor.isObjCClass() ->
|
||||
@@ -196,13 +189,11 @@ internal fun IrBuilderWithScope.irKClass(context: KonanBackendContext, symbol: I
|
||||
it is ClassDescriptor && it.fqNameUnsafe == InteropFqNames.nativePointed
|
||||
} -> irKClassUnsupported(context, "KClass for interop types is not supported yet")
|
||||
|
||||
else -> irCall(symbols.kClassImplConstructor.owner).apply {
|
||||
putValueArgument(0, irCall(symbols.getClassTypeInfo, listOf(symbol.typeWithStarProjections)))
|
||||
}
|
||||
else -> irConstantObject(symbols.kClassImplIntrinsicConstructor, emptyList(), listOf(symbol.typeWithStarProjections))
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irKClassUnsupported(context: KonanBackendContext, message: String) =
|
||||
irCall(context.ir.symbols.kClassUnsupportedImplConstructor.owner).apply {
|
||||
putValueArgument(0, irString(message))
|
||||
}
|
||||
irConstantObject(context.ir.symbols.kClassUnsupportedImpl.owner, mapOf(
|
||||
"message" to irConstantString(message)
|
||||
))
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package kotlin.native.internal
|
||||
|
||||
class ArrayAsList<T>(val array: Array<T>) : AbstractList<T>(), RandomAccess {
|
||||
override val size: Int get() = array.size
|
||||
override fun isEmpty(): Boolean = array.isEmpty()
|
||||
override fun contains(element: T): Boolean = array.contains(element)
|
||||
override fun get(index: Int): T = array[index]
|
||||
override fun indexOf(element: T): Int = array.indexOf(element)
|
||||
override fun lastIndexOf(element: T): Int = array.lastIndexOf(element)
|
||||
}
|
||||
@@ -46,7 +46,6 @@ class IntrinsicType {
|
||||
const val OBJC_GET_SELECTOR = "OBJC_GET_SELECTOR"
|
||||
|
||||
// Other
|
||||
const val GET_CLASS_TYPE_INFO = "GET_CLASS_TYPE_INFO"
|
||||
const val INTEROP_READ_BITS = "INTEROP_READ_BITS"
|
||||
const val INTEROP_WRITE_BITS = "INTEROP_WRITE_BITS"
|
||||
const val CREATE_UNINITIALIZED_INSTANCE = "CREATE_UNINITIALIZED_INSTANCE"
|
||||
|
||||
@@ -78,10 +78,6 @@ private external fun findAssociatedObjectImpl(typeInfo: NativePtr, key: NativePt
|
||||
@GCUnsafeCall("Kotlin_Any_getTypeInfo")
|
||||
internal external fun getObjectTypeInfo(obj: Any): NativePtr
|
||||
|
||||
@ExportForCompiler
|
||||
@TypedIntrinsic(IntrinsicType.GET_CLASS_TYPE_INFO)
|
||||
internal external inline fun <reified T : Any> getClassTypeInfo(): NativePtr
|
||||
|
||||
@GCUnsafeCall("Kotlin_TypeInfo_getPackageName")
|
||||
private external fun getPackageName(typeInfo: NativePtr, checkFlags: Boolean): String?
|
||||
|
||||
|
||||
@@ -7,13 +7,60 @@ package kotlin.native.internal
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal class KTypeImpl(
|
||||
internal object KVarianceMapper {
|
||||
// this constants are copypasted to ReflectionSupport.kt
|
||||
const val VARIANCE_STAR = -1
|
||||
const val VARIANCE_INVARIANT = 0
|
||||
const val VARIANCE_IN = 1
|
||||
const val VARIANCE_OUT = 2
|
||||
|
||||
fun idByVariance(variance: KVariance) = when (variance) {
|
||||
KVariance.INVARIANT -> VARIANCE_INVARIANT
|
||||
KVariance.IN -> VARIANCE_IN
|
||||
KVariance.OUT -> VARIANCE_OUT
|
||||
}
|
||||
|
||||
fun varianceById(id: Int) = when (id) {
|
||||
VARIANCE_STAR -> null
|
||||
VARIANCE_INVARIANT -> KVariance.INVARIANT
|
||||
VARIANCE_IN -> KVariance.IN
|
||||
VARIANCE_OUT -> KVariance.OUT
|
||||
else -> throw IllegalStateException("Unknown variance id ${id}")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This class is used to avoid having enum inside KType class
|
||||
* Static initialization for enum objects is not supported yet,
|
||||
* so to initialize KType statically we need to avoid them.
|
||||
*
|
||||
* When this issue is resolved, this class can be replaced with just ArrayList
|
||||
*/
|
||||
internal class KTypeProjectionList(val variance: IntArray, val type: Array<KType?>) : AbstractList<KTypeProjection>() {
|
||||
override val size
|
||||
get() = variance.size
|
||||
|
||||
|
||||
override fun get(index: Int) : KTypeProjection {
|
||||
AbstractList.checkElementIndex(index, size)
|
||||
val kVariance = KVarianceMapper.varianceById(variance[index]) ?: return KTypeProjection.STAR
|
||||
return KTypeProjection(kVariance, type[index])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class KTypeImpl<T>(
|
||||
override val classifier: KClassifier?,
|
||||
override val arguments: List<KTypeProjection>,
|
||||
override val isMarkedNullable: Boolean
|
||||
) : KType {
|
||||
|
||||
@ExportForCompiler
|
||||
@ConstantConstructorIntrinsic("KTYPE_IMPL")
|
||||
constructor() : this(null, TODO("This is intrinsic constructor and it shouldn't be used directly"), false)
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is KTypeImpl &&
|
||||
other is KTypeImpl<*> &&
|
||||
this.classifier == other.classifier &&
|
||||
this.arguments == other.arguments &&
|
||||
this.isMarkedNullable == other.isMarkedNullable
|
||||
|
||||
@@ -11,9 +11,15 @@ internal class KTypeParameterImpl(
|
||||
override val name: String,
|
||||
private val containerFqName: String,
|
||||
override val upperBounds: List<KType>,
|
||||
override val variance: KVariance,
|
||||
val varianceId: Int, // mapping is used to make static initialization possible
|
||||
override val isReified: Boolean
|
||||
) : KTypeParameter {
|
||||
override val variance: KVariance
|
||||
get() = KVarianceMapper.varianceById(varianceId)!!
|
||||
|
||||
constructor(name: String, containerFqName: String, upperBounds: List<KType>, variance: KVariance, isReified: Boolean) :
|
||||
this(name, containerFqName, upperBounds, KVarianceMapper.idByVariance(variance), isReified)
|
||||
|
||||
override fun toString(): String = when (variance) {
|
||||
KVariance.INVARIANT -> ""
|
||||
KVariance.IN -> "in "
|
||||
|
||||
Reference in New Issue
Block a user