public void visitBinaryMath()

in modules/lang-painless/src/main/java/org/opensearch/painless/phase/DefaultConstantFoldingOptimizationPhase.java [279:617]


    public void visitBinaryMath(BinaryMathNode irBinaryMathNode, Consumer<ExpressionNode> scope) {
        irBinaryMathNode.getLeftNode().visit(this, irBinaryMathNode::setLeftNode);
        irBinaryMathNode.getRightNode().visit(this, irBinaryMathNode::setRightNode);

        if (irBinaryMathNode.getLeftNode() instanceof ConstantNode && irBinaryMathNode.getRightNode() instanceof ConstantNode) {
            ConstantNode irLeftConstantNode = (ConstantNode) irBinaryMathNode.getLeftNode();
            ConstantNode irRightConstantNode = (ConstantNode) irBinaryMathNode.getRightNode();
            Operation operation = irBinaryMathNode.getOperation();
            Class<?> type = irBinaryMathNode.getExpressionType();

            if (operation == Operation.MUL) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() * (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() * (long) irRightConstantNode.getConstant());
                } else if (type == float.class) {
                    irLeftConstantNode.setConstant((float) irLeftConstantNode.getConstant() * (float) irRightConstantNode.getConstant());
                } else if (type == double.class) {
                    irLeftConstantNode.setConstant((double) irLeftConstantNode.getConstant() * (double) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.DIV) {
                try {
                    if (type == int.class) {
                        irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() / (int) irRightConstantNode.getConstant());
                    } else if (type == long.class) {
                        irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() / (long) irRightConstantNode.getConstant());
                    } else if (type == float.class) {
                        irLeftConstantNode.setConstant(
                            (float) irLeftConstantNode.getConstant() / (float) irRightConstantNode.getConstant()
                        );
                    } else if (type == double.class) {
                        irLeftConstantNode.setConstant(
                            (double) irLeftConstantNode.getConstant() / (double) irRightConstantNode.getConstant()
                        );
                    } else {
                        throw irBinaryMathNode.getLocation()
                            .createError(
                                new IllegalStateException(
                                    "constant folding error: "
                                        + "unexpected type ["
                                        + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                        + "] for "
                                        + "binary operation ["
                                        + operation.symbol
                                        + "] on "
                                        + "constants ["
                                        + irLeftConstantNode.getConstant()
                                        + "] and ["
                                        + irRightConstantNode.getConstant()
                                        + "]"
                                )
                            );
                    }
                } catch (ArithmeticException ae) {
                    throw irBinaryMathNode.getLocation().createError(ae);
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.REM) {
                try {
                    if (type == int.class) {
                        irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() % (int) irRightConstantNode.getConstant());
                    } else if (type == long.class) {
                        irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() % (long) irRightConstantNode.getConstant());
                    } else if (type == float.class) {
                        irLeftConstantNode.setConstant(
                            (float) irLeftConstantNode.getConstant() % (float) irRightConstantNode.getConstant()
                        );
                    } else if (type == double.class) {
                        irLeftConstantNode.setConstant(
                            (double) irLeftConstantNode.getConstant() % (double) irRightConstantNode.getConstant()
                        );
                    } else {
                        throw irBinaryMathNode.getLocation()
                            .createError(
                                new IllegalStateException(
                                    "constant folding error: "
                                        + "unexpected type ["
                                        + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                        + "] for "
                                        + "binary operation ["
                                        + operation.symbol
                                        + "] on "
                                        + "constants ["
                                        + irLeftConstantNode.getConstant()
                                        + "] and ["
                                        + irRightConstantNode.getConstant()
                                        + "]"
                                )
                            );
                    }
                } catch (ArithmeticException ae) {
                    throw irBinaryMathNode.getLocation().createError(ae);
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.ADD) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() + (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() + (long) irRightConstantNode.getConstant());
                } else if (type == float.class) {
                    irLeftConstantNode.setConstant((float) irLeftConstantNode.getConstant() + (float) irRightConstantNode.getConstant());
                } else if (type == double.class) {
                    irLeftConstantNode.setConstant((double) irLeftConstantNode.getConstant() + (double) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.SUB) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() - (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() - (long) irRightConstantNode.getConstant());
                } else if (type == float.class) {
                    irLeftConstantNode.setConstant((float) irLeftConstantNode.getConstant() - (float) irRightConstantNode.getConstant());
                } else if (type == double.class) {
                    irLeftConstantNode.setConstant((double) irLeftConstantNode.getConstant() - (double) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.LSH) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() << (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() << (int) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.RSH) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() >> (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() >> (int) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.USH) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() >>> (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() >>> (int) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.BWAND) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() & (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() & (long) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.XOR) {
                if (type == boolean.class) {
                    irLeftConstantNode.setConstant(
                        (boolean) irLeftConstantNode.getConstant() ^ (boolean) irRightConstantNode.getConstant()
                    );
                } else if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() ^ (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() ^ (long) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.BWOR) {
                if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() | (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() | (long) irRightConstantNode.getConstant());
                } else {
                    throw irBinaryMathNode.getLocation()
                        .createError(
                            new IllegalStateException(
                                "constant folding error: "
                                    + "unexpected type ["
                                    + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                    + "] for "
                                    + "binary operation ["
                                    + operation.symbol
                                    + "] on "
                                    + "constants ["
                                    + irLeftConstantNode.getConstant()
                                    + "] and ["
                                    + irRightConstantNode.getConstant()
                                    + "]"
                            )
                        );
                }

                scope.accept(irLeftConstantNode);
            }
        }
    }