[StubIr] Refactor origins

1. Get rid of useless origin for FunctionParameterStub.
2. Add origins for enum entries and struct members.
3. Put all synthetic origins under single sealed class.
4. Add mangling for enum entries.
This commit is contained in:
Sergey Bogolepov
2020-01-27 13:05:00 +07:00
committed by Sergey Bogolepov
parent 3a4620cd33
commit bb34a0f22b
6 changed files with 60 additions and 27 deletions
@@ -37,6 +37,7 @@ sealed class ManglingContext {
interface InteropMangler {
val StructDecl.uniqueSymbolName: String
val EnumDef.uniqueSymbolName: String
val EnumConstant.uniqSymbolName: String
val ObjCClass.uniqueSymbolName: String
val ObjCClass.metaClassUniqueSymbolName: String
val ObjCProtocol.uniqueSymbolName: String
@@ -63,6 +64,9 @@ class KotlinLikeInteropMangler(context: ManglingContext = ManglingContext.Empty)
override val EnumDef.uniqueSymbolName: String
get() = "enumdef:$prefix$spelling"
override val EnumConstant.uniqSymbolName: String
get() = "enumconstant:$prefix$name"
override val ObjCClass.uniqueSymbolName: String
get() = "objcclass:$prefix$name"
@@ -435,7 +435,7 @@ internal abstract class ObjCContainerStubBuilder(
ConstructorStub(
isPrimary = false,
visibility = VisibilityModifier.PROTECTED,
origin = StubOrigin.SyntheticDefaultConstructor)
origin = StubOrigin.Synthetic.DefaultConstructor)
} else null
return Pair(
@@ -91,13 +91,29 @@ sealed class StubOrigin {
/**
* Special case when element of IR was generated.
*/
// TODO: All "synthetic" cases should be handled separately.
object Synthetic : StubOrigin()
sealed class Synthetic : StubOrigin() {
object CompanionObject : Synthetic()
/**
* Denotes default constructor that was generated and has no real origin.
*/
object SyntheticDefaultConstructor : StubOrigin()
/**
* Denotes default constructor that was generated and has no real origin.
*/
object DefaultConstructor : Synthetic()
/**
* CEnum.Companion.byValue.
*/
class EnumByValue(val enum: EnumDef) : Synthetic()
/**
* CEnum.value.
*/
class EnumValueField(val enum: EnumDef) : Synthetic()
/**
* E.CEnumVar.value.
*/
class EnumVarValueField(val enum: EnumDef) : Synthetic()
}
class ObjCCategoryInitMethod(
val method: org.jetbrains.kotlin.native.interop.indexer.ObjCMethod
@@ -125,13 +141,16 @@ sealed class StubOrigin {
class Enum(val enum: EnumDef) : StubOrigin()
class EnumEntry(val constant: EnumConstant) : StubOrigin()
class Function(val function: FunctionDecl) : StubOrigin()
// TODO: Unused, remove.
class FunctionParameter(val parameter: Parameter) : StubOrigin()
class Struct(val struct: StructDecl) : StubOrigin()
class StructMember(
val member: org.jetbrains.kotlin.native.interop.indexer.StructMember
) : StubOrigin()
class Constant(val constantDef: ConstantDef): StubOrigin()
class Global(val global: GlobalDecl) : StubOrigin()
@@ -283,7 +302,7 @@ sealed class ClassStub : StubContainer(), StubElementWithOrigin, AnnotationHolde
override val superClassInit: SuperClassInit? = null,
override val interfaces: List<StubType> = emptyList(),
override val properties: List<PropertyStub> = emptyList(),
override val origin: StubOrigin = StubOrigin.Synthetic,
override val origin: StubOrigin = StubOrigin.Synthetic.CompanionObject,
override val annotations: List<AnnotationStub> = emptyList(),
override val childrenClasses: List<ClassStub> = emptyList(),
override val simpleContainers: List<SimpleStubContainer> = emptyList()
@@ -328,8 +347,7 @@ class FunctionParameterStub(
val name: String,
val type: StubType,
override val annotations: List<AnnotationStub> = emptyList(),
val isVararg: Boolean = false,
val origin: StubOrigin = StubOrigin.Synthetic
val isVararg: Boolean = false
) : AnnotationHolder
enum class MemberStubModality {
@@ -454,7 +472,8 @@ class ConstructorStub(
class EnumEntryStub(
val name: String,
val constant: IntegralConstantStub,
val aliases: List<Alias>
val aliases: List<Alias>,
val origin: StubOrigin.EnumEntry
) {
class Alias(val name: String)
}
@@ -73,7 +73,7 @@ internal class StructStubBuilder(
val offset = field.offset / 8
val fieldRefType = context.mirror(field.type)
val unwrappedFieldType = field.type.unwrapTypedefs()
val origin = StubOrigin.Synthetic
val origin = StubOrigin.StructMember(field)
if (unwrappedFieldType is ArrayType) {
val type = (fieldRefType as TypeMirror.ByValue).valueType
val annotations = if (platform == KotlinPlatform.JVM) {
@@ -115,7 +115,7 @@ internal class StructStubBuilder(
context.bridgeComponentsBuilder.getterToBridgeInfo[readBits] = BridgeGenerationInfo("", typeInfo)
context.bridgeComponentsBuilder.setterToBridgeInfo[writeBits] = BridgeGenerationInfo("", typeInfo)
val kind = PropertyStub.Kind.Var(readBits, writeBits)
PropertyStub(field.name, kotlinType.toStubIrType(), kind, origin = StubOrigin.Synthetic)
PropertyStub(field.name, kotlinType.toStubIrType(), kind, origin = StubOrigin.StructMember(field))
}
val superClass = context.platform.getRuntimeType("CStructVar")
@@ -215,7 +215,7 @@ internal class EnumStubBuilder(
type = baseType,
kind = PropertyStub.Kind.Val(PropertyAccessor.Getter.GetConstructorParameter(constructorParameter)),
modality = MemberStubModality.OPEN,
origin = StubOrigin.Synthetic,
origin = StubOrigin.Synthetic.EnumValueField(enumDef),
isOverride = true)
val canonicalsByValue = enumDef.constants
@@ -233,7 +233,7 @@ internal class EnumStubBuilder(
val literal = context.tryCreateIntegralStub(enumDef.baseType, constant.value)
?: error("Cannot create enum value ${constant.value} of type ${enumDef.baseType}")
val aliases = aliasConstants.filter { it.value == constant.value }.map { EnumEntryStub.Alias(it.name) }
EnumEntryStub(constant.name, literal, aliases)
EnumEntryStub(constant.name, literal, aliases, StubOrigin.EnumEntry(constant))
}
val origin = StubOrigin.Enum(enumDef)
val primaryConstructor = ConstructorStub(listOf(constructorParameter), emptyList(), isPrimary = true, origin = origin)
@@ -303,7 +303,7 @@ internal class EnumStubBuilder(
kind,
MemberStubModality.FINAL,
null,
origin = StubOrigin.Synthetic
origin = StubOrigin.EnumEntry(constant)
)
}
val container = SimpleStubContainer(
@@ -333,7 +333,6 @@ internal class FunctionStubBuilder(
}
val representAsValuesRef = representCFunctionParameterAsValuesRef(parameter.type)
val origin = StubOrigin.FunctionParameter(parameter)
parameters += when {
representCFunctionParameterAsString(func, parameter.type) -> {
val annotations = when (platform) {
@@ -341,7 +340,7 @@ internal class FunctionStubBuilder(
KotlinPlatform.NATIVE -> listOf(AnnotationStub.CCall.CString)
}
val type = KotlinTypes.string.makeNullable().toStubIrType()
val functionParameterStub = FunctionParameterStub(parameterName, type, annotations, origin = origin)
val functionParameterStub = FunctionParameterStub(parameterName, type, annotations)
context.bridgeComponentsBuilder.cStringParameters += functionParameterStub
functionParameterStub
}
@@ -351,17 +350,17 @@ internal class FunctionStubBuilder(
KotlinPlatform.NATIVE -> listOf(AnnotationStub.CCall.WCString)
}
val type = KotlinTypes.string.makeNullable().toStubIrType()
val functionParameterStub = FunctionParameterStub(parameterName, type, annotations, origin = origin)
val functionParameterStub = FunctionParameterStub(parameterName, type, annotations)
context.bridgeComponentsBuilder.wCStringParameters += functionParameterStub
functionParameterStub
}
representAsValuesRef != null -> {
FunctionParameterStub(parameterName, representAsValuesRef.toStubIrType(), origin = origin)
FunctionParameterStub(parameterName, representAsValuesRef.toStubIrType())
}
else -> {
val mirror = context.mirror(parameter.type)
val type = mirror.argType.toStubIrType()
FunctionParameterStub(parameterName, type, origin = origin)
FunctionParameterStub(parameterName, type)
}
}
}
@@ -83,7 +83,7 @@ internal class ModuleMetadataEmitter(
typeParametersInterner = Interner(data.typeParametersInterner)
)
val children = element.children + if (element is ClassStub.Companion) {
listOf(ConstructorStub(isPrimary = true, visibility = VisibilityModifier.PRIVATE, origin = StubOrigin.SyntheticDefaultConstructor))
listOf(ConstructorStub(isPrimary = true, visibility = VisibilityModifier.PRIVATE, origin = StubOrigin.Synthetic.DefaultConstructor))
} else emptyList()
val elements = KmElements(children.map { it.accept(this, classVisitingContext) })
val kmClass = with (MappingExtensions(data.typeParametersInterner)) {
@@ -21,6 +21,7 @@ internal class StubIrUniqIdProvider(private val context: ManglingContext) {
is StubOrigin.Function -> function.origin.function.uniqueSymbolName
is StubOrigin.ObjCMethod -> function.origin.method.uniqueSymbolName
is StubOrigin.ObjCCategoryInitMethod -> "${function.origin.method.uniqueSymbolName}#Create"
is StubOrigin.Synthetic.EnumByValue -> "${function.origin.enum.uniqueSymbolName}#ByValue"
else -> error("Unexpected origin ${function.origin} for function ${function.name}.")
}.toUniqId()
}
@@ -30,7 +31,12 @@ internal class StubIrUniqIdProvider(private val context: ManglingContext) {
is StubOrigin.ObjCProperty -> property.origin.property.uniqueSymbolName
is StubOrigin.Constant -> property.origin.constantDef.uniqueSymbolName
is StubOrigin.Global -> property.origin.global.uniqueSymbolName
// TODO: What to do with origin for enum entries and struct fields?
// TODO: Is it correct for entries that are emitted as top-level constants?
// Should we emit the same uniq id for constants and enum entries?
is StubOrigin.EnumEntry -> property.origin.constant.uniqSymbolName
is StubOrigin.Synthetic.EnumValueField -> "${property.origin.enum.uniqueSymbolName}#Value"
is StubOrigin.StructMember -> property.origin.member.name
is StubOrigin.Synthetic.EnumVarValueField -> "${property.origin.enum.uniqueSymbolName}#Var"
else -> error("Unexpected origin ${property.origin} for property ${property.name}.")
}.toUniqId()
}
@@ -60,6 +66,7 @@ internal class StubIrUniqIdProvider(private val context: ManglingContext) {
}
is StubOrigin.Struct -> origin.struct.uniqueSymbolName
is StubOrigin.Enum -> origin.enum.uniqueSymbolName
is StubOrigin.VarOf -> "${uniqSymbolNameForClass(origin.typeOrigin)}#Var"
else -> null
}
@@ -72,7 +79,7 @@ internal class StubIrUniqIdProvider(private val context: ManglingContext) {
}.toUniqId()
private fun InteropMangler.uniqSymbolNameForConstructor(origin: StubOrigin): String? = when (origin) {
is StubOrigin.SyntheticDefaultConstructor -> "${context.prefix}#Constructor"
is StubOrigin.Synthetic.DefaultConstructor -> "${context.prefix}#Constructor"
is StubOrigin.Enum -> "${origin.enum.uniqueSymbolName}#Constructor"
is StubOrigin.Struct -> "${origin.struct.uniqueSymbolName}#Constructor"
is StubOrigin.ObjCMethod -> "${origin.method.uniqueSymbolName}#Constructor"
@@ -84,6 +91,10 @@ internal class StubIrUniqIdProvider(private val context: ManglingContext) {
?: error("Unexpected origin ${constructorStub.origin} for constructor.")
}.toUniqId()
fun uniqIdForEnumEntry(enumEntry: EnumEntryStub, enum: ClassStub.Enum): UniqId = with (mangler) {
"${uniqSymbolNameForClass(enum.origin)}#${enumEntry.origin.constant.name}"
}.toUniqId()
/**
* MSB should be set to 1 for public declarations.
* @see org.jetbrains.kotlin.ir.util.UniqId