Clarify logic in KotlinTypeMapper.mapType() dealing with enum entries

This allows to write correct class signatures for enum entries
    regardless of whether ASM_TYPE slice was written to
This commit is contained in:
Pavel V. Talanov
2017-02-08 14:52:05 +03:00
parent 6f6a595fef
commit 6924ddeace
4 changed files with 31 additions and 16 deletions
@@ -88,6 +88,7 @@ import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.
import static org.jetbrains.kotlin.types.Variance.INVARIANT; import static org.jetbrains.kotlin.types.Variance.INVARIANT;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isLocalFunction; import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isLocalFunction;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
import static org.jetbrains.org.objectweb.asm.Type.getObjectType;
public class ImplementationBodyCodegen extends ClassBodyCodegen { public class ImplementationBodyCodegen extends ClassBodyCodegen {
private static final String ENUM_VALUES_FIELD_NAME = "$VALUES"; private static final String ENUM_VALUES_FIELD_NAME = "$VALUES";
@@ -113,7 +114,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isLocal boolean isLocal
) { ) {
super(aClass, context, v, state, parentCodegen); super(aClass, context, v, state, parentCodegen);
this.classAsmType = typeMapper.mapClass(descriptor); this.classAsmType = getObjectType(typeMapper.classInternalName(descriptor));
this.isLocal = isLocal; this.isLocal = isLocal;
delegationFieldsInfo = getDelegationFieldsInfo(myClass.getSuperTypeListEntries()); delegationFieldsInfo = getDelegationFieldsInfo(myClass.getSuperTypeListEntries());
} }
@@ -332,7 +333,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (String kotlinMarkerInterface : kotlinMarkerInterfaces) { for (String kotlinMarkerInterface : kotlinMarkerInterfaces) {
sw.writeInterface(); sw.writeInterface();
sw.writeAsmType(Type.getObjectType(kotlinMarkerInterface)); sw.writeAsmType(getObjectType(kotlinMarkerInterface));
sw.writeInterfaceEnd(); sw.writeInterfaceEnd();
} }
@@ -349,10 +349,10 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
DeclarationDescriptor containing = innerClass.getContainingDeclaration(); DeclarationDescriptor containing = innerClass.getContainingDeclaration();
String outerClassInternalName = null; String outerClassInternalName = null;
if (containing instanceof ClassDescriptor) { if (containing instanceof ClassDescriptor) {
outerClassInternalName = typeMapper.mapClass((ClassDescriptor) containing).getInternalName(); outerClassInternalName = typeMapper.classInternalName((ClassDescriptor) containing);
} }
String innerName = innerClass.getName().isSpecial() ? null : innerClass.getName().asString(); String innerName = innerClass.getName().isSpecial() ? null : innerClass.getName().asString();
String innerClassInternalName = typeMapper.mapClass(innerClass).getInternalName(); String innerClassInternalName = typeMapper.classInternalName(innerClass);
v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, calculateInnerClassAccessFlags(innerClass)); v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, calculateInnerClassAccessFlags(innerClass));
} }
@@ -1504,4 +1504,13 @@ public class KotlinTypeMapper {
return null; return null;
} }
@NotNull
public String classInternalName(@NotNull ClassDescriptor classDescriptor) {
Type recordedType = typeMappingConfiguration.getPredefinedTypeForClass(classDescriptor);
if (recordedType != null) {
return recordedType.getInternalName();
}
return TypeSignatureMappingKt.computeInternalName(classDescriptor, typeMappingConfiguration);
}
} }
@@ -16,11 +16,11 @@
package org.jetbrains.kotlin.load.kotlin package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.builtins.FAKE_CONTINUATION_CLASS_DESCRIPTOR
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.MutableClassDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -31,8 +31,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
import org.jetbrains.kotlin.utils.DO_NOTHING_3 import org.jetbrains.kotlin.utils.DO_NOTHING_3
@@ -148,11 +146,19 @@ fun <T : Any> mapType(
descriptor is ClassDescriptor -> { descriptor is ClassDescriptor -> {
val jvmType = val jvmType =
if (mode.isForAnnotationParameter && KotlinBuiltIns.isKClass(descriptor)) if (mode.isForAnnotationParameter && KotlinBuiltIns.isKClass(descriptor)) {
factory.javaLangClassType factory.javaLangClassType
else }
else {
typeMappingConfiguration.getPredefinedTypeForClass(descriptor.original) typeMappingConfiguration.getPredefinedTypeForClass(descriptor.original)
?: factory.createObjectType(computeInternalName(descriptor.original, typeMappingConfiguration)) ?: run {
// refer to enum entries by enum type in bytecode unless ASM_TYPE is written
val enumClassIfEnumEntry = if (descriptor.kind == ClassKind.ENUM_ENTRY)
descriptor.containingDeclaration as ClassDescriptor
else descriptor
factory.createObjectType(computeInternalName(enumClassIfEnumEntry.original, typeMappingConfiguration))
}
}
writeGenericType(kotlinType, jvmType, mode) writeGenericType(kotlinType, jvmType, mode)
@@ -211,7 +217,7 @@ private fun <T : Any> mapBuiltInType(
return null return null
} }
internal fun computeInternalName( fun computeInternalName(
klass: ClassDescriptor, klass: ClassDescriptor,
typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl
): String { ): String {
@@ -229,8 +235,7 @@ internal fun computeInternalName(
val containerInternalName = val containerInternalName =
typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass) ?: typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass) ?:
computeInternalName(containerClass, typeMappingConfiguration) computeInternalName(containerClass, typeMappingConfiguration)
return if (klass.kind == ClassKind.ENUM_ENTRY) containerInternalName return typeMappingConfiguration.innerClassNameFactory(containerInternalName, name)
else typeMappingConfiguration.innerClassNameFactory(containerInternalName, name)
} }
private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType { private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType {