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 c698cee7bd3..07271db8140 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 @@ -166,7 +166,7 @@ private class ObjCMethodStubBuilder( context.configuration.disableDesignatedInitializerChecks val annotations = listOf(AnnotationStub.ObjC.Constructor(method.selector, designated)) - val constructor = ConstructorStub(parameters, annotations, isPrimary = false) + val constructor = ConstructorStub(parameters, annotations, isPrimary = false, origin = origin) constructor } is ObjCCategory -> { @@ -206,7 +206,7 @@ private class ObjCMethodStubBuilder( receiver = receiver, typeParameters = listOf(typeParameter), external = true, - origin = StubOrigin.Synthetic, + origin = StubOrigin.ObjCCategoryInitMethod(method), annotations = annotations, modality = MemberStubModality.FINAL ) @@ -434,7 +434,10 @@ internal abstract class ObjCContainerStubBuilder( val defaultConstructor = if (container is ObjCClass && methodToStub.values.none { it.isDefaultConstructor() }) { // Always generate default constructor. // If it is not produced for an init method, then include it manually: - ConstructorStub(isPrimary = false, visibility = VisibilityModifier.PROTECTED) + ConstructorStub( + isPrimary = false, + visibility = VisibilityModifier.PROTECTED, + origin = StubOrigin.SyntheticDefaultConstructor) } else null return Pair( @@ -482,7 +485,7 @@ internal class ObjCProtocolStubBuilder( private val protocol: ObjCProtocol ) : ObjCClassOrProtocolStubBuilder(context, protocol), StubElementBuilder { override fun build(): List { - val classStub = buildClassStub(StubOrigin.ObjCProtocol(protocol)) + val classStub = buildClassStub(StubOrigin.ObjCProtocol(protocol, isMeta = false)) return listOf(*metaContainerStub!!.build().toTypedArray(), classStub) } } 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 b2062a26c17..22fdeaabc0b 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,7 +91,17 @@ sealed class StubOrigin { /** * Special case when element of IR was generated. */ - object None : StubOrigin() + // TODO: All "synthetic" cases should be handled separately. + object Synthetic : StubOrigin() + + /** + * Denotes default constructor that was generated and has no real origin. + */ + object SyntheticDefaultConstructor : StubOrigin() + + class ObjCCategoryInitMethod( + val method: org.jetbrains.kotlin.native.interop.indexer.ObjCMethod + ) : StubOrigin() class ObjCMethod( val method: org.jetbrains.kotlin.native.interop.indexer.ObjCMethod, @@ -104,11 +114,13 @@ sealed class StubOrigin { ) : StubOrigin() class ObjCClass( - val clazz: org.jetbrains.kotlin.native.interop.indexer.ObjCClass + val clazz: org.jetbrains.kotlin.native.interop.indexer.ObjCClass, + val isMeta: Boolean ) : StubOrigin() class ObjCProtocol( - val protocol: org.jetbrains.kotlin.native.interop.indexer.ObjCProtocol + val protocol: org.jetbrains.kotlin.native.interop.indexer.ObjCProtocol, + val isMeta: Boolean ) : StubOrigin() class Enum(val enum: EnumDef) : StubOrigin() @@ -270,7 +282,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.None, + override val origin: StubOrigin = StubOrigin.Synthetic, override val annotations: List = emptyList(), override val childrenClasses: List = emptyList(), override val simpleContainers: List = emptyList() @@ -316,7 +328,7 @@ class FunctionParameterStub( val type: StubType, override val annotations: List = emptyList(), val isVararg: Boolean = false, - val origin: StubOrigin = StubOrigin.None + val origin: StubOrigin = StubOrigin.Synthetic ) : AnnotationHolder enum class MemberStubModality { @@ -430,7 +442,8 @@ class ConstructorStub( override val parameters: List = emptyList(), override val annotations: List = emptyList(), val isPrimary: Boolean, - val visibility: VisibilityModifier = VisibilityModifier.PUBLIC + val visibility: VisibilityModifier = VisibilityModifier.PUBLIC, + val origin: StubOrigin ) : FunctionalStub { override fun accept(visitor: StubIrVisitor, data: T) = diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt index 5e4bcabc8c4..69dd06dcbb7 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt @@ -73,7 +73,8 @@ class StubIrBridgeBuilder( override fun visitClass(element: ClassStub, owner: StubContainer?) { element.annotations.filterIsInstance().firstOrNull()?.let { - if (it.protocolGetter.isNotEmpty() && element.origin is StubOrigin.ObjCProtocol) { + val origin = element.origin + if (it.protocolGetter.isNotEmpty() && origin is StubOrigin.ObjCProtocol && !origin.isMeta) { val protocol = (element.origin as StubOrigin.ObjCProtocol).protocol // TODO: handle the case when protocol getter stub can't be compiled. generateProtocolGetter(it.protocolGetter, protocol) 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 7adafcdf464..8ed122d2162 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.None + val origin = StubOrigin.Synthetic if (unwrappedFieldType is ArrayType) { val type = (fieldRefType as TypeMirror.ByValue).valueType val annotations = if (platform == KotlinPlatform.JVM) { @@ -115,16 +115,18 @@ 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.None) + PropertyStub(field.name, kotlinType.toStubIrType(), kind, origin = StubOrigin.Synthetic) } val superClass = context.platform.getRuntimeType("CStructVar") require(superClass is ClassifierStubType) val rawPtrConstructorParam = FunctionParameterStub("rawPtr", context.platform.getRuntimeType("NativePtr")) + val origin = StubOrigin.Struct(decl) val primaryConstructor = ConstructorStub( parameters = listOf(rawPtrConstructorParam), isPrimary = true, - annotations = emptyList() + annotations = emptyList(), + origin = origin ) val superClassInit = SuperClassInit(superClass, listOf(GetConstructorParameter(rawPtrConstructorParam))) @@ -136,7 +138,7 @@ internal class StructStubBuilder( return listOf(ClassStub.Simple( classifier, - origin = StubOrigin.Struct(decl), + origin = origin, properties = fields.filterNotNull() + if (platform == KotlinPlatform.NATIVE) bitFields else emptyList(), constructors = listOf(primaryConstructor), methods = emptyList(), @@ -182,7 +184,7 @@ internal class StructStubBuilder( val rawPtrConstructorParam = FunctionParameterStub("rawPtr", context.platform.getRuntimeType("NativePtr")) val superClassInit = SuperClassInit(superClass, listOf(GetConstructorParameter(rawPtrConstructorParam))) val origin = StubOrigin.Struct(s) - val primaryConstructor = ConstructorStub(listOf(rawPtrConstructorParam), emptyList(), isPrimary = true) + val primaryConstructor = ConstructorStub(listOf(rawPtrConstructorParam), emptyList(), isPrimary = true, origin = origin) listOf(ClassStub.Simple( classifier, ClassStubModality.NONE, @@ -213,7 +215,7 @@ internal class EnumStubBuilder( type = baseType, kind = PropertyStub.Kind.Val(PropertyAccessor.Getter.GetConstructorParameter(constructorParameter)), modality = MemberStubModality.OVERRIDE, - origin = StubOrigin.None) + origin = StubOrigin.Synthetic) val canonicalsByValue = enumDef.constants .groupingBy { it.value } @@ -232,11 +234,12 @@ internal class EnumStubBuilder( val aliases = aliasConstants.filter { it.value == constant.value }.map { EnumEntryStub.Alias(it.name) } EnumEntryStub(constant.name, literal, aliases) } - val primaryConstructor = ConstructorStub(listOf(constructorParameter), emptyList(), isPrimary = true) + val origin = StubOrigin.Enum(enumDef) + val primaryConstructor = ConstructorStub(listOf(constructorParameter), emptyList(), isPrimary = true, origin = origin) val enum = ClassStub.Enum(clazz, canonicalEntries, constructors = listOf(primaryConstructor), properties = listOf(valueProperty), - origin = StubOrigin.Enum(enumDef), + origin = origin, interfaces = listOf(context.platform.getRuntimeType("CEnum")) ) context.bridgeComponentsBuilder.enumToTypeMirror[enum] = baseTypeMirror @@ -299,7 +302,7 @@ internal class EnumStubBuilder( kind, MemberStubModality.FINAL, null, - origin = StubOrigin.None + origin = StubOrigin.Synthetic ) } val container = SimpleStubContainer(