[StubIr][Metadata] Add MappingExtensions class

Parent nodes may introduce some kind of context to their children. For example, type parameters.
Because of that we wrap all extension functions into MappingExtensions class.
This commit is contained in:
Sergey Bogolepov
2019-12-12 12:18:34 +07:00
committed by Sergey Bogolepov
parent 7e0a65e480
commit 37f9161ec2
3 changed files with 315 additions and 240 deletions
@@ -59,7 +59,7 @@ class TypeParameterStub(
val upperBound: StubType? = null
) {
fun getStubType(nullable: Boolean) =
TypeParameterType(name, nullable = nullable)
TypeParameterType(name, nullable = nullable, typeParameterDeclaration = this)
}
@@ -6,6 +6,7 @@ package org.jetbrains.kotlin.native.interop.gen
import kotlinx.metadata.*
import kotlinx.metadata.klib.*
import org.jetbrains.kotlin.metadata.serialization.Interner
import org.jetbrains.kotlin.utils.addIfNotNull
class StubIrMetadataEmitter(
@@ -69,7 +70,8 @@ internal class ModuleMetadataEmitter(
*/
private data class VisitingContext(
val container: StubContainer? = null,
val uniqIds: StubIrUniqIdProvider
val uniqIds: StubIrUniqIdProvider,
val typeParametersInterner: Interner<TypeParameterStub> = Interner()
)
private val visitor = object : StubIrVisitor<VisitingContext, Any> {
@@ -79,41 +81,47 @@ internal class ModuleMetadataEmitter(
}
override fun visitTypealias(element: TypealiasStub, data: VisitingContext): KmTypeAlias =
KmTypeAlias(element.flags, element.alias.topLevelName).also { km ->
km.uniqId = data.uniqIds.uniqIdForTypeAlias(element)
km.underlyingType = element.aliasee.map(shouldExpandTypeAliases = false)
km.expandedType = element.aliasee.map()
}
with (MappingExtensions(data.typeParametersInterner)) {
KmTypeAlias(element.flags, element.alias.topLevelName).also { km ->
km.uniqId = data.uniqIds.uniqIdForTypeAlias(element)
km.underlyingType = element.aliasee.map(shouldExpandTypeAliases = false)
km.expandedType = element.aliasee.map()
}
}
override fun visitFunction(element: FunctionStub, data: VisitingContext) =
KmFunction(element.flags, element.name).also { km ->
element.annotations.mapTo(km.annotations, AnnotationStub::map)
km.returnType = element.returnType.map()
element.parameters.mapTo(km.valueParameters, FunctionParameterStub::map)
element.typeParameters.mapTo(km.typeParameters, TypeParameterStub::map)
km.uniqId = data.uniqIds.uniqIdForFunction(element)
}
with (MappingExtensions(data.typeParametersInterner)) {
KmFunction(element.flags, element.name).also { km ->
element.typeParameters.mapTo(km.typeParameters) { it.map() }
element.parameters.mapTo(km.valueParameters) { it.map() }
element.annotations.mapTo(km.annotations) { it.map() }
km.returnType = element.returnType.map()
km.uniqId = data.uniqIds.uniqIdForFunction(element)
}
}
override fun visitProperty(element: PropertyStub, data: VisitingContext) =
KmProperty(element.flags, element.name, element.getterFlags, element.setterFlags).also { km ->
element.annotations.mapTo(km.annotations, AnnotationStub::map)
km.uniqId = data.uniqIds.uniqIdForProperty(element)
km.returnType = element.type.map()
if (element.kind is PropertyStub.Kind.Var) {
val setter = element.kind.setter
setter.annotations.mapTo(km.setterAnnotations, AnnotationStub::map)
// TODO: Maybe it's better to explicitly add setter parameter in stub.
km.setterParameter = FunctionParameterStub("value", element.type).map()
with (MappingExtensions(data.typeParametersInterner)) {
KmProperty(element.flags, element.name, element.getterFlags, element.setterFlags).also { km ->
element.annotations.mapTo(km.annotations) { it.map() }
km.uniqId = data.uniqIds.uniqIdForProperty(element)
km.returnType = element.type.map()
if (element.kind is PropertyStub.Kind.Var) {
val setter = element.kind.setter
setter.annotations.mapTo(km.setterAnnotations) { it.map() }
// TODO: Maybe it's better to explicitly add setter parameter in stub.
km.setterParameter = FunctionParameterStub("value", element.type).map()
}
km.getterAnnotations += when (element.kind) {
is PropertyStub.Kind.Val -> element.kind.getter.annotations.map { it.map() }
is PropertyStub.Kind.Var -> element.kind.getter.annotations.map { it.map() }
is PropertyStub.Kind.Constant -> emptyList()
}
if (element.kind is PropertyStub.Kind.Constant) {
km.compileTimeValue = element.kind.constant.mapToAnnotationArgument()
}
}
}
km.getterAnnotations += when (element.kind) {
is PropertyStub.Kind.Val -> element.kind.getter.annotations.map(AnnotationStub::map)
is PropertyStub.Kind.Var -> element.kind.getter.annotations.map(AnnotationStub::map)
is PropertyStub.Kind.Constant -> emptyList()
}
if (element.kind is PropertyStub.Kind.Constant) {
km.compileTimeValue = element.kind.constant.mapToAnnotationArgument()
}
}
override fun visitConstructor(constructorStub: ConstructorStub, data: VisitingContext) {
// TODO("not implemented")
@@ -129,223 +137,289 @@ internal class ModuleMetadataEmitter(
}
}
private val FunctionStub.flags: Flags
get() = listOfNotNull(
Flag.Common.IS_PUBLIC,
Flag.Function.IS_EXTERNAL,
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() },
Flag.IS_FINAL.takeIf { modality == MemberStubModality.FINAL },
Flag.IS_OPEN.takeIf { modality == MemberStubModality.OPEN },
Flag.IS_ABSTRACT.takeIf { modality == MemberStubModality.ABSTRACT }
).let { flagsOf(*it.toTypedArray()) }
private val Classifier.fqNameSerialized: String
get() = buildString {
if (pkg.isNotEmpty()) {
append(pkg.replace('.', '/'))
append('/')
}
// Nested classes should dot-separated.
append(relativeFqName)
}
private val PropertyStub.flags: Flags
get() = listOfNotNull(
Flag.IS_PUBLIC,
Flag.Property.IS_DECLARATION,
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() },
Flag.IS_FINAL.takeIf { modality == MemberStubModality.FINAL },
when (kind) {
is PropertyStub.Kind.Val -> null
is PropertyStub.Kind.Var -> Flag.Property.IS_VAR
is PropertyStub.Kind.Constant -> Flag.Property.IS_CONST
},
when (kind) {
is PropertyStub.Kind.Constant -> null
is PropertyStub.Kind.Val,
is PropertyStub.Kind.Var -> Flag.Property.HAS_GETTER
},
when (kind) {
is PropertyStub.Kind.Constant -> null
is PropertyStub.Kind.Val -> null
is PropertyStub.Kind.Var -> Flag.Property.HAS_SETTER
}
).let { flagsOf(*it.toTypedArray()) }
private val PropertyStub.getterFlags: Flags
get() = when (kind) {
is PropertyStub.Kind.Val -> kind.getter.flags
is PropertyStub.Kind.Var -> kind.getter.flags
is PropertyStub.Kind.Constant -> flagsOf()
}
private val PropertyAccessor.Getter.flags: Flags
get() = listOfNotNull(
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() },
Flag.IS_PUBLIC,
Flag.IS_FINAL,
Flag.PropertyAccessor.IS_EXTERNAL.takeIf { this is PropertyAccessor.Getter.ExternalGetter }
).let { flagsOf(*it.toTypedArray()) }
private val PropertyStub.setterFlags: Flags
get() = if (kind !is PropertyStub.Kind.Var) flagsOf()
else kind.setter.flags
private val PropertyAccessor.Setter.flags: Flags
get() = listOfNotNull(
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() },
Flag.IS_PUBLIC,
Flag.IS_FINAL,
Flag.PropertyAccessor.IS_EXTERNAL.takeIf { this is PropertyAccessor.Setter.ExternalSetter }
).let { flagsOf(*it.toTypedArray()) }
private val StubType.flags: Flags
get() = listOfNotNull(
Flag.Type.IS_NULLABLE.takeIf { nullable }
).let { flagsOf(*it.toTypedArray()) }
private val TypealiasStub.flags: Flags
get() = listOfNotNull(
Flag.IS_PUBLIC
).let { flagsOf(*it.toTypedArray()) }
private val FunctionParameterStub.flags: Flags
get() = listOfNotNull(
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }
).let { flagsOf(*it.toTypedArray()) }
private fun AnnotationStub.map(): KmAnnotation {
val args = when (this) {
AnnotationStub.ObjC.ConsumesReceiver -> TODO()
AnnotationStub.ObjC.ReturnsRetained -> TODO()
is AnnotationStub.ObjC.Method -> TODO()
is AnnotationStub.ObjC.Factory -> TODO()
AnnotationStub.ObjC.Consumed -> TODO()
is AnnotationStub.ObjC.Constructor -> TODO()
is AnnotationStub.ObjC.ExternalClass -> TODO()
AnnotationStub.CCall.CString -> mapOf()
AnnotationStub.CCall.WCString -> mapOf()
is AnnotationStub.CCall.Symbol ->
mapOf("id" to KmAnnotationArgument.StringValue(symbolName))
is AnnotationStub.CStruct -> TODO()
is AnnotationStub.CNaturalStruct -> TODO()
is AnnotationStub.CLength -> TODO()
is AnnotationStub.Deprecated -> TODO()
}
return KmAnnotation(classifier.fqNameSerialized, args)
}
/**
* @param shouldExpandTypeAliases describes how should we write type aliases.
* If [shouldExpandTypeAliases] is true then type alias-based types are written as
* ```
* Type {
* abbreviatedType = AbbreviatedType.abbreviatedClassifier
* classifier = AbbreviatedType.underlyingType
* arguments = AbbreviatedType.underlyingType.typeArguments
* }
* ```
* So we basically replacing type alias with underlying class.
* Otherwise:
* ```
* Type {
* classifier = AbbreviatedType.abbreviatedClassifier
* }
* ```
* As of 25 Nov 2019, the latter form is used only for KmTypeAlias.underlyingType.
* Collection of extension functions that simplify translation of
* StubIr elements to Kotlin Metadata.
*/
// TODO: Add caching if needed.
private fun StubType.map(shouldExpandTypeAliases: Boolean = true): KmType = when (this) {
is AbbreviatedType -> {
val typeAliasClassifier = KmClassifier.TypeAlias(abbreviatedClassifier.fqNameSerialized)
if (shouldExpandTypeAliases) {
// Abbreviated and expanded types have the same nullability.
KmType(flags).also { km ->
km.abbreviatedType = KmType(flags).also { it.classifier = typeAliasClassifier }
val kmUnderlyingType = underlyingType.map(true)
km.arguments += kmUnderlyingType.arguments
km.classifier = kmUnderlyingType.classifier
}
} else {
KmType(flags).also { km -> km.classifier = typeAliasClassifier }
}
}
is ClassifierStubType -> KmType(flags).also { km ->
typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) }
km.classifier = KmClassifier.Class(classifier.fqNameSerialized)
}
is FunctionalType -> KmType(flags).also { km ->
typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) }
km.classifier = KmClassifier.Class(classifier.fqNameSerialized)
}
is TypeParameterType -> KmType(flags).also { km ->
km.classifier = KmClassifier.TypeParameter(id)
}
}
private class MappingExtensions(
private val typeParametersInterner: Interner<TypeParameterStub>
) {
private fun FunctionParameterStub.map(): KmValueParameter =
KmValueParameter(flags, name).also { km ->
val kmType = type.map()
if (isVararg) {
km.varargElementType = kmType
private fun flagsOfNotNull(vararg flags: Flag?): Flags =
flagsOf(*listOfNotNull(*flags).toTypedArray())
private fun <K, V> mapOfNotNull(vararg entries: Pair<K, V>?): Map<K, V> =
listOfNotNull(*entries).toMap()
private val VisibilityModifier.flags: Flags
get() = flagsOfNotNull(
Flag.IS_PUBLIC.takeIf { this == VisibilityModifier.PUBLIC },
Flag.IS_PROTECTED.takeIf { this == VisibilityModifier.PROTECTED },
Flag.IS_INTERNAL.takeIf { this == VisibilityModifier.INTERNAL },
Flag.IS_PRIVATE.takeIf { this == VisibilityModifier.PRIVATE }
)
private val MemberStubModality.flags: Flags
get() = flagsOfNotNull(
Flag.IS_FINAL.takeIf { this == MemberStubModality.FINAL },
Flag.IS_OPEN.takeIf { this == MemberStubModality.OPEN },
Flag.IS_ABSTRACT.takeIf { this == MemberStubModality.ABSTRACT }
)
val FunctionStub.flags: Flags
get() = flagsOfNotNull(
Flag.IS_PUBLIC,
Flag.Function.IS_EXTERNAL,
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }
) or modality.flags
val Classifier.fqNameSerialized: String
get() = buildString {
if (pkg.isNotEmpty()) {
append(pkg.replace('.', '/'))
append('/')
}
// Nested classes should dot-separated.
append(relativeFqName)
}
val PropertyStub.flags: Flags
get() = flagsOfNotNull(
Flag.IS_PUBLIC,
Flag.Property.IS_DECLARATION,
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() },
when (kind) {
is PropertyStub.Kind.Val -> null
is PropertyStub.Kind.Var -> Flag.Property.IS_VAR
is PropertyStub.Kind.Constant -> Flag.Property.IS_CONST
},
when (kind) {
is PropertyStub.Kind.Constant -> null
is PropertyStub.Kind.Val,
is PropertyStub.Kind.Var -> Flag.Property.HAS_GETTER
},
when (kind) {
is PropertyStub.Kind.Constant -> null
is PropertyStub.Kind.Val -> null
is PropertyStub.Kind.Var -> Flag.Property.HAS_SETTER
}
) or modality.flags
val PropertyStub.getterFlags: Flags
get() = when (kind) {
is PropertyStub.Kind.Val -> kind.getter.flags
is PropertyStub.Kind.Var -> kind.getter.flags
is PropertyStub.Kind.Constant -> flagsOf()
}
private val PropertyAccessor.Getter.flags: Flags
get() = flagsOfNotNull(
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() },
Flag.IS_PUBLIC,
Flag.IS_FINAL,
Flag.PropertyAccessor.IS_EXTERNAL.takeIf { this is PropertyAccessor.Getter.ExternalGetter }
)
val PropertyStub.setterFlags: Flags
get() = if (kind !is PropertyStub.Kind.Var) flagsOf()
else kind.setter.flags
val PropertyAccessor.Setter.flags: Flags
get() = flagsOfNotNull(
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() },
Flag.IS_PUBLIC,
Flag.IS_FINAL,
Flag.PropertyAccessor.IS_EXTERNAL.takeIf { this is PropertyAccessor.Setter.ExternalSetter }
)
val StubType.flags: Flags
get() = flagsOfNotNull(
Flag.Type.IS_NULLABLE.takeIf { nullable }
)
val TypealiasStub.flags: Flags
get() = flagsOfNotNull(
Flag.IS_PUBLIC
)
val FunctionParameterStub.flags: Flags
get() = flagsOfNotNull(
Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }
)
fun AnnotationStub.map(): KmAnnotation {
fun Pair<String, String>.asAnnotationArgument() =
(first to KmAnnotationArgument.StringValue(second)).takeIf { second.isNotEmpty() }
fun replaceWith(replaceWith: String) = KmAnnotationArgument.AnnotationValue(KmAnnotation(
Classifier.topLevel("kotlin", "ReplaceWith").fqNameSerialized,
mapOfNotNull(
"imports" to KmAnnotationArgument.ArrayValue(emptyList()),
("expression" to replaceWith).asAnnotationArgument()
)
))
fun deprecationLevel(level: DeprecationLevel) = KmAnnotationArgument.EnumValue(
Classifier.topLevel("kotlin", "DeprecationLevel").fqNameSerialized,
level.name
)
val args = when (this) {
AnnotationStub.ObjC.ConsumesReceiver -> emptyMap()
AnnotationStub.ObjC.ReturnsRetained -> emptyMap()
is AnnotationStub.ObjC.Method -> mapOfNotNull(
("selector" to selector).asAnnotationArgument(),
("encoding" to encoding).asAnnotationArgument(),
("isStret" to KmAnnotationArgument.BooleanValue(isStret))
)
is AnnotationStub.ObjC.Factory -> mapOfNotNull(
("selector" to selector).asAnnotationArgument(),
("encoding" to encoding).asAnnotationArgument(),
("isStret" to KmAnnotationArgument.BooleanValue(isStret))
)
AnnotationStub.ObjC.Consumed -> emptyMap()
is AnnotationStub.ObjC.Constructor -> mapOfNotNull(
("designated" to KmAnnotationArgument.BooleanValue(designated)),
("initSelector" to selector).asAnnotationArgument()
)
is AnnotationStub.ObjC.ExternalClass -> mapOfNotNull(
("protocolGetter" to protocolGetter).asAnnotationArgument(),
("binaryName" to binaryName).asAnnotationArgument()
)
AnnotationStub.CCall.CString -> emptyMap()
AnnotationStub.CCall.WCString -> emptyMap()
is AnnotationStub.CCall.Symbol -> mapOfNotNull(
("id" to symbolName).asAnnotationArgument()
)
is AnnotationStub.CStruct -> mapOfNotNull(
("spelling" to struct).asAnnotationArgument()
)
is AnnotationStub.CNaturalStruct ->
error("@CNaturalStruct should not be used for Kotlin/Native interop")
is AnnotationStub.CLength -> mapOfNotNull(
"value" to KmAnnotationArgument.LongValue(length)
)
is AnnotationStub.Deprecated -> mapOfNotNull(
("message" to message).asAnnotationArgument(),
("replaceWith" to replaceWith(replaceWith)),
("level" to deprecationLevel(DeprecationLevel.ERROR))
)
}
return KmAnnotation(classifier.fqNameSerialized, args)
}
/**
* @param shouldExpandTypeAliases describes how should we write type aliases.
* If [shouldExpandTypeAliases] is true then type alias-based types are written as
* ```
* Type {
* abbreviatedType = AbbreviatedType.abbreviatedClassifier
* classifier = AbbreviatedType.underlyingType
* arguments = AbbreviatedType.underlyingType.typeArguments
* }
* ```
* So we basically replacing type alias with underlying class.
* Otherwise:
* ```
* Type {
* classifier = AbbreviatedType.abbreviatedClassifier
* }
* ```
* As of 25 Nov 2019, the latter form is used only for KmTypeAlias.underlyingType.
*/
// TODO: Add caching if needed.
fun StubType.map(shouldExpandTypeAliases: Boolean = true): KmType = when (this) {
is AbbreviatedType -> {
val typeAliasClassifier = KmClassifier.TypeAlias(abbreviatedClassifier.fqNameSerialized)
if (shouldExpandTypeAliases) {
// Abbreviated and expanded types have the same nullability.
KmType(flags).also { km ->
km.abbreviatedType = KmType(flags).also { it.classifier = typeAliasClassifier }
val kmUnderlyingType = underlyingType.map(true)
km.arguments += kmUnderlyingType.arguments
km.classifier = kmUnderlyingType.classifier
}
} else {
km.type = kmType
KmType(flags).also { km -> km.classifier = typeAliasClassifier }
}
annotations.mapTo(km.annotations, AnnotationStub::map)
}
private fun TypeParameterStub.map(): KmTypeParameter =
KmTypeParameter(flagsOf(), name, id, KmVariance.INVARIANT).also { km ->
km.upperBounds.addIfNotNull(upperBound?.map())
is ClassifierStubType -> KmType(flags).also { km ->
typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) }
km.classifier = KmClassifier.Class(classifier.fqNameSerialized)
}
private fun TypeArgument.map(expanded: Boolean=true): KmTypeProjection = when (this) {
TypeArgument.StarProjection -> KmTypeProjection.STAR
is TypeArgumentStub -> KmTypeProjection(variance.map(), type.map(expanded))
else -> error("Unexpected TypeArgument: $this")
}
private fun TypeArgument.Variance.map(): KmVariance = when (this) {
TypeArgument.Variance.INVARIANT -> KmVariance.INVARIANT
TypeArgument.Variance.IN -> KmVariance.IN
TypeArgument.Variance.OUT -> KmVariance.OUT
}
private fun ConstantStub.mapToAnnotationArgument(): KmAnnotationArgument<*> = when (this) {
is StringConstantStub -> KmAnnotationArgument.StringValue(value)
is IntegralConstantStub -> when (size) {
1 -> if (isSigned) {
KmAnnotationArgument.ByteValue(value.toByte())
} else {
KmAnnotationArgument.UByteValue(value.toByte())
is FunctionalType -> KmType(flags).also { km ->
typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) }
km.classifier = KmClassifier.Class(classifier.fqNameSerialized)
}
2 -> if (isSigned) {
KmAnnotationArgument.ShortValue(value.toShort())
} else {
KmAnnotationArgument.UShortValue(value.toShort())
is TypeParameterType -> KmType(flags).also { km ->
km.classifier = KmClassifier.TypeParameter(id)
}
4 -> if (isSigned) {
KmAnnotationArgument.IntValue(value.toInt())
} else {
KmAnnotationArgument.UIntValue(value.toInt())
}
8 -> if (isSigned) {
KmAnnotationArgument.LongValue(value)
} else {
KmAnnotationArgument.ULongValue(value)
}
else -> error("Integral constant of value $value with unexpected size of $size.")
}
is DoubleConstantStub -> when (size) {
4 -> KmAnnotationArgument.FloatValue(value.toFloat())
8 -> KmAnnotationArgument.DoubleValue(value)
else -> error("Floating-point constant of value $value with unexpected size of $size.")
fun FunctionParameterStub.map(): KmValueParameter =
KmValueParameter(flags, name).also { km ->
val kmType = type.map()
if (isVararg) {
km.varargElementType = kmType
} else {
km.type = kmType
}
annotations.mapTo(km.annotations, { it.map() })
}
fun TypeParameterStub.map(): KmTypeParameter =
KmTypeParameter(flagsOf(), name, id, KmVariance.INVARIANT).also { km ->
km.upperBounds.addIfNotNull(upperBound?.map())
}
private fun TypeArgument.map(expanded: Boolean = true): KmTypeProjection = when (this) {
TypeArgument.StarProjection -> KmTypeProjection.STAR
is TypeArgumentStub -> KmTypeProjection(variance.map(), type.map(expanded))
else -> error("Unexpected TypeArgument: $this")
}
}
private val TypeParameterType.id: Int
get() = TODO()
private fun TypeArgument.Variance.map(): KmVariance = when (this) {
TypeArgument.Variance.INVARIANT -> KmVariance.INVARIANT
TypeArgument.Variance.IN -> KmVariance.IN
TypeArgument.Variance.OUT -> KmVariance.OUT
}
private val TypeParameterStub.id: Int
get() = TODO()
fun ConstantStub.mapToAnnotationArgument(): KmAnnotationArgument<*> = when (this) {
is StringConstantStub -> KmAnnotationArgument.StringValue(value)
is IntegralConstantStub -> when (size) {
1 -> if (isSigned) {
KmAnnotationArgument.ByteValue(value.toByte())
} else {
KmAnnotationArgument.UByteValue(value.toByte())
}
2 -> if (isSigned) {
KmAnnotationArgument.ShortValue(value.toShort())
} else {
KmAnnotationArgument.UShortValue(value.toShort())
}
4 -> if (isSigned) {
KmAnnotationArgument.IntValue(value.toInt())
} else {
KmAnnotationArgument.UIntValue(value.toInt())
}
8 -> if (isSigned) {
KmAnnotationArgument.LongValue(value)
} else {
KmAnnotationArgument.ULongValue(value)
}
else -> error("Integral constant of value $value with unexpected size of $size.")
}
is DoubleConstantStub -> when (size) {
4 -> KmAnnotationArgument.FloatValue(value.toFloat())
8 -> KmAnnotationArgument.DoubleValue(value)
else -> error("Floating-point constant of value $value with unexpected size of $size.")
}
}
private val TypeParameterType.id: Int
get() = typeParameterDeclaration.id
private val TypeParameterStub.id: Int
get() = typeParametersInterner.intern(this)
}
@@ -65,7 +65,8 @@ class FunctionalType(
class TypeParameterType(
val name: String,
override val nullable: Boolean
override val nullable: Boolean,
val typeParameterDeclaration: TypeParameterStub
) : StubType() {
override val typeArguments: List<TypeArgument> = emptyList()
}