Associate vararg of unsigned types with corresponding arrays

This is a first step, full support will be added later

 #KT-24880 In Progress
This commit is contained in:
Mikhail Zarechenskiy
2018-06-14 15:17:43 +03:00
parent 3e45a1529c
commit 333411c57d
13 changed files with 165 additions and 16 deletions
@@ -74,6 +74,7 @@ public abstract class KotlinBuiltIns {
private ModuleDescriptorImpl builtInsModule;
private final NotNullLazyValue<Primitives> primitives;
private final MemoizedFunctionToNotNull<ModuleDescriptor, UnsignedPrimitives> unsignedPrimitives;
private final NotNullLazyValue<PackageFragments> packageFragments;
private final MemoizedFunctionToNotNull<Integer, ClassDescriptor> suspendFunctionClasses;
@@ -123,6 +124,29 @@ public abstract class KotlinBuiltIns {
}
});
this.unsignedPrimitives = storageManager.createMemoizedFunction(new Function1<ModuleDescriptor, UnsignedPrimitives>() {
@Override
public UnsignedPrimitives invoke(ModuleDescriptor module) {
Map<KotlinType, SimpleType> unsignedKotlinTypeToKotlinArrayType = new HashMap<KotlinType, SimpleType>();
Map<SimpleType, SimpleType> kotlinArrayTypeToUnsignedKotlinType = new HashMap<SimpleType, SimpleType>();
for (UnsignedType unsigned : UnsignedType.values()) {
ClassDescriptor descriptor = FindClassInModuleKt.findClassAcrossModuleDependencies(module, unsigned.getClassId());
if (descriptor == null) continue;
ClassDescriptor arrayDescriptor =
FindClassInModuleKt.findClassAcrossModuleDependencies(module, unsigned.getArrayClassId());
if (arrayDescriptor == null) continue;
SimpleType type = descriptor.getDefaultType();
SimpleType arrayType = arrayDescriptor.getDefaultType();
unsignedKotlinTypeToKotlinArrayType.put(type, arrayType);
kotlinArrayTypeToUnsignedKotlinType.put(arrayType, type);
}
return new UnsignedPrimitives(unsignedKotlinTypeToKotlinArrayType, kotlinArrayTypeToUnsignedKotlinType);
}
});
this.suspendFunctionClasses = storageManager.createMemoizedFunction(new Function1<Integer, ClassDescriptor>() {
@Override
public ClassDescriptor invoke(Integer arity) {
@@ -239,6 +263,19 @@ public abstract class KotlinBuiltIns {
}
}
private static class UnsignedPrimitives {
public final Map<KotlinType, SimpleType> unsignedKotlinTypeToKotlinArrayType;
public final Map<SimpleType, SimpleType> kotlinArrayTypeToUnsignedKotlinType;
private UnsignedPrimitives(
@NotNull Map<KotlinType, SimpleType> unsignedKotlinTypeToKotlinArrayType,
@NotNull Map<SimpleType, SimpleType> kotlinArrayTypeToUnsignedKotlinType
) {
this.unsignedKotlinTypeToKotlinArrayType = unsignedKotlinTypeToKotlinArrayType;
this.kotlinArrayTypeToUnsignedKotlinType = kotlinArrayTypeToUnsignedKotlinType;
}
}
private static class PackageFragments {
public final PackageFragmentDescriptor builtInsPackageFragment;
public final PackageFragmentDescriptor collectionsPackageFragment;
@@ -802,12 +839,20 @@ public abstract class KotlinBuiltIns {
}
return arrayType.getArguments().get(0).getType();
}
KotlinType notNullArrayType = TypeUtils.makeNotNullable(arrayType);
//noinspection SuspiciousMethodCalls
KotlinType primitiveType = primitives.invoke().kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType));
if (primitiveType == null) {
throw new IllegalStateException("not array: " + arrayType);
KotlinType primitiveType = primitives.invoke().kotlinArrayTypeToPrimitiveKotlinType.get(notNullArrayType);
if (primitiveType != null) return primitiveType;
ModuleDescriptor module = DescriptorUtils.getContainingModuleOrNull(notNullArrayType);
if (module != null) {
//noinspection SuspiciousMethodCalls
SimpleType unsignedType = unsignedPrimitives.invoke(module).kotlinArrayTypeToUnsignedKotlinType.get(notNullArrayType);
if (unsignedType != null) return unsignedType;
}
return primitiveType;
throw new IllegalStateException("not array: " + arrayType);
}
@NotNull
@@ -820,7 +865,17 @@ public abstract class KotlinBuiltIns {
*/
@Nullable
public SimpleType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) {
return primitives.invoke().primitiveKotlinTypeToKotlinArrayType.get(kotlinType);
SimpleType primitiveArray = primitives.invoke().primitiveKotlinTypeToKotlinArrayType.get(kotlinType);
if (primitiveArray != null) return primitiveArray;
if (UnsignedTypes.INSTANCE.isUnsignedType(kotlinType)) {
ModuleDescriptor module = DescriptorUtils.getContainingModuleOrNull(kotlinType);
if (module == null) return null;
return unsignedPrimitives.invoke(module).unsignedKotlinTypeToKotlinArrayType.get(kotlinType);
}
return null;
}
public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) {
@@ -7,15 +7,21 @@ package org.jetbrains.kotlin.builtins
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import kotlin.reflect.KClass
enum class UnsignedType(val typeName: Name) {
UBYTE("UByte"), USHORT("UShort"), UINT("UInt"), ULONG("ULong");
enum class UnsignedType(val classId: ClassId) {
UBYTE(ClassId.fromString("kotlin/UByte")),
USHORT(ClassId.fromString("kotlin/UShort")),
UINT(ClassId.fromString("kotlin/UInt")),
ULONG(ClassId.fromString("kotlin/ULong"));
constructor(typeName: String) : this(Name.identifier(typeName))
val typeName = classId.shortClassName
val arrayTypeName = Name.identifier(typeName.asString() + "Array")
val arrayClassId = ClassId(classId.packageFqName, arrayTypeName)
}
object UnsignedTypes {
@@ -184,6 +184,14 @@ public class DescriptorUtils {
return null;
}
@Nullable
public static ModuleDescriptor getContainingModuleOrNull(@NotNull KotlinType kotlinType) {
ClassifierDescriptor descriptor = kotlinType.getConstructor().getDeclarationDescriptor();
if (descriptor == null) return null;
return getContainingModuleOrNull(descriptor);
}
@NotNull
public static ModuleDescriptor getContainingModule(@NotNull DeclarationDescriptor descriptor) {
ModuleDescriptor module = getContainingModuleOrNull(descriptor);