diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 894c9e48da7..0c77eefab45 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -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(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); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/types/KotlinToJavaTypesMap.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/types/KotlinToJavaTypesMap.java index 43158ff7278..a1b5a85cff5 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/types/KotlinToJavaTypesMap.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/types/KotlinToJavaTypesMap.java @@ -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 asmTypes = new HashMap(); - private final Map asmNullableTypes = new HashMap(); private final Map kotlinToJavaFqName = new HashMap(); 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); } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java index 7bccd7d4016..eeee3fffd75 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JvmPrimitiveType.java @@ -20,10 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.builtins.PrimitiveType; import org.jetbrains.kotlin.name.FqName; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; public enum JvmPrimitiveType { BOOLEAN(PrimitiveType.BOOLEAN, "boolean", "Z", "java.lang.Boolean"), @@ -38,14 +35,17 @@ public enum JvmPrimitiveType { private static final Set WRAPPERS_CLASS_NAMES; private static final Map TYPE_BY_NAME; + private static final Map TYPE_BY_PRIMITIVE_TYPE; static { WRAPPERS_CLASS_NAMES = new HashSet(); TYPE_BY_NAME = new HashMap(); + TYPE_BY_PRIMITIVE_TYPE = new EnumMap(PrimitiveType.class); - for (JvmPrimitiveType primitiveType : values()) { - WRAPPERS_CLASS_NAMES.add(primitiveType.getWrapperFqName()); - TYPE_BY_NAME.put(primitiveType.getName(), primitiveType); + for (JvmPrimitiveType type : values()) { + WRAPPERS_CLASS_NAMES.add(type.getWrapperFqName()); + TYPE_BY_NAME.put(type.getName(), type); + TYPE_BY_PRIMITIVE_TYPE.put(type.getPrimitiveType(), type); } } @@ -55,7 +55,16 @@ public enum JvmPrimitiveType { @NotNull public static JvmPrimitiveType get(@NotNull String name) { - return TYPE_BY_NAME.get(name); + JvmPrimitiveType result = TYPE_BY_NAME.get(name); + if (result == null) { + throw new AssertionError("Non-primitive type name passed: " + name); + } + return result; + } + + @NotNull + public static JvmPrimitiveType get(@NotNull PrimitiveType type) { + return TYPE_BY_PRIMITIVE_TYPE.get(type); } private final PrimitiveType primitiveType; diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index 33568332478..69f9e9cbd81 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -165,13 +165,13 @@ public class KotlinBuiltIns { public final FqNameUnsafe kClass = new FqName("kotlin.reflect.KClass").toUnsafe(); - public final Set primitiveTypes; + public final Map fqNameToPrimitiveType; public final Set primitiveArrays; { - primitiveTypes = new HashSet(0); + fqNameToPrimitiveType = new HashMap(0); primitiveArrays = new HashSet(0); for (PrimitiveType primitiveType : PrimitiveType.values()) { - primitiveTypes.add(fqNameUnsafe(primitiveType.getTypeName().asString())); + fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType); primitiveArrays.add(fqNameUnsafe(primitiveType.getArrayTypeName().asString())); } } @@ -184,7 +184,8 @@ public class KotlinBuiltIns { return fqName(simpleName).toUnsafe(); } - private static FqName fqName(String simpleName) { + @NotNull + private static FqName fqName(@NotNull String simpleName) { return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); } @@ -588,6 +589,11 @@ public class KotlinBuiltIns { return primitiveJetTypeToJetArrayType.get(jetType); } + @Nullable + public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) { + return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName); + } + @NotNull public JetType getArrayType(@NotNull Variance projectionType, @NotNull JetType argument) { List types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument)); @@ -681,7 +687,7 @@ public class KotlinBuiltIns { public static boolean isPrimitiveType(@NotNull JetType type) { ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); - return !type.isMarkedNullable() && descriptor != null && FQ_NAMES.primitiveTypes.contains(DescriptorUtils.getFqName(descriptor)); + return !type.isMarkedNullable() && descriptor != null && getPrimitiveTypeByFqName(DescriptorUtils.getFqName(descriptor)) != null; } // Functions