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