From f18b9caa8df9f3bfdd4d6e6b7c39a06b377250f0 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Thu, 14 May 2015 19:19:17 +0300 Subject: [PATCH] JS: Provide MIN_VALUE and MAX_VALUE member constants for Int, Long, Short and Byte companion objects. JVM: Make MIN_VALUE and MAX_VALUE not an extension but member constant properties of Int, Long, Short and Byte companion objects. --- compiler/testData/builtin-classes.txt | 31 +++++++++++++--- core/builtins/native/kotlin/Primitives.kt | 8 ++--- .../src/kotlin/FloatingPointConstants.kt | 2 +- core/builtins/src/kotlin/IntegerConstants.kt | 32 +++++++++++++++++ .../jvm/internal/PrimitiveCompanionObjects.kt | 25 ++++++++++--- .../kotlin/generators/builtins/primitives.kt | 3 ++ .../src/internal/primitiveCompanionObjects.kt | 24 ++++++++++--- jslib_files.xml | 1 + .../src/kotlin/jvm/BuiltinExtensions.kt | 35 ------------------- libraries/stdlib/test/numbers/NumbersTest.kt | 34 ++++++++++++++++++ 10 files changed, 143 insertions(+), 52 deletions(-) create mode 100644 core/builtins/src/kotlin/IntegerConstants.kt diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index 4d301097781..6d9c6fa1234 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -109,8 +109,12 @@ public final class Byte : kotlin.Number, kotlin.Comparable { public open override /*1*/ fun toLong(): kotlin.Long public open override /*1*/ fun toShort(): kotlin.Short - public companion object Companion { + public companion object Companion : kotlin.IntegerConstants { /*primary*/ private constructor Companion() + public abstract override /*1*/ /*fake_override*/ val MAX_VALUE: kotlin.Byte + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Byte + public abstract override /*1*/ /*fake_override*/ val MIN_VALUE: kotlin.Byte + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Byte } } @@ -916,8 +920,12 @@ public final class Int : kotlin.Number, kotlin.Comparable { public final fun ushr(/*0*/ bits: kotlin.Int): kotlin.Int public final fun xor(/*0*/ other: kotlin.Int): kotlin.Int - public companion object Companion { + public companion object Companion : kotlin.IntegerConstants { /*primary*/ private constructor Companion() + public abstract override /*1*/ /*fake_override*/ val MAX_VALUE: kotlin.Int + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Int + public abstract override /*1*/ /*fake_override*/ val MIN_VALUE: kotlin.Int + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Int } } @@ -985,6 +993,13 @@ public final class IntRange : kotlin.Range, kotlin.Progression { + public abstract val MAX_VALUE: T + public abstract fun (): T + public abstract val MIN_VALUE: T + public abstract fun (): T +} + public interface Iterable { public abstract fun iterator(): kotlin.Iterator } @@ -1087,8 +1102,12 @@ public final class Long : kotlin.Number, kotlin.Comparable { public final fun ushr(/*0*/ bits: kotlin.Int): kotlin.Long public final fun xor(/*0*/ other: kotlin.Long): kotlin.Long - public companion object Companion { + public companion object Companion : kotlin.IntegerConstants { /*primary*/ private constructor Companion() + public abstract override /*1*/ /*fake_override*/ val MAX_VALUE: kotlin.Long + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Long + public abstract override /*1*/ /*fake_override*/ val MIN_VALUE: kotlin.Long + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Long } } @@ -1383,8 +1402,12 @@ public final class Short : kotlin.Number, kotlin.Comparable { public open override /*1*/ fun toLong(): kotlin.Long public open override /*1*/ fun toShort(): kotlin.Short - public companion object Companion { + public companion object Companion : kotlin.IntegerConstants { /*primary*/ private constructor Companion() + public abstract override /*1*/ /*fake_override*/ val MAX_VALUE: kotlin.Short + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Short + public abstract override /*1*/ /*fake_override*/ val MIN_VALUE: kotlin.Short + public abstract override /*1*/ /*fake_override*/ fun (): kotlin.Short } } diff --git a/core/builtins/native/kotlin/Primitives.kt b/core/builtins/native/kotlin/Primitives.kt index ff16d084c80..86ba4ebf318 100644 --- a/core/builtins/native/kotlin/Primitives.kt +++ b/core/builtins/native/kotlin/Primitives.kt @@ -23,7 +23,7 @@ package kotlin * On the JVM, non-nullable values of this type are represented as values of the primitive type `byte`. */ public class Byte private () : Number, Comparable { - companion object {} + companion object : IntegerConstants {} /** * Compares this value with the specified value for order. @@ -326,7 +326,7 @@ public class Char private () : Comparable { * On the JVM, non-nullable values of this type are represented as values of the primitive type `short`. */ public class Short private () : Number, Comparable { - companion object {} + companion object : IntegerConstants {} /** * Compares this value with the specified value for order. @@ -484,7 +484,7 @@ public class Short private () : Number, Comparable { * On the JVM, non-nullable values of this type are represented as values of the primitive type `int`. */ public class Int private () : Number, Comparable { - companion object {} + companion object : IntegerConstants {} /** * Compares this value with the specified value for order. @@ -657,7 +657,7 @@ public class Int private () : Number, Comparable { * On the JVM, non-nullable values of this type are represented as values of the primitive type `long`. */ public class Long private () : Number, Comparable { - companion object {} + companion object : IntegerConstants {} /** * Compares this value with the specified value for order. diff --git a/core/builtins/src/kotlin/FloatingPointConstants.kt b/core/builtins/src/kotlin/FloatingPointConstants.kt index c9990d96486..4572413d7d9 100644 --- a/core/builtins/src/kotlin/FloatingPointConstants.kt +++ b/core/builtins/src/kotlin/FloatingPointConstants.kt @@ -17,7 +17,7 @@ package kotlin /** - * Holder for special values of floating point types. + * An interface implemented by companion objects of floating-point types. */ public interface FloatingPointConstants { /** diff --git a/core/builtins/src/kotlin/IntegerConstants.kt b/core/builtins/src/kotlin/IntegerConstants.kt new file mode 100644 index 00000000000..7f4ec1cf6f5 --- /dev/null +++ b/core/builtins/src/kotlin/IntegerConstants.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kotlin + +/** + * An interface implemented by companion objects of integral types. + */ +public interface IntegerConstants { + /** + * A constant holding the minimum value an instance of [T] can have. + */ + public val MIN_VALUE: T + + /** + * A constant holding the maximum value an instance of [T] can have. + */ + public val MAX_VALUE: T +} \ No newline at end of file diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/PrimitiveCompanionObjects.kt b/core/runtime.jvm/src/kotlin/jvm/internal/PrimitiveCompanionObjects.kt index 9ec6106a07c..c172b8c8665 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/PrimitiveCompanionObjects.kt +++ b/core/runtime.jvm/src/kotlin/jvm/internal/PrimitiveCompanionObjects.kt @@ -28,10 +28,27 @@ private object FloatCompanionObject : FloatingPointConstants { override val NaN : Float = java.lang.Float.NaN } -private object IntCompanionObject {} -private object LongCompanionObject {} -private object ShortCompanionObject {} -private object ByteCompanionObject {} +private object IntCompanionObject : IntegerConstants { + override val MIN_VALUE: Int = java.lang.Integer.MIN_VALUE + override val MAX_VALUE: Int = java.lang.Integer.MAX_VALUE +} + +private object LongCompanionObject : IntegerConstants { + override val MIN_VALUE: Long = java.lang.Long.MIN_VALUE + override val MAX_VALUE: Long = java.lang.Long.MAX_VALUE +} + +private object ShortCompanionObject : IntegerConstants { + override val MIN_VALUE: Short = java.lang.Short.MIN_VALUE + override val MAX_VALUE: Short = java.lang.Short.MAX_VALUE +} + +private object ByteCompanionObject : IntegerConstants { + override val MIN_VALUE: Byte = java.lang.Byte.MIN_VALUE + override val MAX_VALUE: Byte = java.lang.Byte.MAX_VALUE +} + + private object CharCompanionObject {} private object StringCompanionObject {} diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt index 22cbb811c0c..f26cde9d480 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt @@ -65,6 +65,9 @@ class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) { if (kind == PrimitiveType.FLOAT || kind == PrimitiveType.DOUBLE) { out.print(" : FloatingPointConstants<$className>") } + if (kind == PrimitiveType.INT || kind == PrimitiveType.LONG || kind == PrimitiveType.SHORT || kind == PrimitiveType.BYTE) { + out.print(" : IntegerConstants<$className>") + } out.println(" {}\n") generateCompareTo(kind) diff --git a/js/js.libraries/src/internal/primitiveCompanionObjects.kt b/js/js.libraries/src/internal/primitiveCompanionObjects.kt index 50ca6b830c7..4d9ab889234 100644 --- a/js/js.libraries/src/internal/primitiveCompanionObjects.kt +++ b/js/js.libraries/src/internal/primitiveCompanionObjects.kt @@ -28,10 +28,26 @@ private object FloatCompanionObject : FloatingPointConstants { override val NaN : Float = js("Number.NaN") } -private object IntCompanionObject {} -private object LongCompanionObject {} -private object ShortCompanionObject {} -private object ByteCompanionObject {} +private object IntCompanionObject : IntegerConstants { + override val MIN_VALUE: Int = -0x80000000 + override val MAX_VALUE: Int = 0x7FFFFFFF +} + +private object LongCompanionObject : IntegerConstants { + override val MIN_VALUE: Long = js("Kotlin.Long.MIN_VALUE") + override val MAX_VALUE: Long = js("Kotlin.Long.MAX_VALUE") +} + +private object ShortCompanionObject : IntegerConstants { + override val MIN_VALUE: Short = -0x8000 + override val MAX_VALUE: Short = 0x7FFF +} + +private object ByteCompanionObject : IntegerConstants { + override val MIN_VALUE: Byte = -0x80 + override val MAX_VALUE: Byte = 0x7F +} + private object CharCompanionObject {} private object StringCompanionObject {} diff --git a/jslib_files.xml b/jslib_files.xml index 176db3d2ff7..6a05d54f78d 100644 --- a/jslib_files.xml +++ b/jslib_files.xml @@ -7,6 +7,7 @@ + diff --git a/libraries/stdlib/src/kotlin/jvm/BuiltinExtensions.kt b/libraries/stdlib/src/kotlin/jvm/BuiltinExtensions.kt index b501672d205..f7306e437e9 100644 --- a/libraries/stdlib/src/kotlin/jvm/BuiltinExtensions.kt +++ b/libraries/stdlib/src/kotlin/jvm/BuiltinExtensions.kt @@ -15,14 +15,6 @@ */ package kotlin.jvm -/** - * A constant holding the minimum value an `Int` can have, -2^31. - */ -public val Int.Companion.MIN_VALUE: Int get() = java.lang.Integer.MIN_VALUE -/** - * A constant holding the maximum value an `Int` can have, 2^31-1. - */ -public val Int.Companion.MAX_VALUE: Int get() = java.lang.Integer.MAX_VALUE /** * A constant holding the smallest positive nonzero value of type `Double`, 2^-1074. @@ -41,30 +33,3 @@ public val Float.Companion.MIN_VALUE: Float get() = java.lang.Float.MIN_VALUE * * A constant holding the largest positive finite value of type `Float`, (2-2^-23)*2^127. */ public val Float.Companion.MAX_VALUE: Float get() = java.lang.Float.MAX_VALUE - -/** - * A constant holding the minimum value a `Long` can have, -2^63. - */ -public val Long.Companion.MIN_VALUE: Long get() = java.lang.Long.MIN_VALUE -/** - * A constant holding the maximum value a `Long` can have, 2^63-1. - */ -public val Long.Companion.MAX_VALUE: Long get() = java.lang.Long.MAX_VALUE - -/** - * A constant holding the minimum value a `Short` can have, -2^15. - */ -public val Short.Companion.MIN_VALUE: Short get() = java.lang.Short.MIN_VALUE -/** - * A constant holding the maximum value a `Short` can have, 2^15-1. - */ -public val Short.Companion.MAX_VALUE: Short get() = java.lang.Short.MAX_VALUE - -/** - * A constant holding the minimum value a `Byte` can have, -128. - */ -public val Byte.Companion.MIN_VALUE: Byte get() = java.lang.Byte.MIN_VALUE -/** - * A constant holding the maximum value a `Byte` can have, 127. - */ -public val Byte.Companion.MAX_VALUE: Byte get() = java.lang.Byte.MAX_VALUE \ No newline at end of file diff --git a/libraries/stdlib/test/numbers/NumbersTest.kt b/libraries/stdlib/test/numbers/NumbersTest.kt index 307d3210bc3..579cd6cf832 100644 --- a/libraries/stdlib/test/numbers/NumbersTest.kt +++ b/libraries/stdlib/test/numbers/NumbersTest.kt @@ -5,6 +5,40 @@ import kotlin.test.* class NumbersTest { + + test fun intMinMaxValues() { + assertTrue(Int.MIN_VALUE < 0) + assertTrue(Int.MAX_VALUE > 0) + + // overflow behavior + // doesn't hold for JS Number + // assertEquals(Int.MIN_VALUE, Int.MAX_VALUE + 1) + } + + test fun longMinMaxValues() { + assertTrue(Long.MIN_VALUE < 0) + assertTrue(Long.MAX_VALUE > 0) + // overflow behavior + assertEquals(Long.MIN_VALUE, Long.MAX_VALUE + 1) + assertEquals(Long.MAX_VALUE, Long.MIN_VALUE - 1) + } + + test fun shortMinMaxValues() { + assertTrue(Short.MIN_VALUE < 0) + assertTrue(Short.MAX_VALUE > 0) + // overflow behavior + assertEquals(Short.MIN_VALUE, (Short.MAX_VALUE + 1).toShort()) + assertEquals(Short.MAX_VALUE, (Short.MIN_VALUE - 1).toShort()) + } + + test fun byteMinMaxValues() { + assertTrue(Byte.MIN_VALUE < 0) + assertTrue(Byte.MAX_VALUE > 0) + // overflow behavior + assertEquals(Byte.MIN_VALUE, (Byte.MAX_VALUE + 1).toByte()) + assertEquals(Byte.MAX_VALUE, (Byte.MIN_VALUE - 1).toByte()) + } + test fun doubleProperties() { for (value in listOf(1.0, 0.0)) doTestNumber(value)