private static ClassNode getMathResultType()

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;
    }