Disable type mapper name mangling for inline classes in the JVM_IR backend

This commit is contained in:
Steven Schäfer
2019-05-10 11:51:55 +02:00
committed by Alexander Udalov
parent f5b9eee83a
commit ad3e03bdbd
@@ -384,7 +384,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) { if (descriptor is ConstructorDescriptor && (kind !== OwnerKind.ERASED_INLINE_CLASS || isIrBackend)) {
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
@@ -454,8 +454,10 @@ class KotlinTypeMapper @JvmOverloads constructor(
} }
} }
} else { } else {
val toInlinedErasedClass = // the IR backend handles inline classes by lowering
functionParent.isInline && (!isAccessor(functionDescriptor) || isInlineClassConstructorAccessor(functionDescriptor)) val toInlinedErasedClass = !isIrBackend && functionParent.isInline &&
(!isAccessor(functionDescriptor) || isInlineClassConstructorAccessor(functionDescriptor))
if (toInlinedErasedClass) { if (toInlinedErasedClass) {
functionDescriptor = descriptor functionDescriptor = descriptor
} }
@@ -616,34 +618,37 @@ class KotlinTypeMapper @JvmOverloads constructor(
return name return name
} }
// Special methods for inline classes. // Mangle inline class methods outside of the Ir backend.
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
// Constructor: if (!isIrBackend) {
// either a constructor method for inline class (should be mangled), // Special methods for inline classes.
// or should stay as it is ('<init>'). if (InlineClassDescriptorResolver.isSynthesizedBoxMethod(descriptor)) {
if (descriptor is ConstructorDescriptor) { return BOX_JVM_METHOD_NAME
if (kind === OwnerKind.ERASED_INLINE_CLASS) { }
newName = JvmAbi.ERASED_INLINE_CONSTRUCTOR_NAME if (InlineClassDescriptorResolver.isSynthesizedUnboxMethod(descriptor)) {
} else { return UNBOX_JVM_METHOD_NAME
}
if (InlineClassDescriptorResolver.isSpecializedEqualsMethod(descriptor)) {
return name return name
} }
}
val suffix = getInlineClassSignatureManglingSuffix(descriptor) // Constructor:
if (suffix != null) { // either a constructor method for inline class (should be mangled),
newName += suffix // or should stay as it is ('<init>').
} else if (kind === OwnerKind.ERASED_INLINE_CLASS) { if (descriptor is ConstructorDescriptor) {
newName += JvmAbi.IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS if (kind === OwnerKind.ERASED_INLINE_CLASS) {
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)
@@ -662,7 +667,6 @@ class KotlinTypeMapper @JvmOverloads constructor(
) { ) {
InternalNameMapper.mangleInternalName(newName, getModuleName(descriptor)) InternalNameMapper.mangleInternalName(newName, getModuleName(descriptor))
} else newName } else newName
} }
private fun getModuleName(descriptor: CallableMemberDescriptor): String { private fun getModuleName(descriptor: CallableMemberDescriptor): String {
@@ -811,13 +815,13 @@ class KotlinTypeMapper @JvmOverloads constructor(
} }
} else { } else {
val directMember = DescriptorUtils.getDirectMember(f) val directMember = DescriptorUtils.getDirectMember(f)
val thisIfNeeded: KotlinType? = when (kind) { val thisIfNeeded: KotlinType? = when {
OwnerKind.DEFAULT_IMPLS -> { kind == OwnerKind.DEFAULT_IMPLS -> {
val receiverTypeAndTypeParameters = patchTypeParametersForDefaultImplMethod(directMember) val receiverTypeAndTypeParameters = patchTypeParametersForDefaultImplMethod(directMember)
writeFormalTypeParameters(receiverTypeAndTypeParameters.typeParameters + directMember.typeParameters, sw) writeFormalTypeParameters(receiverTypeAndTypeParameters.typeParameters + directMember.typeParameters, sw)
receiverTypeAndTypeParameters.receiverType receiverTypeAndTypeParameters.receiverType
} }
OwnerKind.ERASED_INLINE_CLASS -> { !isIrBackend && kind == OwnerKind.ERASED_INLINE_CLASS -> {
(directMember.containingDeclaration as ClassDescriptor).defaultType (directMember.containingDeclaration as ClassDescriptor).defaultType
} }
else -> { else -> {
@@ -942,6 +946,14 @@ class KotlinTypeMapper @JvmOverloads constructor(
getAllOverriddenDescriptors(descriptor).any { !isJvmPrimitive(it.returnType!!) } getAllOverriddenDescriptors(descriptor).any { !isJvmPrimitive(it.returnType!!) }
} }
private fun isBoxMethodForInlineClass(descriptor: FunctionDescriptor): Boolean {
val containingDeclaration = descriptor.containingDeclaration
return containingDeclaration.isInlineClass() &&
descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED &&
(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 {
if (KotlinBuiltIns.isPrimitiveType(kotlinType)) return true if (KotlinBuiltIns.isPrimitiveType(kotlinType)) return true
@@ -1613,13 +1625,6 @@ class KotlinTypeMapper @JvmOverloads constructor(
return callableDescriptor is ClassConstructorDescriptor && callableDescriptor.containingDeclaration.isInlineClass() return callableDescriptor is ClassConstructorDescriptor && callableDescriptor.containingDeclaration.isInlineClass()
} }
private fun isBoxMethodForInlineClass(descriptor: FunctionDescriptor): Boolean {
val containingDeclaration = descriptor.containingDeclaration
return containingDeclaration.isInlineClass() &&
descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED &&
descriptor.name == InlineClassDescriptorResolver.BOX_METHOD_NAME
}
private fun writeVoidReturn(sw: JvmSignatureWriter) { private fun writeVoidReturn(sw: JvmSignatureWriter) {
sw.writeReturnType() sw.writeReturnType()
sw.writeAsmType(Type.VOID_TYPE) sw.writeAsmType(Type.VOID_TYPE)