diff --git a/build.xml b/build.xml index d9c13e97d1f..5def30f07a5 100644 --- a/build.xml +++ b/build.xml @@ -316,7 +316,11 @@ - + + + + + @@ -567,7 +571,6 @@ classpath="${basedir}/core/builtins/src${path.separator}${basedir}/core/runtime.jvm/src"/> - diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b3fa217e3fb..a15089082de 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1023,7 +1023,7 @@ public class ExpressionCodegen extends JetVisitor implem v.load(incrementVar, incrementType); Type methodParamType = asmElementType.getSort() == Type.LONG ? Type.LONG_TYPE : Type.INT_TYPE; - v.invokestatic("jet/runtime/ProgressionUtil", "getProgressionFinalElement", + v.invokestatic("kotlin/internal/InternalPackage", "getProgressionFinalElement", Type.getMethodDescriptor(methodParamType, methodParamType, methodParamType, methodParamType)); finalVar = createLoopTempVariable(asmElementType); diff --git a/compiler/tests/org/jetbrains/jet/ProgressionUtilTest.java b/compiler/tests/org/jetbrains/jet/ProgressionUtilTest.java index d03eff40fc5..12707f17dcd 100644 --- a/compiler/tests/org/jetbrains/jet/ProgressionUtilTest.java +++ b/compiler/tests/org/jetbrains/jet/ProgressionUtilTest.java @@ -16,27 +16,47 @@ package org.jetbrains.jet; -import jet.runtime.ProgressionUtil; -import org.junit.Test; +import com.intellij.testFramework.UsefulTestCase; +import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime; -import static junit.framework.Assert.assertEquals; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; -public class ProgressionUtilTest { +public class ProgressionUtilTest extends UsefulTestCase { private static final int MAX = Integer.MAX_VALUE; private static final int MIN = Integer.MIN_VALUE; - private static void doTest(int start, int end, int increment, int expected) { - int actualInt = ProgressionUtil.getProgressionFinalElement(start, end, increment); + private Method intMethod; + private Method longMethod; + + @Override + protected void setUp() throws Exception { + super.setUp(); + ClassLoader classLoader = new URLClassLoader(new URL[] {ForTestCompileRuntime.runtimeJarForTests().toURI().toURL()}, null); + Class progressionUtil = classLoader.loadClass("kotlin.internal.InternalPackage"); + this.intMethod = progressionUtil.getMethod("getProgressionFinalElement", int.class, int.class, int.class); + this.longMethod = progressionUtil.getMethod("getProgressionFinalElement", long.class, long.class, long.class); + } + + @Override + protected void tearDown() throws Exception { + this.intMethod = null; + this.longMethod = null; + super.tearDown(); + } + + private void doTest(int start, int end, int increment, int expected) throws Exception { + Object actualInt = intMethod.invoke(null, start, end, increment); assertEquals(expected, actualInt); - long actualLong = ProgressionUtil.getProgressionFinalElement((long) start, (long) end, (long) increment); - assertEquals(expected, actualLong); + Object actualLong = longMethod.invoke(null, (long) start, (long) end, (long) increment); + assertEquals((long) expected, actualLong); } private static final int[] INTERESTING = new int[]{ MIN, MIN / 2, -239, -23, -1, 0, 1, 42, 239, MAX / 2, MAX }; - @Test - public void testGetFinalElement() { + public void testGetFinalElement() throws Exception { // start == end for (int x : INTERESTING) { for (int increment : INTERESTING) if (increment != 0) { diff --git a/core/builtins/src/jet/ProgressionIterators.kt b/core/builtins/src/jet/ProgressionIterators.kt index c1fe7ac41b4..35514a16950 100644 --- a/core/builtins/src/jet/ProgressionIterators.kt +++ b/core/builtins/src/jet/ProgressionIterators.kt @@ -18,11 +18,11 @@ package jet -import jet.runtime.ProgressionUtil +import kotlin.internal.getProgressionFinalElement class ByteProgressionIterator(start: Byte, end: Byte, val increment: Int) : ByteIterator() { private var next = start.toInt() - private val finalElement: Byte = ProgressionUtil.getProgressionFinalElement(start.toInt(), end.toInt(), increment).toByte() + private val finalElement: Byte = getProgressionFinalElement(start.toInt(), end.toInt(), increment).toByte() private var hasNext: Boolean = if (increment > 0) start <= end else start >= end override fun hasNext(): Boolean = hasNext @@ -41,7 +41,7 @@ class ByteProgressionIterator(start: Byte, end: Byte, val increment: Int) : Byte class CharProgressionIterator(start: Char, end: Char, val increment: Int) : CharIterator() { private var next = start.toInt() - private val finalElement: Char = ProgressionUtil.getProgressionFinalElement(start.toInt(), end.toInt(), increment).toChar() + private val finalElement: Char = getProgressionFinalElement(start.toInt(), end.toInt(), increment).toChar() private var hasNext: Boolean = if (increment > 0) start <= end else start >= end override fun hasNext(): Boolean = hasNext @@ -60,7 +60,7 @@ class CharProgressionIterator(start: Char, end: Char, val increment: Int) : Char class ShortProgressionIterator(start: Short, end: Short, val increment: Int) : ShortIterator() { private var next = start.toInt() - private val finalElement: Short = ProgressionUtil.getProgressionFinalElement(start.toInt(), end.toInt(), increment).toShort() + private val finalElement: Short = getProgressionFinalElement(start.toInt(), end.toInt(), increment).toShort() private var hasNext: Boolean = if (increment > 0) start <= end else start >= end override fun hasNext(): Boolean = hasNext @@ -79,7 +79,7 @@ class ShortProgressionIterator(start: Short, end: Short, val increment: Int) : S class IntProgressionIterator(start: Int, end: Int, val increment: Int) : IntIterator() { private var next = start - private val finalElement: Int = ProgressionUtil.getProgressionFinalElement(start, end, increment) + private val finalElement: Int = getProgressionFinalElement(start, end, increment) private var hasNext: Boolean = if (increment > 0) start <= end else start >= end override fun hasNext(): Boolean = hasNext @@ -98,7 +98,7 @@ class IntProgressionIterator(start: Int, end: Int, val increment: Int) : IntIter class LongProgressionIterator(start: Long, end: Long, val increment: Long) : LongIterator() { private var next = start - private val finalElement: Long = ProgressionUtil.getProgressionFinalElement(start, end, increment) + private val finalElement: Long = getProgressionFinalElement(start, end, increment) private var hasNext: Boolean = if (increment > 0) start <= end else start >= end override fun hasNext(): Boolean = hasNext diff --git a/core/builtins/src/jet/runtime/ProgressionUtil.java b/core/builtins/src/jet/runtime/ProgressionUtil.java deleted file mode 100644 index 876262c3e32..00000000000 --- a/core/builtins/src/jet/runtime/ProgressionUtil.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2010-2013 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 jet.runtime; - -public class ProgressionUtil { - private ProgressionUtil() { - } - - // a mod b (in arithmetical sense) - private static int mod(int a, int b) { - int mod = a % b; - return mod >= 0 ? mod : mod + b; - } - - private static long mod(long a, long b) { - long mod = a % b; - return mod >= 0 ? mod : mod + b; - } - - // (a - b) mod c - private static int differenceModulo(int a, int b, int c) { - return mod(mod(a, c) - mod(b, c), c); - } - - private static long differenceModulo(long a, long b, long c) { - return mod(mod(a, c) - mod(b, c), c); - } - - - /** - * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range - * from {@code start} to {@code end} in case of a positive {@code increment}, or from {@code end} to {@code start} in case of a negative - * increment. - * - *

No validation on passed parameters is performed. The given parameters should satisfy the condition: either - * {@code increment > 0} and {@code start <= end}, or {@code increment < 0} and {@code start >= end}. - * @param start first element of the progression - * @param end ending bound for the progression - * @param increment increment, or difference of successive elements in the progression - * @return the final element of the progression - */ - public static int getProgressionFinalElement(int start, int end, int increment) { - if (increment > 0) { - return end - differenceModulo(end, start, increment); - } - else { - return end + differenceModulo(start, end, -increment); - } - } - - /** - * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range - * from {@code start} to {@code end} in case of a positive {@code increment}, or from {@code end} to {@code start} in case of a negative - * increment. - * - *

No validation on passed parameters is performed. The given parameters should satisfy the condition: either - * {@code increment > 0} and {@code start <= end}, or {@code increment < 0} and {@code start >= end}. - * @param start first element of the progression - * @param end ending bound for the progression - * @param increment increment, or difference of successive elements in the progression - * @return the final element of the progression - */ - public static long getProgressionFinalElement(long start, long end, long increment) { - if (increment > 0) { - return end - differenceModulo(end, start, increment); - } - else { - return end + differenceModulo(start, end, -increment); - } - } -} diff --git a/core/builtins/src/kotlin/internal/progressionUtil.kt b/core/builtins/src/kotlin/internal/progressionUtil.kt new file mode 100644 index 00000000000..f92cd9a1440 --- /dev/null +++ b/core/builtins/src/kotlin/internal/progressionUtil.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2014 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.internal + +// a mod b (in arithmetical sense) +private fun mod(a: Int, b: Int): Int { + val mod = a % b + return if (mod >= 0) mod else mod + b +} + +private fun mod(a: Long, b: Long): Long { + val mod = a % b + return if (mod >= 0) mod else mod + b +} + +// (a - b) mod c +private fun differenceModulo(a: Int, b: Int, c: Int): Int { + return mod(mod(a, c) - mod(b, c), c) +} + +private fun differenceModulo(a: Long, b: Long, c: Long): Long { + return mod(mod(a, c) - mod(b, c), c) +} + + +/** + * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range + * from {@code start} to {@code end} in case of a positive {@code increment}, or from {@code end} to {@code start} in case of a negative + * increment. + * + *

No validation on passed parameters is performed. The given parameters should satisfy the condition: either + * {@code increment > 0} and {@code start <= end}, or {@code increment < 0} and {@code start >= end}. + * @param start first element of the progression + * @param end ending bound for the progression + * @param increment increment, or difference of successive elements in the progression + * @return the final element of the progression + */ +public fun getProgressionFinalElement(start: Int, end: Int, increment: Int): Int { + if (increment > 0) { + return end - differenceModulo(end, start, increment) + } + else { + return end + differenceModulo(start, end, -increment) + } +} + +/** + * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range + * from {@code start} to {@code end} in case of a positive {@code increment}, or from {@code end} to {@code start} in case of a negative + * increment. + * + *

No validation on passed parameters is performed. The given parameters should satisfy the condition: either + * {@code increment > 0} and {@code start <= end}, or {@code increment < 0} and {@code start >= end}. + * @param start first element of the progression + * @param end ending bound for the progression + * @param increment increment, or difference of successive elements in the progression + * @return the final element of the progression + */ +public fun getProgressionFinalElement(start: Long, end: Long, increment: Long): Long { + if (increment > 0) { + return end - differenceModulo(end, start, increment) + } + else { + return end + differenceModulo(start, end, -increment) + } +} diff --git a/generators/src/org/jetbrains/jet/generators/builtins/progressionIterators.kt b/generators/src/org/jetbrains/jet/generators/builtins/progressionIterators.kt index eec9d02aad8..760ed719d65 100644 --- a/generators/src/org/jetbrains/jet/generators/builtins/progressionIterators.kt +++ b/generators/src/org/jetbrains/jet/generators/builtins/progressionIterators.kt @@ -33,7 +33,7 @@ fun integerProgressionIterator(kind: ProgressionKind): String { return """class ${t}ProgressionIterator(start: $t, end: $t, val increment: $incrementType) : ${t}Iterator() { private var next = start$toInt - private val finalElement: $t = ProgressionUtil.getProgressionFinalElement(start$toInt, end$toInt, increment)$toType + private val finalElement: $t = getProgressionFinalElement(start$toInt, end$toInt, increment)$toType private var hasNext: Boolean = if (increment > 0) start <= end else start >= end override fun hasNext(): Boolean = hasNext @@ -69,7 +69,7 @@ fun floatingPointProgressionIterator(kind: ProgressionKind): String { class GenerateProgressionIterators(out: PrintWriter) : BuiltInsSourceGenerator(out) { override fun generateBody() { - out.println("import jet.runtime.ProgressionUtil") + out.println("import kotlin.internal.getProgressionFinalElement") out.println() for (kind in ProgressionKind.values()) { if (kind != FLOAT && kind != DOUBLE) {