diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt index c8fb407befb..70b869b1936 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt @@ -35,7 +35,7 @@ import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.utils.addIfNotNull interface ObjCExportTranslator { - fun generateBaseDeclarations(): List> + fun generateBaseDeclarations(): List fun getClassIfExtension(receiverType: KotlinType): ClassDescriptor? fun translateFile(file: SourceFile, declarations: List): ObjCInterface fun translateClass(descriptor: ClassDescriptor): ObjCInterface @@ -66,7 +66,7 @@ class ObjCExportTranslatorImpl( private val kotlinAnyName = namer.kotlinAnyName - override fun generateBaseDeclarations(): List> = buildTopLevel { + override fun generateBaseDeclarations(): List = buildTopLevel { add { objCInterface(namer.kotlinAnyName, superClass = "NSObject", members = buildMembers { add { ObjCMethod(null, true, ObjCInstanceType, listOf("init"), emptyList(), listOf("unavailable")) } @@ -116,7 +116,7 @@ class ObjCExportTranslatorImpl( genKotlinNumbers() } - private fun StubBuilder>.genKotlinNumbers() { + private fun StubBuilder.genKotlinNumbers() { val members = buildMembers { NSNumberKind.entries.forEach { add { nsNumberFactory(it, listOf("unavailable")) } @@ -240,7 +240,7 @@ class ObjCExportTranslatorImpl( } val name = translateClassOrInterfaceName(descriptor) - val members: List> = buildMembers { translateInterfaceMembers(descriptor) } + val members: List = buildMembers { translateInterfaceMembers(descriptor) } val superProtocols: List = descriptor.superProtocols val comment = objCCommentOrNull(mustBeDocumentedAttributeList(descriptor.annotations)) @@ -315,7 +315,7 @@ class ObjCExportTranslatorImpl( } val superProtocols: List = descriptor.superProtocols - val members: List> = buildMembers { + val members: List = buildMembers { val presentConstructors = mutableSetOf() descriptor.constructors @@ -510,12 +510,12 @@ class ObjCExportTranslatorImpl( .filter { mapper.shouldBeExposed(it) } .toList() - private fun StubBuilder>.translateClassMembers(descriptor: ClassDescriptor, objCExportScope: ObjCExportScope) { + private fun StubBuilder.translateClassMembers(descriptor: ClassDescriptor, objCExportScope: ObjCExportScope) { require(!descriptor.isInterface) translateClassMembers(descriptor.getExposedMembers(), objCExportScope) } - private fun StubBuilder>.translateInterfaceMembers(descriptor: ClassDescriptor) { + private fun StubBuilder.translateInterfaceMembers(descriptor: ClassDescriptor) { require(descriptor.isInterface) translateBaseMembers(descriptor.getExposedMembers()) } @@ -536,7 +536,7 @@ class ObjCExportTranslatorImpl( } } - private fun StubBuilder>.translateClassMembers( + private fun StubBuilder.translateClassMembers( members: List, objCExportScope: ObjCExportScope, ) { @@ -569,7 +569,7 @@ class ObjCExportTranslatorImpl( } } - private fun StubBuilder>.translateBaseMembers(members: List) { + private fun StubBuilder.translateBaseMembers(members: List) { // TODO: add some marks about modality. val methods = mutableListOf() @@ -593,7 +593,10 @@ class ObjCExportTranslatorImpl( translatePlainMembers(methods, properties, ObjCRootExportScope) } - private fun StubBuilder>.translatePlainMembers(members: List, objCExportScope: ObjCExportScope) { + private fun StubBuilder.translatePlainMembers( + members: List, + objCExportScope: ObjCExportScope, + ) { val methods = mutableListOf() val properties = mutableListOf() @@ -604,7 +607,7 @@ class ObjCExportTranslatorImpl( translatePlainMembers(methods, properties, objCExportScope) } - private fun StubBuilder>.translatePlainMembers( + private fun StubBuilder.translatePlainMembers( methods: List, properties: List, objCExportScope: ObjCExportScope, @@ -804,8 +807,10 @@ class ObjCExportTranslatorImpl( } else emptyList() val visibilityComments = visibilityComments(method.visibility, "method") - val paramComments = parameters.flatMap { parameter -> - parameter.descriptor?.let { mustBeDocumentedParamAttributeList(parameter, descriptor = it) } ?: emptyList() + val paramComments = method.valueParameters.flatMap { parameterDescriptor -> + parameters.find { parameter -> parameter.origin?.name == parameterDescriptor.name }?.let { parameter -> + mustBeDocumentedParamAttributeList(parameter, descriptor = parameterDescriptor) + } ?: emptyList() } val annotationsComments = mustBeDocumentedAttributeList(method.annotations) return objCCommentOrNull(annotationsComments + paramComments + throwsComments + visibilityComments) @@ -1118,9 +1123,9 @@ class ObjCExportTranslatorImpl( } } - private inline fun buildTopLevel(block: StubBuilder>.() -> Unit) = buildStubs(block) - private inline fun buildMembers(block: StubBuilder>.() -> Unit) = buildStubs(block) - private inline fun > buildStubs(block: StubBuilder.() -> Unit): List = + private inline fun buildTopLevel(block: StubBuilder.() -> Unit) = buildStubs(block) + private inline fun buildMembers(block: StubBuilder.() -> Unit) = buildStubs(block) + private inline fun buildStubs(block: StubBuilder.() -> Unit): List = StubBuilder(problemCollector).apply(block).build() } @@ -1131,7 +1136,7 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor( val objcGenerics: Boolean, problemCollector: ObjCExportProblemCollector, ) { - private val stubs = mutableListOf>() + private val stubs = mutableListOf() private val classForwardDeclarations = linkedSetOf() private val protocolForwardDeclarations = linkedSetOf() @@ -1419,7 +1424,7 @@ private fun objCInterface( superClass: String? = null, superClassGenerics: List = emptyList(), superProtocols: List = emptyList(), - members: List> = emptyList(), + members: List = emptyList(), attributes: List = emptyList(), comment: ObjCComment? = null, ): ObjCInterface = ObjCInterfaceImpl( @@ -1439,7 +1444,7 @@ private fun objCProtocol( name: ObjCExportNamer.ClassOrProtocolName, descriptor: ClassDescriptor, superProtocols: List, - members: List>, + members: List, attributes: List = emptyList(), comment: ObjCComment? = null, ): ObjCProtocol = ObjCProtocolImpl( diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt index 4a9b5e02ddc..d4d6ec71878 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.backend.konan.objcexport -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport @@ -54,9 +53,9 @@ interface ObjCExportLazy { get() = false } - fun generateBase(): List> + fun generateBase(): List - fun translate(file: KtFile): List> + fun translate(file: KtFile): List } @JvmOverloads @@ -113,11 +112,11 @@ class ObjCExportLazyImpl( override fun generateBase() = translator.generateBaseDeclarations() - override fun translate(file: KtFile): List> = + override fun translate(file: KtFile): List = translateClasses(file) + translateTopLevels(file) - private fun translateClasses(container: KtDeclarationContainer): List> { - val result = mutableListOf>() + private fun translateClasses(container: KtDeclarationContainer): List { + val result = mutableListOf() container.declarations.forEach { declaration -> // Supposed to be true if ObjCExportMapper.shouldBeVisible is true. if (declaration is KtClassOrObject && declaration.isPublic && declaration !is KtEnumEntry @@ -136,7 +135,7 @@ class ObjCExportLazyImpl( return result } - private fun translateClass(ktClassOrObject: KtClassOrObject): ObjCClass<*> { + private fun translateClass(ktClassOrObject: KtClassOrObject): ObjCClass { val name = nameTranslator.getClassOrProtocolName(ktClassOrObject) // Note: some attributes may be missing (e.g. "unavailable" for unexposed classes). @@ -324,13 +323,12 @@ class ObjCExportLazyImpl( private class LazyObjCProtocolImpl( name: ObjCExportNamer.ClassOrProtocolName, - override val psi: KtClassOrObject, + private val psi: KtClassOrObject, private val lazy: ObjCExportLazyImpl, ) : LazyObjCProtocol(name) { - override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } + private val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } - override val isValid: Boolean - get() = lazy.isValid + override val origin: ObjCExportStubOrigin? by lazy { ObjCExportStubOrigin(descriptor) } override fun computeRealStub(): ObjCProtocol = lazy.translator.translateInterface(descriptor) } @@ -339,13 +337,12 @@ class ObjCExportLazyImpl( name: ObjCExportNamer.ClassOrProtocolName, attributes: List, generics: List, - override val psi: KtClassOrObject, + private val psi: KtClassOrObject, private val lazy: ObjCExportLazyImpl, ) : LazyObjCInterface(name = name, generics = generics, categoryName = null, attributes = attributes) { - override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } + private val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } - override val isValid: Boolean - get() = lazy.isValid + override val origin: ObjCExportStubOrigin? by lazy { ObjCExportStubOrigin(descriptor) } override fun computeRealStub(): ObjCInterface = lazy.translator.translateClass(descriptor) } @@ -356,14 +353,8 @@ class ObjCExportLazyImpl( private val declarations: List, private val lazy: ObjCExportLazyImpl, ) : LazyObjCInterface(name = name, generics = emptyList(), categoryName = null, attributes = listOf(OBJC_SUBCLASSING_RESTRICTED)) { - override val descriptor: ClassDescriptor? - get() = null - override val isValid: Boolean - get() = lazy.isValid - - override val psi: PsiElement? - get() = null + override val origin: Nothing? = null override fun computeRealStub(): ObjCInterface = lazy.translator.translateFile( PsiSourceFile(file), @@ -382,14 +373,8 @@ class ObjCExportLazyImpl( private val declarations: List, private val lazy: ObjCExportLazyImpl, ) : LazyObjCInterface(name = name.objCName, generics = emptyList(), categoryName = categoryName, attributes = emptyList()) { - override val descriptor: ClassDescriptor? - get() = null - override val isValid: Boolean - get() = lazy.isValid - - override val psi: PsiElement? - get() = null + override val origin: ObjCExportStubOrigin? = ObjCExportStubOrigin(classDescriptor) override fun computeRealStub(): ObjCInterface = lazy.translator.translateExtensions( classDescriptor, @@ -400,27 +385,25 @@ class ObjCExportLazyImpl( } } -private abstract class LazyObjCInterface : ObjCInterface { +private abstract class LazyObjCInterface( + override val name: String, + override val generics: List, + override val categoryName: String?, + override val attributes: List, +) : ObjCInterface() { constructor( name: ObjCExportNamer.ClassOrProtocolName, generics: List, categoryName: String?, attributes: List, - ) : super(name.objCName, generics, categoryName, attributes + name.toNameAttributes()) - - constructor( - name: String, - generics: List, - categoryName: String, - attributes: List, - ) : super(name, generics, categoryName, attributes) + ) : this(name.objCName, generics, categoryName, attributes + name.toNameAttributes()) protected abstract fun computeRealStub(): ObjCInterface private val realStub by lazy { computeRealStub() } - override val members: List> + override val members: List get() = realStub.members override val superProtocols: List @@ -431,17 +414,25 @@ private abstract class LazyObjCInterface : ObjCInterface { override val superClassGenerics: List get() = realStub.superClassGenerics + + final override val comment: Nothing? = null } private abstract class LazyObjCProtocol( name: ObjCExportNamer.ClassOrProtocolName, -) : ObjCProtocol(name.objCName, name.toNameAttributes()) { +) : ObjCProtocol() { + + override val name: String = name.objCName + + override val comment: Nothing? = null + + override val attributes: List = name.toNameAttributes() protected abstract fun computeRealStub(): ObjCProtocol private val realStub by lazy { computeRealStub() } - override val members: List> + override val members: List get() = realStub.members override val superProtocols: List diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportStubOrigin.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportStubOrigin.kt new file mode 100644 index 00000000000..54633cb7f2a --- /dev/null +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportStubOrigin.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.konan.objcexport + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.backend.common.serialization.extractSerializedKdocString +import org.jetbrains.kotlin.backend.common.serialization.metadata.findKDocString +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource +import org.jetbrains.kotlin.descriptors.DeserializedDescriptor +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.source.PsiSourceElement + +fun ObjCExportStubOrigin(descriptor: DeclarationDescriptor?): ObjCExportStubOrigin? { + if (descriptor == null) return null + + if (descriptor is DeclarationDescriptorWithSource) { + return ObjCExportStubOrigin.Source(descriptor.name, descriptor.findKDocString(), (descriptor.source as? PsiSourceElement)?.psi) + } + + assert(descriptor is DeserializedDescriptor) { "Expected '$descriptor' to implement ${DeserializedDescriptor::class.simpleName}" } + return ObjCExportStubOrigin.Binary(descriptor.name, descriptor.extractSerializedKdocString()) +} + +sealed class ObjCExportStubOrigin { + + /** + * The original 'Kotlin' name of the entity that is associated with this stub + */ + abstract val name: Name? + + /** + * The original 'Kotlin documentation' of the associated with this stub + */ + abstract val kdoc: String? + + /** + * The stub was produced from Kotlin sources + */ + data class Source(override val name: Name?, override val kdoc: String?, val psi: PsiElement?) : ObjCExportStubOrigin() + + /** + * The stub was produced from a compiled binary (e.g. when translating a dependency inside fleet). + * Note: On CLI invocations, the ObjC export will only operate on binaries. + */ + data class Binary(override val name: Name?, override val kdoc: String?) : ObjCExportStubOrigin() +} diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt index 9529776a249..57077ab6b2d 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt @@ -8,5 +8,5 @@ package org.jetbrains.kotlin.backend.konan.objcexport data class ObjCExportedStubs( val classForwardDeclarations: Set, val protocolForwardDeclarations: Set, - val stubs: List>, + val stubs: List, ) \ No newline at end of file diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubBuilder.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubBuilder.kt index 1ca5f2f800c..6df4853e3d5 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubBuilder.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubBuilder.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.backend.konan.objcexport -internal class StubBuilder>(private val problemCollector: ObjCExportProblemCollector) { +internal class StubBuilder(private val problemCollector: ObjCExportProblemCollector) { private val children = mutableListOf() inline fun add(provider: () -> S) { diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt index d4c7d61d4af..36f555fe053 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt @@ -5,14 +5,8 @@ package org.jetbrains.kotlin.backend.konan.objcexport -import org.jetbrains.kotlin.backend.common.serialization.extractSerializedKdocString -import org.jetbrains.kotlin.backend.common.serialization.metadata.findKDocString -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource - object StubRenderer { - fun render(stub: Stub<*>): List = render(stub, false) + fun render(stub: ObjCExportStub): List = render(stub, false) private fun findPositionToInsertGeneratedCommentLine(kDoc: List, generatedCommentLine: String): Int { val generatedWords = generatedCommentLine.trim().split(" ").map { it.trim() } @@ -27,7 +21,7 @@ object StubRenderer { return kDoc.size } - internal fun render(stub: Stub<*>, shouldExportKDoc: Boolean): List = collect { + internal fun render(stub: ObjCExportStub, shouldExportKDoc: Boolean): List = collect { stub.run { val (kDocEnding, commentBlockEnding) = if (comment?.contentLines == null) { Pair("*/", null) // Close kDoc with `*/`, and print nothing after empty comment @@ -35,7 +29,7 @@ object StubRenderer { Pair("", "*/") // Don't terminate kDoc, though close comment block with `*/` } val kDoc = if (shouldExportKDoc) { - descriptor?.extractKDocString()?.let { + origin?.kdoc?.let { if (it.startsWith("/**") && it.endsWith("*/")) { // Nested comment is allowed inside of preformatted ``` block in kdoc but not in ObjC val kdocClean = "/**${it.substring(3, it.length - 2).replace("*/", "**").replace("/*", "**")}$kDocEnding" @@ -182,7 +176,7 @@ object StubRenderer { appendSuperProtocols(this@renderProtocolHeader) } - private fun StringBuilder.appendSuperProtocols(clazz: ObjCClass) { + private fun StringBuilder.appendSuperProtocols(clazz: ObjCClass) { val protocols = clazz.superProtocols if (protocols.isNotEmpty()) { protocols.joinTo(this, separator = ", ", prefix = " <", postfix = ">") @@ -215,7 +209,7 @@ object StubRenderer { appendSuperProtocols(this@renderInterfaceHeader) } - private fun Collector.renderMembers(clazz: ObjCClass<*>, shouldExportKDoc: Boolean) { + private fun Collector.renderMembers(clazz: ObjCClass, shouldExportKDoc: Boolean) { clazz.members.forEach { +render(it, shouldExportKDoc) } @@ -248,8 +242,3 @@ fun formatGenerics(buffer: Appendable, generics: List) { generics.joinTo(buffer, separator = ", ", prefix = "<", postfix = ">") } } - -private fun DeclarationDescriptor.extractKDocString(): String? { - return (this as? DeclarationDescriptorWithSource)?.findKDocString() - ?: extractSerializedKdocString() -} diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt index d2033e3cd93..b0fa73b692d 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt @@ -3,15 +3,63 @@ * that can be found in the LICENSE file. */ +@file:JvmName("ObjCExportStubKt") + package org.jetbrains.kotlin.backend.konan.objcexport -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource import org.jetbrains.kotlin.descriptors.ParameterDescriptor -import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.resolve.source.PsiSourceElement + +@Deprecated("Use 'ObjCExportStub' instead", replaceWith = ReplaceWith("ObjCExportStub")) +@Suppress("unused") +typealias Stub<@Suppress("UNUSED_TYPEALIAS_PARAMETER") T> = ObjCExportStub + +sealed interface ObjCExportStub { + /** + * The ObjC name of this entity; + * Note: The original 'Kotlin Name' can be found in [origin] + */ + val name: String + + val comment: ObjCComment? + + + /** + * Leaves breadcrumbs, minimal information, about the origin of this stub. + * A [origin] can either be + * - [ObjCExportStubOrigin.Source] indicating that the stub was produced from Source Code (happens inside the IDE) + * - [ObjCExportStubOrigin.Binary] indicating that the stub was produced by deserializing a klib (Note: CLI only works in this mode) + * - null: Indicating that we not provide information about the origin of this stub. This can happen e.g. + * if the stub is just synthetically created by this tool. + */ + val origin: ObjCExportStubOrigin? +} + +val ObjCExportStub.psiOrNull + get() = when (val origin = origin) { + is ObjCExportStubOrigin.Source -> origin.psi + else -> null + } + + +abstract class ObjCTopLevel : ObjCExportStub + +sealed class ObjCClass : ObjCTopLevel() { + abstract val attributes: List + abstract val superProtocols: List + abstract val members: List +} + +abstract class ObjCProtocol : ObjCClass() + +abstract class ObjCInterface : ObjCClass() { + abstract val categoryName: String? + abstract val generics: List + abstract val superClass: String? + abstract val superClassGenerics: List +} class ObjCComment(val contentLines: List) { constructor(vararg contentLines: String) : this(contentLines.toList()) @@ -22,93 +70,146 @@ data class ObjCClassForwardDeclaration( val typeDeclarations: List = emptyList(), ) -abstract class Stub(val name: String, val comment: ObjCComment? = null) { - abstract val descriptor: D? - open val psi: PsiElement? - get() = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi - open val isValid: Boolean - get() = descriptor?.module?.isValid ?: true -} - -abstract class ObjCTopLevel(name: String, comment: ObjCComment? = null) : Stub(name, comment) - -abstract class ObjCClass( - name: String, - val attributes: List, - comment: ObjCComment? = null, -) : ObjCTopLevel(name, comment) { - abstract val superProtocols: List - abstract val members: List> -} - -abstract class ObjCProtocol( - name: String, - attributes: List, - comment: ObjCComment? = null, -) : ObjCClass(name, attributes, comment) - class ObjCProtocolImpl( - name: String, - override val descriptor: ClassDescriptor, + override val name: String, + override val comment: ObjCComment?, + override val origin: ObjCExportStubOrigin?, + override val attributes: List, override val superProtocols: List, - override val members: List>, - attributes: List = emptyList(), - comment: ObjCComment? = null, -) : ObjCProtocol(name, attributes, comment) - -abstract class ObjCInterface( - name: String, - val generics: List, - val categoryName: String?, - attributes: List, - comment: ObjCComment? = null, -) : ObjCClass(name, attributes, comment) { - abstract val superClass: String? - abstract val superClassGenerics: List + override val members: List, +) : ObjCProtocol() { + constructor( + name: String, + descriptor: ClassDescriptor, + superProtocols: List, + members: List, + attributes: List = emptyList(), + comment: ObjCComment? = null, + ) : this( + name = name, + comment = comment, + origin = ObjCExportStubOrigin(descriptor), + attributes = attributes, + superProtocols = superProtocols, + members = members + ) } class ObjCInterfaceImpl( - name: String, - generics: List = emptyList(), - override val descriptor: ClassDescriptor? = null, - override val superClass: String? = null, - override val superClassGenerics: List = emptyList(), - override val superProtocols: List = emptyList(), - categoryName: String? = null, - override val members: List> = emptyList(), - attributes: List = emptyList(), - comment: ObjCComment? = null, -) : ObjCInterface(name, generics, categoryName, attributes, comment) + override val name: String, + override val comment: ObjCComment?, + override val origin: ObjCExportStubOrigin?, + override val attributes: List, + override val superProtocols: List, + override val members: List, + override val categoryName: String?, + override val generics: List, + override val superClass: String?, + override val superClassGenerics: List, +) : ObjCInterface() { + constructor( + name: String, + generics: List = emptyList(), + descriptor: ClassDescriptor? = null, + superClass: String? = null, + superClassGenerics: List = emptyList(), + superProtocols: List = emptyList(), + categoryName: String? = null, + members: List = emptyList(), + attributes: List = emptyList(), + comment: ObjCComment? = null, + ) : this( + name = name, + comment = comment, + origin = ObjCExportStubOrigin(descriptor), + attributes = attributes, + superProtocols = superProtocols, + members = members, + categoryName = categoryName, + generics = generics, + superClass = superClass, + superClassGenerics = superClassGenerics + ) +} class ObjCMethod( - override val descriptor: DeclarationDescriptor?, + override val comment: ObjCComment?, + override val origin: ObjCExportStubOrigin?, val isInstanceMethod: Boolean, val returnType: ObjCType, val selectors: List, val parameters: List, val attributes: List, - comment: ObjCComment? = null, -) : Stub(buildMethodName(selectors, parameters), comment) +) : ObjCExportStub { + constructor( + descriptor: DeclarationDescriptor?, + isInstanceMethod: Boolean, + returnType: ObjCType, + selectors: List, + parameters: List, + attributes: List, + comment: ObjCComment? = null, + ) : this( + comment = comment, + origin = ObjCExportStubOrigin(descriptor), + isInstanceMethod = isInstanceMethod, + returnType = returnType, + selectors = selectors, + parameters = parameters, + attributes = attributes + ) -class ObjCParameter( - name: String, - override val descriptor: ParameterDescriptor?, + override val name: String = buildMethodName(selectors, parameters) +} + +class ObjCParameter private constructor( + override val name: String, + override val origin: ObjCExportStubOrigin?, val type: ObjCType, -) : Stub(name) +) : ObjCExportStub { + + constructor( + name: String, + descriptor: ParameterDescriptor?, + type: ObjCType, + ) : this( + name = name, + origin = ObjCExportStubOrigin(descriptor), + type = type + ) + + override val comment: Nothing? = null +} class ObjCProperty( - name: String, - override val descriptor: DeclarationDescriptorWithSource?, + override val name: String, + override val comment: ObjCComment?, + override val origin: ObjCExportStubOrigin?, val type: ObjCType, val propertyAttributes: List, val setterName: String? = null, val getterName: String? = null, val declarationAttributes: List = emptyList(), - comment: ObjCComment? = null, -) : Stub(name, comment) { - - @Deprecated("", ReplaceWith("this.propertyAttributes"), DeprecationLevel.WARNING) - val attributes: List get() = propertyAttributes +) : ObjCExportStub { + constructor( + name: String, + descriptor: DeclarationDescriptorWithSource?, + type: ObjCType, + propertyAttributes: List, + setterName: String? = null, + getterName: String? = null, + declarationAttributes: List = emptyList(), + comment: ObjCComment? = null, + ) : this( + name = name, + comment = comment, + origin = ObjCExportStubOrigin(descriptor), + type = type, + propertyAttributes = propertyAttributes, + setterName = setterName, + getterName = getterName, + declarationAttributes = declarationAttributes + ) } private fun buildMethodName(selectors: List, parameters: List): String =