Remove IR backend-specific code from KotlinTypeMapper

Add an assertion to check that we don't call mapType anymore in JVM IR.
This commit is contained in:
Alexander Udalov
2019-08-29 18:31:06 +02:00
parent 3d79e77df3
commit 530c1411c3
5 changed files with 71 additions and 157 deletions
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
@@ -144,11 +143,9 @@ class KotlinTypeMapper @JvmOverloads constructor(
return mapClass(descriptor.constructedClass) return mapClass(descriptor.constructedClass)
} }
val container = descriptor.containingDeclaration return when (val container = descriptor.containingDeclaration) {
return when (container) {
is PackageFragmentDescriptor -> { is PackageFragmentDescriptor -> {
val packageMemberOwner = val packageMemberOwner = internalNameForPackageMemberOwner(descriptor as CallableMemberDescriptor, publicFacade)
internalNameForPackageMemberOwner(descriptor as CallableMemberDescriptor, publicFacade, isIrBackend)
Type.getObjectType(packageMemberOwner) Type.getObjectType(packageMemberOwner)
} }
is ClassDescriptor -> mapClass((container as ClassDescriptor?)!!) is ClassDescriptor -> mapClass((container as ClassDescriptor?)!!)
@@ -183,11 +180,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
return Type.VOID_TYPE return Type.VOID_TYPE
} }
if (descriptor.isSuspendFunctionNotSuspensionView() && !isIrBackend) { if (descriptor.isSuspendFunctionNotSuspensionView()) {
return mapReturnType( return mapReturnType(getOrCreateJvmSuspendFunctionView(descriptor as SimpleFunctionDescriptor, isReleaseCoroutines), sw)
getOrCreateJvmSuspendFunctionView(descriptor as SimpleFunctionDescriptor, isReleaseCoroutines),
sw
)
} }
if (hasVoidReturnType(descriptor)) { if (hasVoidReturnType(descriptor)) {
@@ -262,13 +256,17 @@ class KotlinTypeMapper @JvmOverloads constructor(
type: KotlinType, type: KotlinType,
signatureVisitor: JvmSignatureWriter? = null, signatureVisitor: JvmSignatureWriter? = null,
mode: TypeMappingMode = TypeMappingMode.DEFAULT mode: TypeMappingMode = TypeMappingMode.DEFAULT
): Type = mapType( ): Type {
type, AsmTypeFactory, mode, typeMappingConfiguration, signatureVisitor, if (isIrBackend) {
{ ktType, asmType, typeMappingMode -> throw AssertionError("IR backend shouldn't call KotlinTypeMapper.mapType: $type")
}
return mapType(
type, AsmTypeFactory, mode, typeMappingConfiguration, signatureVisitor
) { ktType, asmType, typeMappingMode ->
writeGenericType(ktType, asmType, signatureVisitor, typeMappingMode) writeGenericType(ktType, asmType, signatureVisitor, typeMappingMode)
}, }
isIrBackend }
)
private fun mapInlineClassType(kotlinType: KotlinType): Type { private fun mapInlineClassType(kotlinType: KotlinType): Type {
return mapInlineClassType(kotlinType, TypeMappingMode.DEFAULT, typeMappingConfiguration) return mapInlineClassType(kotlinType, TypeMappingMode.DEFAULT, typeMappingConfiguration)
@@ -371,7 +369,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
resolvedCall: ResolvedCall<*>? = null resolvedCall: ResolvedCall<*>? = null
): CallableMethod { ): CallableMethod {
// we generate constructors of inline classes as usual functions // we generate constructors of inline classes as usual functions
if (descriptor is ConstructorDescriptor && (kind !== OwnerKind.ERASED_INLINE_CLASS || isIrBackend)) { if (descriptor is ConstructorDescriptor && kind != OwnerKind.ERASED_INLINE_CLASS) {
val method = mapSignatureSkipGeneric(descriptor.original) val method = mapSignatureSkipGeneric(descriptor.original)
val owner = mapOwner(descriptor) val owner = mapOwner(descriptor)
val originalDescriptor = descriptor.original val originalDescriptor = descriptor.original
@@ -441,8 +439,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
} }
} }
} else { } else {
// the IR backend handles inline classes by lowering val toInlinedErasedClass = functionParent.isInline &&
val toInlinedErasedClass = !isIrBackend && functionParent.isInline &&
(!isAccessor(functionDescriptor) || isInlineClassConstructorAccessor(functionDescriptor)) (!isAccessor(functionDescriptor) || isInlineClassConstructorAccessor(functionDescriptor))
if (toInlinedErasedClass) { if (toInlinedErasedClass) {
@@ -605,37 +602,34 @@ class KotlinTypeMapper @JvmOverloads constructor(
return name return name
} }
// Mangle inline class methods outside of the Ir backend. // Special methods for inline classes.
if (InlineClassDescriptorResolver.isSynthesizedBoxMethod(descriptor)) {
return BOX_JVM_METHOD_NAME
}
if (InlineClassDescriptorResolver.isSynthesizedUnboxMethod(descriptor)) {
return UNBOX_JVM_METHOD_NAME
}
if (InlineClassDescriptorResolver.isSpecializedEqualsMethod(descriptor)) {
return name
}
var newName = name var newName = name
if (!isIrBackend) { // Constructor:
// Special methods for inline classes. // either a constructor method for inline class (should be mangled),
if (InlineClassDescriptorResolver.isSynthesizedBoxMethod(descriptor)) { // or should stay as it is ('<init>').
return BOX_JVM_METHOD_NAME if (descriptor is ConstructorDescriptor) {
} if (kind === OwnerKind.ERASED_INLINE_CLASS) {
if (InlineClassDescriptorResolver.isSynthesizedUnboxMethod(descriptor)) { newName = JvmAbi.ERASED_INLINE_CONSTRUCTOR_NAME
return UNBOX_JVM_METHOD_NAME } else {
}
if (InlineClassDescriptorResolver.isSpecializedEqualsMethod(descriptor)) {
return name return name
} }
}
// Constructor: val suffix = getInlineClassSignatureManglingSuffix(descriptor)
// either a constructor method for inline class (should be mangled), if (suffix != null) {
// or should stay as it is ('<init>'). newName += suffix
if (descriptor is ConstructorDescriptor) { } else if (kind === OwnerKind.ERASED_INLINE_CLASS) {
if (kind === OwnerKind.ERASED_INLINE_CLASS) { newName += JvmAbi.IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS
newName = JvmAbi.ERASED_INLINE_CONSTRUCTOR_NAME
} else {
return name
}
}
val suffix = getInlineClassSignatureManglingSuffix(descriptor)
if (suffix != null) {
newName += suffix
} else if (kind === OwnerKind.ERASED_INLINE_CLASS) {
newName += JvmAbi.IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS
}
} }
newName = sanitizeNameIfNeeded(newName, languageVersionSettings) newName = sanitizeNameIfNeeded(newName, languageVersionSettings)
@@ -723,11 +717,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
return mapSignature(f.callableFromObject, kind, skipGenericSignature) return mapSignature(f.callableFromObject, kind, skipGenericSignature)
} }
if (f.isSuspendFunctionNotSuspensionView() && !isIrBackend) { if (f.isSuspendFunctionNotSuspensionView()) {
return mapSignature( return mapSignature(getOrCreateJvmSuspendFunctionView(f, isReleaseCoroutines), kind, skipGenericSignature)
getOrCreateJvmSuspendFunctionView(f, isReleaseCoroutines), kind,
skipGenericSignature
)
} }
if (isDeclarationOfBigArityFunctionInvoke(f) || isDeclarationOfBigArityCreateCoroutineMethod(f)) { if (isDeclarationOfBigArityFunctionInvoke(f) || isDeclarationOfBigArityCreateCoroutineMethod(f)) {
@@ -808,7 +799,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
writeFormalTypeParameters(receiverTypeAndTypeParameters.typeParameters + directMember.typeParameters, sw) writeFormalTypeParameters(receiverTypeAndTypeParameters.typeParameters + directMember.typeParameters, sw)
receiverTypeAndTypeParameters.receiverType receiverTypeAndTypeParameters.receiverType
} }
!isIrBackend && kind == OwnerKind.ERASED_INLINE_CLASS -> { kind == OwnerKind.ERASED_INLINE_CLASS -> {
writeFormalTypeParameters(directMember.typeParameters, sw) writeFormalTypeParameters(directMember.typeParameters, sw)
(directMember.containingDeclaration as ClassDescriptor).defaultType (directMember.containingDeclaration as ClassDescriptor).defaultType
} }
@@ -903,17 +894,9 @@ class KotlinTypeMapper @JvmOverloads constructor(
val isConstructor = isConstructor(jvmSignature) val isConstructor = isConstructor(jvmSignature)
val descriptor = getDefaultDescriptor( val descriptor = getDefaultDescriptor(
jvmSignature, jvmSignature,
if (isStaticMethod(kind, functionDescriptor) || isConstructor || (isIrBackend && isStaticDeclaration(functionDescriptor))) if (isStaticMethod(kind, functionDescriptor) || isConstructor) null else ownerType.descriptor,
null else ownerType.descriptor,
functionDescriptor.unwrapFrontendVersion(), functionDescriptor.unwrapFrontendVersion(),
if (isIrBackend && isConstructor) { 0
val containingDeclaration = functionDescriptor.containingDeclaration
when {
isEnumClass(containingDeclaration) -> 2
(containingDeclaration as? ClassDescriptor)?.isInner == true -> 1
else -> 0
}
} else 0
) )
return Method(if (isConstructor) "<init>" else jvmSignature.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor) return Method(if (isConstructor) "<init>" else jvmSignature.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor)
@@ -938,8 +921,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
val containingDeclaration = descriptor.containingDeclaration val containingDeclaration = descriptor.containingDeclaration
return containingDeclaration.isInlineClass() && return containingDeclaration.isInlineClass() &&
descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED && descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED &&
(descriptor.name == InlineClassDescriptorResolver.BOX_METHOD_NAME || descriptor.name == InlineClassDescriptorResolver.BOX_METHOD_NAME
(isIrBackend && descriptor.name.asString() == BOX_JVM_METHOD_NAME))
} }
private fun isJvmPrimitive(kotlinType: KotlinType): Boolean { private fun isJvmPrimitive(kotlinType: KotlinType): Boolean {
@@ -1175,7 +1157,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
fun classInternalName(classDescriptor: ClassDescriptor): String { fun classInternalName(classDescriptor: ClassDescriptor): String {
return typeMappingConfiguration.getPredefinedTypeForClass(classDescriptor)?.internalName return typeMappingConfiguration.getPredefinedTypeForClass(classDescriptor)?.internalName
?: computeInternalName(classDescriptor, typeMappingConfiguration, isIrBackend) ?: computeInternalName(classDescriptor, typeMappingConfiguration)
} }
object InternalNameMapper { object InternalNameMapper {
@@ -1232,11 +1214,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
*/ */
val LANGUAGE_VERSION_SETTINGS_DEFAULT: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT val LANGUAGE_VERSION_SETTINGS_DEFAULT: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT
private fun internalNameForPackageMemberOwner( private fun internalNameForPackageMemberOwner(callableDescriptor: CallableMemberDescriptor, publicFacade: Boolean): String {
callableDescriptor: CallableMemberDescriptor,
publicFacade: Boolean,
isIrBackend: Boolean
): String {
val isAccessor: Boolean val isAccessor: Boolean
val descriptor = if (callableDescriptor is AccessorForCallableDescriptor<*>) { val descriptor = if (callableDescriptor is AccessorForCallableDescriptor<*>) {
isAccessor = true isAccessor = true
@@ -1266,15 +1244,6 @@ class KotlinTypeMapper @JvmOverloads constructor(
if (facadeFqName != null) return facadeFqName if (facadeFqName != null) return facadeFqName
} }
if (isIrBackend && directMember is IrPropertyDelegateDescriptor) {
return internalNameForPackageMemberOwner(directMember.correspondingProperty, publicFacade, isIrBackend)
}
// TODO: drop this usage and move IrBuiltinsPackageFragmentDescriptor to IR modules; it shouldn't be used here
if (descriptor.containingDeclaration is IrBuiltinsPackageFragmentDescriptor) {
return descriptor.containingDeclaration.name.asString()
}
if (directMember is FictitiousArrayConstructor) { if (directMember is FictitiousArrayConstructor) {
return "kotlin.Array" return "kotlin.Array"
} }
@@ -1378,7 +1347,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
mode: TypeMappingMode, mode: TypeMappingMode,
configuration: TypeMappingConfiguration<Type> configuration: TypeMappingConfiguration<Type>
): Type = ): Type =
mapType(kotlinType, AsmTypeFactory, mode, configuration, null, isIrBackend = false) mapType(kotlinType, AsmTypeFactory, mode, configuration, null)
private fun generateErrorMessageForErrorType(type: KotlinType, descriptor: DeclarationDescriptor): String { private fun generateErrorMessageForErrorType(type: KotlinType, descriptor: DeclarationDescriptor): String {
val declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) val declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
@@ -1,19 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.descriptors
interface IrBuiltinsPackageFragmentDescriptor : PackageFragmentDescriptor
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
class IrBuiltinsPackageFragmentDescriptorImpl( class IrBuiltinsPackageFragmentDescriptorImpl(
val containingModule: ModuleDescriptor, val containingModule: ModuleDescriptor,
override val fqName: FqName override val fqName: FqName
) : IrBuiltinsPackageFragmentDescriptor { ) : PackageFragmentDescriptor {
private val shortName = fqName.shortName() private val shortName = fqName.shortName()
override fun getName(): Name = shortName override fun getName(): Name = shortName
@@ -76,7 +76,7 @@ internal val ClassDescriptor.internalName: String
return JvmClassName.byClassId(it).internalName return JvmClassName.byClassId(it).internalName
} }
return computeInternalName(this, isIrBackend = false) return computeInternalName(this)
} }
val ClassId.internalName: String val ClassId.internalName: String
@@ -88,15 +88,8 @@ private fun StringBuilder.appendErasedType(type: KotlinType) {
append(type.mapToJvmType()) append(type.mapToJvmType())
} }
internal fun KotlinType.mapToJvmType() = internal fun KotlinType.mapToJvmType(): JvmType =
mapType( mapType(this, JvmTypeFactoryImpl, TypeMappingMode.DEFAULT, TypeMappingConfigurationImpl, descriptorTypeWriter = null)
this,
JvmTypeFactoryImpl,
TypeMappingMode.DEFAULT,
TypeMappingConfigurationImpl,
descriptorTypeWriter = null,
isIrBackend = false
)
sealed class JvmType { sealed class JvmType {
// null means 'void' // null means 'void'
@@ -54,19 +54,16 @@ fun <T : Any> mapType(
mode: TypeMappingMode, mode: TypeMappingMode,
typeMappingConfiguration: TypeMappingConfiguration<T>, typeMappingConfiguration: TypeMappingConfiguration<T>,
descriptorTypeWriter: JvmDescriptorTypeWriter<T>?, descriptorTypeWriter: JvmDescriptorTypeWriter<T>?,
writeGenericType: (KotlinType, T, TypeMappingMode) -> Unit = DO_NOTHING_3, writeGenericType: (KotlinType, T, TypeMappingMode) -> Unit = DO_NOTHING_3
isIrBackend: Boolean
): T { ): T {
typeMappingConfiguration.preprocessType(kotlinType)?.let { newType -> typeMappingConfiguration.preprocessType(kotlinType)?.let { newType ->
return mapType(newType, factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType, isIrBackend) return mapType(newType, factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType)
} }
if (kotlinType.isSuspendFunctionType) { if (kotlinType.isSuspendFunctionType) {
return mapType( return mapType(
transformSuspendFunctionToRuntimeFunctionType(kotlinType, typeMappingConfiguration.releaseCoroutines()), transformSuspendFunctionToRuntimeFunctionType(kotlinType, typeMappingConfiguration.releaseCoroutines()),
factory, mode, typeMappingConfiguration, descriptorTypeWriter, factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType
writeGenericType,
isIrBackend
) )
} }
@@ -89,7 +86,7 @@ fun <T : Any> mapType(
// It's not very important because such types anyway are prohibited in declarations // It's not very important because such types anyway are prohibited in declarations
return mapType( return mapType(
commonSupertype.replaceArgumentsWithStarProjections(), commonSupertype.replaceArgumentsWithStarProjections(),
factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType, isIrBackend factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType
) )
} }
@@ -123,13 +120,10 @@ fun <T : Any> mapType(
} else { } else {
descriptorTypeWriter?.writeArrayType() descriptorTypeWriter?.writeArrayType()
arrayElementType = arrayElementType = mapType(
mapType( memberType, factory, mode.toGenericArgumentMode(memberProjection.projectionKind), typeMappingConfiguration,
memberType, factory, descriptorTypeWriter, writeGenericType
mode.toGenericArgumentMode(memberProjection.projectionKind), )
typeMappingConfiguration, descriptorTypeWriter, writeGenericType,
isIrBackend
)
descriptorTypeWriter?.writeArrayEnd() descriptorTypeWriter?.writeArrayEnd()
} }
@@ -143,13 +137,8 @@ fun <T : Any> mapType(
val expandedType = SimpleClassicTypeSystemContext.computeExpandedTypeForInlineClass(kotlinType) as KotlinType? val expandedType = SimpleClassicTypeSystemContext.computeExpandedTypeForInlineClass(kotlinType) as KotlinType?
if (expandedType != null) { if (expandedType != null) {
return mapType( return mapType(
expandedType, expandedType, factory, mode.wrapInlineClassesMode(), typeMappingConfiguration,
factory, descriptorTypeWriter, writeGenericType
mode.wrapInlineClassesMode(),
typeMappingConfiguration,
descriptorTypeWriter,
writeGenericType,
isIrBackend
) )
} }
} }
@@ -166,13 +155,7 @@ fun <T : Any> mapType(
descriptor.containingDeclaration as ClassDescriptor descriptor.containingDeclaration as ClassDescriptor
else else
descriptor descriptor
factory.createObjectType( factory.createObjectType(computeInternalName(enumClassIfEnumEntry.original, typeMappingConfiguration))
computeInternalName(
enumClassIfEnumEntry.original,
typeMappingConfiguration,
isIrBackend
)
)
} }
} }
@@ -183,13 +166,8 @@ fun <T : Any> mapType(
descriptor is TypeParameterDescriptor -> { descriptor is TypeParameterDescriptor -> {
val type = mapType( val type = mapType(
descriptor.representativeUpperBound, descriptor.representativeUpperBound, factory, mode, typeMappingConfiguration,
factory, writeGenericType = DO_NOTHING_3, descriptorTypeWriter = null
mode,
typeMappingConfiguration,
writeGenericType = DO_NOTHING_3,
descriptorTypeWriter = null,
isIrBackend = isIrBackend
) )
descriptorTypeWriter?.writeTypeVariable(descriptor.getName(), type) descriptorTypeWriter?.writeTypeVariable(descriptor.getName(), type)
return type return type
@@ -241,13 +219,11 @@ fun <T : Any> TypeSystemCommonBackendContext.mapBuiltInType(
fun computeInternalName( fun computeInternalName(
klass: ClassDescriptor, klass: ClassDescriptor,
typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl, typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl
isIrBackend: Boolean
): String { ): String {
typeMappingConfiguration.getPredefinedFullInternalNameForClass(klass)?.let { return it } typeMappingConfiguration.getPredefinedFullInternalNameForClass(klass)?.let { return it }
val container = if (isIrBackend) getContainer(klass.containingDeclaration) else klass.containingDeclaration val container = klass.containingDeclaration
val name = SpecialNames.safeIdentifier(klass.name).identifier val name = SpecialNames.safeIdentifier(klass.name).identifier
if (container is PackageFragmentDescriptor) { if (container is PackageFragmentDescriptor) {
@@ -259,17 +235,12 @@ fun computeInternalName(
?: throw IllegalArgumentException("Unexpected container: $container for $klass") ?: throw IllegalArgumentException("Unexpected container: $container for $klass")
val containerInternalName = val containerInternalName =
typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass) ?: computeInternalName( typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass)
containerClass, ?: computeInternalName(containerClass, typeMappingConfiguration)
typeMappingConfiguration,
isIrBackend
)
return "$containerInternalName$$name" return "$containerInternalName$$name"
} }
private fun getContainer(container: DeclarationDescriptor?): DeclarationDescriptor? =
container as? ClassDescriptor ?: container as? PackageFragmentDescriptor ?: container?.let { getContainer(it.containingDeclaration) }
open class JvmDescriptorTypeWriter<T : Any>(private val jvmTypeFactory: JvmTypeFactory<T>) { open class JvmDescriptorTypeWriter<T : Any>(private val jvmTypeFactory: JvmTypeFactory<T>) {
private var jvmCurrentTypeArrayLevel: Int = 0 private var jvmCurrentTypeArrayLevel: Int = 0
protected var jvmCurrentType: T? = null protected var jvmCurrentType: T? = null