diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/InteropMangler.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/InteropMangler.kt index cbde8f84f77..037abaeb92d 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/InteropMangler.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/InteropMangler.kt @@ -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" diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/ObjCStubs.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/ObjCStubs.kt index 1d97a325d10..6f9b895f787 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/ObjCStubs.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/ObjCStubs.kt @@ -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( diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIr.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIr.kt index f721b3f9ddc..bdec5b7e92f 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIr.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIr.kt @@ -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 = emptyList(), override val properties: List = emptyList(), - override val origin: StubOrigin = StubOrigin.Synthetic, + override val origin: StubOrigin = StubOrigin.Synthetic.CompanionObject, override val annotations: List = emptyList(), override val childrenClasses: List = emptyList(), override val simpleContainers: List = emptyList() @@ -328,8 +347,7 @@ class FunctionParameterStub( val name: String, val type: StubType, override val annotations: List = 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 + val aliases: List, + val origin: StubOrigin.EnumEntry ) { class Alias(val name: String) } diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt index 3f8eaf3419b..f84c56f1e8c 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt @@ -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) } } } diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt index b649974f4a0..32aac55c013 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt @@ -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)) { diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrUniqIdProvider.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrUniqIdProvider.kt index e108ade4baf..81285f6b6a0 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrUniqIdProvider.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrUniqIdProvider.kt @@ -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