Warning for integer overflow

This commit is contained in:
Natalia Ukhorskaya
2013-11-27 10:42:36 +04:00
parent b4b7988eec
commit 9c176ddaa8
12 changed files with 630 additions and 419 deletions
@@ -465,6 +465,7 @@ public interface Errors {
// Compile-time values
DiagnosticFactory0<JetExpression> INTEGER_OVERFLOW = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<JetConstantExpression> INT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetConstantExpression> FLOAT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<JetConstantExpression, String, JetType> CONSTANT_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR);
@@ -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");
@@ -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<CompileTimeConstant<*>, 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<JetExpression>()) ?: 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<JetExpression>()) ?: 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<String>()
private val ANY = CompileTimeType<Any>()
[suppress("UNCHECKED_CAST")]
private fun <A, B> binaryOperationKey(
private fun <A, B> binaryOperation(
a: CompileTimeType<A>,
b: CompileTimeType<B>,
functionName: String,
f: (A, B) -> Any
) = BinaryOperationKey(a, b, functionName) to f as Function2<Any?, Any?, Any>
operation: Function2<A, B, Any>,
checker: Function2<BigInteger, BigInteger, BigInteger>
) = BinaryOperationKey(a, b, functionName) to Pair(operation, checker) as Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>
[suppress("UNCHECKED_CAST")]
private fun <A> unaryOperationKey(
private fun <A> unaryOperation(
a: CompileTimeType<A>,
functionName: String,
f: (A) -> Any
) = UnaryOperationKey(a, functionName) to f as Function1<Any?, Any>
operation: Function1<A, Any>,
checker: Function1<Long, Long>
) = UnaryOperationKey(a, functionName) to Pair(operation, checker) as Pair<Function1<Any?, Any>, Function1<Long, Long>>
private data class BinaryOperationKey<A, B>(val f: CompileTimeType<out A>, val s: CompileTimeType<out B>, val functionName: String)
private data class UnaryOperationKey<A>(val f: CompileTimeType<out A>, val functionName: String)
@@ -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<UnaryOperationKey<*>, (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<BigInteger, BigInteger, BigInteger> = { a, b -> BigInteger("0") }
private val emptyUnaryFun: Function1<Long, Long> = { a -> 1.toLong() }
private val unaryOperations: HashMap<UnaryOperationKey<*>, Pair<Function1<Any?, Any>, Function1<Long, Long>>>
= hashMapOf<UnaryOperationKey<*>, Pair<Function1<Any?, Any>, Function1<Long, Long>>>(
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<BinaryOperationKey<*, *>, (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<BinaryOperationKey<*, *>, Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>>
= hashMapOf<BinaryOperationKey<*, *>, Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>>(
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)
)
@@ -0,0 +1,21 @@
val intMaxValue: Int = 0x7fffffff
val intMinValue: Int = 1 shl 31
val a3: Int = <!INTEGER_OVERFLOW!><!INTEGER_OVERFLOW!>intMaxValue + 1<!> - 10<!>
val a4: Int = <!INTEGER_OVERFLOW!>intMaxValue + 1<!> + 10
val i2: Int = <!INTEGER_OVERFLOW!>intMaxValue - 1 + 2<!>
val i3: Int = <!INTEGER_OVERFLOW!>intMaxValue - intMinValue<!>
val i4: Int = <!INTEGER_OVERFLOW!>-intMinValue<!>
val i5: Int = <!INTEGER_OVERFLOW!>intMinValue - 1<!>
val i6: Int = <!INTEGER_OVERFLOW!>intMinValue - intMaxValue<!>
val i7: Int = intMinValue + intMaxValue
val i8: Int = -intMaxValue
val i10: Int = <!INTEGER_OVERFLOW!>intMinValue * -1<!>
val i11: Int = <!INTEGER_OVERFLOW!>intMinValue * 2<!>
val i12: Int = <!INTEGER_OVERFLOW!>intMaxValue * -2<!>
val i13: Int = intMaxValue * -1
val i15: Int = <!INTEGER_OVERFLOW!>intMinValue / -1<!>
val l20: Int = <!INTEGER_OVERFLOW!>30 * 24 * 60 * 60 * 1000<!>
val l21: Int = intMinValue - intMinValue
val l22: Int = <!INTEGER_OVERFLOW!>intMinValue + <!INTEGER_OVERFLOW!>-intMinValue<!><!>
val l23: Int = intMaxValue + <!INTEGER_OVERFLOW!>-intMinValue<!>
@@ -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 = <!INTEGER_OVERFLOW!>longMinValue - 10<!>
val l1: Long = <!INTEGER_OVERFLOW!>longMaxValue + 1<!>
val l2: Long = <!INTEGER_OVERFLOW!>longMaxValue - 1 + 2<!>
val l3: Long = <!INTEGER_OVERFLOW!>longMaxValue - longMinValue<!>
val l4: Long = <!INTEGER_OVERFLOW!>-longMinValue<!>
val l5: Long = <!INTEGER_OVERFLOW!>longMinValue - 1<!>
val l6: Long = <!INTEGER_OVERFLOW!>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 = <!INTEGER_OVERFLOW!>longMinValue * intMinValue<!>
val l13: Long = <!INTEGER_OVERFLOW!>longMinValue * -1<!>
val l14: Long = <!INTEGER_OVERFLOW!>longMinValue * 2<!>
val l15: Long = <!INTEGER_OVERFLOW!>longMaxValue * -2<!>
val l16: Long = intMinValue.toLong() * -1
val l19: Long = <!INTEGER_OVERFLOW!>longMinValue / -1<!>
@@ -0,0 +1,2 @@
val a1: Int = <!INTEGER_OVERFLOW!>32000.toShort() * 32000.toShort() * 32000.toShort()<!>
val a2: Int = <!INTEGER_OVERFLOW!>128.toByte() * 128.toByte() * 128.toByte() * 128.toByte() * 128.toByte()<!>
@@ -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()
+6 -6
View File
@@ -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
@@ -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());
@@ -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");
@@ -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<Pair<String, List<String>>>()
val binaryOperationsMap = arrayListOf<Pair<String, List<String>>>()
val unaryOperationsMap = arrayListOf<Pair<String, List<JetType>>>()
val binaryOperationsMap = arrayListOf<Pair<String, List<JetType>>>()
val builtIns = KotlinBuiltIns.getInstance()
[suppress("UNCHECKED_CAST")]
@@ -67,18 +70,24 @@ fun generate(): String {
}
}
p.println("private val unaryOperations = hashMapOf<UnaryOperationKey<*>, (Any?) -> Any>(")
p.println("private val emptyBinaryFun: Function2<BigInteger, BigInteger, BigInteger> = { a, b -> BigInteger(\"0\") }")
p.println("private val emptyUnaryFun: Function1<Long, Long> = { a -> 1.toLong() }")
p.println()
p.println("private val unaryOperations: HashMap<UnaryOperationKey<*>, Pair<Function1<Any?, Any>, Function1<Long, Long>>>")
p.println(" = hashMapOf<UnaryOperationKey<*>, Pair<Function1<Any?, Any>, Function1<Long, Long>>>(")
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<BinaryOperationKey<*, *>, (Any?, Any?) -> Any>(")
p.println("private val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>>")
p.println(" = hashMapOf<BinaryOperationKey<*, *>, Pair<Function2<Any?, Any?, Any>, Function2<BigInteger, BigInteger, BigInteger>>>(")
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<String> {
val list = arrayListOf(getExpectedThisObject()!!.getType().asSrting().toUpperCase())
fun renderCheckUnaryOperation(name: String, params: List<JetType>): 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<JetType>): 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<JetType> {
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()