diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerContext.kt index b153ec07842..e384425d9ee 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerContext.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.SimpleTypeMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker -class IrTypeCheckerContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext, AbstractTypeCheckerContext() { +open class IrTypeCheckerContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext, AbstractTypeCheckerContext() { override fun substitutionSupertypePolicy(type: SimpleTypeMarker): SupertypesPolicy.DoCustomTransform { require(type is IrSimpleType) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrTypeCheckerUtils.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrTypeCheckerUtils.kt new file mode 100644 index 00000000000..fab6d19a7a4 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrTypeCheckerUtils.kt @@ -0,0 +1,34 @@ +package org.jetbrains.kotlin.backend.common.serialization + +import org.jetbrains.kotlin.ir.declarations.IrTypeParameter +import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.types.IrTypeCheckerContext +import org.jetbrains.kotlin.types.model.TypeConstructorMarker + +open class IrTypeCheckerContextWithAdditionalAxioms( + override val irBuiltIns: IrBuiltIns, + firstParameters: List, + secondParameters: List +) : IrTypeCheckerContext(irBuiltIns) { + init { + assert(firstParameters.size == secondParameters.size) { + "different length of type parameter lists: $firstParameters vs $secondParameters" + } + } + + private val firstTypeParameterConstructors = firstParameters.map { it.symbol } + private val secondTypeParameterConstructors = secondParameters.map { it.symbol } + private val matchingTypeConstructors = firstTypeParameterConstructors.zip(secondTypeParameterConstructors).toMap() + + override fun areEqualTypeConstructors(a: TypeConstructorMarker, b: TypeConstructorMarker): Boolean { + if (super.isEqualTypeConstructors(a, b)) return true + if (matchingTypeConstructors[a] == b || matchingTypeConstructors[b] == a) return true + return false + } + + override fun isEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean { + if (super.isEqualTypeConstructors(c1, c2)) return true + if (matchingTypeConstructors[c1] == c2 || matchingTypeConstructors[c2] == c1) return true + return false + } +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrVisibilityUtil.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrVisibilityUtil.kt new file mode 100644 index 00000000000..e63999a83e9 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrVisibilityUtil.kt @@ -0,0 +1,66 @@ +package org.jetbrains.kotlin.backend.common.serialization + +import org.jetbrains.kotlin.backend.common.lower.parents +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithVisibility +import org.jetbrains.kotlin.ir.declarations.IrOverridableMember +import org.jetbrains.kotlin.ir.util.module +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue + +// The contents of this file is from VisibilityUtil.kt adapted to IR. +// TODO: The code would better be commonized for descriptors, ir and fir. + +private fun findInvisibleMember( + receiver: ReceiverValue?, + what: IrDeclarationWithVisibility, + from: IrDeclaration +): IrDeclarationWithVisibility? { + // TODO: We need the proper code for IR, + // but that requires many of Visibilities.java available in IR. + // So for now we stick to a quick hack serving the needs + // of fake override construction algorithm. + val parentsWithSelf = sequenceOf(what) + what.parents + parentsWithSelf.forEach { + if (it !is IrDeclarationWithVisibility) return null + if (it.visibility == Visibilities.INTERNAL && + (from.module != it.module) + ) { + return it + } + } + return null +} + +fun isVisibleIgnoringReceiver( + what: IrDeclarationWithVisibility, + from: IrDeclaration +): Boolean { + return findInvisibleMember(Visibilities.ALWAYS_SUITABLE_RECEIVER, what, from) == null +} + +fun isVisibleForOverride( + overriding: IrOverridableMember, + fromSuper: IrOverridableMember +): Boolean { + return !Visibilities.isPrivate((fromSuper as IrDeclarationWithVisibility).visibility) && + isVisibleIgnoringReceiver(fromSuper, overriding) +} + +fun findMemberWithMaxVisibility(members: Collection): IrOverridableMember { + assert(members.isNotEmpty()) + + var member: IrOverridableMember? = null + for (candidate in members) { + if (member == null) { + member = candidate + continue + } + + val result = Visibilities.compare(member.visibility, candidate.visibility) + if (result != null && result < 0) { + member = candidate + } + } + return member ?: error("Could not find a visible member") +}