diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 066aa46a1a6..afbc3c58757 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -465,6 +465,7 @@ public interface Errors { // Compile-time values + DiagnosticFactory0 INTEGER_OVERFLOW = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 INT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 FLOAT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR); DiagnosticFactory2 CONSTANT_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index 8142722be04..97791b6e577 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -297,6 +297,7 @@ public class DefaultErrorMessages { MAP.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", DescriptorRenderer.TEXT); MAP.put(CONSTANT_EXPECTED_TYPE_MISMATCH, "An {0} literal does not conform to the expected type {1}", TO_STRING, RENDER_TYPE); + MAP.put(INTEGER_OVERFLOW, "This operation has led to an overflow"); MAP.put(INT_LITERAL_OUT_OF_RANGE, "The value is out of range"); MAP.put(FLOAT_LITERAL_OUT_OF_RANGE, "The value is out of range"); MAP.put(INCORRECT_CHARACTER_LITERAL, "Incorrect character literal"); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt index e225ba9f673..cbe564b1079 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt @@ -34,6 +34,9 @@ import org.jetbrains.jet.lang.types.TypeUtils import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument import org.jetbrains.jet.JetNodeTypes import java.lang.Long.parseLong as javaParseLong +import java.math.BigInteger +import org.jetbrains.jet.lang.diagnostics.Errors +import com.intellij.psi.util.PsiTreeUtil [suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")] public class ConstantExpressionEvaluator private (val trace: BindingTrace) : JetVisitor, JetType>() { @@ -176,9 +179,7 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet val argumentsEntrySet = resolvedCall.getValueArguments().entrySet() if (argumentsEntrySet.isEmpty()) { - val function = unaryOperations[UnaryOperationKey(argumentForReceiver.ctcType, resultingDescriptorName)] - if (function == null) return null - return function(argumentForReceiver.value) + return evaluateUnaryAndCheck(argumentForReceiver, resultingDescriptorName, callExpression) } else if (argumentsEntrySet.size() == 1) { val (parameter, argument) = argumentsEntrySet.first() @@ -186,14 +187,67 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet val argumentForParameter = createOperationArgumentForFirstParameter(argument, parameter) if (argumentForParameter == null) return null - val function = binaryOperations[BinaryOperationKey(argumentForReceiver.ctcType, argumentForParameter.ctcType, resultingDescriptorName)] - if (function == null) return null - return function(argumentForReceiver.value, argumentForParameter.value) + return evaluateBinaryAndCheck(argumentForReceiver, argumentForParameter, resultingDescriptorName, callExpression) } return null } + private fun evaluateUnaryAndCheck(receiver: OperationArgument, name: String, callExpression: JetExpression): Any? { + val functions = unaryOperations[UnaryOperationKey(receiver.ctcType, name)] + if (functions == null) return null + + val (function, check) = functions + val result = function(receiver.value) + if (check == emptyUnaryFun) { + return result + } + assert (isIntegerType(receiver.value), "Only integer constants should be checked for overflow") + assert (name == "minus", "Only negation should be checked for overflow") + + if (receiver.value == result) { + trace.report(Errors.INTEGER_OVERFLOW.on(PsiTreeUtil.getParentOfType(callExpression, javaClass()) ?: callExpression)) + } + return result + } + + private fun evaluateBinaryAndCheck(receiver: OperationArgument, parameter: OperationArgument, name: String, callExpression: JetExpression): Any? { + val functions = binaryOperations[BinaryOperationKey(receiver.ctcType, parameter.ctcType, name)] + if (functions == null) return null + + if (isDividingByZero(name, parameter.value)) { + return null + } + + val (function, checker) = functions + val actualResult = function(receiver.value, parameter.value) + if (checker == emptyBinaryFun) { + return actualResult + } + assert (isIntegerType(receiver.value) && isIntegerType(parameter.value)) { "Only integer constants should be checked for overflow" } + + fun toBigInteger(value: Any?) = BigInteger.valueOf((value as Number).toLong()) + + val resultInBigIntegers = checker(toBigInteger(receiver.value), toBigInteger(parameter.value)) + + if (toBigInteger(actualResult) != resultInBigIntegers) { + trace.report(Errors.INTEGER_OVERFLOW.on(PsiTreeUtil.getParentOfType(callExpression, javaClass()) ?: callExpression)) + } + return actualResult + } + + private fun isDividingByZero(name: String, parameter: Any?): Boolean { + if (name == OperatorConventions.BINARY_OPERATION_NAMES[JetTokens.DIV]!!.asString()) { + if (isIntegerType(parameter)) { + return (parameter as Number).toLong() == 0.toLong() + } + else if (parameter is Float || parameter is Double) { + return (parameter as Number).toDouble() == 0.0 + } + } + return false + } + override fun visitUnaryExpression(expression: JetUnaryExpression, expectedType: JetType?): CompileTimeConstant<*>? { val leftExpression = expression.getBaseExpression() if (leftExpression == null) return null @@ -406,6 +460,8 @@ public fun createCompileTimeConstant(value: Any?, expectedType: JetType?): Compi } } +fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int || value is Long + private fun getIntegerValue(value: Long, expectedType: JetType): CompileTimeConstant<*>? { fun defaultIntegerValue(value: Long) = when (value) { value.toInt().toLong() -> IntValue(value.toInt()) @@ -474,19 +530,22 @@ private val STRING = CompileTimeType() private val ANY = CompileTimeType() [suppress("UNCHECKED_CAST")] -private fun binaryOperationKey( +private fun binaryOperation( a: CompileTimeType, b: CompileTimeType, functionName: String, - f: (A, B) -> Any -) = BinaryOperationKey(a, b, functionName) to f as Function2 + operation: Function2, + checker: Function2 +) = BinaryOperationKey(a, b, functionName) to Pair(operation, checker) as Pair, Function2> [suppress("UNCHECKED_CAST")] -private fun unaryOperationKey( +private fun unaryOperation( a: CompileTimeType, functionName: String, - f: (A) -> Any -) = UnaryOperationKey(a, functionName) to f as Function1 + operation: Function1, + checker: Function1 +) = UnaryOperationKey(a, functionName) to Pair(operation, checker) as Pair, Function1> private data class BinaryOperationKey(val f: CompileTimeType, val s: CompileTimeType, val functionName: String) private data class UnaryOperationKey(val f: CompileTimeType, val functionName: String) + diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/OperationsMapGenerated.kt b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/OperationsMapGenerated.kt index 886ce7d7648..4d5328c4406 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/OperationsMapGenerated.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/OperationsMapGenerated.kt @@ -16,393 +16,401 @@ package org.jetbrains.jet.lang.evaluate +import java.math.BigInteger +import java.util.HashMap + /** This file is generated by org.jetbrains.jet.generators.evaluate:generate(). DO NOT MODIFY MANUALLY */ -private val unaryOperations = hashMapOf, (Any?) -> Any>( - unaryOperationKey(BOOLEAN, "not", { a -> a.not() }), - unaryOperationKey(BYTE, "toInt", { a -> a.toInt() }), - unaryOperationKey(BYTE, "minus", { a -> a.minus() }), - unaryOperationKey(BYTE, "toChar", { a -> a.toChar() }), - unaryOperationKey(BYTE, "toLong", { a -> a.toLong() }), - unaryOperationKey(BYTE, "plus", { a -> a.plus() }), - unaryOperationKey(BYTE, "toFloat", { a -> a.toFloat() }), - unaryOperationKey(BYTE, "toDouble", { a -> a.toDouble() }), - unaryOperationKey(BYTE, "toShort", { a -> a.toShort() }), - unaryOperationKey(BYTE, "toByte", { a -> a.toByte() }), - unaryOperationKey(CHAR, "toInt", { a -> a.toInt() }), - unaryOperationKey(CHAR, "minus", { a -> a.minus() }), - unaryOperationKey(CHAR, "toChar", { a -> a.toChar() }), - unaryOperationKey(CHAR, "toLong", { a -> a.toLong() }), - unaryOperationKey(CHAR, "plus", { a -> a.plus() }), - unaryOperationKey(CHAR, "toFloat", { a -> a.toFloat() }), - unaryOperationKey(CHAR, "toDouble", { a -> a.toDouble() }), - unaryOperationKey(CHAR, "toShort", { a -> a.toShort() }), - unaryOperationKey(CHAR, "toByte", { a -> a.toByte() }), - unaryOperationKey(DOUBLE, "toInt", { a -> a.toInt() }), - unaryOperationKey(DOUBLE, "minus", { a -> a.minus() }), - unaryOperationKey(DOUBLE, "toChar", { a -> a.toChar() }), - unaryOperationKey(DOUBLE, "toLong", { a -> a.toLong() }), - unaryOperationKey(DOUBLE, "plus", { a -> a.plus() }), - unaryOperationKey(DOUBLE, "toFloat", { a -> a.toFloat() }), - unaryOperationKey(DOUBLE, "toDouble", { a -> a.toDouble() }), - unaryOperationKey(DOUBLE, "toShort", { a -> a.toShort() }), - unaryOperationKey(DOUBLE, "toByte", { a -> a.toByte() }), - unaryOperationKey(FLOAT, "toInt", { a -> a.toInt() }), - unaryOperationKey(FLOAT, "minus", { a -> a.minus() }), - unaryOperationKey(FLOAT, "toChar", { a -> a.toChar() }), - unaryOperationKey(FLOAT, "toLong", { a -> a.toLong() }), - unaryOperationKey(FLOAT, "plus", { a -> a.plus() }), - unaryOperationKey(FLOAT, "toFloat", { a -> a.toFloat() }), - unaryOperationKey(FLOAT, "toDouble", { a -> a.toDouble() }), - unaryOperationKey(FLOAT, "toShort", { a -> a.toShort() }), - unaryOperationKey(FLOAT, "toByte", { a -> a.toByte() }), - unaryOperationKey(INT, "plus", { a -> a.plus() }), - unaryOperationKey(INT, "toShort", { a -> a.toShort() }), - unaryOperationKey(INT, "toByte", { a -> a.toByte() }), - unaryOperationKey(INT, "inv", { a -> a.inv() }), - unaryOperationKey(INT, "toInt", { a -> a.toInt() }), - unaryOperationKey(INT, "minus", { a -> a.minus() }), - unaryOperationKey(INT, "toChar", { a -> a.toChar() }), - unaryOperationKey(INT, "toLong", { a -> a.toLong() }), - unaryOperationKey(INT, "toDouble", { a -> a.toDouble() }), - unaryOperationKey(INT, "toFloat", { a -> a.toFloat() }), - unaryOperationKey(LONG, "plus", { a -> a.plus() }), - unaryOperationKey(LONG, "toShort", { a -> a.toShort() }), - unaryOperationKey(LONG, "toByte", { a -> a.toByte() }), - unaryOperationKey(LONG, "inv", { a -> a.inv() }), - unaryOperationKey(LONG, "toInt", { a -> a.toInt() }), - unaryOperationKey(LONG, "minus", { a -> a.minus() }), - unaryOperationKey(LONG, "toChar", { a -> a.toChar() }), - unaryOperationKey(LONG, "toLong", { a -> a.toLong() }), - unaryOperationKey(LONG, "toDouble", { a -> a.toDouble() }), - unaryOperationKey(LONG, "toFloat", { a -> a.toFloat() }), - unaryOperationKey(SHORT, "toInt", { a -> a.toInt() }), - unaryOperationKey(SHORT, "minus", { a -> a.minus() }), - unaryOperationKey(SHORT, "toChar", { a -> a.toChar() }), - unaryOperationKey(SHORT, "toLong", { a -> a.toLong() }), - unaryOperationKey(SHORT, "plus", { a -> a.plus() }), - unaryOperationKey(SHORT, "toFloat", { a -> a.toFloat() }), - unaryOperationKey(SHORT, "toDouble", { a -> a.toDouble() }), - unaryOperationKey(SHORT, "toShort", { a -> a.toShort() }), - unaryOperationKey(SHORT, "toByte", { a -> a.toByte() }), - unaryOperationKey(STRING, "toString", { a -> a.toString() }) +private val emptyBinaryFun: Function2 = { a, b -> BigInteger("0") } +private val emptyUnaryFun: Function1 = { a -> 1.toLong() } + +private val unaryOperations: HashMap, Pair, Function1>> + = hashMapOf, Pair, Function1>>( + unaryOperation(BOOLEAN, "not", { a -> a.not() }, emptyUnaryFun), + unaryOperation(BYTE, "toInt", { a -> a.toInt() }, emptyUnaryFun), + unaryOperation(BYTE, "minus", { a -> a.minus() }, { a -> a.minus() }), + unaryOperation(BYTE, "toChar", { a -> a.toChar() }, emptyUnaryFun), + unaryOperation(BYTE, "toLong", { a -> a.toLong() }, emptyUnaryFun), + unaryOperation(BYTE, "plus", { a -> a.plus() }, emptyUnaryFun), + unaryOperation(BYTE, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), + unaryOperation(BYTE, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), + unaryOperation(BYTE, "toShort", { a -> a.toShort() }, emptyUnaryFun), + unaryOperation(BYTE, "toByte", { a -> a.toByte() }, emptyUnaryFun), + unaryOperation(CHAR, "toInt", { a -> a.toInt() }, emptyUnaryFun), + unaryOperation(CHAR, "minus", { a -> a.minus() }, emptyUnaryFun), + unaryOperation(CHAR, "toChar", { a -> a.toChar() }, emptyUnaryFun), + unaryOperation(CHAR, "toLong", { a -> a.toLong() }, emptyUnaryFun), + unaryOperation(CHAR, "plus", { a -> a.plus() }, emptyUnaryFun), + unaryOperation(CHAR, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), + unaryOperation(CHAR, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), + unaryOperation(CHAR, "toShort", { a -> a.toShort() }, emptyUnaryFun), + unaryOperation(CHAR, "toByte", { a -> a.toByte() }, emptyUnaryFun), + unaryOperation(DOUBLE, "toInt", { a -> a.toInt() }, emptyUnaryFun), + unaryOperation(DOUBLE, "minus", { a -> a.minus() }, emptyUnaryFun), + unaryOperation(DOUBLE, "toChar", { a -> a.toChar() }, emptyUnaryFun), + unaryOperation(DOUBLE, "toLong", { a -> a.toLong() }, emptyUnaryFun), + unaryOperation(DOUBLE, "plus", { a -> a.plus() }, emptyUnaryFun), + unaryOperation(DOUBLE, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), + unaryOperation(DOUBLE, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), + unaryOperation(DOUBLE, "toShort", { a -> a.toShort() }, emptyUnaryFun), + unaryOperation(DOUBLE, "toByte", { a -> a.toByte() }, emptyUnaryFun), + unaryOperation(FLOAT, "toInt", { a -> a.toInt() }, emptyUnaryFun), + unaryOperation(FLOAT, "minus", { a -> a.minus() }, emptyUnaryFun), + unaryOperation(FLOAT, "toChar", { a -> a.toChar() }, emptyUnaryFun), + unaryOperation(FLOAT, "toLong", { a -> a.toLong() }, emptyUnaryFun), + unaryOperation(FLOAT, "plus", { a -> a.plus() }, emptyUnaryFun), + unaryOperation(FLOAT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), + unaryOperation(FLOAT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), + unaryOperation(FLOAT, "toShort", { a -> a.toShort() }, emptyUnaryFun), + unaryOperation(FLOAT, "toByte", { a -> a.toByte() }, emptyUnaryFun), + unaryOperation(INT, "plus", { a -> a.plus() }, emptyUnaryFun), + unaryOperation(INT, "toShort", { a -> a.toShort() }, emptyUnaryFun), + unaryOperation(INT, "toByte", { a -> a.toByte() }, emptyUnaryFun), + unaryOperation(INT, "inv", { a -> a.inv() }, emptyUnaryFun), + unaryOperation(INT, "toInt", { a -> a.toInt() }, emptyUnaryFun), + unaryOperation(INT, "minus", { a -> a.minus() }, { a -> a.minus() }), + unaryOperation(INT, "toChar", { a -> a.toChar() }, emptyUnaryFun), + unaryOperation(INT, "toLong", { a -> a.toLong() }, emptyUnaryFun), + unaryOperation(INT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), + unaryOperation(INT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), + unaryOperation(LONG, "plus", { a -> a.plus() }, emptyUnaryFun), + unaryOperation(LONG, "toShort", { a -> a.toShort() }, emptyUnaryFun), + unaryOperation(LONG, "toByte", { a -> a.toByte() }, emptyUnaryFun), + unaryOperation(LONG, "inv", { a -> a.inv() }, emptyUnaryFun), + unaryOperation(LONG, "toInt", { a -> a.toInt() }, emptyUnaryFun), + unaryOperation(LONG, "minus", { a -> a.minus() }, { a -> a.minus() }), + unaryOperation(LONG, "toChar", { a -> a.toChar() }, emptyUnaryFun), + unaryOperation(LONG, "toLong", { a -> a.toLong() }, emptyUnaryFun), + unaryOperation(LONG, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), + unaryOperation(LONG, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), + unaryOperation(SHORT, "toInt", { a -> a.toInt() }, emptyUnaryFun), + unaryOperation(SHORT, "minus", { a -> a.minus() }, { a -> a.minus() }), + unaryOperation(SHORT, "toChar", { a -> a.toChar() }, emptyUnaryFun), + unaryOperation(SHORT, "toLong", { a -> a.toLong() }, emptyUnaryFun), + unaryOperation(SHORT, "plus", { a -> a.plus() }, emptyUnaryFun), + unaryOperation(SHORT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), + unaryOperation(SHORT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), + unaryOperation(SHORT, "toShort", { a -> a.toShort() }, emptyUnaryFun), + unaryOperation(SHORT, "toByte", { a -> a.toByte() }, emptyUnaryFun), + unaryOperation(STRING, "toString", { a -> a.toString() }, emptyUnaryFun) ) -private val binaryOperations = hashMapOf, (Any?, Any?) -> Any>( - binaryOperationKey(BOOLEAN, BOOLEAN, "xor", { a, b -> a.xor(b) }), - binaryOperationKey(BOOLEAN, BOOLEAN, "or", { a, b -> a.or(b) }), - binaryOperationKey(BOOLEAN, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(BOOLEAN, BOOLEAN, "and", { a, b -> a.and(b) }), - binaryOperationKey(BYTE, BYTE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(BYTE, CHAR, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(BYTE, DOUBLE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(BYTE, FLOAT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(BYTE, INT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(BYTE, LONG, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(BYTE, SHORT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(BYTE, BYTE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(BYTE, CHAR, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(BYTE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(BYTE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(BYTE, INT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(BYTE, LONG, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(BYTE, SHORT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(BYTE, BYTE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(BYTE, CHAR, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(BYTE, DOUBLE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(BYTE, FLOAT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(BYTE, INT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(BYTE, LONG, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(BYTE, SHORT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(BYTE, BYTE, "div", { a, b -> a.div(b) }), - binaryOperationKey(BYTE, CHAR, "div", { a, b -> a.div(b) }), - binaryOperationKey(BYTE, DOUBLE, "div", { a, b -> a.div(b) }), - binaryOperationKey(BYTE, FLOAT, "div", { a, b -> a.div(b) }), - binaryOperationKey(BYTE, INT, "div", { a, b -> a.div(b) }), - binaryOperationKey(BYTE, LONG, "div", { a, b -> a.div(b) }), - binaryOperationKey(BYTE, SHORT, "div", { a, b -> a.div(b) }), - binaryOperationKey(BYTE, BYTE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(BYTE, CHAR, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(BYTE, DOUBLE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(BYTE, FLOAT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(BYTE, INT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(BYTE, LONG, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(BYTE, SHORT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(BYTE, BYTE, "times", { a, b -> a.times(b) }), - binaryOperationKey(BYTE, CHAR, "times", { a, b -> a.times(b) }), - binaryOperationKey(BYTE, DOUBLE, "times", { a, b -> a.times(b) }), - binaryOperationKey(BYTE, FLOAT, "times", { a, b -> a.times(b) }), - binaryOperationKey(BYTE, INT, "times", { a, b -> a.times(b) }), - binaryOperationKey(BYTE, LONG, "times", { a, b -> a.times(b) }), - binaryOperationKey(BYTE, SHORT, "times", { a, b -> a.times(b) }), - binaryOperationKey(BYTE, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(CHAR, BYTE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(CHAR, CHAR, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(CHAR, DOUBLE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(CHAR, FLOAT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(CHAR, INT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(CHAR, LONG, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(CHAR, SHORT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(CHAR, BYTE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(CHAR, CHAR, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(CHAR, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(CHAR, FLOAT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(CHAR, INT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(CHAR, LONG, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(CHAR, SHORT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(CHAR, BYTE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(CHAR, DOUBLE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(CHAR, FLOAT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(CHAR, INT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(CHAR, LONG, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(CHAR, SHORT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(CHAR, BYTE, "div", { a, b -> a.div(b) }), - binaryOperationKey(CHAR, DOUBLE, "div", { a, b -> a.div(b) }), - binaryOperationKey(CHAR, FLOAT, "div", { a, b -> a.div(b) }), - binaryOperationKey(CHAR, INT, "div", { a, b -> a.div(b) }), - binaryOperationKey(CHAR, LONG, "div", { a, b -> a.div(b) }), - binaryOperationKey(CHAR, SHORT, "div", { a, b -> a.div(b) }), - binaryOperationKey(CHAR, BYTE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(CHAR, DOUBLE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(CHAR, FLOAT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(CHAR, INT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(CHAR, LONG, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(CHAR, SHORT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(CHAR, BYTE, "times", { a, b -> a.times(b) }), - binaryOperationKey(CHAR, DOUBLE, "times", { a, b -> a.times(b) }), - binaryOperationKey(CHAR, FLOAT, "times", { a, b -> a.times(b) }), - binaryOperationKey(CHAR, INT, "times", { a, b -> a.times(b) }), - binaryOperationKey(CHAR, LONG, "times", { a, b -> a.times(b) }), - binaryOperationKey(CHAR, SHORT, "times", { a, b -> a.times(b) }), - binaryOperationKey(CHAR, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(DOUBLE, BYTE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(DOUBLE, CHAR, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(DOUBLE, DOUBLE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(DOUBLE, FLOAT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(DOUBLE, INT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(DOUBLE, LONG, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(DOUBLE, SHORT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(DOUBLE, BYTE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(DOUBLE, CHAR, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(DOUBLE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(DOUBLE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(DOUBLE, INT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(DOUBLE, LONG, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(DOUBLE, SHORT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(DOUBLE, BYTE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(DOUBLE, CHAR, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(DOUBLE, DOUBLE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(DOUBLE, FLOAT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(DOUBLE, INT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(DOUBLE, LONG, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(DOUBLE, SHORT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(DOUBLE, BYTE, "div", { a, b -> a.div(b) }), - binaryOperationKey(DOUBLE, CHAR, "div", { a, b -> a.div(b) }), - binaryOperationKey(DOUBLE, DOUBLE, "div", { a, b -> a.div(b) }), - binaryOperationKey(DOUBLE, FLOAT, "div", { a, b -> a.div(b) }), - binaryOperationKey(DOUBLE, INT, "div", { a, b -> a.div(b) }), - binaryOperationKey(DOUBLE, LONG, "div", { a, b -> a.div(b) }), - binaryOperationKey(DOUBLE, SHORT, "div", { a, b -> a.div(b) }), - binaryOperationKey(DOUBLE, BYTE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(DOUBLE, DOUBLE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(DOUBLE, FLOAT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(DOUBLE, INT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(DOUBLE, LONG, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(DOUBLE, SHORT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(DOUBLE, BYTE, "times", { a, b -> a.times(b) }), - binaryOperationKey(DOUBLE, CHAR, "times", { a, b -> a.times(b) }), - binaryOperationKey(DOUBLE, DOUBLE, "times", { a, b -> a.times(b) }), - binaryOperationKey(DOUBLE, FLOAT, "times", { a, b -> a.times(b) }), - binaryOperationKey(DOUBLE, INT, "times", { a, b -> a.times(b) }), - binaryOperationKey(DOUBLE, LONG, "times", { a, b -> a.times(b) }), - binaryOperationKey(DOUBLE, SHORT, "times", { a, b -> a.times(b) }), - binaryOperationKey(DOUBLE, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(FLOAT, BYTE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(FLOAT, CHAR, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(FLOAT, DOUBLE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(FLOAT, FLOAT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(FLOAT, INT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(FLOAT, LONG, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(FLOAT, SHORT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(FLOAT, BYTE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(FLOAT, CHAR, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(FLOAT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(FLOAT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(FLOAT, INT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(FLOAT, LONG, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(FLOAT, SHORT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(FLOAT, BYTE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(FLOAT, CHAR, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(FLOAT, DOUBLE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(FLOAT, FLOAT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(FLOAT, INT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(FLOAT, LONG, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(FLOAT, SHORT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(FLOAT, BYTE, "div", { a, b -> a.div(b) }), - binaryOperationKey(FLOAT, CHAR, "div", { a, b -> a.div(b) }), - binaryOperationKey(FLOAT, DOUBLE, "div", { a, b -> a.div(b) }), - binaryOperationKey(FLOAT, FLOAT, "div", { a, b -> a.div(b) }), - binaryOperationKey(FLOAT, INT, "div", { a, b -> a.div(b) }), - binaryOperationKey(FLOAT, LONG, "div", { a, b -> a.div(b) }), - binaryOperationKey(FLOAT, SHORT, "div", { a, b -> a.div(b) }), - binaryOperationKey(FLOAT, BYTE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(FLOAT, CHAR, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(FLOAT, DOUBLE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(FLOAT, FLOAT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(FLOAT, INT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(FLOAT, LONG, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(FLOAT, SHORT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(FLOAT, BYTE, "times", { a, b -> a.times(b) }), - binaryOperationKey(FLOAT, CHAR, "times", { a, b -> a.times(b) }), - binaryOperationKey(FLOAT, DOUBLE, "times", { a, b -> a.times(b) }), - binaryOperationKey(FLOAT, FLOAT, "times", { a, b -> a.times(b) }), - binaryOperationKey(FLOAT, INT, "times", { a, b -> a.times(b) }), - binaryOperationKey(FLOAT, LONG, "times", { a, b -> a.times(b) }), - binaryOperationKey(FLOAT, SHORT, "times", { a, b -> a.times(b) }), - binaryOperationKey(FLOAT, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(INT, BYTE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(INT, CHAR, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(INT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(INT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(INT, INT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(INT, LONG, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(INT, SHORT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(INT, BYTE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(INT, CHAR, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(INT, DOUBLE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(INT, FLOAT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(INT, INT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(INT, LONG, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(INT, SHORT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(INT, INT, "shl", { a, b -> a.shl(b) }), - binaryOperationKey(INT, INT, "ushr", { a, b -> a.ushr(b) }), - binaryOperationKey(INT, BYTE, "div", { a, b -> a.div(b) }), - binaryOperationKey(INT, CHAR, "div", { a, b -> a.div(b) }), - binaryOperationKey(INT, DOUBLE, "div", { a, b -> a.div(b) }), - binaryOperationKey(INT, FLOAT, "div", { a, b -> a.div(b) }), - binaryOperationKey(INT, INT, "div", { a, b -> a.div(b) }), - binaryOperationKey(INT, LONG, "div", { a, b -> a.div(b) }), - binaryOperationKey(INT, SHORT, "div", { a, b -> a.div(b) }), - binaryOperationKey(INT, INT, "shr", { a, b -> a.shr(b) }), - binaryOperationKey(INT, BYTE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(INT, CHAR, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(INT, DOUBLE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(INT, FLOAT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(INT, INT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(INT, LONG, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(INT, SHORT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(INT, BYTE, "times", { a, b -> a.times(b) }), - binaryOperationKey(INT, CHAR, "times", { a, b -> a.times(b) }), - binaryOperationKey(INT, DOUBLE, "times", { a, b -> a.times(b) }), - binaryOperationKey(INT, FLOAT, "times", { a, b -> a.times(b) }), - binaryOperationKey(INT, INT, "times", { a, b -> a.times(b) }), - binaryOperationKey(INT, LONG, "times", { a, b -> a.times(b) }), - binaryOperationKey(INT, SHORT, "times", { a, b -> a.times(b) }), - binaryOperationKey(INT, INT, "or", { a, b -> a.or(b) }), - binaryOperationKey(INT, BYTE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(INT, CHAR, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(INT, DOUBLE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(INT, FLOAT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(INT, INT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(INT, LONG, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(INT, SHORT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(INT, INT, "and", { a, b -> a.and(b) }), - binaryOperationKey(INT, INT, "xor", { a, b -> a.xor(b) }), - binaryOperationKey(INT, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(LONG, BYTE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(LONG, CHAR, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(LONG, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(LONG, FLOAT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(LONG, INT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(LONG, LONG, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(LONG, SHORT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(LONG, BYTE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(LONG, CHAR, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(LONG, DOUBLE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(LONG, FLOAT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(LONG, INT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(LONG, LONG, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(LONG, SHORT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(LONG, INT, "shl", { a, b -> a.shl(b) }), - binaryOperationKey(LONG, INT, "ushr", { a, b -> a.ushr(b) }), - binaryOperationKey(LONG, BYTE, "div", { a, b -> a.div(b) }), - binaryOperationKey(LONG, CHAR, "div", { a, b -> a.div(b) }), - binaryOperationKey(LONG, DOUBLE, "div", { a, b -> a.div(b) }), - binaryOperationKey(LONG, FLOAT, "div", { a, b -> a.div(b) }), - binaryOperationKey(LONG, INT, "div", { a, b -> a.div(b) }), - binaryOperationKey(LONG, LONG, "div", { a, b -> a.div(b) }), - binaryOperationKey(LONG, SHORT, "div", { a, b -> a.div(b) }), - binaryOperationKey(LONG, INT, "shr", { a, b -> a.shr(b) }), - binaryOperationKey(LONG, BYTE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(LONG, CHAR, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(LONG, DOUBLE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(LONG, FLOAT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(LONG, INT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(LONG, LONG, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(LONG, SHORT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(LONG, BYTE, "times", { a, b -> a.times(b) }), - binaryOperationKey(LONG, CHAR, "times", { a, b -> a.times(b) }), - binaryOperationKey(LONG, DOUBLE, "times", { a, b -> a.times(b) }), - binaryOperationKey(LONG, FLOAT, "times", { a, b -> a.times(b) }), - binaryOperationKey(LONG, INT, "times", { a, b -> a.times(b) }), - binaryOperationKey(LONG, LONG, "times", { a, b -> a.times(b) }), - binaryOperationKey(LONG, SHORT, "times", { a, b -> a.times(b) }), - binaryOperationKey(LONG, LONG, "or", { a, b -> a.or(b) }), - binaryOperationKey(LONG, BYTE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(LONG, CHAR, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(LONG, DOUBLE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(LONG, FLOAT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(LONG, INT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(LONG, LONG, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(LONG, SHORT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(LONG, LONG, "and", { a, b -> a.and(b) }), - binaryOperationKey(LONG, LONG, "xor", { a, b -> a.xor(b) }), - binaryOperationKey(LONG, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(SHORT, BYTE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(SHORT, CHAR, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(SHORT, DOUBLE, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(SHORT, FLOAT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(SHORT, INT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(SHORT, LONG, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(SHORT, SHORT, "minus", { a, b -> a.minus(b) }), - binaryOperationKey(SHORT, BYTE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(SHORT, CHAR, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(SHORT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(SHORT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(SHORT, INT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(SHORT, LONG, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(SHORT, SHORT, "compareTo", { a, b -> a.compareTo(b) }), - binaryOperationKey(SHORT, BYTE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(SHORT, CHAR, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(SHORT, DOUBLE, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(SHORT, FLOAT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(SHORT, INT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(SHORT, LONG, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(SHORT, SHORT, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(SHORT, BYTE, "div", { a, b -> a.div(b) }), - binaryOperationKey(SHORT, CHAR, "div", { a, b -> a.div(b) }), - binaryOperationKey(SHORT, DOUBLE, "div", { a, b -> a.div(b) }), - binaryOperationKey(SHORT, FLOAT, "div", { a, b -> a.div(b) }), - binaryOperationKey(SHORT, INT, "div", { a, b -> a.div(b) }), - binaryOperationKey(SHORT, LONG, "div", { a, b -> a.div(b) }), - binaryOperationKey(SHORT, SHORT, "div", { a, b -> a.div(b) }), - binaryOperationKey(SHORT, BYTE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(SHORT, CHAR, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(SHORT, DOUBLE, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(SHORT, FLOAT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(SHORT, INT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(SHORT, LONG, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(SHORT, SHORT, "mod", { a, b -> a.mod(b) }), - binaryOperationKey(SHORT, BYTE, "times", { a, b -> a.times(b) }), - binaryOperationKey(SHORT, CHAR, "times", { a, b -> a.times(b) }), - binaryOperationKey(SHORT, DOUBLE, "times", { a, b -> a.times(b) }), - binaryOperationKey(SHORT, FLOAT, "times", { a, b -> a.times(b) }), - binaryOperationKey(SHORT, INT, "times", { a, b -> a.times(b) }), - binaryOperationKey(SHORT, LONG, "times", { a, b -> a.times(b) }), - binaryOperationKey(SHORT, SHORT, "times", { a, b -> a.times(b) }), - binaryOperationKey(SHORT, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(STRING, ANY, "plus", { a, b -> a.plus(b) }), - binaryOperationKey(STRING, INT, "get", { a, b -> a.get(b) }), - binaryOperationKey(STRING, ANY, "equals", { a, b -> a.equals(b) }), - binaryOperationKey(STRING, STRING, "compareTo", { a, b -> a.compareTo(b) }) +private val binaryOperations: HashMap, Pair, Function2>> + = hashMapOf, Pair, Function2>>( + binaryOperation(BOOLEAN, BOOLEAN, "xor", { a, b -> a.xor(b) }, emptyBinaryFun), + binaryOperation(BOOLEAN, BOOLEAN, "or", { a, b -> a.or(b) }, emptyBinaryFun), + binaryOperation(BOOLEAN, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(BOOLEAN, BOOLEAN, "and", { a, b -> a.and(b) }, emptyBinaryFun), + binaryOperation(BYTE, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(BYTE, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(BYTE, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(BYTE, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(BYTE, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(BYTE, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(BYTE, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(BYTE, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(BYTE, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(BYTE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(BYTE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(BYTE, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(BYTE, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(BYTE, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(BYTE, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), + binaryOperation(BYTE, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(BYTE, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(BYTE, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + 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, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(BYTE, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(BYTE, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(BYTE, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(BYTE, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(BYTE, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(BYTE, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(BYTE, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(BYTE, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(BYTE, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(BYTE, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(BYTE, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(BYTE, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(BYTE, SHORT, "mod", { 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, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(BYTE, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(BYTE, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(BYTE, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(BYTE, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(BYTE, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(BYTE, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(CHAR, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(CHAR, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(CHAR, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(CHAR, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(CHAR, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(CHAR, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(CHAR, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(CHAR, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(CHAR, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(CHAR, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(CHAR, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(CHAR, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(CHAR, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(CHAR, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(CHAR, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(CHAR, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(CHAR, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(CHAR, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(CHAR, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(CHAR, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(CHAR, BYTE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(CHAR, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(CHAR, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(CHAR, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(CHAR, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(CHAR, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(CHAR, BYTE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(CHAR, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(CHAR, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(CHAR, INT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(CHAR, LONG, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(CHAR, SHORT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(CHAR, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(CHAR, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(CHAR, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(CHAR, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(CHAR, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(CHAR, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(CHAR, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + 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, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, BYTE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, INT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, LONG, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, SHORT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, CHAR, "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), + binaryOperation(DOUBLE, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(DOUBLE, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(FLOAT, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(FLOAT, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(FLOAT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(FLOAT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(FLOAT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(FLOAT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(FLOAT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(FLOAT, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(FLOAT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + 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, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(FLOAT, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(FLOAT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(FLOAT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(FLOAT, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(FLOAT, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(FLOAT, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(FLOAT, BYTE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(FLOAT, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(FLOAT, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(FLOAT, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(FLOAT, INT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(FLOAT, LONG, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(FLOAT, SHORT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(FLOAT, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(FLOAT, CHAR, "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), + binaryOperation(FLOAT, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(FLOAT, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(FLOAT, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(FLOAT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(INT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(INT, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(INT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(INT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(INT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(INT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(INT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(INT, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), + binaryOperation(INT, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(INT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(INT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + 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, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun), + binaryOperation(INT, INT, "ushr", { a, b -> a.ushr(b) }, emptyBinaryFun), + binaryOperation(INT, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(INT, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(INT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(INT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(INT, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(INT, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(INT, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(INT, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun), + binaryOperation(INT, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(INT, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(INT, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(INT, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(INT, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(INT, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(INT, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(INT, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(INT, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(INT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(INT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(INT, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(INT, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(INT, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(INT, INT, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }), + binaryOperation(INT, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(INT, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(INT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(INT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(INT, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(INT, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(INT, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(INT, INT, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }), + binaryOperation(INT, INT, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }), + binaryOperation(INT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(LONG, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(LONG, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(LONG, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(LONG, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(LONG, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(LONG, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(LONG, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(LONG, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), + binaryOperation(LONG, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(LONG, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(LONG, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + 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, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun), + binaryOperation(LONG, INT, "ushr", { a, b -> a.ushr(b) }, emptyBinaryFun), + binaryOperation(LONG, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(LONG, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(LONG, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(LONG, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(LONG, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(LONG, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(LONG, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(LONG, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun), + binaryOperation(LONG, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(LONG, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(LONG, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(LONG, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(LONG, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(LONG, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(LONG, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(LONG, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(LONG, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(LONG, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(LONG, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(LONG, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(LONG, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(LONG, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(LONG, LONG, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }), + binaryOperation(LONG, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(LONG, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(LONG, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(LONG, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(LONG, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(LONG, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(LONG, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(LONG, LONG, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }), + binaryOperation(LONG, LONG, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }), + binaryOperation(LONG, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(SHORT, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(SHORT, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(SHORT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(SHORT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), + binaryOperation(SHORT, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(SHORT, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(SHORT, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), + binaryOperation(SHORT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(SHORT, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(SHORT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(SHORT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(SHORT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(SHORT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(SHORT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), + binaryOperation(SHORT, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), + binaryOperation(SHORT, CHAR, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(SHORT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(SHORT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + 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, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(SHORT, CHAR, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(SHORT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(SHORT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), + binaryOperation(SHORT, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(SHORT, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(SHORT, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), + binaryOperation(SHORT, BYTE, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(SHORT, CHAR, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(SHORT, DOUBLE, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(SHORT, FLOAT, "mod", { a, b -> a.mod(b) }, emptyBinaryFun), + binaryOperation(SHORT, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(SHORT, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }), + binaryOperation(SHORT, SHORT, "mod", { 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, CHAR, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(SHORT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(SHORT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), + binaryOperation(SHORT, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(SHORT, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(SHORT, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), + binaryOperation(SHORT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(STRING, ANY, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), + binaryOperation(STRING, INT, "get", { a, b -> a.get(b) }, emptyBinaryFun), + binaryOperation(STRING, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), + binaryOperation(STRING, STRING, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun) ) diff --git a/compiler/testData/diagnostics/tests/evaluate/intOverflow.kt b/compiler/testData/diagnostics/tests/evaluate/intOverflow.kt new file mode 100644 index 00000000000..91ab993a6a8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/evaluate/intOverflow.kt @@ -0,0 +1,21 @@ +val intMaxValue: Int = 0x7fffffff +val intMinValue: Int = 1 shl 31 + +val a3: Int = intMaxValue + 1 - 10 +val a4: Int = intMaxValue + 1 + 10 +val i2: Int = intMaxValue - 1 + 2 +val i3: Int = intMaxValue - intMinValue +val i4: Int = -intMinValue +val i5: Int = intMinValue - 1 +val i6: Int = intMinValue - intMaxValue +val i7: Int = intMinValue + intMaxValue +val i8: Int = -intMaxValue +val i10: Int = intMinValue * -1 +val i11: Int = intMinValue * 2 +val i12: Int = intMaxValue * -2 +val i13: Int = intMaxValue * -1 +val i15: Int = intMinValue / -1 +val l20: Int = 30 * 24 * 60 * 60 * 1000 +val l21: Int = intMinValue - intMinValue +val l22: Int = intMinValue + -intMinValue +val l23: Int = intMaxValue + -intMinValue \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/evaluate/longOverflow.kt b/compiler/testData/diagnostics/tests/evaluate/longOverflow.kt new file mode 100644 index 00000000000..298c37b1b4e --- /dev/null +++ b/compiler/testData/diagnostics/tests/evaluate/longOverflow.kt @@ -0,0 +1,23 @@ +val longMaxValue: Long = 0x7fffffffffffffff +val longMinValue: Long = -longMaxValue - 1 +val intMaxValue: Int = 0x7fffffff +val intMinValue: Int = 1 shl 31 + +val a2: Long = longMinValue - 10 + +val l1: Long = longMaxValue + 1 +val l2: Long = longMaxValue - 1 + 2 +val l3: Long = longMaxValue - longMinValue +val l4: Long = -longMinValue +val l5: Long = longMinValue - 1 +val l6: Long = longMinValue - longMaxValue +val l7: Long = longMinValue + longMaxValue +val l8: Long = -longMaxValue +val l10: Long = -intMinValue.toLong() +val l11: Long = -1 + intMinValue.toLong() +val l12: Long = longMinValue * intMinValue +val l13: Long = longMinValue * -1 +val l14: Long = longMinValue * 2 +val l15: Long = longMaxValue * -2 +val l16: Long = intMinValue.toLong() * -1 +val l19: Long = longMinValue / -1 \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/evaluate/otherOverflow.kt b/compiler/testData/diagnostics/tests/evaluate/otherOverflow.kt new file mode 100644 index 00000000000..3e116614ffa --- /dev/null +++ b/compiler/testData/diagnostics/tests/evaluate/otherOverflow.kt @@ -0,0 +1,2 @@ +val a1: Int = 32000.toShort() * 32000.toShort() * 32000.toShort() +val a2: Int = 128.toByte() * 128.toByte() * 128.toByte() * 128.toByte() * 128.toByte() \ No newline at end of file diff --git a/compiler/testData/evaluate/divideByZero.kt b/compiler/testData/evaluate/divideByZero.kt new file mode 100644 index 00000000000..13808d5c4a3 --- /dev/null +++ b/compiler/testData/evaluate/divideByZero.kt @@ -0,0 +1,16 @@ +package test + +// val prop1: null +val prop1 = 1 / 0 + +// val prop2: null +val prop2 = 1 / 0.0 + +// val prop3: null +val prop3 = 1.0 / 0 + +// val prop4: 10.0.toDouble() +val prop4 = 1 / 0.1 + +// val prop5: null +val prop5 = 1 / 0.toLong() diff --git a/compiler/testData/evaluate/integers.kt b/compiler/testData/evaluate/integers.kt index 6eafc3dce61..b780e6b25a2 100644 --- a/compiler/testData/evaluate/integers.kt +++ b/compiler/testData/evaluate/integers.kt @@ -1,19 +1,19 @@ package test -// _ prop1: 513105426295.toLong() +// val prop1: 513105426295.toLong() val prop1: Int = 0x7777777777 -// _ prop2: 513105426295.toLong() +// val prop2: 513105426295.toLong() val prop2: Long = 0x7777777777 -// _ prop3: 513105426295.toLong() +// val prop3: 513105426295.toLong() val prop3 = 0x7777777777 -// _ prop4: -2147483648.toInt() +// val prop4: -2147483648.toInt() val prop4: Int = Integer.MAX_VALUE + 1 -// _ prop5: -2147483648.toLong() +// val prop5: -2147483648.toLong() val prop5: Long = Integer.MAX_VALUE + 1 -// _ prop6: -2147483648.toInt() +// val prop6: -2147483648.toInt() val prop6 = Integer.MAX_VALUE + 1 diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 9445d48dba8..a430119e283 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -33,7 +33,7 @@ import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve; @InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class}) public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("compiler/testData/diagnostics/tests") - @InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ClassObjects.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inline.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Numbers.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Suppress.class, Tests.ThisAndSuper.class, Tests.Varargs.class, Tests.When.class}) + @InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ClassObjects.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Evaluate.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inline.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Numbers.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Suppress.class, Tests.ThisAndSuper.class, Tests.Varargs.class, Tests.When.class}) public static class Tests extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("Abstract.kt") public void testAbstract() throws Exception { @@ -2728,6 +2728,29 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } } + @TestMetadata("compiler/testData/diagnostics/tests/evaluate") + public static class Evaluate extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInEvaluate() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/evaluate"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("intOverflow.kt") + public void testIntOverflow() throws Exception { + doTest("compiler/testData/diagnostics/tests/evaluate/intOverflow.kt"); + } + + @TestMetadata("longOverflow.kt") + public void testLongOverflow() throws Exception { + doTest("compiler/testData/diagnostics/tests/evaluate/longOverflow.kt"); + } + + @TestMetadata("otherOverflow.kt") + public void testOtherOverflow() throws Exception { + doTest("compiler/testData/diagnostics/tests/evaluate/otherOverflow.kt"); + } + + } + @TestMetadata("compiler/testData/diagnostics/tests/extensions") public static class Extensions extends AbstractDiagnosticsTestWithEagerResolve { public void testAllFilesPresentInExtensions() throws Exception { @@ -6540,6 +6563,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage suite.addTest(DelegatedProperty.innerSuite()); suite.addTestSuite(Deparenthesize.class); suite.addTest(Enum.innerSuite()); + suite.addTestSuite(Evaluate.class); suite.addTestSuite(Extensions.class); suite.addTest(FunctionLiterals.innerSuite()); suite.addTest(Generics.innerSuite()); diff --git a/compiler/tests/org/jetbrains/jet/evaluate/EvaluateExpressionTestGenerated.java b/compiler/tests/org/jetbrains/jet/evaluate/EvaluateExpressionTestGenerated.java index 44f36e25419..f03ad66cd54 100644 --- a/compiler/tests/org/jetbrains/jet/evaluate/EvaluateExpressionTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/evaluate/EvaluateExpressionTestGenerated.java @@ -36,6 +36,11 @@ public class EvaluateExpressionTestGenerated extends AbstractEvaluateExpressionT JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/evaluate"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("divideByZero.kt") + public void testDivideByZero() throws Exception { + doTest("compiler/testData/evaluate/divideByZero.kt"); + } + @TestMetadata("floatsAndDoubles.kt") public void testFloatsAndDoubles() throws Exception { doTest("compiler/testData/evaluate/floatsAndDoubles.kt"); diff --git a/generators/src/org/jetbrains/jet/generators/evaluate/GenerateOperationsMap.kt b/generators/src/org/jetbrains/jet/generators/evaluate/GenerateOperationsMap.kt index 8d19ea73d80..0e63b33fb71 100644 --- a/generators/src/org/jetbrains/jet/generators/evaluate/GenerateOperationsMap.kt +++ b/generators/src/org/jetbrains/jet/generators/evaluate/GenerateOperationsMap.kt @@ -40,11 +40,14 @@ fun generate(): String { p.println(FileUtil.loadFile(File("injector-generator/copyright.txt"))) p.println("package org.jetbrains.jet.lang.evaluate") p.println() + p.println("import java.math.BigInteger") + p.println("import java.util.HashMap") + p.println() p.println("/** This file is generated by org.jetbrains.jet.generators.evaluate:generate(). DO NOT MODIFY MANUALLY */") p.println() - val unaryOperationsMap = arrayListOf>>() - val binaryOperationsMap = arrayListOf>>() + val unaryOperationsMap = arrayListOf>>() + val binaryOperationsMap = arrayListOf>>() val builtIns = KotlinBuiltIns.getInstance() [suppress("UNCHECKED_CAST")] @@ -67,18 +70,24 @@ fun generate(): String { } } - p.println("private val unaryOperations = hashMapOf, (Any?) -> Any>(") + p.println("private val emptyBinaryFun: Function2 = { a, b -> BigInteger(\"0\") }") + p.println("private val emptyUnaryFun: Function1 = { a -> 1.toLong() }") + p.println() + p.println("private val unaryOperations: HashMap, Pair, Function1>>") + p.println(" = hashMapOf, Pair, Function1>>(") p.pushIndent() val unaryOperationsMapIterator = unaryOperationsMap.iterator() while (unaryOperationsMapIterator.hasNext()) { val (funcName, parameters) = unaryOperationsMapIterator.next() p.print( - "unaryOperationKey(", - parameters.makeString(", "), + "unaryOperation(", + parameters.map { it.asSrting() }.makeString(", "), ", ", "\"$funcName\"", - ", { a -> a.${funcName}() })" + ", { a -> a.${funcName}() }, ", + renderCheckUnaryOperation(funcName, parameters), + ")" ) if (unaryOperationsMapIterator.hasNext()) { p.printWithNoIndent(", ") @@ -90,19 +99,21 @@ fun generate(): String { p.println() - - p.println("private val binaryOperations = hashMapOf, (Any?, Any?) -> Any>(") + p.println("private val binaryOperations: HashMap, Pair, Function2>>") + p.println(" = hashMapOf, Pair, Function2>>(") p.pushIndent() val binaryOperationsMapIterator = binaryOperationsMap.iterator() while (binaryOperationsMapIterator.hasNext()) { val (funcName, parameters) = binaryOperationsMapIterator.next() p.print( - "binaryOperationKey(", - parameters.makeString(", "), + "binaryOperation(", + parameters.map { it.asSrting() }.makeString(", "), ", ", "\"$funcName\"", - ", { a, b -> a.${funcName}(b) })" + ", { a, b -> a.${funcName}(b) }, ", + renderCheckBinaryOperation(funcName, parameters), + ")" ) if (binaryOperationsMapIterator.hasNext()) { p.printWithNoIndent(", ") @@ -115,12 +126,52 @@ fun generate(): String { return sb.toString() } -private fun FunctionDescriptor.getParametersTypes(): List { - val list = arrayListOf(getExpectedThisObject()!!.getType().asSrting().toUpperCase()) +fun renderCheckUnaryOperation(name: String, params: List): String { + val isAllParamsIntegers = params.fold(true) { a, b -> a && b.isIntegerType() } + if (!isAllParamsIntegers) { + return "emptyUnaryFun" + } + + return when(name) { + "minus" -> "{ a -> a.$name() }" + else -> "emptyUnaryFun" + } +} + +fun renderCheckBinaryOperation(name: String, params: List): String { + val isAllParamsIntegers = params.fold(true) { a, b -> a && b.isIntegerType() } + if (!isAllParamsIntegers) { + return "emptyBinaryFun" + } + + return when(name) { + "plus" -> "{ a, b -> a.add(b) }" + "minus" -> "{ a, b -> a.subtract(b) }" + "div" -> "{ a, b -> a.divide(b) }" + "times" -> "{ a, b -> a.multiply(b) }" + "mod", + "xor", + "or", + "and" -> "{ a, b -> a.$name(b) }" + else -> "emptyBinaryFun" + } +} + +private fun JetType.isIntegerType(): Boolean { + val builtIns = KotlinBuiltIns.getInstance() + return this == builtIns.getIntType() || + this == builtIns.getShortType() || + this == builtIns.getByteType() || + this == builtIns.getLongType() +} + + +private fun FunctionDescriptor.getParametersTypes(): List { + val list = arrayListOf(getExpectedThisObject()!!.getType()) getValueParameters().map { it.getType() }.forEach { - list.add(TypeUtils.makeNotNullable(it).asSrting().toUpperCase()) + list.add(TypeUtils.makeNotNullable(it)) } return list } -private fun JetType.asSrting(): String = getConstructor().getDeclarationDescriptor()!!.getName().asString() +private fun JetType.asSrting(): String = getConstructor().getDeclarationDescriptor()!!.getName().asString().toUpperCase()