in src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java [4781:4838]
private static ClassNode getMathResultType(final int op, final ClassNode leftRedirect, final ClassNode rightRedirect, final String operationName) {
if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) {
if (isOperationInGroup(op)) {
if (isIntCategory(leftRedirect) && isIntCategory(rightRedirect)) return int_TYPE;
if (isLongCategory(leftRedirect) && isLongCategory(rightRedirect)) return long_TYPE;
if (isFloat(leftRedirect) && isFloat(rightRedirect)) return float_TYPE;
if (isDouble(leftRedirect) && isDouble(rightRedirect)) return double_TYPE;
} else if (isPowerOperator(op)) {
return Number_TYPE;
} else if (isBitOperator(op) || op == INTDIV || op == INTDIV_EQUAL) {
if (isIntCategory(getUnwrapper(leftRedirect)) && isIntCategory(getUnwrapper(rightRedirect)))
return int_TYPE;
if (isLongCategory(getUnwrapper(leftRedirect)) && isLongCategory(getUnwrapper(rightRedirect)))
return long_TYPE;
if (isBigIntCategory(getUnwrapper(leftRedirect)) && isBigIntCategory(getUnwrapper(rightRedirect)))
return BigInteger_TYPE;
} else if (isCompareToBoolean(op) || op == COMPARE_EQUAL || op == COMPARE_NOT_EQUAL) {
return boolean_TYPE;
}
} else if (isPrimitiveChar(leftRedirect) && isPrimitiveChar(rightRedirect)) {
if (isCompareToBoolean(op) || op == COMPARE_EQUAL || op == COMPARE_NOT_EQUAL) {
return boolean_TYPE;
}
}
if (isShiftOperation(operationName) && isNumberCategory(leftRedirect) && isLongCategory(getUnwrapper(rightRedirect))) {
return leftRedirect;
}
if (isNumberCategory(getWrapper(leftRedirect)) && isNumberCategory(getWrapper(rightRedirect))) {
switch (op) {
case DIVIDE:
case DIVIDE_EQUAL:
// divisions may produce different results depending on operand types
if (isFloatingCategory(leftRedirect) || isFloatingCategory(rightRedirect)) {
if (!isPrimitiveType(leftRedirect) || !isPrimitiveType(rightRedirect)) {
return Double_TYPE;
}
return double_TYPE;
}
if (DIVIDE == op) {
return BigDecimal_TYPE;
}
// falls through
case MOD:
case MOD_EQUAL:
case REMAINDER:
case REMAINDER_EQUAL:
return leftRedirect;
}
if (isOperationInGroup(op)) {
return getGroupOperationResultType(leftRedirect, rightRedirect);
}
}
return null;
}