Somewhat simplify mapping of JVM primitive types

This commit is contained in:
Alexander Udalov
2015-04-21 19:51:11 +03:00
parent 0a66c78449
commit 23a792aa44
4 changed files with 62 additions and 54 deletions
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.builtins.jvm.IntrinsicObjects;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
@@ -53,6 +54,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.StringValue;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
@@ -67,8 +69,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.codegen.AsmUtil.boxType;
import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
@@ -166,7 +167,7 @@ public class JetTypeMapper {
if (directMember instanceof DeserializedCallableMemberDescriptor) {
FqName packagePartFqName = PackagePartClassUtils.getPackagePartFqName((DeserializedCallableMemberDescriptor) directMember);
return AsmUtil.internalNameByFqNameWithoutInnerClasses(packagePartFqName);
return internalNameByFqNameWithoutInnerClasses(packagePartFqName);
}
}
@@ -266,15 +267,7 @@ public class JetTypeMapper {
@NotNull JetTypeMapperMode kind,
@NotNull Variance howThisTypeIsUsed
) {
Type known = null;
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor) {
FqNameUnsafe className = DescriptorUtils.getFqName(descriptor);
if (className.isSafe()) {
known = KotlinToJavaTypesMap.getInstance().getJavaAnalog(className.toSafe(), TypeUtils.isNullableType(jetType));
}
}
Type known = mapBuiltinType(jetType);
boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE;
if (known != null) {
@@ -296,6 +289,7 @@ public class JetTypeMapper {
}
TypeConstructor constructor = jetType.getConstructor();
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
if (constructor instanceof IntersectionTypeConstructor) {
jetType = CommonSupertypes.commonSupertype(new ArrayList<JetType>(constructor.getSupertypes()));
}
@@ -349,7 +343,7 @@ public class JetTypeMapper {
if (descriptor instanceof ClassDescriptor) {
FqName companionObjectMappedFqName = IntrinsicObjects.mapType((ClassDescriptor) descriptor);
if (companionObjectMappedFqName != null) {
Type asmType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(companionObjectMappedFqName);
Type asmType = asmTypeByFqNameWithoutInnerClasses(companionObjectMappedFqName);
if (signatureVisitor != null) {
signatureVisitor.writeAsmType(asmType);
}
@@ -376,6 +370,22 @@ public class JetTypeMapper {
throw new UnsupportedOperationException("Unknown type " + jetType);
}
@Nullable
private static Type mapBuiltinType(@NotNull JetType type) {
DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (!(descriptor instanceof ClassDescriptor)) return null;
FqNameUnsafe fqName = DescriptorUtils.getFqName(descriptor);
PrimitiveType primitiveType = KotlinBuiltIns.getPrimitiveTypeByFqName(fqName);
if (primitiveType != null) {
Type asmType = Type.getType(JvmPrimitiveType.get(primitiveType).getDesc());
return TypeUtils.isNullableType(type) ? boxType(asmType) : asmType;
}
return fqName.isSafe() ? KotlinToJavaTypesMap.getInstance().getJavaAnalog(fqName.toSafe()) : null;
}
@NotNull
private Type computeAsmType(@NotNull ClassDescriptor klass) {
Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass);
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMapBuilder;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
import org.jetbrains.org.objectweb.asm.Type;
@@ -44,7 +43,6 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
}
private final Map<FqName, Type> asmTypes = new HashMap<FqName, Type>();
private final Map<FqName, Type> asmNullableTypes = new HashMap<FqName, Type>();
private final Map<FqName, FqName> kotlinToJavaFqName = new HashMap<FqName, FqName>();
private KotlinToJavaTypesMap() {
@@ -58,31 +56,21 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
PrimitiveType primitiveType = type.getPrimitiveType();
FqName fqName = builtInsFqName.child(primitiveType.getTypeName());
register(fqName, Type.getType(type.getDesc()));
register(fqName, type.getWrapperFqName(), Type.getType(type.getDesc()));
FqName wrapperFqName = type.getWrapperFqName();
registerNullable(fqName, Type.getObjectType(JvmClassName.byFqNameWithoutInnerClasses(wrapperFqName).getInternalName()));
registerFqName(fqName, wrapperFqName);
register(builtInsFqName.child(primitiveType.getArrayTypeName()), Type.getType("[" + type.getDesc()));
asmTypes.put(builtInsFqName.child(primitiveType.getArrayTypeName()), Type.getType("[" + type.getDesc()));
}
}
@Nullable
public Type getJavaAnalog(@NotNull FqName fqName, boolean isNullable) {
if (isNullable) {
Type nullableType = asmNullableTypes.get(fqName);
if (nullableType != null) {
return nullableType;
}
}
public Type getJavaAnalog(@NotNull FqName fqName) {
return asmTypes.get(fqName);
}
/**
* E.g.
* kotlin.Throwable -> java.lang.Throwable
* kotlin.deprecated -> java.lang.annotation.Deprecated
* kotlin.deprecated -> java.lang.Deprecated
* kotlin.Int -> java.lang.Integer
* kotlin.IntArray -> null
*/
@@ -94,9 +82,11 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
@Override
protected void register(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) {
if (direction == Direction.BOTH || direction == Direction.KOTLIN_TO_JAVA) {
FqName fqName = DescriptorUtils.getFqNameSafe(kotlinDescriptor);
register(fqName, AsmTypes.getType(javaClass));
registerFqName(fqName, new FqName(javaClass.getCanonicalName()));
register(
DescriptorUtils.getFqNameSafe(kotlinDescriptor),
new FqName(javaClass.getCanonicalName()),
AsmTypes.getType(javaClass)
);
}
}
@@ -110,15 +100,8 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
register(javaClass, kotlinMutableDescriptor, Direction.BOTH);
}
private void register(@NotNull FqName fqName, @NotNull Type type) {
asmTypes.put(fqName, type);
}
private void registerNullable(@NotNull FqName fqName, @NotNull Type nullableType) {
asmNullableTypes.put(fqName, nullableType);
}
private void registerFqName(@NotNull FqName kotlinFqName, @NotNull FqName javaFqName) {
private void register(@NotNull FqName kotlinFqName, @NotNull FqName javaFqName, @NotNull Type asmType) {
asmTypes.put(kotlinFqName, asmType);
kotlinToJavaFqName.put(kotlinFqName, javaFqName);
}
}