From b5fabf3f725fd7f502accc1ad50cbde52722138e Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 3 Jul 2018 14:56:26 +0300 Subject: [PATCH] Make unsigned types experimental (with warning if not opted-in) --- generators/builtins/unsignedTypes.kt | 9 ++++++++ libraries/stdlib/common/build.gradle | 2 ++ libraries/stdlib/jvm/build.gradle | 2 ++ libraries/stdlib/unsigned/src/kotlin/UByte.kt | 5 ++++ .../stdlib/unsigned/src/kotlin/UByteArray.kt | 3 +++ libraries/stdlib/unsigned/src/kotlin/UInt.kt | 5 ++++ .../stdlib/unsigned/src/kotlin/UIntArray.kt | 3 +++ .../stdlib/unsigned/src/kotlin/UIntRange.kt | 3 +++ .../stdlib/unsigned/src/kotlin/UIterators.kt | 4 ++++ libraries/stdlib/unsigned/src/kotlin/ULong.kt | 5 ++++ .../stdlib/unsigned/src/kotlin/ULongArray.kt | 3 +++ .../stdlib/unsigned/src/kotlin/ULongRange.kt | 3 +++ .../stdlib/unsigned/src/kotlin/UShort.kt | 5 ++++ .../stdlib/unsigned/src/kotlin/UShortArray.kt | 3 +++ .../src/kotlin/annotations/Unsigned.kt | 23 +++++++++++++++++++ 15 files changed, 78 insertions(+) create mode 100644 libraries/stdlib/unsigned/src/kotlin/annotations/Unsigned.kt diff --git a/generators/builtins/unsignedTypes.kt b/generators/builtins/unsignedTypes.kt index 6d65b600f63..3e96421b64d 100644 --- a/generators/builtins/unsignedTypes.kt +++ b/generators/builtins/unsignedTypes.kt @@ -43,6 +43,7 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns out.println("@Suppress(\"NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS\")") out.println("@SinceKotlin(\"1.3\")") + out.println("@ExperimentalUnsignedTypes") out.println("public inline class $className internal constructor(private val data: $storageType) : Comparable<$className> {") out.println() out.println(""" companion object { @@ -198,6 +199,7 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns val otherSigned = otherType.asSigned.capitalized val thisSigned = type.asSigned.capitalized out.println("@SinceKotlin(\"1.3\")") + out.println("@ExperimentalUnsignedTypes") out.print("public fun $otherSigned.to$className(): $className = ") out.println(when { otherType < type -> "$className(this.to$thisSigned() and ${otherType.mask})" @@ -241,6 +243,7 @@ class UnsignedIteratorsGenerator(out: PrintWriter) : BuiltInsSourceGenerator(out val s = type.capitalized out.println("/** An iterator over a sequence of values of type `$s`. */") out.println("@SinceKotlin(\"1.3\")") + out.println("@ExperimentalUnsignedTypes") out.println("public abstract class ${s}Iterator : Iterator<$s> {") // TODO: Sort modifiers out.println(" override final fun next() = next$s()") @@ -261,6 +264,7 @@ class UnsignedArrayGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIn val storageArrayType = storageElementType + "Array" override fun generateBody() { out.println("@SinceKotlin(\"1.3\")") + out.println("@ExperimentalUnsignedTypes") out.println("public inline class $arrayType") out.println("@Suppress(\"NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS\")") out.println("@PublishedApi") @@ -299,11 +303,13 @@ class UnsignedArrayGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIn // TODO: Make inline constructor, like in ByteArray out.println() out.println("@SinceKotlin(\"1.3\")") + out.println("@ExperimentalUnsignedTypes") out.println("""public inline fun $arrayType(size: Int, init: (Int) -> $elementType): $arrayType { return $arrayType($storageArrayType(size) { index -> init(index).to$storageElementType() }) } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes // TODO: @kotlin.internal.InlineOnly public inline fun $arrayTypeOf(vararg elements: $elementType): $arrayType = elements""" ) @@ -330,6 +336,7 @@ import kotlin.internal.* * A range of values of type `$elementType`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public class ${elementType}Range(start: $elementType, endInclusive: $elementType) : ${elementType}Progression(start, endInclusive, 1), ClosedRange<${elementType}> { override val start: $elementType get() = first override val endInclusive: $elementType get() = last @@ -357,6 +364,7 @@ public class ${elementType}Range(start: $elementType, endInclusive: $elementType * A progression of values of type `$elementType`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public open class ${elementType}Progression internal constructor( start: $elementType, @@ -413,6 +421,7 @@ internal constructor( * @property step the number by which the value is incremented on each step. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes private class ${elementType}ProgressionIterator(first: $elementType, last: $elementType, step: $stepType) : ${elementType}Iterator() { private val finalElement = last private var hasNext: Boolean = if (step > 0) first <= last else first >= last diff --git a/libraries/stdlib/common/build.gradle b/libraries/stdlib/common/build.gradle index 8e7225aa2e1..cf8390ac924 100644 --- a/libraries/stdlib/common/build.gradle +++ b/libraries/stdlib/common/build.gradle @@ -67,6 +67,8 @@ compileUnsignedKotlinCommon { languageVersion = "1.3" apiVersion = "1.3" freeCompilerArgs += [ + "-Xuse-experimental=kotlin.Experimental", + "-Xuse-experimental=kotlin.ExperimentalUnsignedTypes", "-XXLanguage:+InlineClasses" ] } diff --git a/libraries/stdlib/jvm/build.gradle b/libraries/stdlib/jvm/build.gradle index b3f038b8c58..2f13c716086 100644 --- a/libraries/stdlib/jvm/build.gradle +++ b/libraries/stdlib/jvm/build.gradle @@ -212,6 +212,8 @@ compileUnsignedKotlin { languageVersion = "1.3" apiVersion = "1.3" freeCompilerArgs += [ + "-Xuse-experimental=kotlin.Experimental", + "-Xuse-experimental=kotlin.ExperimentalUnsignedTypes", "-XXLanguage:+InlineClasses" ] } diff --git a/libraries/stdlib/unsigned/src/kotlin/UByte.kt b/libraries/stdlib/unsigned/src/kotlin/UByte.kt index a1a89cc69c8..6ce7657d655 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UByte.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UByte.kt @@ -11,6 +11,7 @@ import kotlin.experimental.* @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class UByte internal constructor(private val data: Byte) : Comparable { companion object { @@ -130,10 +131,14 @@ public inline class UByte internal constructor(private val data: Byte) : Compara } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Byte.toUByte(): UByte = UByte(this) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Short.toUByte(): UByte = UByte(this.toByte()) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Int.toUByte(): UByte = UByte(this.toByte()) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Long.toUByte(): UByte = UByte(this.toByte()) diff --git a/libraries/stdlib/unsigned/src/kotlin/UByteArray.kt b/libraries/stdlib/unsigned/src/kotlin/UByteArray.kt index fc28484d5a1..a2ab0849f97 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UByteArray.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UByteArray.kt @@ -8,6 +8,7 @@ package kotlin @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class UByteArray @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @PublishedApi @@ -41,10 +42,12 @@ internal constructor(private val storage: ByteArray) : Collection { } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline fun UByteArray(size: Int, init: (Int) -> UByte): UByteArray { return UByteArray(ByteArray(size) { index -> init(index).toByte() }) } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes // TODO: @kotlin.internal.InlineOnly public inline fun ubyteArrayOf(vararg elements: UByte): UByteArray = elements diff --git a/libraries/stdlib/unsigned/src/kotlin/UInt.kt b/libraries/stdlib/unsigned/src/kotlin/UInt.kt index 3d96bb18cf2..6840d53ef78 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UInt.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UInt.kt @@ -11,6 +11,7 @@ import kotlin.experimental.* @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class UInt internal constructor(private val data: Int) : Comparable { companion object { @@ -134,10 +135,14 @@ public inline class UInt internal constructor(private val data: Int) : Comparabl } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Byte.toUInt(): UInt = UInt(this.toInt() and 0xFF) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Short.toUInt(): UInt = UInt(this.toInt() and 0xFFFF) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Int.toUInt(): UInt = UInt(this) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Long.toUInt(): UInt = UInt(this.toInt()) diff --git a/libraries/stdlib/unsigned/src/kotlin/UIntArray.kt b/libraries/stdlib/unsigned/src/kotlin/UIntArray.kt index a84d4efde2a..52a0d376dd3 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UIntArray.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UIntArray.kt @@ -8,6 +8,7 @@ package kotlin @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class UIntArray @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @PublishedApi @@ -41,10 +42,12 @@ internal constructor(private val storage: IntArray) : Collection { } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline fun UIntArray(size: Int, init: (Int) -> UInt): UIntArray { return UIntArray(IntArray(size) { index -> init(index).toInt() }) } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes // TODO: @kotlin.internal.InlineOnly public inline fun uintArrayOf(vararg elements: UInt): UIntArray = elements diff --git a/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt b/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt index 9081032fcf2..bbba3e3058b 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UIntRange.kt @@ -15,6 +15,7 @@ import kotlin.internal.* * A range of values of type `UInt`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public class UIntRange(start: UInt, endInclusive: UInt) : UIntProgression(start, endInclusive, 1), ClosedRange { override val start: UInt get() = first override val endInclusive: UInt get() = last @@ -42,6 +43,7 @@ public class UIntRange(start: UInt, endInclusive: UInt) : UIntProgression(start, * A progression of values of type `UInt`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public open class UIntProgression internal constructor( start: UInt, @@ -98,6 +100,7 @@ internal constructor( * @property step the number by which the value is incremented on each step. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes private class UIntProgressionIterator(first: UInt, last: UInt, step: Int) : UIntIterator() { private val finalElement = last private var hasNext: Boolean = if (step > 0) first <= last else first >= last diff --git a/libraries/stdlib/unsigned/src/kotlin/UIterators.kt b/libraries/stdlib/unsigned/src/kotlin/UIterators.kt index 18bd7aba9af..a9c4f0b60ee 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UIterators.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UIterators.kt @@ -9,6 +9,7 @@ package kotlin.collections /** An iterator over a sequence of values of type `UByte`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public abstract class UByteIterator : Iterator { override final fun next() = nextUByte() @@ -18,6 +19,7 @@ public abstract class UByteIterator : Iterator { /** An iterator over a sequence of values of type `UShort`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public abstract class UShortIterator : Iterator { override final fun next() = nextUShort() @@ -27,6 +29,7 @@ public abstract class UShortIterator : Iterator { /** An iterator over a sequence of values of type `UInt`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public abstract class UIntIterator : Iterator { override final fun next() = nextUInt() @@ -36,6 +39,7 @@ public abstract class UIntIterator : Iterator { /** An iterator over a sequence of values of type `ULong`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public abstract class ULongIterator : Iterator { override final fun next() = nextULong() diff --git a/libraries/stdlib/unsigned/src/kotlin/ULong.kt b/libraries/stdlib/unsigned/src/kotlin/ULong.kt index a23c438f420..4fa79ea6d2a 100644 --- a/libraries/stdlib/unsigned/src/kotlin/ULong.kt +++ b/libraries/stdlib/unsigned/src/kotlin/ULong.kt @@ -11,6 +11,7 @@ import kotlin.experimental.* @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class ULong internal constructor(private val data: Long) : Comparable { companion object { @@ -134,10 +135,14 @@ public inline class ULong internal constructor(private val data: Long) : Compara } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Byte.toULong(): ULong = ULong(this.toLong() and 0xFF) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Short.toULong(): ULong = ULong(this.toLong() and 0xFFFF) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Int.toULong(): ULong = ULong(this.toLong() and 0xFFFF_FFFF) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Long.toULong(): ULong = ULong(this) diff --git a/libraries/stdlib/unsigned/src/kotlin/ULongArray.kt b/libraries/stdlib/unsigned/src/kotlin/ULongArray.kt index df34cc36979..105787adebc 100644 --- a/libraries/stdlib/unsigned/src/kotlin/ULongArray.kt +++ b/libraries/stdlib/unsigned/src/kotlin/ULongArray.kt @@ -8,6 +8,7 @@ package kotlin @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class ULongArray @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @PublishedApi @@ -41,10 +42,12 @@ internal constructor(private val storage: LongArray) : Collection { } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline fun ULongArray(size: Int, init: (Int) -> ULong): ULongArray { return ULongArray(LongArray(size) { index -> init(index).toLong() }) } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes // TODO: @kotlin.internal.InlineOnly public inline fun ulongArrayOf(vararg elements: ULong): ULongArray = elements diff --git a/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt b/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt index ca77502cf6c..fc0ef2ef591 100644 --- a/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt +++ b/libraries/stdlib/unsigned/src/kotlin/ULongRange.kt @@ -15,6 +15,7 @@ import kotlin.internal.* * A range of values of type `ULong`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public class ULongRange(start: ULong, endInclusive: ULong) : ULongProgression(start, endInclusive, 1), ClosedRange { override val start: ULong get() = first override val endInclusive: ULong get() = last @@ -42,6 +43,7 @@ public class ULongRange(start: ULong, endInclusive: ULong) : ULongProgression(st * A progression of values of type `ULong`. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public open class ULongProgression internal constructor( start: ULong, @@ -98,6 +100,7 @@ internal constructor( * @property step the number by which the value is incremented on each step. */ @SinceKotlin("1.3") +@ExperimentalUnsignedTypes private class ULongProgressionIterator(first: ULong, last: ULong, step: Long) : ULongIterator() { private val finalElement = last private var hasNext: Boolean = if (step > 0) first <= last else first >= last diff --git a/libraries/stdlib/unsigned/src/kotlin/UShort.kt b/libraries/stdlib/unsigned/src/kotlin/UShort.kt index 3032fecffa4..a6bd60853c3 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UShort.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UShort.kt @@ -11,6 +11,7 @@ import kotlin.experimental.* @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class UShort internal constructor(private val data: Short) : Comparable { companion object { @@ -130,10 +131,14 @@ public inline class UShort internal constructor(private val data: Short) : Compa } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Byte.toUShort(): UShort = UShort(this.toShort() and 0xFF) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Short.toUShort(): UShort = UShort(this) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Int.toUShort(): UShort = UShort(this.toShort()) @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public fun Long.toUShort(): UShort = UShort(this.toShort()) diff --git a/libraries/stdlib/unsigned/src/kotlin/UShortArray.kt b/libraries/stdlib/unsigned/src/kotlin/UShortArray.kt index 3f53deaae65..34f2c522cf8 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UShortArray.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UShortArray.kt @@ -8,6 +8,7 @@ package kotlin @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline class UShortArray @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") @PublishedApi @@ -41,10 +42,12 @@ internal constructor(private val storage: ShortArray) : Collection { } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes public inline fun UShortArray(size: Int, init: (Int) -> UShort): UShortArray { return UShortArray(ShortArray(size) { index -> init(index).toShort() }) } @SinceKotlin("1.3") +@ExperimentalUnsignedTypes // TODO: @kotlin.internal.InlineOnly public inline fun ushortArrayOf(vararg elements: UShort): UShortArray = elements diff --git a/libraries/stdlib/unsigned/src/kotlin/annotations/Unsigned.kt b/libraries/stdlib/unsigned/src/kotlin/annotations/Unsigned.kt new file mode 100644 index 00000000000..268d23d4432 --- /dev/null +++ b/libraries/stdlib/unsigned/src/kotlin/annotations/Unsigned.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") +package kotlin + +import kotlin.annotation.AnnotationTarget.* +import kotlin.internal.RequireKotlin +import kotlin.internal.RequireKotlinVersionKind + +/** + * Marks the API that is dependent on the experimental unsigned types, including those types themselves. + * + * Usages of such API will be reported as warnings unless an explicit opt-in with the [UseExperimental] annotation + * or the `-Xuse-experimental=kotlin.ExperimentalUnsignedTypes` compiler option is done. + */ +@Experimental(level = Experimental.Level.WARNING) +@Target(CLASS, ANNOTATION_CLASS, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPEALIAS) +@Retention(AnnotationRetention.BINARY) +@RequireKotlin("1.2.50", versionKind = RequireKotlinVersionKind.COMPILER_VERSION) +public annotation class ExperimentalUnsignedTypes