Typechecker and visibility utils for fake overrides
This commit is contained in:
@@ -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)
|
||||
|
||||
+34
@@ -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<IrTypeParameter>,
|
||||
secondParameters: List<IrTypeParameter>
|
||||
) : 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
|
||||
}
|
||||
}
|
||||
+66
@@ -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>): 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")
|
||||
}
|
||||
Reference in New Issue
Block a user