Drop unneeded hack relating to matching header class to impl typealias
This is not needed anymore because we use a special TypeCheckerContext which correctly matches header class to impl typealias. Also fix 'platformModule' in areCompatibleClassifiers: it's not b's module (b is already the expansion of a typealias), but the module of "other", original 'impl' classifier
This commit is contained in:
+12
-25
@@ -276,6 +276,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
a: CallableMemberDescriptor,
|
a: CallableMemberDescriptor,
|
||||||
b: CallableMemberDescriptor,
|
b: CallableMemberDescriptor,
|
||||||
checkImpl: Boolean,
|
checkImpl: Boolean,
|
||||||
|
platformModule: ModuleDescriptor = b.module,
|
||||||
parentSubstitutor: Substitutor? = null
|
parentSubstitutor: Substitutor? = null
|
||||||
): Compatibility {
|
): Compatibility {
|
||||||
assert(a.name == b.name) { "This function should be invoked only for declarations with the same name: $a, $b" }
|
assert(a.name == b.name) { "This function should be invoked only for declarations with the same name: $a, $b" }
|
||||||
@@ -295,7 +296,6 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
val bTypeParams = b.typeParameters
|
val bTypeParams = b.typeParameters
|
||||||
if (aTypeParams.size != bTypeParams.size) return Incompatible.TypeParameterCount
|
if (aTypeParams.size != bTypeParams.size) return Incompatible.TypeParameterCount
|
||||||
|
|
||||||
val platformModule = b.module
|
|
||||||
val substitutor = Substitutor(aTypeParams, bTypeParams, parentSubstitutor)
|
val substitutor = Substitutor(aTypeParams, bTypeParams, parentSubstitutor)
|
||||||
|
|
||||||
if (!areCompatibleTypeLists(aParams.map { substitutor(it.type) }, bParams.map { it.type }, platformModule) ||
|
if (!areCompatibleTypeLists(aParams.map { substitutor(it.type) }, bParams.map { it.type }, platformModule) ||
|
||||||
@@ -406,23 +406,12 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
private fun areCompatibleClassifiers(a: ClassDescriptor, other: ClassifierDescriptor, checkImpl: Boolean): Compatibility {
|
private fun areCompatibleClassifiers(a: ClassDescriptor, other: ClassifierDescriptor, checkImpl: Boolean): Compatibility {
|
||||||
assert(a.fqNameUnsafe == other.fqNameUnsafe) { "This function should be invoked only for declarations with the same name: $a, $other" }
|
assert(a.fqNameUnsafe == other.fqNameUnsafe) { "This function should be invoked only for declarations with the same name: $a, $other" }
|
||||||
|
|
||||||
var parentSubstitutor: Substitutor? = null
|
|
||||||
var implTypealias = false
|
var implTypealias = false
|
||||||
|
|
||||||
val b = when (other) {
|
val b = when (other) {
|
||||||
is ClassDescriptor -> other
|
is ClassDescriptor -> other
|
||||||
is TypeAliasDescriptor -> {
|
is TypeAliasDescriptor -> {
|
||||||
val classDescriptor = other.classDescriptor ?: return Compatible // do not report extra error on erroneous typealias
|
|
||||||
implTypealias = true
|
implTypealias = true
|
||||||
// If a header class test.C is implemented by a typealias test.C = test.CImpl, we must now state that any occurrence
|
other.classDescriptor ?: return Compatible // do not report extra error on erroneous typealias
|
||||||
// of the type "test.C" in the header class scope should be replaced with "test.CImpl".
|
|
||||||
// Otherwise the types would not be equal and e.g. test.C's constructor is not going to be found in test.CImpl's scope.
|
|
||||||
// For this, we construct an additional substitutor with a single mapping test.C -> test.CImpl
|
|
||||||
// TODO: this looks like a dirty hack
|
|
||||||
parentSubstitutor = Substitutor(null, TypeSubstitutor.create(TypeConstructorSubstitution.createByConstructorsMap(
|
|
||||||
mapOf(a.typeConstructor to classDescriptor.defaultType.asTypeProjection())
|
|
||||||
)))
|
|
||||||
classDescriptor
|
|
||||||
}
|
}
|
||||||
else -> throw AssertionError("Incorrect impl classifier for $a: $other")
|
else -> throw AssertionError("Incorrect impl classifier for $a: $other")
|
||||||
}
|
}
|
||||||
@@ -439,8 +428,8 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
|
|
||||||
if (a.visibility != b.visibility) return Incompatible.Visibility
|
if (a.visibility != b.visibility) return Incompatible.Visibility
|
||||||
|
|
||||||
val platformModule = b.module
|
val platformModule = other.module
|
||||||
val substitutor = Substitutor(aTypeParams, bTypeParams, parentSubstitutor)
|
val substitutor = Substitutor(aTypeParams, bTypeParams)
|
||||||
areCompatibleTypeParameters(aTypeParams, bTypeParams, platformModule, substitutor).let { if (it != Compatible) return it }
|
areCompatibleTypeParameters(aTypeParams, bTypeParams, platformModule, substitutor).let { if (it != Compatible) return it }
|
||||||
|
|
||||||
// Subtract kotlin.Any from supertypes because it's implicitly added if no explicit supertype is specified,
|
// Subtract kotlin.Any from supertypes because it's implicitly added if no explicit supertype is specified,
|
||||||
@@ -451,7 +440,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
bSupertypes.none { bSupertype -> areCompatibleTypes(aSupertype, bSupertype, platformModule) }
|
bSupertypes.none { bSupertype -> areCompatibleTypes(aSupertype, bSupertype, platformModule) }
|
||||||
}) return Incompatible.Supertypes
|
}) return Incompatible.Supertypes
|
||||||
|
|
||||||
areCompatibleClassScopes(a, b, checkImpl && !implTypealias, substitutor).let { if (it != Compatible) return it }
|
areCompatibleClassScopes(a, b, checkImpl && !implTypealias, platformModule, substitutor).let { if (it != Compatible) return it }
|
||||||
|
|
||||||
if (checkImpl && !b.isImpl && !implTypealias) return Incompatible.NoImpl
|
if (checkImpl && !b.isImpl && !implTypealias) return Incompatible.NoImpl
|
||||||
|
|
||||||
@@ -462,6 +451,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
a: ClassDescriptor,
|
a: ClassDescriptor,
|
||||||
b: ClassDescriptor,
|
b: ClassDescriptor,
|
||||||
checkImpl: Boolean,
|
checkImpl: Boolean,
|
||||||
|
platformModule: ModuleDescriptor,
|
||||||
substitutor: Substitutor
|
substitutor: Substitutor
|
||||||
): Compatibility {
|
): Compatibility {
|
||||||
val unimplemented = arrayListOf<Pair<CallableMemberDescriptor, Map<Incompatible, MutableCollection<CallableMemberDescriptor>>>>()
|
val unimplemented = arrayListOf<Pair<CallableMemberDescriptor, Map<Incompatible, MutableCollection<CallableMemberDescriptor>>>>()
|
||||||
@@ -472,7 +462,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
if (!aMember.kind.isReal) continue
|
if (!aMember.kind.isReal) continue
|
||||||
|
|
||||||
val mapping = bMembersByName[aMember.name].orEmpty().keysToMap { bMember ->
|
val mapping = bMembersByName[aMember.name].orEmpty().keysToMap { bMember ->
|
||||||
areCompatibleCallables(aMember, bMember, checkImpl, substitutor)
|
areCompatibleCallables(aMember, bMember, checkImpl, platformModule, substitutor)
|
||||||
}
|
}
|
||||||
if (mapping.values.any { it == Compatible }) continue
|
if (mapping.values.any { it == Compatible }) continue
|
||||||
|
|
||||||
@@ -522,18 +512,15 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
|
|
||||||
// This substitutor takes the type from A's signature and returns the type that should be in that place in B's signature
|
// This substitutor takes the type from A's signature and returns the type that should be in that place in B's signature
|
||||||
private class Substitutor(
|
private class Substitutor(
|
||||||
private val parent: Substitutor?,
|
aTypeParams: List<TypeParameterDescriptor>,
|
||||||
private val typeSubstitutor: TypeSubstitutor
|
bTypeParams: List<TypeParameterDescriptor>,
|
||||||
|
private val parent: Substitutor? = null
|
||||||
) : (KotlinType?) -> KotlinType? {
|
) : (KotlinType?) -> KotlinType? {
|
||||||
constructor(
|
private val typeSubstitutor = TypeSubstitutor.create(
|
||||||
aTypeParams: List<TypeParameterDescriptor>,
|
|
||||||
bTypeParams: List<TypeParameterDescriptor>,
|
|
||||||
parent: Substitutor? = null
|
|
||||||
) : this(parent, TypeSubstitutor.create(
|
|
||||||
TypeConstructorSubstitution.createByParametersMap(aTypeParams.keysToMap {
|
TypeConstructorSubstitution.createByParametersMap(aTypeParams.keysToMap {
|
||||||
bTypeParams[it.index].defaultType.asTypeProjection()
|
bTypeParams[it.index].defaultType.asTypeProjection()
|
||||||
})
|
})
|
||||||
))
|
)
|
||||||
|
|
||||||
override fun invoke(type: KotlinType?): KotlinType? =
|
override fun invoke(type: KotlinType?): KotlinType? =
|
||||||
(parent?.invoke(type) ?: type)?.asTypeProjection()?.let(typeSubstitutor::substitute)?.type
|
(parent?.invoke(type) ?: type)?.asTypeProjection()?.let(typeSubstitutor::substitute)?.type
|
||||||
|
|||||||
Reference in New Issue
Block a user