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.expressions.ExpressionTypingUtils.isLocalFunction;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
import static org.jetbrains.org.objectweb.asm.Type.getObjectType;
public class ImplementationBodyCodegen extends ClassBodyCodegen {
private static final String ENUM_VALUES_FIELD_NAME = "$VALUES";
@@ -113,7 +114,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isLocal
) {
super(aClass, context, v, state, parentCodegen);
this.classAsmType = typeMapper.mapClass(descriptor);
this.classAsmType = getObjectType(typeMapper.classInternalName(descriptor));
this.isLocal = isLocal;
delegationFieldsInfo = getDelegationFieldsInfo(myClass.getSuperTypeListEntries());
}
@@ -332,7 +333,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (String kotlinMarkerInterface : kotlinMarkerInterfaces) {
sw.writeInterface();
sw.writeAsmType(Type.getObjectType(kotlinMarkerInterface));
sw.writeAsmType(getObjectType(kotlinMarkerInterface));
sw.writeInterfaceEnd();
}
@@ -349,10 +349,10 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
DeclarationDescriptor containing = innerClass.getContainingDeclaration();
String outerClassInternalName = null;
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 innerClassInternalName = typeMapper.mapClass(innerClass).getInternalName();
String innerClassInternalName = typeMapper.classInternalName(innerClass);
v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, calculateInnerClassAccessFlags(innerClass));
}
@@ -1504,4 +1504,13 @@ public class KotlinTypeMapper {
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
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.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.name.ClassId
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.JvmPrimitiveType
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.utils.DO_NOTHING_3
@@ -148,11 +146,19 @@ fun <T : Any> mapType(
descriptor is ClassDescriptor -> {
val jvmType =
if (mode.isForAnnotationParameter && KotlinBuiltIns.isKClass(descriptor))
if (mode.isForAnnotationParameter && KotlinBuiltIns.isKClass(descriptor)) {
factory.javaLangClassType
else
}
else {
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)
@@ -211,7 +217,7 @@ private fun <T : Any> mapBuiltInType(
return null
}
internal fun computeInternalName(
fun computeInternalName(
klass: ClassDescriptor,
typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl
): String {
@@ -229,8 +235,7 @@ internal fun computeInternalName(
val containerInternalName =
typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass) ?:
computeInternalName(containerClass, typeMappingConfiguration)
return if (klass.kind == ClassKind.ENUM_ENTRY) containerInternalName
else typeMappingConfiguration.innerClassNameFactory(containerInternalName, name)
return typeMappingConfiguration.innerClassNameFactory(containerInternalName, name)
}
private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType {