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.SimpleTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
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 {
|
override fun substitutionSupertypePolicy(type: SimpleTypeMarker): SupertypesPolicy.DoCustomTransform {
|
||||||
require(type is IrSimpleType)
|
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