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