Support number conversion for binary 'rem' operator

This commit is contained in:
Mikhail Zarechenskiy
2016-12-13 20:55:23 +03:00
parent 62ac91a121
commit 42d867b3bf
5 changed files with 70 additions and 2 deletions
@@ -144,6 +144,12 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(BYTE, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, BYTE, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, DOUBLE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(BYTE, INT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, LONG, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, SHORT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
@@ -187,6 +193,12 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(DOUBLE, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, INT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, LONG, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, SHORT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(DOUBLE, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
@@ -224,6 +236,12 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(FLOAT, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, INT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, LONG, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, SHORT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(FLOAT, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(FLOAT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
@@ -263,6 +281,12 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(INT, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(INT, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(INT, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(INT, BYTE, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, DOUBLE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(INT, FLOAT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, LONG, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, SHORT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(INT, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun),
binaryOperation(INT, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun),
binaryOperation(INT, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
@@ -306,6 +330,12 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(LONG, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(LONG, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(LONG, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(LONG, BYTE, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, DOUBLE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(LONG, FLOAT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, LONG, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, SHORT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(LONG, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun),
binaryOperation(LONG, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun),
binaryOperation(LONG, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
@@ -349,6 +379,12 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(SHORT, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, BYTE, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, DOUBLE, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "rem", { a, b -> a.mod(b) }, emptyBinaryFun),
binaryOperation(SHORT, INT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, LONG, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, SHORT, "rem", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun),
@@ -0,0 +1,15 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun fooInt(p: Int) = p
fun fooLong(p: Long) = p
fun fooByte(p: Byte) = p
fun fooShort(p: Short) = p
fun test() {
fooInt(1 % 1)
fooByte(1 % 1)
fooLong(1 % 1)
fooShort(1 % 1)
}
public operator fun Int.rem(other: Int): Int = 0
@@ -0,0 +1,8 @@
package
public fun fooByte(/*0*/ p: kotlin.Byte): kotlin.Byte
public fun fooInt(/*0*/ p: kotlin.Int): kotlin.Int
public fun fooLong(/*0*/ p: kotlin.Long): kotlin.Long
public fun fooShort(/*0*/ p: kotlin.Short): kotlin.Short
public fun test(): kotlin.Unit
public operator fun kotlin.Int.rem(/*0*/ other: kotlin.Int): kotlin.Int
@@ -13429,6 +13429,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("numberRemConversions.kt")
public void testNumberRemConversions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/numberRemConversions.kt");
doTest(fileName);
}
@TestMetadata("operatorRem.kt")
public void testOperatorRem() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/operatorRem.kt");
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.Printer
import java.io.File
@@ -104,13 +105,15 @@ fun generate(): String {
val binaryOperationsMapIterator = binaryOperationsMap.iterator()
while (binaryOperationsMapIterator.hasNext()) {
val (funcName, parameters) = binaryOperationsMapIterator.next()
// TODO: remove this when 'rem' will be added into the stdlib
val funcCall = if (OperatorNameConventions.REM.asString() == funcName) OperatorNameConventions.MOD.asString() else funcName
p.println(
"binaryOperation(",
parameters.map { it.asString() }.joinToString(", "),
", ",
"\"$funcName\"",
", { a, b -> a.${funcName}(b) }, ",
renderCheckBinaryOperation(funcName, parameters),
", { a, b -> a.${funcCall}(b) }, ",
renderCheckBinaryOperation(funcCall, parameters),
")",
if (binaryOperationsMapIterator.hasNext()) "," else ""
)