public void visitBinaryExpression()

in src/main/java/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java [676:763]


        public void visitBinaryExpression(final BinaryExpression expression) {
            if (expression.getNodeMetaData(StatementMeta.class) != null) return;
            super.visitBinaryExpression(expression);

            ClassNode leftType = typeChooser.resolveType(expression.getLeftExpression(), node);
            ClassNode rightType = typeChooser.resolveType(expression.getRightExpression(), node);
            ClassNode resultType = null;
            int operation = expression.getOperation().getType();

            if (operation == Types.LEFT_SQUARE_BRACKET && leftType.isArray()) {
                opt.chainShouldOptimize(true);
                resultType = leftType.getComponentType();
            } else {
                switch (operation) {
                    case Types.COMPARE_EQUAL:
                    case Types.COMPARE_LESS_THAN:
                    case Types.COMPARE_LESS_THAN_EQUAL:
                    case Types.COMPARE_GREATER_THAN:
                    case Types.COMPARE_GREATER_THAN_EQUAL:
                    case Types.COMPARE_NOT_EQUAL:
                        if (isIntCategory(leftType) && isIntCategory(rightType)) {
                            opt.chainShouldOptimize(true);
                        } else if (isLongCategory(leftType) && isLongCategory(rightType)) {
                            opt.chainShouldOptimize(true);
                        } else if (isDoubleCategory(leftType) && isDoubleCategory(rightType)) {
                            opt.chainShouldOptimize(true);
                        } else {
                            opt.chainCanOptimize(true);
                        }
                        resultType = boolean_TYPE;
                        break;
                    case Types.LOGICAL_AND:
                    case Types.LOGICAL_AND_EQUAL:
                    case Types.LOGICAL_OR:
                    case Types.LOGICAL_OR_EQUAL:
                        if (isPrimitiveBoolean(leftType) && isPrimitiveBoolean(rightType)) {
                            opt.chainShouldOptimize(true);
                        } else {
                            opt.chainCanOptimize(true);
                        }
                        expression.setType(boolean_TYPE);
                        resultType = boolean_TYPE;
                        break;
                    case Types.DIVIDE:
                    case Types.DIVIDE_EQUAL:
                        if (isLongCategory(leftType) && isLongCategory(rightType)) {
                            resultType = BigDecimal_TYPE;
                            opt.chainShouldOptimize(true);
                        } else if (isBigDecCategory(leftType) && isBigDecCategory(rightType)) {
                            // no optimization for BigDecimal yet
                            //resultType = BigDecimal_TYPE;
                        } else if (isDoubleCategory(leftType) && isDoubleCategory(rightType)) {
                            resultType = double_TYPE;
                            opt.chainShouldOptimize(true);
                        }
                        break;
                    case Types.POWER:
                    case Types.POWER_EQUAL:
                        // TODO: implement
                        break;
                    case Types.ASSIGN:
                        resultType = optimizeDivWithIntOrLongTarget(expression.getRightExpression(), leftType);
                        opt.chainCanOptimize(true);
                        break;
                    default:
                        if (isIntCategory(leftType) && isIntCategory(rightType)) {
                            resultType = int_TYPE;
                            opt.chainShouldOptimize(true);
                        } else if (isLongCategory(leftType) && isLongCategory(rightType)) {
                            resultType = long_TYPE;
                            opt.chainShouldOptimize(true);
                        } else if (isBigDecCategory(leftType) && isBigDecCategory(rightType)) {
                            // no optimization for BigDecimal yet
                            //resultType = BigDecimal_TYPE;
                        } else if (isDoubleCategory(leftType) && isDoubleCategory(rightType)) {
                            resultType = double_TYPE;
                            opt.chainShouldOptimize(true);
                        }
                }
            }

            if (resultType != null) {
                addMeta(expression).type = resultType;
                opt.chainInvolvedType(resultType);
                opt.chainInvolvedType(rightType);
                opt.chainInvolvedType(leftType);
            }
        }