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
@@ -0,0 +1,34 @@
// !LANGUAGE: +InlineClasses
// !SKIP_METADATA_VERSION_CHECK
// WITH_UNSIGNED
fun uint(vararg us: UInt): UIntArray = us
fun nullableUInt(vararg us: UInt?): UIntArray {
val ls = us.filterNotNull()
return UIntArray(ls.size) { ls[it] }
}
inline fun inlinedUInt(vararg us: UInt): UIntArray = us
fun box(): String {
val uints = uint(1u, 2u, 3u)
if (sum(*uints) != 6u) return "Fail 1"
val nullableUInts = nullableUInt(1u, null, 2u, null)
if (sum(*nullableUInts) != 3u) return "Fail 2"
val inlinedUInts = inlinedUInt(1u, 3u)
if (sum(*inlinedUInts) != 4u) return "Fail 3"
return "OK"
}
fun sum(vararg us: UInt): UInt {
var sum = 0u
for (i in us) {
sum += i
}
return sum
}
@@ -1,22 +1,22 @@
package
public fun array(/*0*/ vararg a: kotlin.UIntArray /*kotlin.Array<out kotlin.UIntArray>*/): kotlin.Unit
public fun ubyte(/*0*/ vararg a: kotlin.UByte /*kotlin.Array<out kotlin.UByte>*/): kotlin.Unit
public fun uint(/*0*/ vararg a: kotlin.UInt /*kotlin.Array<out kotlin.UInt>*/): kotlin.Unit
public fun ulong(/*0*/ vararg a: kotlin.ULong /*kotlin.Array<out kotlin.ULong>*/): kotlin.Unit
public fun ushort(/*0*/ vararg a: kotlin.UShort /*kotlin.Array<out kotlin.UShort>*/): kotlin.Unit
public fun ubyte(/*0*/ vararg a: kotlin.UByte /*kotlin.UByteArray*/): kotlin.Unit
public fun uint(/*0*/ vararg a: kotlin.UInt /*kotlin.UIntArray*/): kotlin.Unit
public fun ulong(/*0*/ vararg a: kotlin.ULong /*kotlin.ULongArray*/): kotlin.Unit
public fun ushort(/*0*/ vararg a: kotlin.UShort /*kotlin.UShortArray*/): kotlin.Unit
public final annotation class Ann : kotlin.Annotation {
public constructor Ann(/*0*/ vararg a: kotlin.UInt /*kotlin.Array<out kotlin.UInt>*/)
public final val a: kotlin.Array<out kotlin.UInt>
public constructor Ann(/*0*/ vararg a: kotlin.UInt /*kotlin.UIntArray*/)
public final val a: kotlin.UIntArray
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class ValueParam {
public constructor ValueParam(/*0*/ vararg a: kotlin.ULong /*kotlin.Array<out kotlin.ULong>*/)
public final val a: kotlin.Array<out kotlin.ULong>
public constructor ValueParam(/*0*/ vararg a: kotlin.ULong /*kotlin.ULongArray*/)
public final val a: kotlin.ULongArray
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -0,0 +1,9 @@
// !LANGUAGE: +InlineClasses
// !SKIP_METADATA_VERSION_CHECK
fun ubyte(vararg a: UByte): UByteArray = a
fun ushort(vararg a: UShort): UShortArray = a
fun uint(vararg a: UInt): UIntArray = a
fun ulong(vararg a: ULong): ULongArray = a
fun rawUInt(vararg a: UInt): IntArray = <!TYPE_MISMATCH!>a<!>
@@ -0,0 +1,7 @@
package
public fun rawUInt(/*0*/ vararg a: kotlin.UInt /*kotlin.UIntArray*/): kotlin.IntArray
public fun ubyte(/*0*/ vararg a: kotlin.UByte /*kotlin.UByteArray*/): kotlin.UByteArray
public fun uint(/*0*/ vararg a: kotlin.UInt /*kotlin.UIntArray*/): kotlin.UIntArray
public fun ulong(/*0*/ vararg a: kotlin.ULong /*kotlin.ULongArray*/): kotlin.ULongArray
public fun ushort(/*0*/ vararg a: kotlin.UShort /*kotlin.UShortArray*/): kotlin.UShortArray
@@ -21323,6 +21323,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
}
@TestMetadata("varargsOfUnsignedTypes.kt")
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/vararg")
@@ -58,4 +58,9 @@ public class DiagnosticsWithUnsignedTypesGenerated extends AbstractDiagnosticsWi
public void testUnsignedLiteralsTypeCheck() throws Exception {
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/unsignedLiteralsTypeCheck.kt");
}
@TestMetadata("varargTypeToArrayTypeCheck.kt")
public void testVarargTypeToArrayTypeCheck() throws Exception {
runTest("compiler/testData/diagnostics/testsWithUnsignedTypes/varargTypeToArrayTypeCheck.kt");
}
}
@@ -21323,6 +21323,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
}
@TestMetadata("varargsOfUnsignedTypes.kt")
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/vararg")
@@ -21323,6 +21323,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
}
@TestMetadata("varargsOfUnsignedTypes.kt")
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/vararg")
@@ -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);
@@ -20338,6 +20338,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testAllFilesPresentInUnsignedTypes() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/unsignedTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true);
}
@TestMetadata("varargsOfUnsignedTypes.kt")
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/vararg")
@@ -19210,6 +19210,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testAllFilesPresentInUnsignedTypes() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/unsignedTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
}
@TestMetadata("varargsOfUnsignedTypes.kt")
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/vararg")