Support declarations returning object literals in ultra-light classes
This commit is contained in:
@@ -21,13 +21,18 @@ import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.replace
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
import java.text.StringCharacterIterator
|
||||
|
||||
internal fun buildTypeParameterList(
|
||||
@@ -105,5 +110,38 @@ internal fun typeMapper(support: UltraLightSupport): KotlinTypeMapper = KotlinTy
|
||||
IncompatibleClassTracker.DoNothing, support.moduleName,
|
||||
JvmTarget.JVM_1_8,
|
||||
KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT, // TODO use proper LanguageVersionSettings
|
||||
false
|
||||
false,
|
||||
KotlinType::cleanFromAnonymousTypes
|
||||
)
|
||||
|
||||
// Returns null when type is unchanged
|
||||
fun KotlinType.cleanFromAnonymousTypes(): KotlinType? {
|
||||
val returnTypeClass = constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
if (DescriptorUtils.isAnonymousObject(returnTypeClass)) {
|
||||
// We choose just the first supertype because:
|
||||
// - In public declarations, object literals should always have a single supertype (otherwise it's an error)
|
||||
// - For private declarations, they might have more than one supertype
|
||||
// but it looks like it's not important how we choose a representative for them
|
||||
val representative = returnTypeClass.defaultType.supertypes().firstOrNull() ?: return null
|
||||
return representative.cleanFromAnonymousTypes() ?: representative
|
||||
}
|
||||
|
||||
if (arguments.isEmpty()) return null
|
||||
|
||||
var wasUpdates = false
|
||||
|
||||
val newArguments = arguments.map { typeProjection ->
|
||||
val updatedType =
|
||||
typeProjection.takeUnless { it.isStarProjection }
|
||||
?.type?.cleanFromAnonymousTypes()
|
||||
?: return@map typeProjection
|
||||
|
||||
wasUpdates = true
|
||||
|
||||
TypeProjectionImpl(typeProjection.projectionKind, updatedType)
|
||||
}
|
||||
|
||||
if (!wasUpdates) return null
|
||||
|
||||
return replace(newArguments = newArguments)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user