[IR] Reduce memory pollution during by mangler
- Make some ObjCInterop utils garbage-free (cherry picked from commit 6388b9ca72c7f96f85df32cde4b53a262467333e)
This commit is contained in:
committed by
Vasily Levchenko
parent
7680722f23
commit
2c1e9a9e2d
+25
-12
@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.backend.konan.descriptors.getStringValueOrNull
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -28,6 +30,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
internal val interopPackageName = InteropFqNames.packageName
|
||||
internal val objCObjectFqName = interopPackageName.child(Name.identifier("ObjCObject"))
|
||||
@@ -40,17 +43,20 @@ private val objCFactoryFqName = interopPackageName.child(Name.identifier("ObjCFa
|
||||
private val objcnamesForwardDeclarationsPackageName = Name.identifier("objcnames")
|
||||
|
||||
fun ClassDescriptor.isObjCClass(): Boolean =
|
||||
this.getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName } && // TODO: this is not cheap. Cache me!
|
||||
this.containingDeclaration.fqNameSafe != interopPackageName
|
||||
this.containingDeclaration.fqNameSafe != interopPackageName &&
|
||||
this.getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName } // TODO: this is not cheap. Cache me!
|
||||
|
||||
fun KotlinType.isObjCObjectType(): Boolean =
|
||||
(this.supertypes() + this).any { TypeUtils.getClassDescriptor(it)?.fqNameSafe == objCObjectFqName }
|
||||
|
||||
private fun IrClass.getAllSuperClassifiers(): List<IrClass> =
|
||||
listOf(this) + this.superTypes.flatMap { (it.classifierOrFail.owner as IrClass).getAllSuperClassifiers() }
|
||||
private fun IrClass.selfOrAnySuperClass(pred: (IrClass) -> Boolean): Boolean {
|
||||
if (pred(this)) return true
|
||||
|
||||
internal fun IrClass.isObjCClass() = this.getAllSuperClassifiers().any { it.fqNameForIrSerialization == objCObjectFqName } &&
|
||||
this.parent.fqNameForIrSerialization != interopPackageName
|
||||
return superTypes.any { it.classOrNull!!.owner.selfOrAnySuperClass(pred) }
|
||||
}
|
||||
|
||||
internal fun IrClass.isObjCClass() = this.parent.fqNameForIrSerialization != interopPackageName &&
|
||||
selfOrAnySuperClass { it.fqNameForIrSerialization == objCObjectFqName }
|
||||
|
||||
fun ClassDescriptor.isExternalObjCClass(): Boolean = this.isObjCClass() &&
|
||||
this.parentsWithSelf.filterIsInstance<ClassDescriptor>().any {
|
||||
@@ -68,7 +74,7 @@ fun ClassDescriptor.isObjCMetaClass(): Boolean = this.getAllSuperClassifiers().a
|
||||
it.fqNameSafe == objCClassFqName
|
||||
}
|
||||
|
||||
fun IrClass.isObjCMetaClass(): Boolean = this.getAllSuperClassifiers().any {
|
||||
fun IrClass.isObjCMetaClass(): Boolean = selfOrAnySuperClass {
|
||||
it.fqNameForIrSerialization == objCClassFqName
|
||||
}
|
||||
|
||||
@@ -142,7 +148,7 @@ private fun FunctionDescriptor.getObjCMethodInfo(onlyExternal: Boolean): ObjCMet
|
||||
}
|
||||
}
|
||||
|
||||
return this.overriddenDescriptors.asSequence().mapNotNull { it.getObjCMethodInfo(onlyExternal) }.firstOrNull()
|
||||
return overriddenDescriptors.firstNotNullResult { it.getObjCMethodInfo(onlyExternal) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,7 +163,7 @@ private fun IrSimpleFunction.getObjCMethodInfo(onlyExternal: Boolean): ObjCMetho
|
||||
}
|
||||
}
|
||||
|
||||
return this.overriddenSymbols.mapNotNull { it.owner.getObjCMethodInfo(onlyExternal) }.firstOrNull()
|
||||
return overriddenSymbols.firstNotNullResult { it.owner.getObjCMethodInfo(onlyExternal) }
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.getExternalObjCMethodInfo(): ObjCMethodInfo? = this.getObjCMethodInfo(onlyExternal = true)
|
||||
@@ -268,9 +274,16 @@ fun IrConstructor.getObjCInitMethod(): IrSimpleFunction? {
|
||||
fun ConstructorDescriptor.getObjCInitMethod(): FunctionDescriptor? {
|
||||
return this.annotations.findAnnotation(objCConstructorFqName)?.let {
|
||||
val initSelector = it.getAnnotationStringValue("initSelector")
|
||||
this.constructedClass.unsubstitutedMemberScope.getContributedDescriptors().asSequence()
|
||||
.filterIsInstance<FunctionDescriptor>()
|
||||
.single { it.getExternalObjCMethodInfo()?.selector == initSelector }
|
||||
val memberScope = constructedClass.unsubstitutedMemberScope
|
||||
val functionNames = memberScope.getFunctionNames()
|
||||
for (name in functionNames) {
|
||||
val functions = memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
|
||||
for (function in functions) {
|
||||
val objectInfo = function.getExternalObjCMethodInfo() ?: continue
|
||||
if (objectInfo.selector == initSelector) return function
|
||||
}
|
||||
}
|
||||
error("Cannot find ObjInitMethod for $this")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user