[ObjCExport] ObjCExportStub: Do not retain reference to descriptor

FL-23390
^KT-64076 Fixed
This commit is contained in:
Sebastian Sellmair
2023-12-05 11:06:57 +01:00
committed by Space Team
parent e97463afb3
commit 3e57265fcb
7 changed files with 283 additions and 147 deletions
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.kotlin.utils.addIfNotNull
interface ObjCExportTranslator {
fun generateBaseDeclarations(): List<ObjCTopLevel<*>>
fun generateBaseDeclarations(): List<ObjCTopLevel>
fun getClassIfExtension(receiverType: KotlinType): ClassDescriptor?
fun translateFile(file: SourceFile, declarations: List<CallableMemberDescriptor>): ObjCInterface
fun translateClass(descriptor: ClassDescriptor): ObjCInterface
@@ -66,7 +66,7 @@ class ObjCExportTranslatorImpl(
private val kotlinAnyName = namer.kotlinAnyName
override fun generateBaseDeclarations(): List<ObjCTopLevel<*>> = buildTopLevel {
override fun generateBaseDeclarations(): List<ObjCTopLevel> = 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<ObjCTopLevel<*>>.genKotlinNumbers() {
private fun StubBuilder<ObjCTopLevel>.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<Stub<*>> = buildMembers { translateInterfaceMembers(descriptor) }
val members: List<ObjCExportStub> = buildMembers { translateInterfaceMembers(descriptor) }
val superProtocols: List<String> = descriptor.superProtocols
val comment = objCCommentOrNull(mustBeDocumentedAttributeList(descriptor.annotations))
@@ -315,7 +315,7 @@ class ObjCExportTranslatorImpl(
}
val superProtocols: List<String> = descriptor.superProtocols
val members: List<Stub<*>> = buildMembers {
val members: List<ObjCExportStub> = buildMembers {
val presentConstructors = mutableSetOf<String>()
descriptor.constructors
@@ -510,12 +510,12 @@ class ObjCExportTranslatorImpl(
.filter { mapper.shouldBeExposed(it) }
.toList()
private fun StubBuilder<Stub<*>>.translateClassMembers(descriptor: ClassDescriptor, objCExportScope: ObjCExportScope) {
private fun StubBuilder<ObjCExportStub>.translateClassMembers(descriptor: ClassDescriptor, objCExportScope: ObjCExportScope) {
require(!descriptor.isInterface)
translateClassMembers(descriptor.getExposedMembers(), objCExportScope)
}
private fun StubBuilder<Stub<*>>.translateInterfaceMembers(descriptor: ClassDescriptor) {
private fun StubBuilder<ObjCExportStub>.translateInterfaceMembers(descriptor: ClassDescriptor) {
require(descriptor.isInterface)
translateBaseMembers(descriptor.getExposedMembers())
}
@@ -536,7 +536,7 @@ class ObjCExportTranslatorImpl(
}
}
private fun StubBuilder<Stub<*>>.translateClassMembers(
private fun StubBuilder<ObjCExportStub>.translateClassMembers(
members: List<CallableMemberDescriptor>,
objCExportScope: ObjCExportScope,
) {
@@ -569,7 +569,7 @@ class ObjCExportTranslatorImpl(
}
}
private fun StubBuilder<Stub<*>>.translateBaseMembers(members: List<CallableMemberDescriptor>) {
private fun StubBuilder<ObjCExportStub>.translateBaseMembers(members: List<CallableMemberDescriptor>) {
// TODO: add some marks about modality.
val methods = mutableListOf<FunctionDescriptor>()
@@ -593,7 +593,10 @@ class ObjCExportTranslatorImpl(
translatePlainMembers(methods, properties, ObjCRootExportScope)
}
private fun StubBuilder<Stub<*>>.translatePlainMembers(members: List<CallableMemberDescriptor>, objCExportScope: ObjCExportScope) {
private fun StubBuilder<ObjCExportStub>.translatePlainMembers(
members: List<CallableMemberDescriptor>,
objCExportScope: ObjCExportScope,
) {
val methods = mutableListOf<FunctionDescriptor>()
val properties = mutableListOf<PropertyDescriptor>()
@@ -604,7 +607,7 @@ class ObjCExportTranslatorImpl(
translatePlainMembers(methods, properties, objCExportScope)
}
private fun StubBuilder<Stub<*>>.translatePlainMembers(
private fun StubBuilder<ObjCExportStub>.translatePlainMembers(
methods: List<FunctionDescriptor>,
properties: List<PropertyDescriptor>,
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<ObjCTopLevel<*>>.() -> Unit) = buildStubs(block)
private inline fun buildMembers(block: StubBuilder<Stub<*>>.() -> Unit) = buildStubs(block)
private inline fun <S : Stub<*>> buildStubs(block: StubBuilder<S>.() -> Unit): List<S> =
private inline fun buildTopLevel(block: StubBuilder<ObjCTopLevel>.() -> Unit) = buildStubs(block)
private inline fun buildMembers(block: StubBuilder<ObjCExportStub>.() -> Unit) = buildStubs(block)
private inline fun <S : ObjCExportStub> buildStubs(block: StubBuilder<S>.() -> Unit): List<S> =
StubBuilder<S>(problemCollector).apply(block).build()
}
@@ -1131,7 +1136,7 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor(
val objcGenerics: Boolean,
problemCollector: ObjCExportProblemCollector,
) {
private val stubs = mutableListOf<Stub<*>>()
private val stubs = mutableListOf<ObjCExportStub>()
private val classForwardDeclarations = linkedSetOf<ObjCClassForwardDeclaration>()
private val protocolForwardDeclarations = linkedSetOf<String>()
@@ -1419,7 +1424,7 @@ private fun objCInterface(
superClass: String? = null,
superClassGenerics: List<ObjCNonNullReferenceType> = emptyList(),
superProtocols: List<String> = emptyList(),
members: List<Stub<*>> = emptyList(),
members: List<ObjCExportStub> = emptyList(),
attributes: List<String> = emptyList(),
comment: ObjCComment? = null,
): ObjCInterface = ObjCInterfaceImpl(
@@ -1439,7 +1444,7 @@ private fun objCProtocol(
name: ObjCExportNamer.ClassOrProtocolName,
descriptor: ClassDescriptor,
superProtocols: List<String>,
members: List<Stub<*>>,
members: List<ObjCExportStub>,
attributes: List<String> = emptyList(),
comment: ObjCComment? = null,
): ObjCProtocol = ObjCProtocolImpl(
@@ -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<ObjCTopLevel<*>>
fun generateBase(): List<ObjCTopLevel>
fun translate(file: KtFile): List<ObjCTopLevel<*>>
fun translate(file: KtFile): List<ObjCTopLevel>
}
@JvmOverloads
@@ -113,11 +112,11 @@ class ObjCExportLazyImpl(
override fun generateBase() = translator.generateBaseDeclarations()
override fun translate(file: KtFile): List<ObjCTopLevel<*>> =
override fun translate(file: KtFile): List<ObjCTopLevel> =
translateClasses(file) + translateTopLevels(file)
private fun translateClasses(container: KtDeclarationContainer): List<ObjCClass<*>> {
val result = mutableListOf<ObjCClass<*>>()
private fun translateClasses(container: KtDeclarationContainer): List<ObjCClass> {
val result = mutableListOf<ObjCClass>()
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<String>,
generics: List<ObjCGenericTypeDeclaration>,
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<KtCallableDeclaration>,
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<KtCallableDeclaration>,
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<ObjCGenericTypeDeclaration>,
override val categoryName: String?,
override val attributes: List<String>,
) : ObjCInterface() {
constructor(
name: ObjCExportNamer.ClassOrProtocolName,
generics: List<ObjCGenericTypeDeclaration>,
categoryName: String?,
attributes: List<String>,
) : super(name.objCName, generics, categoryName, attributes + name.toNameAttributes())
constructor(
name: String,
generics: List<ObjCGenericTypeDeclaration>,
categoryName: String,
attributes: List<String>,
) : 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<Stub<*>>
override val members: List<ObjCExportStub>
get() = realStub.members
override val superProtocols: List<String>
@@ -431,17 +414,25 @@ private abstract class LazyObjCInterface : ObjCInterface {
override val superClassGenerics: List<ObjCNonNullReferenceType>
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<String> = name.toNameAttributes()
protected abstract fun computeRealStub(): ObjCProtocol
private val realStub by lazy { computeRealStub() }
override val members: List<Stub<*>>
override val members: List<ObjCExportStub>
get() = realStub.members
override val superProtocols: List<String>
@@ -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()
}
@@ -8,5 +8,5 @@ package org.jetbrains.kotlin.backend.konan.objcexport
data class ObjCExportedStubs(
val classForwardDeclarations: Set<ObjCClassForwardDeclaration>,
val protocolForwardDeclarations: Set<String>,
val stubs: List<Stub<*>>,
val stubs: List<ObjCExportStub>,
)
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.backend.konan.objcexport
internal class StubBuilder<S : Stub<*>>(private val problemCollector: ObjCExportProblemCollector) {
internal class StubBuilder<S : ObjCExportStub>(private val problemCollector: ObjCExportProblemCollector) {
private val children = mutableListOf<S>()
inline fun add(provider: () -> S) {
@@ -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<String> = render(stub, false)
fun render(stub: ObjCExportStub): List<String> = render(stub, false)
private fun findPositionToInsertGeneratedCommentLine(kDoc: List<String>, 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<String> = collect {
internal fun render(stub: ObjCExportStub, shouldExportKDoc: Boolean): List<String> = 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<ClassDescriptor>) {
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<Any>) {
generics.joinTo(buffer, separator = ", ", prefix = "<", postfix = ">")
}
}
private fun DeclarationDescriptor.extractKDocString(): String? {
return (this as? DeclarationDescriptorWithSource)?.findKDocString()
?: extractSerializedKdocString()
}
@@ -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<String>
abstract val superProtocols: List<String>
abstract val members: List<ObjCExportStub>
}
abstract class ObjCProtocol : ObjCClass()
abstract class ObjCInterface : ObjCClass() {
abstract val categoryName: String?
abstract val generics: List<ObjCGenericTypeDeclaration>
abstract val superClass: String?
abstract val superClassGenerics: List<ObjCNonNullReferenceType>
}
class ObjCComment(val contentLines: List<String>) {
constructor(vararg contentLines: String) : this(contentLines.toList())
@@ -22,93 +70,146 @@ data class ObjCClassForwardDeclaration(
val typeDeclarations: List<ObjCGenericTypeDeclaration> = emptyList(),
)
abstract class Stub<out D : DeclarationDescriptor>(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<out D : DeclarationDescriptor>(name: String, comment: ObjCComment? = null) : Stub<D>(name, comment)
abstract class ObjCClass<out D : DeclarationDescriptor>(
name: String,
val attributes: List<String>,
comment: ObjCComment? = null,
) : ObjCTopLevel<D>(name, comment) {
abstract val superProtocols: List<String>
abstract val members: List<Stub<*>>
}
abstract class ObjCProtocol(
name: String,
attributes: List<String>,
comment: ObjCComment? = null,
) : ObjCClass<ClassDescriptor>(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<String>,
override val superProtocols: List<String>,
override val members: List<Stub<*>>,
attributes: List<String> = emptyList(),
comment: ObjCComment? = null,
) : ObjCProtocol(name, attributes, comment)
abstract class ObjCInterface(
name: String,
val generics: List<ObjCGenericTypeDeclaration>,
val categoryName: String?,
attributes: List<String>,
comment: ObjCComment? = null,
) : ObjCClass<ClassDescriptor>(name, attributes, comment) {
abstract val superClass: String?
abstract val superClassGenerics: List<ObjCNonNullReferenceType>
override val members: List<ObjCExportStub>,
) : ObjCProtocol() {
constructor(
name: String,
descriptor: ClassDescriptor,
superProtocols: List<String>,
members: List<ObjCExportStub>,
attributes: List<String> = emptyList(),
comment: ObjCComment? = null,
) : this(
name = name,
comment = comment,
origin = ObjCExportStubOrigin(descriptor),
attributes = attributes,
superProtocols = superProtocols,
members = members
)
}
class ObjCInterfaceImpl(
name: String,
generics: List<ObjCGenericTypeDeclaration> = emptyList(),
override val descriptor: ClassDescriptor? = null,
override val superClass: String? = null,
override val superClassGenerics: List<ObjCNonNullReferenceType> = emptyList(),
override val superProtocols: List<String> = emptyList(),
categoryName: String? = null,
override val members: List<Stub<*>> = emptyList(),
attributes: List<String> = 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<String>,
override val superProtocols: List<String>,
override val members: List<ObjCExportStub>,
override val categoryName: String?,
override val generics: List<ObjCGenericTypeDeclaration>,
override val superClass: String?,
override val superClassGenerics: List<ObjCNonNullReferenceType>,
) : ObjCInterface() {
constructor(
name: String,
generics: List<ObjCGenericTypeDeclaration> = emptyList(),
descriptor: ClassDescriptor? = null,
superClass: String? = null,
superClassGenerics: List<ObjCNonNullReferenceType> = emptyList(),
superProtocols: List<String> = emptyList(),
categoryName: String? = null,
members: List<ObjCExportStub> = emptyList(),
attributes: List<String> = 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<String>,
val parameters: List<ObjCParameter>,
val attributes: List<String>,
comment: ObjCComment? = null,
) : Stub<DeclarationDescriptor>(buildMethodName(selectors, parameters), comment)
) : ObjCExportStub {
constructor(
descriptor: DeclarationDescriptor?,
isInstanceMethod: Boolean,
returnType: ObjCType,
selectors: List<String>,
parameters: List<ObjCParameter>,
attributes: List<String>,
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<ParameterDescriptor>(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<String>,
val setterName: String? = null,
val getterName: String? = null,
val declarationAttributes: List<String> = emptyList(),
comment: ObjCComment? = null,
) : Stub<DeclarationDescriptorWithSource>(name, comment) {
@Deprecated("", ReplaceWith("this.propertyAttributes"), DeprecationLevel.WARNING)
val attributes: List<String> get() = propertyAttributes
) : ObjCExportStub {
constructor(
name: String,
descriptor: DeclarationDescriptorWithSource?,
type: ObjCType,
propertyAttributes: List<String>,
setterName: String? = null,
getterName: String? = null,
declarationAttributes: List<String> = 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<String>, parameters: List<ObjCParameter>): String =