[K/N] Fix KT-57541

Root cause: commonizer does not add `ExternalObjCClass` annotation
to expect declarations, so forward declarations aren't resolved.

It is simpler (and safer) to fix it on the compiler side by checking
superclass instead of annotation.
This commit is contained in:
Sergey Bogolepov
2023-03-28 20:13:23 +03:00
committed by Space Team
parent 37c776b233
commit 51d441ee38
@@ -180,12 +180,12 @@ enum class ExportedForwardDeclarationChecker(val fqName: FqName) {
ObjCClass(ForwardDeclarationsFqNames.objCNamesClasses) { ObjCClass(ForwardDeclarationsFqNames.objCNamesClasses) {
override fun check(classifierDescriptor: ClassifierDescriptor): Boolean = override fun check(classifierDescriptor: ClassifierDescriptor): Boolean =
classifierDescriptor is ClassDescriptor && classifierDescriptor.kind.isClass && classifierDescriptor is ClassDescriptor && classifierDescriptor.kind.isClass &&
classifierDescriptor.isExternalObjCClass() classifierDescriptor.isObjCObjectBase()
}, },
ObjCProtocol(ForwardDeclarationsFqNames.objCNamesProtocols) { ObjCProtocol(ForwardDeclarationsFqNames.objCNamesProtocols) {
override fun check(classifierDescriptor: ClassifierDescriptor): Boolean = override fun check(classifierDescriptor: ClassifierDescriptor): Boolean =
classifierDescriptor is ClassDescriptor && classifierDescriptor.kind.isInterface && classifierDescriptor is ClassDescriptor && classifierDescriptor.kind.isInterface &&
classifierDescriptor.isExternalObjCClass() classifierDescriptor.isObjCObject()
} }
; ;
@@ -193,11 +193,17 @@ enum class ExportedForwardDeclarationChecker(val fqName: FqName) {
companion object { companion object {
private val cStructVarFqName = FqName("kotlinx.cinterop.CStructVar") private val cStructVarFqName = FqName("kotlinx.cinterop.CStructVar")
private val externalObjCClassFqName = FqName("kotlinx.cinterop.ExternalObjCClass") private val objCObjectBaseFqName = FqName("kotlinx.cinterop.ObjCObjectBase")
private val objCObjectFqName = FqName("kotlinx.cinterop.ObjCObject")
// We can check that there is kotlinx.cinterop.ObjCObjectBase among supertypes, but it seems slower. // We can stop at ObjCObjectBase when checking Obj-C classes.
private fun ClassifierDescriptor.isExternalObjCClass(): Boolean = // Checking @ExternalObjCClass would be faster, but this annotation is not commonized. See KT-57541.
annotations.hasAnnotation(externalObjCClassFqName) private fun ClassifierDescriptor.isObjCObjectBase(): Boolean =
getAllSuperClassifiers().any { it.fqNameSafe == objCObjectBaseFqName }
// For protocols, we have to go all the way up to ObjCObject.
private fun ClassifierDescriptor.isObjCObject(): Boolean =
getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName }
private fun ClassifierDescriptor.isCStructVar(): Boolean = private fun ClassifierDescriptor.isCStructVar(): Boolean =
getAllSuperClassifiers().any { it.fqNameSafe == cStructVarFqName } getAllSuperClassifiers().any { it.fqNameSafe == cStructVarFqName }