[MPP] Refine enum entries and Enum-type
Enum-type inherits java.io.Serializable on JVM, so it needs to be refinement ot avoid TYPE_MISMATCH errors. Note that for the refinement of Enum-type itself it's necessary to force refinement of enum-entries, otherwise their supertypes (and Enum-type specifically) won't be touched Tests are added on IJ side ^KT-53514
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
@@ -78,6 +79,7 @@ class KotlinTypeRefinerImpl(
|
||||
require(type is KotlinType)
|
||||
return when {
|
||||
!type.needsRefinement() -> type
|
||||
|
||||
type.canBeCached() -> {
|
||||
val cached = refinedTypeCache.computeIfAbsent(type.constructor) {
|
||||
type.constructor.declarationDescriptor!!.defaultType.refineWithRespectToAbbreviatedTypes(this)
|
||||
@@ -85,6 +87,7 @@ class KotlinTypeRefinerImpl(
|
||||
|
||||
cached.restoreAdditionalTypeInformation(type)
|
||||
}
|
||||
|
||||
else -> type.refineWithRespectToAbbreviatedTypes(this)
|
||||
}
|
||||
}
|
||||
@@ -131,8 +134,11 @@ class KotlinTypeRefinerImpl(
|
||||
|
||||
@TypeRefinement
|
||||
override fun isRefinementNeededForTypeConstructor(typeConstructor: TypeConstructor): Boolean {
|
||||
val owner = typeConstructor.declarationDescriptor ?: return typeConstructor.areThereExpectSupertypes()
|
||||
return isRefinementNeededForTypeConstructorCache.computeIfAbsent(owner) { typeConstructor.areThereExpectSupertypes() }
|
||||
val owner = typeConstructor.declarationDescriptor
|
||||
?: return typeConstructor.isRefinementNeededForTypeConstructorNoCache()
|
||||
return isRefinementNeededForTypeConstructorCache.computeIfAbsent(owner) {
|
||||
typeConstructor.isRefinementNeededForTypeConstructorNoCache()
|
||||
}
|
||||
}
|
||||
|
||||
@TypeRefinement
|
||||
@@ -141,6 +147,20 @@ class KotlinTypeRefinerImpl(
|
||||
return scopes.computeIfAbsent(classDescriptor, compute) as S
|
||||
}
|
||||
|
||||
private fun TypeConstructor.isRefinementNeededForTypeConstructorNoCache(): Boolean {
|
||||
return declarationDescriptor.isEnumEntryOrEnum() || areThereExpectSupertypes()
|
||||
}
|
||||
|
||||
// Enum-type itself should be refined because on JVM it has Serializable
|
||||
// supertype, but it's not marked as expect.
|
||||
// Enum entries need refinement only to force refinement of the Enum-type
|
||||
// in their supertypes.
|
||||
private fun DeclarationDescriptor?.isEnumEntryOrEnum(): Boolean =
|
||||
if (this is ClassDescriptor)
|
||||
kind == ClassKind.ENUM_CLASS || KotlinBuiltIns.isEnum(this)
|
||||
else
|
||||
false
|
||||
|
||||
private fun TypeConstructor.areThereExpectSupertypes(): Boolean {
|
||||
var result = false
|
||||
DFS.dfs(
|
||||
@@ -178,6 +198,7 @@ private val TypeConstructor.allDependentTypeConstructors: Collection<TypeConstru
|
||||
is NewCapturedTypeConstructor -> {
|
||||
supertypes.map { it.constructor } + projection.type.constructor
|
||||
}
|
||||
|
||||
else -> supertypes.map { it.constructor }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user