|
|
|
@@ -35,13 +35,11 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
|
|
|
|
import org.jetbrains.kotlin.ir.types.*
|
|
|
|
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
|
|
|
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
|
|
|
|
import org.jetbrains.kotlin.ir.util.classId
|
|
|
|
|
import org.jetbrains.kotlin.ir.util.defaultType
|
|
|
|
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
|
|
|
|
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
|
|
|
|
import org.jetbrains.kotlin.ir.util.*
|
|
|
|
|
import org.jetbrains.kotlin.name.FqName
|
|
|
|
|
import org.jetbrains.kotlin.name.Name
|
|
|
|
|
import org.jetbrains.kotlin.types.Variance
|
|
|
|
|
import org.jetbrains.kotlin.utils.DFS
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A generator for delegated members from implementation by delegation.
|
|
|
|
@@ -56,22 +54,56 @@ internal class DelegatedMemberGenerator(
|
|
|
|
|
|
|
|
|
|
// Generate delegated members for [subClass]. The synthetic field [irField] has the super interface type.
|
|
|
|
|
fun generate(irField: IrField, subClass: IrClass) {
|
|
|
|
|
val superClass = (irField.type as IrSimpleTypeImpl).classOrNull?.owner ?: return
|
|
|
|
|
val superClassId = superClass.classId ?: return
|
|
|
|
|
superClass.declarations.filter {
|
|
|
|
|
it.isDelegatable() && !subClass.declarations.any { decl -> isOverriding(irBuiltIns, decl, it) }
|
|
|
|
|
}.forEach {
|
|
|
|
|
if (it is IrSimpleFunction) {
|
|
|
|
|
val firFunction = declarationStorage.findOverriddenFirFunction(it, superClassId) ?: return
|
|
|
|
|
val function = generateDelegatedFunction(subClass, irField, it, firFunction)
|
|
|
|
|
subClass.addMember(function)
|
|
|
|
|
} else if (it is IrProperty) {
|
|
|
|
|
val firProperty = declarationStorage.findOverriddenFirProperty(it, superClassId) ?: return
|
|
|
|
|
generateDelegatedProperty(subClass, irField, it, firProperty)
|
|
|
|
|
val delegateClass = (irField.type as IrSimpleTypeImpl).classOrNull?.owner ?: return
|
|
|
|
|
val subClasses = mutableMapOf(delegateClass to mutableListOf(subClass))
|
|
|
|
|
DFS.dfs(
|
|
|
|
|
listOf(delegateClass), { node -> node.superTypes.mapNotNull { it.classOrNull?.owner } },
|
|
|
|
|
object : DFS.NodeHandler<IrClass, Unit> {
|
|
|
|
|
override fun beforeChildren(current: IrClass): Boolean {
|
|
|
|
|
for (superType in current.superTypes) {
|
|
|
|
|
superType.classOrNull?.owner?.let { subClasses.getOrPut(it) { mutableListOf() }.add(current) }
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun afterChildren(current: IrClass) = Unit
|
|
|
|
|
override fun result() = Unit
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
for ((superClass, mayOverride) in subClasses) {
|
|
|
|
|
val classId = superClass.classId ?: continue
|
|
|
|
|
if (classId == irBuiltIns.anyClass.owner.classId) continue
|
|
|
|
|
for (member in superClass.declarations) {
|
|
|
|
|
val delegatable = member.isDelegatable() && !DFS.ifAny(mayOverride, { subClasses[it] ?: emptyList() }) {
|
|
|
|
|
// Delegate to the most specific version of each member.
|
|
|
|
|
it.declarations.any { !it.isFakeOverride && it.overrides(member) }
|
|
|
|
|
}
|
|
|
|
|
if (!delegatable) continue
|
|
|
|
|
if (member is IrSimpleFunction) {
|
|
|
|
|
val firFunction = declarationStorage.findOverriddenFirFunction(member, classId) ?: return
|
|
|
|
|
val function = generateDelegatedFunction(subClass, irField, member, firFunction)
|
|
|
|
|
subClass.addMember(function)
|
|
|
|
|
} else if (member is IrProperty) {
|
|
|
|
|
val firProperty = declarationStorage.findOverriddenFirProperty(member, classId) ?: return
|
|
|
|
|
generateDelegatedProperty(subClass, irField, member, firProperty)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun IrDeclaration.overrides(other: IrDeclaration) = when {
|
|
|
|
|
// Imported declarations have overridden symbols, so check that first.
|
|
|
|
|
this is IrProperty && other is IrProperty ->
|
|
|
|
|
getter?.let { getter -> other.getter?.symbol in getter.overriddenSymbols }
|
|
|
|
|
?: setter?.let { setter -> other.setter?.symbol in setter.overriddenSymbols }
|
|
|
|
|
?: false
|
|
|
|
|
this is IrSimpleFunction && other is IrSimpleFunction ->
|
|
|
|
|
other.symbol in overriddenSymbols
|
|
|
|
|
else ->
|
|
|
|
|
false
|
|
|
|
|
} || isOverriding(irBuiltIns, this, other) // TODO check if this behaves correctly with generic arguments
|
|
|
|
|
|
|
|
|
|
private fun IrDeclaration.isDelegatable(): Boolean {
|
|
|
|
|
return isOverridable()
|
|
|
|
|
&& !isFakeOverride
|
|
|
|
|