Somewhat simplify mapping of JVM primitive types
This commit is contained in:
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
|
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||||
import org.jetbrains.kotlin.builtins.jvm.IntrinsicObjects;
|
import org.jetbrains.kotlin.builtins.jvm.IntrinsicObjects;
|
||||||
import org.jetbrains.kotlin.codegen.*;
|
import org.jetbrains.kotlin.codegen.*;
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
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.CompileTimeConstant;
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
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.JvmMethodParameterKind;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
@@ -67,8 +69,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.boxType;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod;
|
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
|
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
|
||||||
@@ -166,7 +167,7 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
if (directMember instanceof DeserializedCallableMemberDescriptor) {
|
if (directMember instanceof DeserializedCallableMemberDescriptor) {
|
||||||
FqName packagePartFqName = PackagePartClassUtils.getPackagePartFqName((DeserializedCallableMemberDescriptor) directMember);
|
FqName packagePartFqName = PackagePartClassUtils.getPackagePartFqName((DeserializedCallableMemberDescriptor) directMember);
|
||||||
return AsmUtil.internalNameByFqNameWithoutInnerClasses(packagePartFqName);
|
return internalNameByFqNameWithoutInnerClasses(packagePartFqName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,15 +267,7 @@ public class JetTypeMapper {
|
|||||||
@NotNull JetTypeMapperMode kind,
|
@NotNull JetTypeMapperMode kind,
|
||||||
@NotNull Variance howThisTypeIsUsed
|
@NotNull Variance howThisTypeIsUsed
|
||||||
) {
|
) {
|
||||||
Type known = null;
|
Type known = mapBuiltinType(jetType);
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE;
|
boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE;
|
||||||
if (known != null) {
|
if (known != null) {
|
||||||
@@ -296,6 +289,7 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypeConstructor constructor = jetType.getConstructor();
|
TypeConstructor constructor = jetType.getConstructor();
|
||||||
|
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
|
||||||
if (constructor instanceof IntersectionTypeConstructor) {
|
if (constructor instanceof IntersectionTypeConstructor) {
|
||||||
jetType = CommonSupertypes.commonSupertype(new ArrayList<JetType>(constructor.getSupertypes()));
|
jetType = CommonSupertypes.commonSupertype(new ArrayList<JetType>(constructor.getSupertypes()));
|
||||||
}
|
}
|
||||||
@@ -349,7 +343,7 @@ public class JetTypeMapper {
|
|||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
FqName companionObjectMappedFqName = IntrinsicObjects.mapType((ClassDescriptor) descriptor);
|
FqName companionObjectMappedFqName = IntrinsicObjects.mapType((ClassDescriptor) descriptor);
|
||||||
if (companionObjectMappedFqName != null) {
|
if (companionObjectMappedFqName != null) {
|
||||||
Type asmType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(companionObjectMappedFqName);
|
Type asmType = asmTypeByFqNameWithoutInnerClasses(companionObjectMappedFqName);
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
signatureVisitor.writeAsmType(asmType);
|
signatureVisitor.writeAsmType(asmType);
|
||||||
}
|
}
|
||||||
@@ -376,6 +370,22 @@ public class JetTypeMapper {
|
|||||||
throw new UnsupportedOperationException("Unknown type " + jetType);
|
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
|
@NotNull
|
||||||
private Type computeAsmType(@NotNull ClassDescriptor klass) {
|
private Type computeAsmType(@NotNull ClassDescriptor klass) {
|
||||||
Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass);
|
Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass);
|
||||||
|
|||||||
+11
-28
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.name.FqName;
|
|||||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMapBuilder;
|
import org.jetbrains.kotlin.platform.JavaToKotlinClassMapBuilder;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
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> 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 final Map<FqName, FqName> kotlinToJavaFqName = new HashMap<FqName, FqName>();
|
||||||
|
|
||||||
private KotlinToJavaTypesMap() {
|
private KotlinToJavaTypesMap() {
|
||||||
@@ -58,31 +56,21 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
|
|||||||
PrimitiveType primitiveType = type.getPrimitiveType();
|
PrimitiveType primitiveType = type.getPrimitiveType();
|
||||||
FqName fqName = builtInsFqName.child(primitiveType.getTypeName());
|
FqName fqName = builtInsFqName.child(primitiveType.getTypeName());
|
||||||
|
|
||||||
register(fqName, Type.getType(type.getDesc()));
|
register(fqName, type.getWrapperFqName(), Type.getType(type.getDesc()));
|
||||||
|
|
||||||
FqName wrapperFqName = type.getWrapperFqName();
|
asmTypes.put(builtInsFqName.child(primitiveType.getArrayTypeName()), Type.getType("[" + type.getDesc()));
|
||||||
registerNullable(fqName, Type.getObjectType(JvmClassName.byFqNameWithoutInnerClasses(wrapperFqName).getInternalName()));
|
|
||||||
registerFqName(fqName, wrapperFqName);
|
|
||||||
|
|
||||||
register(builtInsFqName.child(primitiveType.getArrayTypeName()), Type.getType("[" + type.getDesc()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Type getJavaAnalog(@NotNull FqName fqName, boolean isNullable) {
|
public Type getJavaAnalog(@NotNull FqName fqName) {
|
||||||
if (isNullable) {
|
|
||||||
Type nullableType = asmNullableTypes.get(fqName);
|
|
||||||
if (nullableType != null) {
|
|
||||||
return nullableType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return asmTypes.get(fqName);
|
return asmTypes.get(fqName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* E.g.
|
* E.g.
|
||||||
* kotlin.Throwable -> java.lang.Throwable
|
* kotlin.Throwable -> java.lang.Throwable
|
||||||
* kotlin.deprecated -> java.lang.annotation.Deprecated
|
* kotlin.deprecated -> java.lang.Deprecated
|
||||||
* kotlin.Int -> java.lang.Integer
|
* kotlin.Int -> java.lang.Integer
|
||||||
* kotlin.IntArray -> null
|
* kotlin.IntArray -> null
|
||||||
*/
|
*/
|
||||||
@@ -94,9 +82,11 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
|
|||||||
@Override
|
@Override
|
||||||
protected void register(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) {
|
protected void register(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) {
|
||||||
if (direction == Direction.BOTH || direction == Direction.KOTLIN_TO_JAVA) {
|
if (direction == Direction.BOTH || direction == Direction.KOTLIN_TO_JAVA) {
|
||||||
FqName fqName = DescriptorUtils.getFqNameSafe(kotlinDescriptor);
|
register(
|
||||||
register(fqName, AsmTypes.getType(javaClass));
|
DescriptorUtils.getFqNameSafe(kotlinDescriptor),
|
||||||
registerFqName(fqName, new FqName(javaClass.getCanonicalName()));
|
new FqName(javaClass.getCanonicalName()),
|
||||||
|
AsmTypes.getType(javaClass)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,15 +100,8 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder {
|
|||||||
register(javaClass, kotlinMutableDescriptor, Direction.BOTH);
|
register(javaClass, kotlinMutableDescriptor, Direction.BOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void register(@NotNull FqName fqName, @NotNull Type type) {
|
private void register(@NotNull FqName kotlinFqName, @NotNull FqName javaFqName, @NotNull Type asmType) {
|
||||||
asmTypes.put(fqName, type);
|
asmTypes.put(kotlinFqName, asmType);
|
||||||
}
|
|
||||||
|
|
||||||
private void registerNullable(@NotNull FqName fqName, @NotNull Type nullableType) {
|
|
||||||
asmNullableTypes.put(fqName, nullableType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerFqName(@NotNull FqName kotlinFqName, @NotNull FqName javaFqName) {
|
|
||||||
kotlinToJavaFqName.put(kotlinFqName, javaFqName);
|
kotlinToJavaFqName.put(kotlinFqName, javaFqName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-8
@@ -20,10 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public enum JvmPrimitiveType {
|
public enum JvmPrimitiveType {
|
||||||
BOOLEAN(PrimitiveType.BOOLEAN, "boolean", "Z", "java.lang.Boolean"),
|
BOOLEAN(PrimitiveType.BOOLEAN, "boolean", "Z", "java.lang.Boolean"),
|
||||||
@@ -38,14 +35,17 @@ public enum JvmPrimitiveType {
|
|||||||
|
|
||||||
private static final Set<FqName> WRAPPERS_CLASS_NAMES;
|
private static final Set<FqName> WRAPPERS_CLASS_NAMES;
|
||||||
private static final Map<String, JvmPrimitiveType> TYPE_BY_NAME;
|
private static final Map<String, JvmPrimitiveType> TYPE_BY_NAME;
|
||||||
|
private static final Map<PrimitiveType, JvmPrimitiveType> TYPE_BY_PRIMITIVE_TYPE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
WRAPPERS_CLASS_NAMES = new HashSet<FqName>();
|
WRAPPERS_CLASS_NAMES = new HashSet<FqName>();
|
||||||
TYPE_BY_NAME = new HashMap<String, JvmPrimitiveType>();
|
TYPE_BY_NAME = new HashMap<String, JvmPrimitiveType>();
|
||||||
|
TYPE_BY_PRIMITIVE_TYPE = new EnumMap<PrimitiveType, JvmPrimitiveType>(PrimitiveType.class);
|
||||||
|
|
||||||
for (JvmPrimitiveType primitiveType : values()) {
|
for (JvmPrimitiveType type : values()) {
|
||||||
WRAPPERS_CLASS_NAMES.add(primitiveType.getWrapperFqName());
|
WRAPPERS_CLASS_NAMES.add(type.getWrapperFqName());
|
||||||
TYPE_BY_NAME.put(primitiveType.getName(), primitiveType);
|
TYPE_BY_NAME.put(type.getName(), type);
|
||||||
|
TYPE_BY_PRIMITIVE_TYPE.put(type.getPrimitiveType(), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,16 @@ public enum JvmPrimitiveType {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JvmPrimitiveType get(@NotNull String name) {
|
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;
|
private final PrimitiveType primitiveType;
|
||||||
|
|||||||
@@ -165,13 +165,13 @@ public class KotlinBuiltIns {
|
|||||||
|
|
||||||
public final FqNameUnsafe kClass = new FqName("kotlin.reflect.KClass").toUnsafe();
|
public final FqNameUnsafe kClass = new FqName("kotlin.reflect.KClass").toUnsafe();
|
||||||
|
|
||||||
public final Set<FqNameUnsafe> primitiveTypes;
|
public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType;
|
||||||
public final Set<FqNameUnsafe> primitiveArrays;
|
public final Set<FqNameUnsafe> primitiveArrays;
|
||||||
{
|
{
|
||||||
primitiveTypes = new HashSet<FqNameUnsafe>(0);
|
fqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
|
||||||
primitiveArrays = new HashSet<FqNameUnsafe>(0);
|
primitiveArrays = new HashSet<FqNameUnsafe>(0);
|
||||||
for (PrimitiveType primitiveType : PrimitiveType.values()) {
|
for (PrimitiveType primitiveType : PrimitiveType.values()) {
|
||||||
primitiveTypes.add(fqNameUnsafe(primitiveType.getTypeName().asString()));
|
fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType);
|
||||||
primitiveArrays.add(fqNameUnsafe(primitiveType.getArrayTypeName().asString()));
|
primitiveArrays.add(fqNameUnsafe(primitiveType.getArrayTypeName().asString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,8 @@ public class KotlinBuiltIns {
|
|||||||
return fqName(simpleName).toUnsafe();
|
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));
|
return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,6 +589,11 @@ public class KotlinBuiltIns {
|
|||||||
return primitiveJetTypeToJetArrayType.get(jetType);
|
return primitiveJetTypeToJetArrayType.get(jetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) {
|
||||||
|
return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType getArrayType(@NotNull Variance projectionType, @NotNull JetType argument) {
|
public JetType getArrayType(@NotNull Variance projectionType, @NotNull JetType argument) {
|
||||||
List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument));
|
List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument));
|
||||||
@@ -681,7 +687,7 @@ public class KotlinBuiltIns {
|
|||||||
|
|
||||||
public static boolean isPrimitiveType(@NotNull JetType type) {
|
public static boolean isPrimitiveType(@NotNull JetType type) {
|
||||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
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
|
// Functions
|
||||||
|
|||||||
Reference in New Issue
Block a user